hamlib-4.6.5/0000775000175000017500000000000015056640502006530 5hamlib-4.6.5/README.md0000664000175000017500000001521515056640442007736 Hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) (C) Stephane Fillod 2000-2011 (C) The Hamlib Group 2000-2022 The purpose of this project is to provide stable, flexible, shared libraries that enable quicker development of Amateur Radio Equipment Control Applications. The master repository is https://github.com/Hamlib/Hamlib Daily snapshots are available at https://n0nb.users.sourceforge.net/ Development happens on the github master (often by merging feature branches) and each release has a release branch. Many Amateur Radio Transceivers come with serial interfaces that allows software to control the radio. This project will endeavour to provide shared libraries that greatly simplify the application programmer's interaction with radio equipment and other controllable devices such as rotators, switches, etc. Supported Radios ---------------- The Hamlib Wiki page, Supported Radios, contains a snapshot of the supported radios at the time of the last Hamlib release. Go to http://www.hamlib.org to reach the Wiki. Hamlib Design ------------- The library provides functions for radio, rotator and amplifier control, and data retrieval for supported devices. A number of functions useful for calculating distance and bearing and grid square conversion are included. libhamlib.so - library that provides generic API for all RIG types. This is what Application programmers will "see". Will have different names on other platforms, e.g. libhamlib-2.dll on MS windows. Also contains all radio, rotator and amplifier "backends" (formerly in their own dlopen'ed libraries) provided by Hamlib. Backend Examples are: --------------------- 1. yaesu will provide connectivity to Yaesu FT 747GX Transceiver, FT 847 "Earth Station", etc. via a standard API. 2. xxxx. will provide connectivity to the Wiz-bang moon-melter 101A (yikes..) Hamlib will also enable developers to develop professional looking GUI's towards a standard control library API, and they would not have to worry about the underlying connection towards physical hardware. Initially serial (RS232) connectivity will be handled, but we expect that IP (and other) connectivity will follow afterwards. Connection via a USB port is accomplished via the Linux kernel support. USB to serial converters are well supported. Other such devices may be supported as long as they present a serial (RS-232) interface to Hamlib. Availability ------------ Most distributions have the latest Hamlib release in their testing or alpha versions of their distribution. Check your package manager for the Hamlib version included in your distribution. Developing with Hamlib API -------------------------- API documentation is at: https://github.com/Hamlib/Hamlib/wiki/Documentation Take a look at tests/README for more info on simple programming examples and test programs. C++ programming is supported and language bindings are available for Perl, Python, and TCL. A network daemon utility is also available for any programming language that supports network sockets (even netcat!). Recompiling ----------- Hamlib is entirely developed using GNU tools, under various Linux systems. The library may be recompiled by the familiar "three step": Note: if ./configure does not exist run ./bootstrap first ./configure make sudo make install For debugging use this configure ./configure CFLAGS=-g -O0 -fPIC --no-create --no-recursio See the INSTALL file for more information. Contributing ------------ Consult the README.betatester and README.developer files in this directory if you feel like testing or helping with Hamlib development. Contributions of rig specifications and protocol documentation are highly encouraged. Do keep in mind that in some cases the manufacturer may not provide complete control information or it is only available under a Non-Disclosure Agreement (NDA). Any documentation *must* be publicly available so we can legally write and distribute Free Software supporting a given device. The Hamlib team is very interested to hear from you, how Hamlib builds and works on your system, especially on non-Linux system or non-PC systems. We try to make Hamlib as portable as possible. Please report in case of problems at hamlib-developer@lists.sourceforge.net Git email formatted patches or in unified diff format are welcome! Also, take a look at http://sourceforge.net/projects/hamlib/ Here you will find a mail list, link to the Wiki, and the latest releases. Feedback, questions, etc. about Hamlib are very welcome at the mail list: Hamlib Version Numbers ---------------------- Like other software projects, Hamlib uses a version numbering scheme to help program authors and users understand which releases are compatible and which are not. Hamlib releases now follow the format of: Major.minor.incremental Where Major: Currently at 4, but can be advanced when changes to the API require client programs to be rewritten to take advantage of new features of Hamlib. This number has advanced a couple of times throughout the life of Hamlib. Advancement of the major number is only for frontend API changes that require modification of client source. ABI compatibility is presently maintained to prior releases so that a program linked to an earlier 1.2.Y.[Z] release will work with a later 3.Y[.Z] release without recompiling. It is our intention to maintain such ABI compatibility as long as practical. Minor: This number advances when either new backend(s) or new rig model(s) to existing backend(s) are added. Advancing this number informs client program authors (and users of those programs) that new model/backend support has been added. Will also include bug fixes since the last Incremental release. Incremental: May be undefined (e.g. Hamlib 3.0) and would advance to 1 (e.g. Hamlib 3.0.1) for any bug fixes or feature additions to existing model(s) or backend(s), then to 2, etc. New rig models or backends are not included in Incremental. When Release is advanced, Incremental will reset to undefined and will not be included as part of the version number. Release schedule ---------------- Hamlib has in the past maintained a "ready when it's ready" philosophy. However, given that much of the Linux user base is now influenced by the Ubuntu distribution and its timed six month release schedule, Hamlib releases will be scheduled in advance of Ubuntu releases. Planned release dates for Hamlib are now 1 February and 1 August of each calendar year. Between those dates various Incremental releases will occur as development warrants. Have Fun / Frank S / Stephane F / The Hamlib Group 73's de vk3fcs/km5ws / f8cfe hamlib-4.6.5/AUTHORS0000664000175000017500000001635415056640442007534 This file is licensed to you under the license specified in the included file `COPYING'. Look there for further details. Authors of the Hamlib API, original code: Frank Singleton and Stephane Fillod Contributors: (if any is missing, please email the current maintainer). For any reason, if you prefer not to appear in this list, please let me know. M: Current maintainer C: Contributors W: Web-page with status/info S: Status, one of the following: Supported: Someone is actually bothered to look after this. Maintained: Someone actually looks after it. Odd Fixes: It has a maintainer but they don't have time to do much other than throw the odd patch in. See below.. Orphan: No current maintainer [but maybe you could take the role as you write your new code]. Obsolete: Old code. Something tagged obsolete generally means it has been replaced by a better system and you should be using that. Backends: [adat: ADT-200A] M: Frank Goenninger DG1SBG [alinco: DX77-T] M: Ben Coleman NJ8J [aor] C: testing by John Ronan [aor: AR-7030] M: Friedrich Melchert DC9RP [aor: AR-7030 Plus] M: Larry Gadallah VE6VQ [aor: AR-3030] M: Tristan Mills [aor: AR-8200] M: Rob Walker [drake] M: Mark J. Fine [icom: ic7000] M: Kent Hill, AD7AI [icom: ic7200] M: James Watson, HZ1JW [icom: ic718] M: Chuck Gilkes, WD0FCL/4 [icom: icr7000] M: Chuck Hemker, N2POR [icom: ic735] C: Darren Hatcher, G0WCW [icom: ic751] C: Lars E. Pettersson, SM6RPZ [icom: icr75] M: Mark J. Fine [icom: OptoScan] M: Michael Smith, KE4RJQ [icom] M: Stephane Fillod, F8CFE [jrc] M: Mark J. Fine C: Manual and testing by Bob Parnass, AJ9S [kenwood] M: Joop Stakenborg, PG4I C: Alessandro Zummo, IZ1PRB [kenwood: K2] M: Nate Bargmann, N0NB M: Brian Mury, VE7NGR C: Leigh Klotz, WA5ZNU [kenwood: K3] M: Nate Bargmann, N0NB C: Alexander Sack [kenwood: TS-480SAT] M: Juergen Rinas, DC3BW [kenwood: TS-570] M: Rob Frohne, KL7NA C: Thomas Beierlein, DL1JBE [kenwood: R-5000] M: Mark J. Fine [kenwood: tmd700] M: Charles Suprin, AA1VS [kenwood: thg71,tmv7,tmd700] C: Thierry Leconte, F4DWV [kenwood: thg71,tmv7] M: Andrew McNamara [kenwood: thd7] M: Stephane Fillod, F8CFE [kenwood: ts-850] C: Rob Frohne, KL7NA [kit: Si570 AVR-USB] C: Fabrice, F4AVI [kit: Elektor SDR] C: John Nogatch, AC6SL [pcr: pcr100,pcr1000] M: Alessandro Zummo, IZ1PRB C: Darren Hatcher, G0WCW [tentec] M: C: testing by James Chance, N3TKD [tentec: tt516] M: James Nykiel [tentec: tt538] M: Mike Markowski AB3AP [tentec: tt550] M: Ken Koster, N7IPB [tentec: tt565] M: Martin Ewing AA6E [tentec: Argonaut V] C: Dave Freese, W1HKJ [tentec: tt585] C: Bert, KG4BEC [tentec: rx331] M: Berndt Josef Wulf, VK5ABN [uniden: 245xlt] M: Eric Cottrell WB1HBU [winradio] M: C: Pascal Brisset [yeasu: ft1000d] M: Serge Pashenkov [yeasu: ft100] M: Alex V Flinsch, KC2IVL [yaesu: ft736] C: Ron Patterson, W6FM [yaesu: ft747] M: C: Chris Bryant, G3WIE C: Frank Singleton, VK3FCS [yaesu: ft767gx] M: Steve Conklin, AI4QR [yaesu: ft817] M: Chris Karpinsky, AA1VL [yaesu: ft847] M: Jim Jerzycke, KQ6EA C: Frank Singleton, VK3FCS [yaesu: ft920, ft890, ft900] M: Nate Bargmann, N0NB [yaesu: ft980] M: Wolfgang Buesser, DK1BW [yaesu: ft990] M: Berndt Josef Wulf, VK5ABN [yaesu: ft950,newcat] M: Terry Embry, KJ4EED [yaesu: VR-5000] M: Jacob Heder [yaesu: FT-600] C: Kārlis Millers [CM108 GPIO PTT] M: Andrew Errington, ZL3AME Rotators [celestron] M: Stephane Fillod, F8CFE C: Eric/N3KQX [easycomm] M: Luc Langehegermann, LX2GT C: Francois Retief [fodtrack] M: Luc Langehegermann, LX2GT [amsat/if-100] M: Stephane Fillod, F8CFE C: Patrick Strasser, OE6PSE [heathkit:HD 1780 Intellirotor] M: Rob Frohne, KL7NA [rotorez] M: Nate Bargmann, N0NB [spid] M: Norvald H. Ryeng, LA6YKA [m2] M: Magne Mæhre, LA1BFA C: Ron Patterson, W6FM [ars] M: Stephane Fillod, F8CFE C: Chris Bryant, G3WIE [ts7400] M: Øystein Hårberg, LA7LKA [indi] M: Norbert Varga, HA2NON [Frontend] M: Stephane Fillod, F8CFE [src/locator.c] M: Dave Hines, M1CXW C: Stephane Fillod, F8CFE C: Nate Bargmann, N0NB [test utilities] M: Stephane Fillod, F8CFE C: Nate Bargmann, N0NB C: Nirgal Vourgère [platform: FreeBSD] M: Diane Bruce, VA3DB [platform: NetBSD] M: Berndt Josef Wulf, VK5ABN [platform: win32] M: Stephane Fillod, F8CFE C: VB & testing by Darren Hatcher, G0WCW C: VB.NET wrapper by Michael Benz [packaging: debian] M: Kamal Mostafa, KA6MAL M: Jaime Robles, EA4TV C: Joop Stakenborg, PG4I [packaging: RPM] M: Alexandru Csete, OZ9AEC M: Joop Stakenborg, PG4I [Web site: http://www.hamlib.org] M: Joop Stakenborg, PG4I M: Stephane Fillod, F8CFE M: Nate Bargmann, N0NB E-mail addresses: Frank Singleton, VK3FCS, Stephane Fillod, F8CFE, Pascal Brisset Nate Bargmann, N0NB, Chris Karpinsky, AA1VL, Joop Stakenborg, PG4I, Bob Parnass, AJ9S, Francois Retief, James Chance, N3TKD, Chuck Hemker, N2POR, Alex V Flinsch, KC2IVL, Chuck Gilkes, WD0FCL/4, Dale E. Edmons, KD7ENI, Michael Smith, KE4RJQ Berndt Josef Wulf, VK5ABN Mark J. Fine Jim Jerzycke, KQ6EA Alexandru Csete OZ9AEC Diane Bruce, VA3DB Dave Hines, M1CXW, Darren Hatcher, G0WCW, Ben Coleman, NJ8J, Serge Pashenkov Lars E. Pettersson SM6RPZ Thomas Beierlein, DL1JBE, Kent Hill, AD7AI, Dave Freese, W1HKJ, Rob Frohne, KL7NA, Steve Conklin, AI4QR, Martin Ewing, AA6E, Terry Embry, KJ4EED, Alessandro Zummo, IZ1PRB Norvald H. Ryeng, LA6YKA Larry Gadallah, VE6VQ Kamal Mostafa, KA6MAL, Jaime Robles, EA4TV, Wolfgang Buesser, DK1BW, Magne Mæhre, LA1BFA, Charles Suprin, AA1VS, Robert Steinhäußer, DL1NC, James Watson, HZ1JW, Juergen Rinas, DC3BW, Kamal Mostafa, KA6MAL, Roger, Tristan Mills, Terry Dawson, VK2KTJ, Øystein Hårberg, LA7LKA, Alexander Sack Nirgal Vourgère Andrew Errington Kārlis Millers YL3ALK Norbert Varga HA2NON hamlib-4.6.5/security/0000775000175000017500000000000015056640475010410 5hamlib-4.6.5/security/password.h0000775000175000017500000000200615056640443012337 /* * password.h * * AESStringCrypt 1.1 * Copyright (C) 2007, 2008, 2009, 2012, 2015 * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. * */ #ifndef __STRINGCRYPT_PASSWORD_H #define __STRINGCRYPT_PASSWORD_H #define MAX_PASSWD_LEN 1024 #ifdef NOTWORKING /* * Function Prototypes */ int passwd_to_utf16(char *in_passwd, int length, int max_length, char *out_passwd); #endif #endif /* __STRINGCRYPT_PASSWORD_H */ hamlib-4.6.5/security/security.h0000664000175000017500000000007115056640443012341 int my_rand(int max); void rig_make_key(char key[33]); hamlib-4.6.5/security/password.c0000664000175000017500000000515315056640443012335 /* * password.c * * AESStringCrypt 1.1 * Copyright (C) 2007, 2008, 2009, 2012, 2015 * * Contributors: * Glenn Washburn * Paul E. Jones * Mauro Gilardi * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. * */ #include #include #include #include "hamlib/rig.h" #include "password.h" #include "md5.h" #define HAMLIB_SECRET_LENGTH 32 // makes a 32-byte secret key from password using MD5 // yes -- this is security-by-obscurity // but password hacking software doesn't use this type of logic // we want a repeatable password that is not subject to "normal" md5 decryption logic // could use a MAC address to make it more random but making that portable is TBD HAMLIB_EXPORT(void) rig_password_generate_secret(char *pass, char result[HAMLIB_SECRET_LENGTH + 1]) { unsigned int product; char newpass[256]; product = pass[0]; int i; for (i = 1; pass[i]; ++i) { product *= pass[i]; } srand(product); snprintf(newpass, sizeof(newpass) - 1, "%s\t%ld\t%ld", pass, (long)rand(), (long)time(NULL)); //printf("debug=%s\n", newpass); const char *md5str = rig_make_md5(newpass); strncpy(result, md5str, HAMLIB_SECRET_LENGTH); // now that we have the md5 we'll do the AES256 printf("sharedkey=%s\n", result); printf("\nCan be used with rigctl --password [secret]\nOr can be placed in ~/.hamlib_settings\n"); } //#define TESTPASSWORD #ifdef TESTPASSWORD int main(int argc, const char *argv[]) { char secret[HAMLIB_SECRET_LENGTH + 1]; char password[HAMLIB_SECRET_LENGTH + 1]; // maximum length usable for password too // anything longer will not be used to generate the secret if (argc == 1) { strcpy(password, "testpass"); } else { strcpy(password, argv[1]); } printf("Using password \"%s\" to generate shared key\n", password); rig_password_generate_secret(password, secret); return 0; } #endif hamlib-4.6.5/security/aes.h0000775000175000017500000000107515056640443011252 #ifndef _AES_H #define _AES_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 erk[64]; /* encryption round keys */ uint32 drk[64]; /* decryption round keys */ int nr; /* number of rounds */ } aes_context; int aes_set_key( aes_context *ctx, uint8 *key, int nbits ); void aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); #endif /* aes.h */ hamlib-4.6.5/security/sctest.c0000664000175000017500000001553315056640443012003 /* * String Crypt Test (Linux) * Copyright (C) 2012, 2015 * * Author: Paul E. Jones * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. * */ #include #include #ifdef _WIN32 #include //#include #else #include #endif #include "AESStringCrypt.h" #include "password.h" /* * Define how many test vectors to consider */ #define TEST_COUNT 21 /* * Dummy string */ #define DUMMY_STRING \ "VOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOID" \ "VOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOID" \ "VOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOID" \ "VOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOIDVOID" /* * Main will just perform some simple test */ int main(int argc, char *argv[]) { #ifdef __linux__ char pass_input[MAX_PASSWD_LEN + 1]; #endif char plaintext[512], ciphertext[512 + 68]; #ifdef _WIN32 wchar_t pass[MAX_PASSWD_LEN + 1]; #else char pass[MAX_PASSWD_LEN * 2 + 2]; #endif int i, passlen; unsigned long long plaintext_length, ciphertext_length; const char *plaintext_tests[TEST_COUNT] = { "", "0", "012", "0123456789ABCDE", "0123456789ABCDEF", "0123456789ABCDEF0", "0123456789ABCDEF0123456789ABCDE", "0123456789ABCDEF0123456789ABCDEF", "0123456789ABCDEF0123456789ABCDEF0", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDE", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDE", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0" }; /* * Run through tests */ for (i = 0; i < TEST_COUNT; i++) { printf("\nStarting test %i\n", i + 1); /* * We will use the password "Hello" */ #ifdef _WIN32 wcscpy(pass, L"Hello"); passlen = (int) wcslen(pass) * 2; #else strcpy(pass_input, "Hello"); passlen = passwd_to_utf16(pass_input, strlen(pass_input), MAX_PASSWD_LEN + 1, pass); #endif if (passlen <= 0) { printf("Error converting the password to UTF-16LE\n"); return -1; } /* * Put the text vector into "plaintext" */ strcpy(plaintext, pass_input); printf("Plaintext: %s\n", plaintext); printf("Plaintext length: %d\n", (int)strlen(plaintext)); /* * Encrypt the string */ printf("Encrypting...\n"); ciphertext_length = AESStringCrypt((unsigned char *) pass, passlen, (unsigned char *) plaintext, strlen(plaintext), (unsigned char *) ciphertext); if (ciphertext_length == AESSTRINGCRYPT_ERROR) { printf("Error encrypting the string\n"); } printf("Ciphertext length: %llu\n", ciphertext_length); #if 0 /* * One could verify that the data encrypted properly using * any version of AES Crypt. */ { char file[64]; FILE *fp; sprintf(file, "test-%i.txt.aes", i); fp = fopen(file, "wb"); fwrite(ciphertext, ciphertext_length, 1, fp); fclose(fp); } #endif /* * Decrypt the ciphertext */ strcpy(plaintext, DUMMY_STRING); printf("Decrypting...\n"); plaintext_length = AESStringDecrypt((unsigned char *) pass, passlen, (unsigned char *) ciphertext, ciphertext_length, (unsigned char *) plaintext); if (plaintext_length == AESSTRINGCRYPT_ERROR) { printf("Error decrypting the string\n"); } printf("Decrypted plaintext length: %llu, %s\n", plaintext_length, plaintext); if (plaintext_length != strlen(plaintext_tests[i])) { printf("Decrypted length does not match original input length!\n"); return -1; } /* * Let's insert a string terminator */ plaintext[plaintext_length] = '\0'; if (plaintext_length && strcmp(plaintext_tests[i], plaintext)) { printf("Decrypted string does not match!\n"); return -1; } printf("Plaintext matches input: %s\n", plaintext); } printf("\nAll tests passed successfully\n\n"); return 0; } hamlib-4.6.5/security/aes.c0000664000175000017500000007513015056640443011245 /* * FIPS-197 compliant AES implementation * * Copyright (C) 2001-2004 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "aes.h" /* uncomment the following line to run the test suite */ /* #define TEST */ /* uncomment the following line to use pre-computed tables */ /* otherwise the tables will be generated at the first run */ /* #define FIXED_TABLES */ #ifndef FIXED_TABLES /* forward S-box & tables */ uint32 FSb[256]; uint32 FT0[256]; uint32 FT1[256]; uint32 FT2[256]; uint32 FT3[256]; /* reverse S-box & tables */ uint32 RSb[256]; uint32 RT0[256]; uint32 RT1[256]; uint32 RT2[256]; uint32 RT3[256]; /* round constants */ uint32 RCON[10]; /* tables generation flag */ int do_init = 1; /* tables generation routine */ #define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \ ( ( x & 0xFFFFFFFF ) >> 8 ) ) #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) #define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 ) void aes_gen_tables(void) { int i; uint8 x, y; uint8 pow[256]; uint8 log[256]; /* compute pow and log tables over GF(2^8) */ for (i = 0, x = 1; i < 256; i++, x ^= XTIME(x)) { pow[i] = x; log[x] = i; } /* calculate the round constants */ for (i = 0, x = 1; i < 10; i++, x = XTIME(x)) { RCON[i] = (uint32) x << 24; } /* generate the forward and reverse S-boxes */ FSb[0x00] = 0x63; RSb[0x63] = 0x00; for (i = 1; i < 256; i++) { x = pow[255 - log[i]]; y = x; y = (y << 1) | (y >> 7); x ^= y; y = (y << 1) | (y >> 7); x ^= y; y = (y << 1) | (y >> 7); x ^= y; y = (y << 1) | (y >> 7); x ^= y ^ 0x63; FSb[i] = x; RSb[x] = i; } /* generate the forward and reverse tables */ for (i = 0; i < 256; i++) { x = (unsigned char) FSb[i]; y = XTIME(x); FT0[i] = (uint32)(x ^ y) ^ ((uint32) x << 8) ^ ((uint32) x << 16) ^ ((uint32) y << 24); FT0[i] &= 0xFFFFFFFF; FT1[i] = ROTR8(FT0[i]); FT2[i] = ROTR8(FT1[i]); FT3[i] = ROTR8(FT2[i]); y = (unsigned char) RSb[i]; RT0[i] = ((uint32) MUL(0x0B, y)) ^ ((uint32) MUL(0x0D, y) << 8) ^ ((uint32) MUL(0x09, y) << 16) ^ ((uint32) MUL(0x0E, y) << 24); RT0[i] &= 0xFFFFFFFF; RT1[i] = ROTR8(RT0[i]); RT2[i] = ROTR8(RT1[i]); RT3[i] = ROTR8(RT2[i]); } } #else /* forward S-box */ static const uint32 FSb[256] = { 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 }; /* forward tables */ #define FT \ \ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) #define V(a,b,c,d) 0x##a##b##c##d static const uint32 FT0[256] = { FT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static const uint32 FT1[256] = { FT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static const uint32 FT2[256] = { FT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static const uint32 FT3[256] = { FT }; #undef V #undef FT /* reverse S-box */ static const uint32 RSb[256] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D }; /* reverse tables */ #define RT \ \ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) #define V(a,b,c,d) 0x##a##b##c##d static const uint32 RT0[256] = { RT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c static const uint32 RT1[256] = { RT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b static const uint32 RT2[256] = { RT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a static const uint32 RT3[256] = { RT }; #undef V #undef RT /* round constants */ static const uint32 RCON[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; int do_init = 0; void aes_gen_tables(void) { } #endif /* platform-independant 32-bit integer manipulation macros */ #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } /* decryption key schedule tables */ int KT_init = 1; uint32 KT0[256]; uint32 KT1[256]; uint32 KT2[256]; uint32 KT3[256]; /* AES key scheduling routine */ int aes_set_key(aes_context *ctx, uint8 *key, int nbits) { int i; uint32 *RK, *SK; if (do_init) { aes_gen_tables(); do_init = 0; } switch (nbits) { case 128: ctx->nr = 10; break; case 192: ctx->nr = 12; break; case 256: ctx->nr = 14; break; default : return (1); } RK = ctx->erk; for (i = 0; i < (nbits >> 5); i++) { GET_UINT32(RK[i], key, i * 4); } /* setup encryption round keys */ switch (nbits) { case 128: for (i = 0; i < 10; i++, RK += 4) { RK[4] = RK[0] ^ RCON[i] ^ (FSb[(uint8)(RK[3] >> 16) ] << 24) ^ (FSb[(uint8)(RK[3] >> 8) ] << 16) ^ (FSb[(uint8)(RK[3]) ] << 8) ^ (FSb[(uint8)(RK[3] >> 24) ]); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; RK[7] = RK[3] ^ RK[6]; } break; case 192: for (i = 0; i < 8; i++, RK += 6) { RK[6] = RK[0] ^ RCON[i] ^ (FSb[(uint8)(RK[5] >> 16) ] << 24) ^ (FSb[(uint8)(RK[5] >> 8) ] << 16) ^ (FSb[(uint8)(RK[5]) ] << 8) ^ (FSb[(uint8)(RK[5] >> 24) ]); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; RK[9] = RK[3] ^ RK[8]; RK[10] = RK[4] ^ RK[9]; RK[11] = RK[5] ^ RK[10]; } break; case 256: for (i = 0; i < 7; i++, RK += 8) { RK[8] = RK[0] ^ RCON[i] ^ (FSb[(uint8)(RK[7] >> 16) ] << 24) ^ (FSb[(uint8)(RK[7] >> 8) ] << 16) ^ (FSb[(uint8)(RK[7]) ] << 8) ^ (FSb[(uint8)(RK[7] >> 24) ]); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; RK[11] = RK[3] ^ RK[10]; RK[12] = RK[4] ^ (FSb[(uint8)(RK[11] >> 24) ] << 24) ^ (FSb[(uint8)(RK[11] >> 16) ] << 16) ^ (FSb[(uint8)(RK[11] >> 8) ] << 8) ^ (FSb[(uint8)(RK[11]) ]); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; RK[15] = RK[7] ^ RK[14]; } break; } /* setup decryption round keys */ if (KT_init) { for (i = 0; i < 256; i++) { KT0[i] = RT0[ FSb[i] ]; KT1[i] = RT1[ FSb[i] ]; KT2[i] = RT2[ FSb[i] ]; KT3[i] = RT3[ FSb[i] ]; } KT_init = 0; } SK = ctx->drk; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; for (i = 1; i < ctx->nr; i++) { RK -= 8; *SK++ = KT0[(uint8)(*RK >> 24) ] ^ KT1[(uint8)(*RK >> 16) ] ^ KT2[(uint8)(*RK >> 8) ] ^ KT3[(uint8)(*RK) ]; RK++; *SK++ = KT0[(uint8)(*RK >> 24) ] ^ KT1[(uint8)(*RK >> 16) ] ^ KT2[(uint8)(*RK >> 8) ] ^ KT3[(uint8)(*RK) ]; RK++; *SK++ = KT0[(uint8)(*RK >> 24) ] ^ KT1[(uint8)(*RK >> 16) ] ^ KT2[(uint8)(*RK >> 8) ] ^ KT3[(uint8)(*RK) ]; RK++; *SK++ = KT0[(uint8)(*RK >> 24) ] ^ KT1[(uint8)(*RK >> 16) ] ^ KT2[(uint8)(*RK >> 8) ] ^ KT3[(uint8)(*RK) ]; RK++; } RK -= 8; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; return (0); } /* AES 128-bit block encryption routine */ void aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16]) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->erk; GET_UINT32(X0, input, 0); X0 ^= RK[0]; GET_UINT32(X1, input, 4); X1 ^= RK[1]; GET_UINT32(X2, input, 8); X2 ^= RK[2]; GET_UINT32(X3, input, 12); X3 ^= RK[3]; #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ FT3[ (uint8) ( Y3 ) ]; \ \ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ FT3[ (uint8) ( Y0 ) ]; \ \ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ FT3[ (uint8) ( Y1 ) ]; \ \ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ FT3[ (uint8) ( Y2 ) ]; \ } AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ if (ctx->nr > 10) { AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ } if (ctx->nr > 12) { AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ (FSb[(uint8)(Y0 >> 24) ] << 24) ^ (FSb[(uint8)(Y1 >> 16) ] << 16) ^ (FSb[(uint8)(Y2 >> 8) ] << 8) ^ (FSb[(uint8)(Y3) ]); X1 = RK[1] ^ (FSb[(uint8)(Y1 >> 24) ] << 24) ^ (FSb[(uint8)(Y2 >> 16) ] << 16) ^ (FSb[(uint8)(Y3 >> 8) ] << 8) ^ (FSb[(uint8)(Y0) ]); X2 = RK[2] ^ (FSb[(uint8)(Y2 >> 24) ] << 24) ^ (FSb[(uint8)(Y3 >> 16) ] << 16) ^ (FSb[(uint8)(Y0 >> 8) ] << 8) ^ (FSb[(uint8)(Y1) ]); X3 = RK[3] ^ (FSb[(uint8)(Y3 >> 24) ] << 24) ^ (FSb[(uint8)(Y0 >> 16) ] << 16) ^ (FSb[(uint8)(Y1 >> 8) ] << 8) ^ (FSb[(uint8)(Y2) ]); PUT_UINT32(X0, output, 0); PUT_UINT32(X1, output, 4); PUT_UINT32(X2, output, 8); PUT_UINT32(X3, output, 12); } /* AES 128-bit block decryption routine */ void aes_decrypt(aes_context *ctx, uint8 input[16], uint8 output[16]) { uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->drk; GET_UINT32(X0, input, 0); X0 ^= RK[0]; GET_UINT32(X1, input, 4); X1 ^= RK[1]; GET_UINT32(X2, input, 8); X2 ^= RK[2]; GET_UINT32(X3, input, 12); X3 ^= RK[3]; #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ RK += 4; \ \ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ RT3[ (uint8) ( Y1 ) ]; \ \ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ RT3[ (uint8) ( Y2 ) ]; \ \ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ RT3[ (uint8) ( Y3 ) ]; \ \ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ RT3[ (uint8) ( Y0 ) ]; \ } AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ if (ctx->nr > 10) { AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ } if (ctx->nr > 12) { AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ (RSb[(uint8)(Y0 >> 24) ] << 24) ^ (RSb[(uint8)(Y3 >> 16) ] << 16) ^ (RSb[(uint8)(Y2 >> 8) ] << 8) ^ (RSb[(uint8)(Y1) ]); X1 = RK[1] ^ (RSb[(uint8)(Y1 >> 24) ] << 24) ^ (RSb[(uint8)(Y0 >> 16) ] << 16) ^ (RSb[(uint8)(Y3 >> 8) ] << 8) ^ (RSb[(uint8)(Y2) ]); X2 = RK[2] ^ (RSb[(uint8)(Y2 >> 24) ] << 24) ^ (RSb[(uint8)(Y1 >> 16) ] << 16) ^ (RSb[(uint8)(Y0 >> 8) ] << 8) ^ (RSb[(uint8)(Y3) ]); X3 = RK[3] ^ (RSb[(uint8)(Y3 >> 24) ] << 24) ^ (RSb[(uint8)(Y2 >> 16) ] << 16) ^ (RSb[(uint8)(Y1 >> 8) ] << 8) ^ (RSb[(uint8)(Y0) ]); PUT_UINT32(X0, output, 0); PUT_UINT32(X1, output, 4); PUT_UINT32(X2, output, 8); PUT_UINT32(X3, output, 12); } #ifdef TEST #include #include /* * Rijndael Monte Carlo Test: ECB mode * source: NIST - rijndael-vals.zip */ static unsigned char AES_enc_test[3][16] = { { 0xA0, 0x43, 0x77, 0xAB, 0xE2, 0x59, 0xB0, 0xD0, 0xB5, 0xBA, 0x2D, 0x40, 0xA5, 0x01, 0x97, 0x1B }, { 0x4E, 0x46, 0xF8, 0xC5, 0x09, 0x2B, 0x29, 0xE2, 0x9A, 0x97, 0x1A, 0x0C, 0xD1, 0xF6, 0x10, 0xFB }, { 0x1F, 0x67, 0x63, 0xDF, 0x80, 0x7A, 0x7E, 0x70, 0x96, 0x0D, 0x4C, 0xD3, 0x11, 0x8E, 0x60, 0x1A } }; static unsigned char AES_dec_test[3][16] = { { 0xF5, 0xBF, 0x8B, 0x37, 0x13, 0x6F, 0x2E, 0x1F, 0x6B, 0xEC, 0x6F, 0x57, 0x20, 0x21, 0xE3, 0xBA }, { 0xF1, 0xA8, 0x1B, 0x68, 0xF6, 0xE5, 0xA6, 0x27, 0x1A, 0x8C, 0xB2, 0x4E, 0x7D, 0x94, 0x91, 0xEF }, { 0x4D, 0xE0, 0xC6, 0xDF, 0x7C, 0xB1, 0x69, 0x72, 0x84, 0x60, 0x4D, 0x60, 0x27, 0x1B, 0xC5, 0x9A } }; #if 0 int main(void) { int m, n, i, j; aes_context ctx; unsigned char buf[16]; unsigned char key[32]; for (m = 0; m < 2; m++) { printf("\n Rijndael Monte Carlo Test (ECB mode) - "); if (m == 0) { printf("encryption\n\n"); } if (m == 1) { printf("decryption\n\n"); } for (n = 0; n < 3; n++) { printf(" Test %d, key size = %3d bits: ", n + 1, 128 + n * 64); fflush(stdout); memset(buf, 0, 16); memset(key, 0, 16 + n * 8); for (i = 0; i < 400; i++) { aes_set_key(&ctx, key, 128 + n * 64); for (j = 0; j < 9999; j++) { if (m == 0) { aes_encrypt(&ctx, buf, buf); } if (m == 1) { aes_decrypt(&ctx, buf, buf); } } if (n > 0) { for (j = 0; j < (n << 3); j++) { key[j] ^= buf[j + 16 - (n << 3)]; } } if (m == 0) { aes_encrypt(&ctx, buf, buf); } if (m == 1) { aes_decrypt(&ctx, buf, buf); } for (j = 0; j < 16; j++) { key[j + (n << 3)] ^= buf[j]; } } if ((m == 0 && memcmp(buf, AES_enc_test[n], 16) != 0) || (m == 1 && memcmp(buf, AES_dec_test[n], 16) != 0)) { printf("failed!\n"); return (1); } printf("passed.\n"); } } printf("\n"); return (0); } #endif #endif hamlib-4.6.5/security/md5.h0000664000175000017500000000276015056640443011166 #ifndef MD5_h #define MD5_h //#include "Arduino.h" /* * This is an OpenSSL-compatible implementation of the RSA Data Security, * Inc. MD5 Message-Digest Algorithm (RFC 1321). * * Written by Solar Designer in 2001, and placed * in the public domain. There's absolutely no warranty. * * This differs from Colin Plumb's older public domain implementation in * that no 32-bit integer data type is required, there's no compile-time * endianness configuration, and the function prototypes match OpenSSL's. * The primary goals are portability and ease of use. * * This implementation is meant to be fast, but not as fast as possible. * Some known optimizations are not included to reduce source code size * and avoid compile-time configuration. */ /* * Updated by Scott MacVicar for arduino * */ #include #include "hamlib/rig.h" typedef unsigned long MD5_u32plus; typedef struct { MD5_u32plus lo, hi; MD5_u32plus a, b, c, d; unsigned char buffer[64]; MD5_u32plus block[16]; } MD5_CTX; #if 0 class MD5 { public: MD5(); static unsigned char* make_hash(char *arg); static unsigned char* make_hash(char *arg,size_t size); static char* make_digest(const unsigned char *digest, int len); static const void *body(void *ctxBuf, const void *data, size_t size); static void MD5Init(void *ctxBuf); static void MD5Final(unsigned char *result, void *ctxBuf); static void MD5Update(void *ctxBuf, const void *data, size_t size); }; #endif #endif hamlib-4.6.5/security/Makefile.in0000664000175000017500000005431315056640453012377 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = security ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsecurity_la_LIBADD = am_libsecurity_la_OBJECTS = aes.lo AESStringCrypt.lo password.lo \ security.lo sha256.lo md5.lo libsecurity_la_OBJECTS = $(am_libsecurity_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/AESStringCrypt.Plo \ ./$(DEPDIR)/aes.Plo ./$(DEPDIR)/md5.Plo \ ./$(DEPDIR)/password.Plo ./$(DEPDIR)/security.Plo \ ./$(DEPDIR)/sha256.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libsecurity_la_SOURCES) DIST_SOURCES = $(libsecurity_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I. EXTRA_DIST = sctest.c noinst_LTLIBRARIES = libsecurity.la libsecurity_la_SOURCES = aes.c AESStringCrypt.c password.c security.c sha256.c md5.c aes.h AESStringCrypt.h password.h security.h sha256.h md5.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu security/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu security/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libsecurity.la: $(libsecurity_la_OBJECTS) $(libsecurity_la_DEPENDENCIES) $(EXTRA_libsecurity_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsecurity_la_OBJECTS) $(libsecurity_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AESStringCrypt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/password.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/AESStringCrypt.Plo -rm -f ./$(DEPDIR)/aes.Plo -rm -f ./$(DEPDIR)/md5.Plo -rm -f ./$(DEPDIR)/password.Plo -rm -f ./$(DEPDIR)/security.Plo -rm -f ./$(DEPDIR)/sha256.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/AESStringCrypt.Plo -rm -f ./$(DEPDIR)/aes.Plo -rm -f ./$(DEPDIR)/md5.Plo -rm -f ./$(DEPDIR)/password.Plo -rm -f ./$(DEPDIR)/security.Plo -rm -f ./$(DEPDIR)/sha256.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/security/sha256.c0000664000175000017500000002575715056640443011517 /* * FIPS-180-2 compliant SHA-256 implementation * * Copyright (C) 2001-2003 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "sha256.h" #define GET_UINT32(n,b,i) \ { \ (n) = ( (uint32) (b)[(i) ] << 24 ) \ | ( (uint32) (b)[(i) + 1] << 16 ) \ | ( (uint32) (b)[(i) + 2] << 8 ) \ | ( (uint32) (b)[(i) + 3] ); \ } #define PUT_UINT32(n,b,i) \ { \ (b)[(i) ] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 3] = (uint8) ( (n) ); \ } void sha256_starts(sha256_context *ctx) { ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x6A09E667; ctx->state[1] = 0xBB67AE85; ctx->state[2] = 0x3C6EF372; ctx->state[3] = 0xA54FF53A; ctx->state[4] = 0x510E527F; ctx->state[5] = 0x9B05688C; ctx->state[6] = 0x1F83D9AB; ctx->state[7] = 0x5BE0CD19; } void sha256_process(sha256_context *ctx, uint8 data[64]) { uint32 temp1, temp2, W[64]; uint32 A, B, C, D, E, F, G, H; GET_UINT32(W[0], data, 0); GET_UINT32(W[1], data, 4); GET_UINT32(W[2], data, 8); GET_UINT32(W[3], data, 12); GET_UINT32(W[4], data, 16); GET_UINT32(W[5], data, 20); GET_UINT32(W[6], data, 24); GET_UINT32(W[7], data, 28); GET_UINT32(W[8], data, 32); GET_UINT32(W[9], data, 36); GET_UINT32(W[10], data, 40); GET_UINT32(W[11], data, 44); GET_UINT32(W[12], data, 48); GET_UINT32(W[13], data, 52); GET_UINT32(W[14], data, 56); GET_UINT32(W[15], data, 60); #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) #define F0(x,y,z) ((x & y) | (z & (x | y))) #define F1(x,y,z) (z ^ (x & (y ^ z))) #define R(t) \ ( \ W[t] = S1(W[t - 2]) + W[t - 7] + \ S0(W[t - 15]) + W[t - 16] \ ) #define P(a,b,c,d,e,f,g,h,x,K) \ { \ temp1 = h + S3(e) + F1(e,f,g) + K + x; \ temp2 = S2(a) + F0(a,b,c); \ d += temp1; h = temp1 + temp2; \ } A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; E = ctx->state[4]; F = ctx->state[5]; G = ctx->state[6]; H = ctx->state[7]; P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); P(B, C, D, E, F, G, H, A, R(31), 0x14292967); P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); ctx->state[0] += A; ctx->state[1] += B; ctx->state[2] += C; ctx->state[3] += D; ctx->state[4] += E; ctx->state[5] += F; ctx->state[6] += G; ctx->state[7] += H; } void sha256_update(sha256_context *ctx, uint8 *input, uint32 length) { uint32 left, fill; if (! length) { return; } left = ctx->total[0] & 0x3F; fill = 64 - left; ctx->total[0] += length; ctx->total[0] &= 0xFFFFFFFF; if (ctx->total[0] < length) { ctx->total[1]++; } if (left && length >= fill) { memcpy((void *)(ctx->buffer + left), (void *) input, fill); sha256_process(ctx, ctx->buffer); length -= fill; input += fill; left = 0; } while (length >= 64) { sha256_process(ctx, input); length -= 64; input += 64; } if (length) { memcpy((void *)(ctx->buffer + left), (void *) input, length); } } static uint8 sha256_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void sha256_finish(sha256_context *ctx, uint8 digest[32]) { uint32 last, padn; uint32 high, low; uint8 msglen[8]; high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); low = (ctx->total[0] << 3); PUT_UINT32(high, msglen, 0); PUT_UINT32(low, msglen, 4); last = ctx->total[0] & 0x3F; padn = (last < 56) ? (56 - last) : (120 - last); sha256_update(ctx, sha256_padding, padn); sha256_update(ctx, msglen, 8); PUT_UINT32(ctx->state[0], digest, 0); PUT_UINT32(ctx->state[1], digest, 4); PUT_UINT32(ctx->state[2], digest, 8); PUT_UINT32(ctx->state[3], digest, 12); PUT_UINT32(ctx->state[4], digest, 16); PUT_UINT32(ctx->state[5], digest, 20); PUT_UINT32(ctx->state[6], digest, 24); PUT_UINT32(ctx->state[7], digest, 28); } #ifdef TEST #include #include /* * those are the standard FIPS-180-2 test vectors */ static char *msg[] = { "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", NULL }; static char *val[] = { "ba7816bf8f01cfea414140de5dae2223" \ "b00361a396177a9cb410ff61f20015ad", "248d6a61d20638b8e5c026930c3e6039" \ "a33ce45964ff2167f6ecedd419db06c1", "cdc76e5c9914fb9281a1c7e284d73e67" \ "f1809a48a497200e046d39ccc7112cd0" }; int main(int argc, const char *argv[]) { int i, j; sha256_context ctx; unsigned char buf[1000]; unsigned char sha256sum[32]; if (argc < 2) { char output[65]; printf("\n SHA-256 Validation Tests:\n\n"); for (i = 0; i < 3; i++) { printf(" Test %d ", i + 1); sha256_starts(&ctx); if (i < 2) { sha256_update(&ctx, (uint8 *) msg[i], strlen(msg[i])); } else { memset(buf, 'a', 1000); for (j = 0; j < 1000; j++) { sha256_update(&ctx, (uint8 *) buf, 1000); } } sha256_finish(&ctx, sha256sum); for (j = 0; j < 32; j++) { sprintf(output + j * 2, "%02x", sha256sum[j]); } if (memcmp(output, val[i], 64)) { printf("failed!\n"); return (1); } printf("passed.\n"); } printf("\n"); } else { FILE *f; if (!(f = fopen(argv[1], "rb"))) { perror("fopen"); return (1); } sha256_starts(&ctx); while ((i = fread(buf, 1, sizeof(buf), f)) > 0) { sha256_update(&ctx, buf, i); } sha256_finish(&ctx, sha256sum); for (j = 0; j < 32; j++) { printf("%02x", sha256sum[j]); } printf(" %s\n", argv[1]); } return (0); } #endif hamlib-4.6.5/security/md5.c0000664000175000017500000002104215056640443011153 #include "md5.h" char *make_digest(const unsigned char *digest, int len) /* {{{ */ { int md5len = sizeof(char) * (len * 2 + 1); char *md5str = (char *) calloc(1, md5len); static const char hexits[17] = "0123456789abcdef"; int i; for (i = 0; i < len; i++) { md5str[i * 2] = hexits[digest[i] >> 4]; md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F]; } return md5str; } /* * The basic MD5 functions. * * F and G are optimized compared to their RFC 1321 definitions for * architectures that lack an AND-NOT instruction, just like in Colin Plumb's * implementation. */ #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | ~(z))) /* * The MD5 transformation for all four rounds. */ #define STEP(f, a, b, c, d, x, t, s) \ (a) += f((b), (c), (d)) + (x) + (t); \ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ (a) += (b); /* * SET reads 4 input bytes in little-endian byte order and stores them * in a properly aligned word in host byte order. * * The check for little-endian architectures that tolerate unaligned * memory accesses is just an optimization. Nothing will break if it * doesn't work. */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) # define SET(n) \ (*(MD5_u32plus *)&ptr[(n) * 4]) # define GET(n) \ SET(n) #else # define SET(n) \ (ctx->block[(n)] = \ (MD5_u32plus)ptr[(n) * 4] | \ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) # define GET(n) \ (ctx->block[(n)]) #endif /* * This processes one or more 64-byte data blocks, but does NOT update * the bit counters. There are no alignment requirements. */ const void *body(void *ctxBuf, const void *data, size_t size) { MD5_CTX *ctx = (MD5_CTX *)ctxBuf; const unsigned char *ptr; MD5_u32plus a, b, c, d; ptr = (unsigned char *)data; a = ctx->a; b = ctx->b; c = ctx->c; d = ctx->d; do { MD5_u32plus saved_a, saved_b, saved_c, saved_d; saved_a = a; saved_b = b; saved_c = c; saved_d = d; /* Round 1 */ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) STEP(F, c, d, a, b, SET(2), 0x242070db, 17) STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) /* Round 2 */ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) STEP(G, d, a, b, c, GET(10), 0x02441453, 9) STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) /* Round 3 */ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) /* Round 4 */ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) a += saved_a; b += saved_b; c += saved_c; d += saved_d; ptr += 64; } while (size -= 64); ctx->a = a; ctx->b = b; ctx->c = c; ctx->d = d; return ptr; } void MD5Init(void *ctxBuf) { MD5_CTX *ctx = (MD5_CTX *)ctxBuf; ctx->a = 0x67452301; ctx->b = 0xefcdab89; ctx->c = 0x98badcfe; ctx->d = 0x10325476; ctx->lo = 0; ctx->hi = 0; } void MD5Update(void *ctxBuf, const void *data, size_t size) { MD5_CTX *ctx = (MD5_CTX *)ctxBuf; MD5_u32plus saved_lo; MD5_u32plus used; saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) { ctx->hi++; } ctx->hi += size >> 29; used = saved_lo & 0x3f; if (used) { MD5_u32plus free; free = 64 - used; if (size < free) { memcpy(&ctx->buffer[used], data, size); return; } memcpy(&ctx->buffer[used], data, free); data = (unsigned char *)data + free; size -= free; body(ctx, ctx->buffer, 64); } if (size >= 64) { data = body(ctx, data, size & ~(size_t)0x3f); size &= 0x3f; } memcpy(ctx->buffer, data, size); } void MD5Final(unsigned char *result, void *ctxBuf) { MD5_CTX *ctx = (MD5_CTX *)ctxBuf; MD5_u32plus used, free; used = ctx->lo & 0x3f; ctx->buffer[used++] = 0x80; free = 64 - used; if (free < 8) { memset(&ctx->buffer[used], 0, free); body(ctx, ctx->buffer, 64); used = 0; free = 64; } memset(&ctx->buffer[used], 0, free - 8); ctx->lo <<= 3; ctx->buffer[56] = ctx->lo; ctx->buffer[57] = ctx->lo >> 8; ctx->buffer[58] = ctx->lo >> 16; ctx->buffer[59] = ctx->lo >> 24; ctx->buffer[60] = ctx->hi; ctx->buffer[61] = ctx->hi >> 8; ctx->buffer[62] = ctx->hi >> 16; ctx->buffer[63] = ctx->hi >> 24; body(ctx, ctx->buffer, 64); result[0] = ctx->a; result[1] = ctx->a >> 8; result[2] = ctx->a >> 16; result[3] = ctx->a >> 24; result[4] = ctx->b; result[5] = ctx->b >> 8; result[6] = ctx->b >> 16; result[7] = ctx->b >> 24; result[8] = ctx->c; result[9] = ctx->c >> 8; result[10] = ctx->c >> 16; result[11] = ctx->c >> 24; result[12] = ctx->d; result[13] = ctx->d >> 8; result[14] = ctx->d >> 16; result[15] = ctx->d >> 24; memset(ctx, 0, sizeof(*ctx)); } unsigned char *make_hash(const char *arg) { MD5_CTX context; static unsigned char digest[65]; MD5Init(&context); MD5Update(&context, arg, strlen(arg)); MD5Final(digest, &context); return digest; } char *rig_make_md5(char *pass) { const unsigned char *hash = make_hash(pass); char *md5str = make_digest(hash, 16); return md5str; } //#define TEST #ifdef TEST #include int main() { const char *md5str = make_md5("password"); printf("md5=%s\n", md5str); return 0; } #endif hamlib-4.6.5/security/sha256.h0000775000175000017500000000072315056640443011511 #ifndef _SHA256_H #define _SHA256_H #ifndef uint8 #define uint8 unsigned char #endif #ifndef uint32 #define uint32 unsigned long int #endif typedef struct { uint32 total[2]; uint32 state[8]; uint8 buffer[64]; } sha256_context; void sha256_starts( sha256_context *ctx ); void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); void sha256_finish( sha256_context *ctx, uint8 digest[32] ); #endif /* sha256.h */ hamlib-4.6.5/security/AESStringCrypt.h0000775000175000017500000001002315056640443013314 /* * AESStringCrypt.h * * AES String Crypt 1.1 * Copyright (C) 2007, 2008, 2009, 2012, 2015 * * Author: Paul E. Jones * * This library will encrypt octet strings of the specified length up * to ULLONG_MAX - 70 octet in length. If there is an error, the return * value from the encryption or decryption function will be * AESSTRINGCRYPT_ERROR. Any other value, including zero, is a valid * length value. Note that an encrypted string can be up to 69 octets * longer than the original plaintext string, thus the restriction on the * input string size. * * The output of the string encryption function is a string that is * compliant with the AES Crypt version 0 file format. For reference, * see: https://www.aescrypt.com/aes_file_format.html. * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. */ #ifndef __STRINGCRYPT_H #define __STRINGCRYPT_H #include #include "aes.h" #include "sha256.h" /* * Define the value to return to indicate an error */ #define AESSTRINGCRYPT_ERROR -1 typedef unsigned char sha256_t[32]; /* * AESStringCrypt * * Description * This function is called to encrypt the string "plaintext". * The encrypted string is placed in "ciphertext". Note that * the encrypted string is up to 68 bytes larger than the * plaintext string. This is to accomodate the header defined * by "AES Crypt File Format 0" and to store the last cipher * block (which is padded to 16 octets). * * Parameters * password [in] * The password used to encrypt the string in UCS-16 * format. * password_length [in] * The length of the password in octets * plaintext [in] * The plaintext string to be encrypted * plaintext_length [in] * The length of the plaintext string * ciphertext [out] * The encrypted string * * Returns * Returns the length of the ciphertext string or AESSTRINGCRYPT_ERROR * if there was an error when trying to encrypt the string. */ unsigned long long AESStringCrypt( unsigned char *password, unsigned long password_length, unsigned char *plaintext, unsigned long long plaintext_length, unsigned char *ciphertext); /* * AESStringDecrypt * * Description * This function is called to decrypt the string "ciphertext". * The decrypted string is placed in "plaintext". * * Parameters * password [in] * The password used to encrypt the string in UCS-16 * format. * password_length [in] * The length of the password in octets * ciphertext [in] * The ciphertext string to be decrypted * ciphertext_length [in] * The length of the ciphertext string * plaintext [out] * The decrypted string * * Returns * Returns the length of the plaintext string or AESSTRINGCRYPT_ERROR * if there was an error when trying to encrypt the string. */ unsigned long long AESStringDecrypt(unsigned char *password, unsigned long password_length, unsigned char *ciphertext, unsigned long long ciphertext_length, unsigned char *plaintext); #endif /* __STRINGCRYPT_H */ hamlib-4.6.5/security/AESStringCrypt.c0000664000175000017500000003417115056640443013316 /* * AESStringCrypt.c * * AES String Crypt 1.1 * Copyright (C) 2007, 2008, 2009, 2012, 2015 * * Author: Paul E. Jones * * This library will encrypt octet strings of the specified length up * to ULLONG_MAX - 70 octet in length. If there is an error, the return * value from the encryption or decryption function will be * AESSTRINGCRYPT_ERROR. Any other value, including zero, is a valid * length value. Note that an encrypted string can be up to 69 octets * longer than the original plaintext string, thus the restriction on the * input string size. * * The output of the string encryption function is a string that is * compliant with the AES Crypt version 0 file format. For reference, * see: https://www.aescrypt.com/aes_file_format.html. * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. */ #include #include #ifdef _WIN32 #include #include #else #include #include #include #endif #include "AESStringCrypt.h" /* * AESStringCrypt * * Description * This function is called to encrypt the string "plaintext". * The encrypted string is placed in "ciphertext". Note that * the encrypted string is up to 68 bytes larger than the * plaintext string. This is to accomodate the header defined * by "AES Crypt File Format 0" and to store the last cipher * block (which is padded to 16 octets). * * Parameters * password [in] * The password used to encrypt the string in UCS-16 * format. * password_length [in] * The length of the password in octets * plaintext [in] * The plaintext string to be encrypted * plaintext_length [in] * The length of the plaintext string * ciphertext [out] * The encrypted string * * Returns * Returns the length of the ciphertext string or AESSTRINGCRYPT_ERROR * if there was an error when trying to encrypt the string. */ unsigned long long AESStringCrypt(unsigned char *password, unsigned long password_length, unsigned char *plaintext, unsigned long long plaintext_length, unsigned char *ciphertext) { aes_context aes_ctx; sha256_context sha_ctx; sha256_t digest; unsigned char IV[16]; int i, n; unsigned char buffer[32]; unsigned char ipad[64], opad[64]; #ifdef _WIN32 HCRYPTPROV hProv; DWORD result_code; #else time_t current_time; pid_t process_id; FILE *randfp = NULL; #endif unsigned char *p; /* * Write an AES signature at the head of the file, along * with the AES file format version number. */ ciphertext[0] = 'A'; ciphertext[1] = 'E'; ciphertext[2] = 'S'; ciphertext[3] = 0x00; /* Version 0 */ ciphertext[4] = (plaintext_length & 0x0F); /* * We will use p as the pointer into the cipher */ p = ciphertext + 5; #ifdef _WIN32 /* * Prepare for random number generation */ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { result_code = GetLastError(); if (GetLastError() == NTE_BAD_KEYSET) { if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) { result_code = GetLastError(); } else { result_code = ERROR_SUCCESS; } } if (result_code != ERROR_SUCCESS) { return AESSTRINGCRYPT_ERROR; } } /* * Create the 16-bit IV used for encrypting the plaintext. * We do not fully trust the system's randomization functions, * so we improve on that by also hashing the random octets * and using only a portion of the hash. This IV * generation could be replaced with any good random * source of data. */ memset(IV, 0, 16); memset(buffer, 0, 32); sha256_starts(&sha_ctx); for (i = 0; i < 256; i++) { if (!CryptGenRandom(hProv, 32, (BYTE *) buffer)) { CryptReleaseContext(hProv, 0); return AESSTRINGCRYPT_ERROR; } sha256_update(&sha_ctx, buffer, 32); } sha256_finish(&sha_ctx, digest); /* * We're finished collecting random data */ CryptReleaseContext(hProv, 0); /* * Get the IV from the digest buffer */ memcpy(IV, digest, 16); #else /* * Open the source for random data. Note that while the entropy * might be lower with /dev/urandom than /dev/random, it will not * fail to produce something. Also, we're going to hash the result * anyway. */ if ((randfp = fopen("/dev/urandom", "r")) == NULL) { return AESSTRINGCRYPT_ERROR; } /* * We will use an initialization vector comprised of the current time * process ID, and random data, all hashed together with SHA-256. */ current_time = time(NULL); for (i = 0; i < 8; i++) { buffer[i] = (unsigned char) (current_time >> (i * 8)); } process_id = getpid(); for (i = 0; i < 8; i++) { buffer[i + 8] = (unsigned char) (process_id >> (i * 8)); } sha256_starts(&sha_ctx); sha256_update(&sha_ctx, buffer, 16); for (i = 0; i < 256; i++) { if (fread(buffer, 1, 32, randfp) != 32) { return AESSTRINGCRYPT_ERROR; } sha256_update(&sha_ctx, buffer, 32); } sha256_finish(&sha_ctx, digest); /* * We're finished collecting random data */ fclose(randfp); /* * Get the IV from the digest buffer */ memcpy(IV, digest, 16); #endif /* * Copy the IV to the ciphertext string */ memcpy(p, IV, 16); p += 16; /* * Hash the IV and password 8192 times */ memset(digest, 0, 32); memcpy(digest, IV, 16); for (i = 0; i < 8192; i++) { sha256_starts(&sha_ctx); sha256_update(&sha_ctx, digest, 32); sha256_update(&sha_ctx, password, password_length); sha256_finish(&sha_ctx, digest); } /* * Set the AES encryption key */ aes_set_key(&aes_ctx, digest, 256); /* * Set the ipad and opad arrays with values as * per RFC 2104 (HMAC). HMAC is defined as * H(K XOR opad, H(K XOR ipad, text)) */ memset(ipad, 0x36, 64); memset(opad, 0x5C, 64); for (i = 0; i < 32; i++) { ipad[i] ^= digest[i]; opad[i] ^= digest[i]; } sha256_starts(&sha_ctx); sha256_update(&sha_ctx, ipad, 64); while (plaintext_length > 0) { /* * Grab the next block of plaintext */ if (plaintext_length >= 16) { n = 16; } else { n = (int) plaintext_length; } plaintext_length -= n; memcpy(buffer, plaintext, n); plaintext += n; /* * XOR plain text block with previous encrypted * output (i.e., use CBC) */ for (i = 0; i < 16; i++) { buffer[i] ^= IV[i]; } /* * Encrypt the contents of the buffer */ aes_encrypt(&aes_ctx, buffer, buffer); /* * Concatenate the "text" as we compute the HMAC */ sha256_update(&sha_ctx, buffer, 16); /* * Write the encrypted block */ memcpy(p, buffer, 16); p += 16; /* * Update the IV (CBC mode) */ memcpy(IV, buffer, 16); } /* * Write the HMAC */ sha256_finish(&sha_ctx, digest); sha256_starts(&sha_ctx); sha256_update(&sha_ctx, opad, 64); sha256_update(&sha_ctx, digest, 32); sha256_finish(&sha_ctx, digest); memcpy(p, digest, 32); p += 32; return (p - ciphertext); } /* * AESStringDecrypt * * Description * This function is called to decrypt the string "ciphertext". * The decrypted string is placed in "plaintext". * * Parameters * password [in] * The password used to encrypt the string in UCS-16 * format. * password_length [in] * The length of the password in octets * ciphertext [in] * The ciphertext string to be decrypted * ciphertext_length [in] * The length of the ciphertext string * plaintext [out] * The decrypted string * * Returns * Returns the length of the plaintext string or AESSTRINGCRYPT_ERROR * if there was an error when trying to encrypt the string. */ unsigned long long AESStringDecrypt(unsigned char *password, unsigned long password_length, unsigned char *ciphertext, unsigned long long ciphertext_length, unsigned char *plaintext) { aes_context aes_ctx; sha256_context sha_ctx; sha256_t digest; unsigned char IV[16]; int i, n; unsigned char buffer[64], buffer2[32]; unsigned char ipad[64], opad[64]; unsigned char *p; int final_block_size; /* * Encrypted strings will be at least 53 octets in length * and the rest must be a multiple of 16 octets */ if (ciphertext_length < 53) { return AESSTRINGCRYPT_ERROR; } if (!(ciphertext[0] == 'A' && ciphertext[1] == 'E' && ciphertext[2] == 'S')) { return AESSTRINGCRYPT_ERROR; } /* * Validate the version number and take any version-specific actions */ if (ciphertext[3] > 0) { return AESSTRINGCRYPT_ERROR; } /* * Take note of the final block size */ final_block_size = ciphertext[4]; /* * Move pointers and count beyond header */ ciphertext += 5; ciphertext_length -= 5; /* * We will use p to write into the plaintext buffer */ p = plaintext; /* * Read the initialization vector */ memcpy(IV, ciphertext, 16); ciphertext += 16; ciphertext_length -= 16; /* * Hash the IV and password 8192 times */ memset(digest, 0, 32); memcpy(digest, IV, 16); for (i = 0; i < 8192; i++) { sha256_starts(&sha_ctx); sha256_update(&sha_ctx, digest, 32); sha256_update(&sha_ctx, password, password_length); sha256_finish(&sha_ctx, digest); } /* * Set the AES encryption key */ aes_set_key(&aes_ctx, digest, 256); /* * Set the ipad and opad arrays with values as * per RFC 2104 (HMAC). HMAC is defined as * H(K XOR opad, H(K XOR ipad, text)) */ memset(ipad, 0x36, 64); memset(opad, 0x5C, 64); for (i = 0; i < 32; i++) { ipad[i] ^= digest[i]; opad[i] ^= digest[i]; } sha256_starts(&sha_ctx); sha256_update(&sha_ctx, ipad, 64); while (ciphertext_length > 32) { memcpy(buffer, ciphertext, 16); memcpy(buffer2, ciphertext, 16); ciphertext += 16; ciphertext_length -= 16; sha256_update(&sha_ctx, buffer, 16); aes_decrypt(&aes_ctx, buffer, buffer); /* * XOR plain text block with previous encrypted output (i.e., use CBC) */ for (i = 0; i < 16; i++) { buffer[i] ^= IV[i]; } /* * Update the IV (CBC mode) */ memcpy(IV, buffer2, 16); /* * If this is the final block, then we may * write less than 16 octets */ if ((ciphertext_length > 32) || (!final_block_size)) { n = 16; } else { n = final_block_size; } /* * Write the decrypted block */ memcpy(p, buffer, n); p += n; } /* * Verify that the HMAC is correct */ if (ciphertext_length != 32) { return AESSTRINGCRYPT_ERROR; } sha256_finish(&sha_ctx, digest); sha256_starts(&sha_ctx); sha256_update(&sha_ctx, opad, 64); sha256_update(&sha_ctx, digest, 32); sha256_finish(&sha_ctx, digest); if (memcmp(digest, ciphertext, 32)) { return AESSTRINGCRYPT_ERROR; } return (p - plaintext); } hamlib-4.6.5/security/security.c0000664000175000017500000000374615056640443012350 /* Borrowed for Hamlib from: * String Crypt Test (Linux) * Copyright (C) 2012, 2015 * * Author: Paul E. Jones * * This software is licensed as "freeware." Permission to distribute * this software in source and binary forms is hereby granted without a * fee. THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM * THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING, * BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE. * */ #include #include #include #ifdef _WIN32 #include //#include #else #include #endif #include "AESStringCrypt.h" #include "password.h" #include "../src/misc.h" #include "hamlib/config.h" #if defined(_WIN32) // gmtime_r can be defined by mingw #ifndef gmtime_r static struct tm *gmtime_r(const time_t *t, struct tm *r) { // gmtime is threadsafe in windows because it uses TLS const struct tm *theTm = gmtime(t); if (theTm) { *r = *theTm; return r; } else { return 0; } } #endif // gmtime_r #endif // _WIN32 // using tv_usec with a sleep gives a fairly good random number static int my_rand(int max) { time_t t; struct timeval tv; struct tm result; t = time(NULL); gmtime_r(&t, &result); gettimeofday(&tv, NULL); hl_usleep(100); int val = tv.tv_usec % max; return val; } void rig_make_key(char key[33]) { const char *all = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123467890!@#$%^&*()_=~<>/?"; int max = strlen(all); int i; for (i = 0; i < 32; ++i) { key[i] = all[my_rand(max)]; } key[32] = 0; } hamlib-4.6.5/security/Makefile.am0000664000175000017500000000034415056640443012360 ACLOCAL_AMFLAGS = -I. EXTRA_DIST = sctest.c noinst_LTLIBRARIES = libsecurity.la libsecurity_la_SOURCES = aes.c AESStringCrypt.c password.c security.c sha256.c md5.c aes.h AESStringCrypt.h password.h security.h sha256.h md5.h hamlib-4.6.5/android/0000775000175000017500000000000015056640475010161 5hamlib-4.6.5/android/config.h0000664000175000017500000002773215056640442011524 /* config.h for android port */ /* Frontend ABI version */ #define ABI_VERSION 2 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARGZ_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the `atexit' function. */ #define HAVE_ATEXIT 1 /* Define to 1 if you have the `cfmakeraw' function. */ #define HAVE_CFMAKERAW 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_DEV_PPBUS_PPBCONF_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_DEV_PPBUS_PPI_H */ /* Define to 1 if you have the header file, and it defines `DIR'. */ #define HAVE_DIRENT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `gai_strerror' function. */ #define HAVE_GAI_STRERROR 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_GD_H */ /* Define to 1 if you have the `getaddrinfo' function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if you have the `getopt' function. */ #define HAVE_GETOPT 1 /* Define to 1 if you have the header file. */ #define HAVE_GETOPT_H 1 /* Define to 1 if you have the `getopt_long' function. */ #define HAVE_GETOPT_LONG 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `ioctl' function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the `syslog' library (-lsyslog). */ /* #undef HAVE_LIBSYSLOG */ /* Define to 1 if you have the header file. */ #define HAVE_LINUX_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `memset' function. */ #define HAVE_MEMSET 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_NDIR_H */ /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_NET_ERRNO_H */ /* If available, contains the Python version number currently in use. */ /* #undef HAVE_PYTHON */ /* Define to 1 if you have the `select' function. */ #define HAVE_SELECT 1 /* Define to 1 if you have the `setitimer' function. */ #define HAVE_SETITIMER 1 /* Define to 1 if you have the header file. */ #define HAVE_SGTTY_H 1 /* Define to 1 if you have the `sigaction' function. */ #define HAVE_SIGACTION 1 /* Define to 1 if the system has the type `siginfo_t'. */ #define HAVE_SIGINFO_T 1 /* Define to 1 if you have the `sleep' function. */ #define HAVE_SLEEP 1 /* Define to 1 if you have the `snprintf' function. */ #define HAVE_SNPRINTF 1 /* Define to 1 if the system has the type `ssize_t'. */ #define HAVE_SSIZE_T 1 /* Define to 1 if you have win32 Sleep */ /* #undef HAVE_SSLEEP */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strrchr' function. */ #define HAVE_STRRCHR 1 /* Define to 1 if you have the `strstr' function. */ #define HAVE_STRSTR 1 /* Define to 1 if you have the `strtol' function. */ #define HAVE_STRTOL 1 /* Define to 1 if the system has the type `struct addrinfo'. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if the system has the type `struct timezone'. */ #define HAVE_STRUCT_TIMEZONE 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_DIR_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_IOCCOM_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_NDIR_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_TCL_H */ /* Define to 1 if you have the header file. */ #define HAVE_TERMIOS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TERMIO_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_TERM_H */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ //#define HAVE_LIBUSB_H 1 /* Define to 1 if you have the header file. */ //#define HAVE_LIBUSB_1_0_LIBUSB_H 1 /* Define to 1 if you have the `usleep' function. */ #define HAVE_USLEEP 1 /* Define if usrp is available */ /* #undef HAVE_USRP */ /* Define to 1 if you have the header file. */ #define HAVE_VALUES_H 1 /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_WINBASE_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_WINIOCTL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define if libxml2 is available */ /* #undef HAVE_XML2 */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "hamlib-developer@lists.sourceforge.net" /* Define to the full name of this package. */ #define PACKAGE_NAME "Hamlib" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "Hamlib 1.2.15" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "hamlib" /* Define to the home page for this package. */ #define PACKAGE_URL "http://www.hamlib.org" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.2.15" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ /* #undef PTHREAD_CREATE_JOINABLE */ /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # define _POSIX_PTHREAD_SEMANTICS 1 #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # define _TANDEM_SOURCE 1 #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # define __EXTENSIONS__ 1 #endif /* Define to 1 if on MINIX. */ /* #undef _MINIX */ /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define to 1 if you need to in order for `stat' and other things to work. */ /* #undef _POSIX_SOURCE */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* Define missing prototypes, implemented in replacement lib */ #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_GETOPT int getopt (int argc, char * const argv[], const char * optstring); extern char * optarg; extern int optind, opterr, optopt; #endif #ifndef HAVE_GETOPT_LONG struct option; int getopt_long (int argc, char * const argv[], const char * optstring, const struct option * longopts, int * longindex); #endif #ifndef HAVE_USLEEP int usleep(unsigned long usec); /* SUSv2 */ #endif #if defined(HAVE_SSLEEP) && !defined(HAVE_SLEEP) #ifdef HAVE_WINBASE_H #include #include #endif /* TODO: what about SleepEx? */ static inline unsigned int sleep (unsigned int nb_sec) { Sleep(nb_sec*1000); return 0; } #endif #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_SYS_TIME_H #include #endif #ifndef HAVE_STRUCT_TIMEZONE struct timezone { int tz_minuteswest; int tz_dsttime; }; #endif int gettimeofday(struct timeval *tv, struct timezone *tz); #endif #ifndef HAVE_SSIZE_T typedef size_t ssize_t; #endif #ifdef __cplusplus } #endif /* Define missing prototypes, implemented in replacement lib */ #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_STRUCT_ADDRINFO #ifdef HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #elif HAVE_WS2TCPIP_H #include #endif struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; }; #endif #ifndef HAVE_GETADDRINFO #ifdef HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #elif HAVE_WS2TCPIP_H #include #endif #ifndef AI_PASSIVE #define AI_PASSIVE 0x0001 #endif int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); #endif #if !defined(HAVE_GAI_STRERROR) && !defined(gai_strerror) const char *gai_strerror(int errcode); #endif /* !HAVE_GAI_STRERROR */ #ifdef __cplusplus } #endif #define HAMLIB_MODULE_DIR "." hamlib-4.6.5/android/ltdl.h0000664000175000017500000000226215056640442011205 /* * ltdl.h - ltdl emulation for android * * Copyright (C) 2012 Ladislav Vaiz * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ typedef void *lt_dlhandle; int lt_dlinit(void); int lt_dlexit(void); int lt_dladdsearchdir(const char *search_dir); lt_dlhandle lt_dlopen(const char *filename); lt_dlhandle lt_dlopenext(const char *filename); int lt_dlclose(lt_dlhandle handle); void *lt_dlsym(lt_dlhandle handle, const char *name); const char *lt_dlerror(void); hamlib-4.6.5/android/README.android0000664000175000017500000000236315056640442012376 Update Note: These Android NDK scripts can compile the 4.3 version of hamlib normally, but they may be corrupted as the master branch code is updated. If you encounter compile-time errors, please try to fix them, or choose to recompile with version 4.3. This is android port of hamlib (C) 2012 Ladislav Vaiz Notes: * use hamlib-compile script to build hamlib for android * script deletes file include/config.h, it conflicts with android/config.h * android port implements ltdl interface and calls dlfcn functions directly * RPC is not present on android * ARS backend is compiled without pthreads because of deprecated pthread_cancel * I don'k know how to connect to real radio: ** Bluetooth API is available only under Java, not from native code ** FTDI USB to serial converter driver is not included in standard kernel. It should work on rooted device. ** But NET rigctl works fine * Backends are named libhamlib-vendor.so, I don't know how to include libraries without lib prefix into APK * Check the location of libusb.h and define the corresponding macro accordingly in config.h. * Had to build without libusb as ndk did not contain it ** comment out HAVE_LIBUSB_H in android/config.h if you get libusb errors Happy hacking 73 Lada, OK1ZIA hamlib-4.6.5/android/ltdl.c0000664000175000017500000001016415056640442011200 /* * ltdl.c - ltdl emulation for android * Copyright (C) 2012 Ladislav Vaiz * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #ifdef ANDROID #include #endif #define APREFIX "lib" #define ASUFFIX ".so" #define AMAXSTR 1024 #define ASONAME "libhamlib.so" // path to application's libraries with trailing slash char *libpath = NULL; char *getlibpath(void) { char s[AMAXSTR]; FILE *f; if (libpath != NULL) { return libpath; } f = fopen("/proc/self/maps", "rt"); if (!f) { return "./"; } while (fgets(s, AMAXSTR - 1, f)) { char *c; s[AMAXSTR - 1] = '\0'; c = strstr(s, ASONAME); if (!c) { continue; } // s is like "4a8a5000-4a8a6000 r--p 00018000 1f:01 743 /data/data/cz.nagano.tucnak/lib/libhamlib.so\n" *c = '\0'; c = strchr(s, '/'); if (!c) { continue; } libpath = calloc(1, strlen(c) + 1); strcpy(libpath, c); break; } fclose(f); return libpath; } #ifdef XXREMOVEDXX // Not referenced anywhere int lt_dlinit(void) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlinit"); return 0; } #endif // not called from hamlib #ifdef XXREMOVEDXX // Not referenced anywhere int lt_dlexit(void) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlexit"); if (libpath != NULL) { free(libpath); libpath = NULL; } return 0; } #endif #ifdef XXREMOVEDXX int lt_dladdsearchdir(const char *search_dir) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dladdsearchdir"); return 0; } #endif lt_dlhandle adlopen(const char *filename) { char *c; lt_dlhandle *ret; // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "adlopen('%s')", filename); getlibpath(); if (libpath == NULL || filename == NULL) { return NULL; } c = calloc(1, strlen(libpath) + strlen(APREFIX) + strlen(filename) + strlen( ASUFFIX) + 1); strcpy(c, libpath); strcat(c, APREFIX); strcat(c, filename); strcat(c, ASUFFIX); ret = dlopen(c, 0); // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "adlopen('%s')=%p", c, ret); free(c); return ret; } #ifdef XXREMOVEDXX // Not referenced anywhere lt_dlhandle lt_dlopen(const char *filename) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlopen(%s)", filename); return adlopen(filename); } #endif #ifdef XXREMOVEDXX // Not referenced anywhere lt_dlhandle lt_dlopenext(const char *filename) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlopenext(%s)", filename); return adlopen(filename); } #endif #ifdef XXREMOVEDXX // Not referenced anywhere int lt_dlclose(lt_dlhandle handle) { // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlclose"); return dlclose(handle); } #endif #ifdef XXREMOVEDXX // Not referenced anywhere void *lt_dlsym(lt_dlhandle handle, const char *name) { void *ret = dlsym(handle, name); // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlsym(%s)=%p", name, ret); return ret; } #endif #ifdef XXREMOVEDXX // Not referenced anywhere const char *lt_dlerror(void) { const char *ret = dlerror(); // __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "lt_dlerror=%s", ret); return ret; } #endif hamlib-4.6.5/android/Makefile.in0000664000175000017500000003665515056640452012160 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = android ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = config.h hamlib-compile ltdl.c ltdl.h README.android all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu android/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu android/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/android/hamlib-compile0000775000175000017500000000103215056640442012677 #!/bin/sh set -e set -x tmp=$(dirname $0) HAMLIB=$(readlink -f $tmp/..) cd $HAMLIB rm -f $HAMLIB/include/config.h if [ "$1" = "clean" ]; then ndk-build NDK_PROJECT_PATH=$HAMLIB APP_BUILD_SCRIPT=$HAMLIB/Android.mk clean exit fi if [ -n "$1" ]; then ndk-build --trace NDK_PROJECT_PATH=$HAMLIB APP_BUILD_SCRIPT=$HAMLIB/Android.mk PP_ALLOW_MISSING_DEPS=true $1 exit fi #ndk-build NDK_PROJECT_PATH=$HAMLIB APP_BUILD_SCRIPT=$HAMLIB/Android.mk hamlib ndk-build NDK_PROJECT_PATH=$HAMLIB APP_BUILD_SCRIPT=$HAMLIB/Android.mk hamlib-4.6.5/android/Makefile.am0000664000175000017500000000010615056640442012124 EXTRA_DIST = config.h hamlib-compile ltdl.c ltdl.h README.android hamlib-4.6.5/README.freqranges0000664000175000017500000000124115056640442011465 Frequency ranges are being changed to reflect rig capabilities instead of region restrictions As of 2020-05-05 the behavior is: #1 Any range which shows ITU# or TBD has not been modified to this convention #2 Ranges on the backends are being change to USA/EUR/KOR/TPE/ITR per the IC-9700 convention. So if you see one of those monikers on a rig's freq range it should accurately reflect the rig's capabilities. Note that most rigs will have just USA or USA/EUR models. Not too many rigs have more than 2 models but it appears at least Icom is headed that way. USA - United States of America EUR - Europe KOR - Korea TPE - Japan ITR - ?? AUS - Australia CHN - China hamlib-4.6.5/README.osx0000664000175000017500000000136715056640442010152 OSX Builds ---------- To compile Hamlib on OSX you have to install autoconf, automake and libtool. The easiest way to install them is either via the brew package manager or macports.. Brew: https://brew.sh Once brew is installed, execute $ brew install automake autoconf libtool Macports: https://www.macports.org/install.php Once installed, execute $ sudo port install automake autoconf libtool Build ----- Execute bootstrap to generate the build system files $ ./bootstrap Then configure with the desired flags $ ./configure Then compile the hamlib files $ make Hint: "make -jx" with x for the amount of CPU cores will speed up the compilation Install hamlib -------------- Install the Hamlib libraries and executables $ sudo make install hamlib-4.6.5/rotators/0000775000175000017500000000000015056640502010405 5hamlib-4.6.5/rotators/celestron/0000775000175000017500000000000015056640501012402 5hamlib-4.6.5/rotators/celestron/celestron.h0000664000175000017500000000173415056640443014503 /* * Hamlib Rotator backend - Celestron interface protocol * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_CELESTRON_H #define _ROT_CELESTRON_H 1 #include "rotator.h" extern const struct rot_caps nexstar_rot_caps; #endif /* _ROT_CELESTRON_H */ hamlib-4.6.5/rotators/celestron/Android.mk0000664000175000017500000000040015056640443014232 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := celestron.c LOCAL_MODULE := celestron LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/celestron/Makefile.in0000664000175000017500000005244315056640453014405 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/celestron ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_celestron_la_LIBADD = am_libhamlib_celestron_la_OBJECTS = celestron.lo libhamlib_celestron_la_OBJECTS = $(am_libhamlib_celestron_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/celestron.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_celestron_la_SOURCES) DIST_SOURCES = $(libhamlib_celestron_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-celestron.la libhamlib_celestron_la_SOURCES = celestron.c celestron.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/celestron/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/celestron/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-celestron.la: $(libhamlib_celestron_la_OBJECTS) $(libhamlib_celestron_la_DEPENDENCIES) $(EXTRA_libhamlib_celestron_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_celestron_la_OBJECTS) $(libhamlib_celestron_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/celestron.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/celestron.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/celestron.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/celestron/celestron.c0000664000175000017500000001520315056640443014472 /* * Hamlib Rotator backend - Celestron * Copyright (c) 2011 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "celestron.h" #define ACK "#" #define BUFSZ 128 /** * celestron_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. */ static int celestron_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; char replybuf[BUFSZ]; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to know whether the cmd went OK */ if (!data) { data = replybuf; } if (!data_len) { data_len = BUFSZ; } /* the answer */ memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, ACK, strlen(ACK), 0, 1); if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } /* check for acknowledge */ if (retval < 1 || data[retval - 1] != '#') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected response, len %d: '%s'\n", __func__, retval, data); return -RIG_EPROTO; } data[retval - 1] = '\0'; retval = RIG_OK; transaction_quit: return retval; } static int celestron_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[32]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); /* Note: if the telescope has not been aligned, the RA/DEC values will not be meaningful and the AZM-ALT values will be relative to where the telescope was powered on. After alignment, RA/DEC values will reflect the actual sky, azimuth will be indexed to North equals 0 and altitude will be indexed with 0 equal to the orientation where the optical tube is perpendicular to the azimuth axis. */ SNPRINTF(cmdstr, sizeof(cmdstr), "B%04X,%04X", (unsigned)((az / 360.) * 65535), (unsigned)((el / 360.) * 65535)); retval = celestron_transaction(rot, cmdstr, NULL, 0); return retval; } static int celestron_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; int retval; unsigned w; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* Get Azm-Alt */ retval = celestron_transaction(rot, "Z", posbuf, sizeof(posbuf)); if (retval != RIG_OK || strlen(posbuf) < 9 || posbuf[4] != ',') { return retval < 0 ? retval : -RIG_EPROTO; } if (sscanf(posbuf, "%04X", &w) != 1) { return -RIG_EPROTO; } *az = ((azimuth_t)w * 360.) / 65536.; if (sscanf(posbuf + 5, "%04X", &w) != 1) { return -RIG_EPROTO; } *el = ((elevation_t)w * 360.) / 65536.; rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int celestron_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* Cancel Goto */ retval = celestron_transaction(rot, "M", NULL, 0); return retval; } static const char * celestron_get_info(ROT *rot) { static char info[32]; char str[8]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (celestron_transaction(rot, "V", str, sizeof(str)) != RIG_OK) { return NULL; } SNPRINTF(info, sizeof(info), "V%c.%c", str[0], str[1]); return info; } /* ************************************************************************* */ /* * Celestron Nexstar telescope(rotator) capabilities. * * Protocol documentation: * from Celestron: * http://www.celestron.com/c3/images/files/downloads/1154108406_nexstarcommprot.pdf * from Orion Teletrack Az-G: * http://content.telescope.com/rsc/img/catalog/product/instructions/29295.pdf */ const struct rot_caps nexstar_rot_caps = { ROT_MODEL(ROT_MODEL_NEXSTAR), .model_name = "NexStar", // Any Celestron starting with version 1.2 .mfg_name = "Celestron", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 0, .timeout = 3500, /* worst case scenario */ .retry = 1, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .get_position = celestron_get_position, .set_position = celestron_set_position, .stop = celestron_stop, .get_info = celestron_get_info, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(celestron) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&nexstar_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/celestron/Makefile.am0000664000175000017500000000017715056640443014370 noinst_LTLIBRARIES = libhamlib-celestron.la libhamlib_celestron_la_SOURCES = celestron.c celestron.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/skywatcher/0000775000175000017500000000000015056640502012571 5hamlib-4.6.5/rotators/skywatcher/skywatcher.h0000664000175000017500000000204015056640443015046 /* * Hamlib Rotator backend - SkyWatcher interface protocol * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef HAMLIB_SKYWATCHER_H #define HAMLIB_SKYWATCHER_H 1 #define SKYWATCHER_PARK_AZ 0 #define SKYWATCHER_PARK_EL 0 #include "rotator.h" extern const struct rot_caps skywatcher_rot_caps; #endif //HAMLIB_SKYWATCHER_H hamlib-4.6.5/rotators/skywatcher/Android.mk0000664000175000017500000000040215056640443014422 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := skywatcher.c LOCAL_MODULE := skywatcher LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/skywatcher/Makefile.in0000664000175000017500000005247715056640453014602 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/skywatcher ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_skywatcher_la_LIBADD = am_libhamlib_skywatcher_la_OBJECTS = skywatcher.lo libhamlib_skywatcher_la_OBJECTS = \ $(am_libhamlib_skywatcher_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/skywatcher.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_skywatcher_la_SOURCES) DIST_SOURCES = $(libhamlib_skywatcher_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-skywatcher.la libhamlib_skywatcher_la_SOURCES = skywatcher.c skywatcher.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/skywatcher/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/skywatcher/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-skywatcher.la: $(libhamlib_skywatcher_la_OBJECTS) $(libhamlib_skywatcher_la_DEPENDENCIES) $(EXTRA_libhamlib_skywatcher_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_skywatcher_la_OBJECTS) $(libhamlib_skywatcher_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skywatcher.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/skywatcher.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/skywatcher.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/skywatcher/skywatcher.c0000664000175000017500000002217115056640443015050 /* * Hamlib Rotator backend - SkyWatcher * Copyright (c) 2024 by Andrey Rodionov * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "skywatcher.h" #include "register.h" #include "serial.h" #define SKYWATCHER_ERROR_CODES_LENGTH 9 #define ERROR_CHECK(x) \ do { \ int __err_rc = (x); \ if (__err_rc != RIG_OK) { \ return __err_rc; \ } \ } while (0) static const char *skywatcher_error_codes[SKYWATCHER_ERROR_CODES_LENGTH] = { "Unknown Command", "Command Length Error", "Motor not Stopped", "Invalid Character", "Not Initialized", "Driver Sleeping", "Unknown", "PEC Training is running", "No Valid PEC data" }; typedef struct { uint32_t cpr[2]; } skywatcher_priv_data; static int skywatcher_cmd(ROT *rot, const char *cmd, char *response, size_t response_len) { hamlib_port_t *port = ROTPORT(rot); rig_flush(port); size_t cmd_len = strlen(cmd); ERROR_CHECK(write_block(port, (unsigned char *) cmd, cmd_len)); // echo from the device int code = read_string(port, (unsigned char *) response, response_len, "\r", 1, 0, 1); if (code < 0) { return -code; } // the actual response code = read_string(port, (unsigned char *) response, response_len, "\r", 1, 0, 1); if (code < 0) { return -code; } // nullify last \r response[strlen(response) - 1] = '\0'; if (response[0] == '!') { code = atoi(&response[1]); if (code < SKYWATCHER_ERROR_CODES_LENGTH) { rig_debug(RIG_DEBUG_ERR, "Error code: %d Message: '%s'\n", code, skywatcher_error_codes[code]); } else { rig_debug(RIG_DEBUG_ERR, "Error response: '%s'\n", response); } return RIG_EPROTO; } // remove leading '=' memmove(response, response + 1, strlen(response) - 1); response[strlen(response) - 1] = '\0'; return RIG_OK; } uint32_t skywatcher_convert24bit(long input) { return ((input & 0x0000FF) << 16) | (input & 0x00FF00) | (( input & 0xFF0000) >> 16); } static const char *skywatcher_get_info(ROT *rot) { static char info[32]; char str[16]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); // Read from 1st motor only. In practice both motors have the same version if (skywatcher_cmd(rot, ":e1\r", str, sizeof(str)) != RIG_OK) { return NULL; } SNPRINTF(info, sizeof(info), "V%s", str); return info; } int skywatcher_get_spr(ROT *rot, int motor_index, uint32_t *result) { skywatcher_priv_data *priv = ROTSTATE(rot)->priv; if (priv->cpr[motor_index - 1] != 0) { *result = priv->cpr[motor_index - 1]; return RIG_OK; } char str[16]; char req[16]; SNPRINTF(req, sizeof(req), ":a%d\r", motor_index); ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); priv->cpr[motor_index - 1] = skywatcher_convert24bit(strtol(str, NULL, 16)); *result = priv->cpr[motor_index - 1]; return RIG_OK; } int skywatcher_get_motor_position(ROT *rot, int motor_index, float *result) { char str[16]; char req[16]; SNPRINTF(req, sizeof(req), ":j%d\r", motor_index); ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); long motor_ticks = skywatcher_convert24bit(strtol(str, NULL, 16)) ^ 0x800000; uint32_t cpr; ERROR_CHECK(skywatcher_get_spr(rot, motor_index, &cpr)); double ticks_per_angle = (double) cpr / 360.0; *result = (float)((double) motor_ticks / ticks_per_angle); return RIG_OK; } static int skywatcher_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); ERROR_CHECK(skywatcher_get_motor_position(rot, 1, (float *) az)); // normalize to 0 ~ 360 if (*az < 0.0f) { *az = 360.0f + *az; } ERROR_CHECK(skywatcher_get_motor_position(rot, 2, (float *) el)); rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int skywatcher_stop(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); char str[16]; // don't wait for actual stop. Operation can be async ERROR_CHECK(skywatcher_cmd(rot, ":K1\r", str, sizeof(str))); ERROR_CHECK(skywatcher_cmd(rot, ":K2\r", str, sizeof(str))); return RIG_OK; } int skywatcher_set_motor_position(ROT *rot, int motor_index, float angle) { char str[16]; char req[16]; hamlib_port_t *rotp = ROTPORT(rot); SNPRINTF(req, sizeof(req), ":f%d\r", motor_index); int current_retry = 0; int stopped = 0; while (current_retry < rotp->retry) { ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); int status = str[1] - '0'; if (status & 0b10) { rig_debug(RIG_DEBUG_ERR, "%s: motor is blocked\n", __func__); return RIG_EPROTO; } if (status & 0b1) { current_retry++; //10ms sleep just to make sure motor is fully stopped hl_usleep(10000); continue; } stopped = 1; break; } if (!stopped) { return RIG_EPROTO; } SNPRINTF(req, sizeof(req), ":G%d00\r", motor_index); ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); uint32_t cpr; ERROR_CHECK(skywatcher_get_spr(rot, motor_index, &cpr)); double ticks_per_angle = (double) cpr / 360.0; uint32_t value = ((uint32_t)(ticks_per_angle * angle)) & 0xFFFFFF; value = value | 0x800000; SNPRINTF(req, sizeof(req), ":S%d%02X%02X%02X\r", motor_index, (value & 0xFF), (value & 0xFF00) >> 8, (value & 0xFF0000) >> 16); ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); // start motion, don't wait until it completes SNPRINTF(req, sizeof(req), ":J%d\r", motor_index); ERROR_CHECK(skywatcher_cmd(rot, req, str, sizeof(str))); return RIG_OK; } static int skywatcher_set_position(ROT *rot, azimuth_t az, elevation_t el) { rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); ERROR_CHECK(skywatcher_stop(rot)); // stop is called for 1 then for 2 motor. do motor position in reverse because it awaits "stop motor" state. // potentially saving 1 call to :f ERROR_CHECK(skywatcher_set_motor_position(rot, 2, el)); ERROR_CHECK(skywatcher_set_motor_position(rot, 1, az)); return RIG_OK; } static int skywatcher_init(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); skywatcher_priv_data *result = calloc(1, sizeof(skywatcher_priv_data)); if (result == NULL) { return -RIG_ENOMEM; } memset(result->cpr, 0, sizeof(result->cpr)); ROTSTATE(rot)->priv = result; return RIG_OK; } static int skywatcher_cleanup(ROT *rot) { skywatcher_priv_data *priv = ROTSTATE(rot)->priv; if (priv == NULL) { return RIG_OK; } free(priv); return RIG_OK; } /* ************************************************************************* */ /* * Protocol documentation: * https://inter-static.skywatcher.com/downloads/skywatcher_motor_controller_command_set.pdf */ const struct rot_caps skywatcher_rot_caps = { ROT_MODEL(ROT_MODEL_SKYWATCHER), .model_name = "Sky-Watcher", .mfg_name = "Sky-Watcher", .version = "20240825.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 0, .timeout = 3500, /* worst case scenario */ .retry = 1, .min_az = 0.0f, .max_az = 360.0f, .min_el = 0.0f, .max_el = 180.0f, .rot_init = skywatcher_init, .rot_cleanup = skywatcher_cleanup, .get_position = skywatcher_get_position, .set_position = skywatcher_set_position, .stop = skywatcher_stop, .get_info = skywatcher_get_info, }; DECLARE_INITROT_BACKEND(skywatcher) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&skywatcher_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/skywatcher/Makefile.am0000664000175000017500000000020315056640443014544 noinst_LTLIBRARIES = libhamlib-skywatcher.la libhamlib_skywatcher_la_SOURCES = skywatcher.c skywatcher.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/ioptron/0000775000175000017500000000000015056640502012077 5hamlib-4.6.5/rotators/ioptron/Android.mk0000664000175000017500000000036715056640443013742 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := rot_ioptron.c LOCAL_MODULE := ioptron LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/ioptron/Makefile.in0000664000175000017500000005251315056640453014077 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/ioptron ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_ioptron_la_LIBADD = am__objects_1 = rot_ioptron.lo am_libhamlib_ioptron_la_OBJECTS = $(am__objects_1) libhamlib_ioptron_la_OBJECTS = $(am_libhamlib_ioptron_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/rot_ioptron.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_ioptron_la_SOURCES) DIST_SOURCES = $(libhamlib_ioptron_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ IOPTRONSRC = rot_ioptron.c rot_ioptron.h noinst_LTLIBRARIES = libhamlib-ioptron.la libhamlib_ioptron_la_SOURCES = $(IOPTRONSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/ioptron/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/ioptron/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-ioptron.la: $(libhamlib_ioptron_la_OBJECTS) $(libhamlib_ioptron_la_DEPENDENCIES) $(EXTRA_libhamlib_ioptron_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_ioptron_la_OBJECTS) $(libhamlib_ioptron_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_ioptron.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/rot_ioptron.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/rot_ioptron.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/ioptron/rot_ioptron.h0000664000175000017500000000203215056640443014547 /* * Hamlib Meade telescope rotor backend - main header * Copyright (c) 2018 by Andreas Mueller (DC1MIL) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _IOPTRON_H #define _IOPTRON_H 1 #define BUFSIZE 128 #define CR "\r" #define LF "\x0a" extern const struct rot_caps ioptron_caps; #endif /* _IOPTRON_H */ hamlib-4.6.5/rotators/ioptron/rot_ioptron.c0000664000175000017500000002476015056640443014556 /* * Hamlib Rotator backend - Celestron * Copyright (c) 2011 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "rot_ioptron.h" #define ACK "#" #define ACK1 '1' #define BUFSZ 128 /** * ioptron_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. * resp_len - in: Expected length of response. It is the caller's responsibility to * provide a buffer at least 1 byte larger than this for null terminator. * * COMMANDS note: as of 12/2018 a mixture of V2 and V3 * | TTTTTTTT(T) .01 arc seconds * | alt- sign with 8 digits, az - 9 digits | * | Command | Attribute | Return value | Description | * -------------------------------------------------------------------| * | :GAC# | .01 arcsec | sTTTTTTTTTTTTTTTTT# | gets alt(s8), az(9) | * | :SzTTTTTTTTT# | .01 arcsec | '1' == OK | Set Target azimuth | * | :SasTTTTTTTT# |.01 arcsec | '1' == OK | Set Target elevation | * | :Q# | - | '1' == OK | Halt all slewing | * | :ST0# | - | '1' == OK | Halt tracking | * | :MS# | - | '1' == OK | GoTo Target | * | * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. */ static int ioptron_transaction(ROT *rot, const char *cmdstr, char *data, size_t resp_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval = 0; int retry_read; for (retry_read = 0; retry_read <= rotp->retry; retry_read++) { rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } } /** the answer */ memset(data, 0, resp_len + 1); retval = read_block(rotp, (unsigned char *) data, resp_len); /** if expected number of bytes received, return OK status */ if (retval == resp_len) { return RIG_OK; } } /** if got here, retry loop failed */ rig_debug(RIG_DEBUG_ERR, "%s: unexpected response, len %d: '%s'\n", __func__, retval, data); return -RIG_EPROTO; } /** get mount type code, initializes mount */ static const char * ioptron_get_info(ROT *rot) { static char info[32]; char str[6]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = ioptron_transaction(rot, ":MountInfo#", str, 4); rig_debug(RIG_DEBUG_TRACE, "retval, RIG_OK str %d %d %str\n", retval, RIG_OK, str); SNPRINTF(info, sizeof(info), "MountInfo %s", str); return info; } /** * Opens the Port and sets all needed parameters for operation * as of 12/2018 initiates mount with V3 :MountInfo# */ static int ioptron_open(ROT *rot) { const char *info; int retval; char retbuf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); info = ioptron_get_info(rot); /* ioptron_get_info returns "MountInfo xxxx", check model number from string */ /* string of 4 numeric digits is likely model number */ if ((strlen(&info[10]) != 4) || (strspn(&info[10], "1234567890") != 4)) { return -RIG_ETIMEOUT; } /** stops tracking, returns "1" if OK */ retval = ioptron_transaction(rot, ":ST0#", retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } /** set alt limit to -1 since firmware bug sometimes doesn't allow alt of 0 when limit is 0 */ /** returns "1" if OK */ retval = ioptron_transaction(rot, ":SAL-01#", retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } return RIG_OK; } /** gets current position */ static int ioptron_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; int retval; float w; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /** Get Az-Alt */ retval = ioptron_transaction(rot, ":GAC#", posbuf, 19); if (retval != RIG_OK || strlen(posbuf) < 19) { return retval < 0 ? retval : -RIG_EPROTO; } if (sscanf(posbuf, "%9f", &w) != 1) { return -RIG_EPROTO; } /** convert from .01 arc sec to degrees */ /** note that firmware only reports alt between -90 and +90 */ /** e.g. both 80 and 100 degrees are read as 80 degrees */ *el = ((elevation_t)w / 360000.); if (sscanf(posbuf + 9, "%9f", &w) != 1) { return -RIG_EPROTO; } *az = ((azimuth_t)w / 360000.); rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } /** stop everything **/ static int ioptron_stop(ROT *rot) { int retval; char retbuf[10]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /** stop slew, returns "1" if OK */ retval = ioptron_transaction(rot, ":Q#", retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } /** stops tracking returns "1" if OK */ retval = ioptron_transaction(rot, ":ST0#", retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } return RIG_OK; } /** sets mount position, requires 4 steps * set azimuth * set altitude * goto set * stop tracking - mount starts tracking after goto */ static int ioptron_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[32]; char retbuf[10]; int retval; double faz, fel; azimuth_t curr_az; elevation_t curr_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); /* units .01 arc sec */ faz = az * 360000; fel = el * 360000; /** Firmware bug: (at least for AZ Mount Pro as of FW 20200305) * azimuth has problems going to 0 * going to 0 from <=180 causes it to overshoot 0 and never stop * going to 0 from >180 causes it to make a hard stop at 0 and a following * command to <= 180 will make it rotate forever until manually stopped, * and require resetting the mount for azimuth to work correctly again * similar behavior is seen the other direction (>180 to 360 goes past 360, * <=180 to 360 makes a hard stop with the possibility of loss of * azimuth control) * Workaround: * get current position, if 0 is requested, go to 0.01 arcseconds away from * 0 from the same direction (e.g. go to 0.01 arcseconds if currently <= 180, * 129599999 arcseconds if currently > 180) */ if (faz == 0) { /* make sure stopped */ retval = ioptron_stop(rot); if (retval != RIG_OK) { return -RIG_EPROTO; } /* get current position */ retval = ioptron_get_position(rot, &curr_az, &curr_el); if (retval != RIG_OK) { return -RIG_EPROTO; } if (curr_az <= 180) { faz = 1; } else { faz = 129599999; /* needs double precision float */ } } /* set azimuth, returns '1" if OK */ SNPRINTF(cmdstr, sizeof(cmdstr), ":Sz%09.0f#", faz); retval = ioptron_transaction(rot, cmdstr, retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } /* set altitude, returns '1" if OK */ SNPRINTF(cmdstr, sizeof(cmdstr), ":Sa+%08.0f#", fel); retval = ioptron_transaction(rot, cmdstr, retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } /* move to set target, V2 command, returns '1" if OK */ SNPRINTF(cmdstr, sizeof(cmdstr), ":MS#"); // retval = ioptron_transaction(rot, cmdstr, retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } /* stop tracking, V2 command, returns '1" if OK */ SNPRINTF(cmdstr, sizeof(cmdstr), ":ST0#"); retval = ioptron_transaction(rot, cmdstr, retbuf, 1); if (retval != RIG_OK || retbuf[0] != ACK1) { return -RIG_EPROTO; } return retval; } /** ************************************************************************* * * ioptron mount capabilities. * * Protocol documentation: * from ioptron: * RS232-Command_Language pdf * note that iOptron is currently (12/2018) using a mix of V2 and V3 commands :( */ const struct rot_caps ioptron_rot_caps = { ROT_MODEL(ROT_MODEL_IOPTRON), .model_name = "iOptron", .mfg_name = "iOptron", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, /* worst case scenario 3500 */ .retry = 1, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .rot_open = ioptron_open, .get_position = ioptron_get_position, .set_position = ioptron_set_position, .stop = ioptron_stop, .get_info = ioptron_get_info, }; /* ****************************************************************** */ DECLARE_INITROT_BACKEND(ioptron) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&ioptron_rot_caps); return RIG_OK; } /* ****************************************************************** */ /* end of file */ hamlib-4.6.5/rotators/ioptron/Makefile.am0000664000175000017500000000023315056640443014055 IOPTRONSRC = rot_ioptron.c rot_ioptron.h noinst_LTLIBRARIES = libhamlib-ioptron.la libhamlib_ioptron_la_SOURCES = $(IOPTRONSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/ts7400/0000775000175000017500000000000015056640502011346 5hamlib-4.6.5/rotators/ts7400/ts7400.h0000664000175000017500000000203515056640443012404 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_ts7400_H #define _ROT_ts7400_H 1 #include "rotator.h" extern const struct rot_caps ts7400_rot_caps; extern const struct rot_caps netrotctl_caps; #endif /* _ROT_DUMMY_H */ hamlib-4.6.5/rotators/ts7400/Android.mk0000664000175000017500000000037115056640443013204 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ts7400.c LOCAL_MODULE := ts7400 LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/ts7400/Makefile.in0000664000175000017500000005252215056640453013346 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/ts7400 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_ts7400_la_LIBADD = am_libhamlib_ts7400_la_OBJECTS = ts7400.lo libhamlib_ts7400_la_OBJECTS = $(am_libhamlib_ts7400_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ts7400.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_ts7400_la_SOURCES) DIST_SOURCES = $(libhamlib_ts7400_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-ts7400.la libhamlib_ts7400_la_SOURCES = ts7400.c ts7400.h EXTRA_DIST = include/ep93xx_adc.h include/peekpoke.h \ include/io.c include/peekpoke.c include/readADC.c \ include/test7400ADC.c Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/ts7400/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/ts7400/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-ts7400.la: $(libhamlib_ts7400_la_OBJECTS) $(libhamlib_ts7400_la_DEPENDENCIES) $(EXTRA_libhamlib_ts7400_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_ts7400_la_OBJECTS) $(libhamlib_ts7400_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts7400.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ts7400.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ts7400.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/ts7400/include/0000775000175000017500000000000015056640502012771 5hamlib-4.6.5/rotators/ts7400/include/io.c0000664000175000017500000000314115056640443013467 // filename button.c // connect a button to DIO pin 1 and ground // blinks green and red led on the ts-7200 when button is pressed // // compile arm-linux-gcc -o button button.c // #include #include #include #include #include #include int main(int argc, char **argv) { volatile unsigned int *PEDR, *PEDDR, *PBDR, *PBDDR, *GPIOBDB; int i; unsigned char state; unsigned char *start; int fd = open("/dev/mem", O_RDWR | O_SYNC); start = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x80840000); PBDR = (unsigned int *)(start + 0x04); // port b PBDDR = (unsigned int *)(start + 0x14); // port b direction register PEDR = (unsigned int *)(start + 0x20); // port e data PEDDR = (unsigned int *)(start + 0x24); // port e direction register GPIOBDB = (unsigned int *)(start + 0xC4); // debounce on port b *PBDDR = 0xf0; // upper nibble output, lower nibble input *PEDDR = 0xff; // all output (just 2 bits) *GPIOBDB = 0x01; // enable debounce on bit 0 state = *PBDR; // read initial state while (state & 0x01) // wait until button goes low { state = *PBDR; // remember bit 0 is pulled up with 4.7k ohm } // blink 5 times, sleep 1 second so it's visible for (i = 0; i < 5; i++) { *PEDR = 0xff; sleep(1); *PEDR = 0x00; sleep(1); } close(fd); return 0; } hamlib-4.6.5/rotators/ts7400/include/peekpoke.h0000664000175000017500000000352015056640443014671 // We can't expect that a dereference of an unsigned short * always // produces a ldrh or strh since the compiler may choose to use // a byte write instead. Hence, we emit the peeks and pokes using // inline assembler. --JO // cppcheck-suppress unusedFunction static inline unsigned short PEEK16(unsigned long addr) { unsigned short ret; asm volatile ( "ldrh %0, [ %1 ]\n" : "=r" (ret) : "r" (addr) : "memory" ); return ret; } // cppcheck-suppress unusedFunction static inline void POKE16(unsigned long addr, unsigned short dat) { asm volatile ( "strh %1, [ %0 ]\n" : : "r" (addr), "r" (dat) : "memory" ); } static inline unsigned long PEEK32(unsigned long addr) { unsigned long ret; asm volatile ( "ldr %0, [ %1 ]\n" : "=r" (ret) : "r" (addr) : "memory" ); return ret; } static inline void POKE32(unsigned long addr, unsigned long dat) { asm volatile ( "str %1, [ %0 ]\n" : : "r" (addr), "r" (dat) : "memory" ); } // cppcheck-suppress unusedFunction static inline unsigned char PEEK8(unsigned long addr) { unsigned char ret; asm volatile ( "ldrb %0, [ %1 ]\n" : "=r" (ret) : "r" (addr) : "memory" ); return ret; } // cppcheck-suppress unusedFunction static inline void POKE8(unsigned long addr, unsigned char dat) { asm volatile ( "strb %1, [ %0 ]\n" : : "r" (addr), "r" (dat) : "memory" ); } #define TRUE 0x01 #define FALSE 0x00 hamlib-4.6.5/rotators/ts7400/include/ep93xx_adc.h0000664000175000017500000000421615056640443015040 #define ADC_PAGE 0x80900000 #define ADCRESULT_OFFSET 0x0008 #define SDR_MASK 0x80000000 #define DATA_OFFSET 0x0008 #define DATA_MASK 0xFFFF #define ADCSWITCH_OFFSET 0x0018 #define ADC_CH0 0x0608 #define ADC_CH1 0x0680 #define ADC_CH2 0x0640 #define ADC_CH3 0x0620 #define ADC_CH4 0x0610 #define ADCSWLOCK_OFFSET 0x0020 #define UNLOCK_VAL 0xAA #define SYSCON_PAGE 0x80930000 #define ADCCLKDIV_OFFSET 0x0090 #define SYSCON_UNLOCK 0x00C0 #define TSEN_MASK 0x80000000 #define DEVICECFG_OFFSET 0x0080 #define ADCPD_MASK 0x04 #define ADCEN_MASK 0x20000 /* prototypes */ void init_ADC(unsigned long adc_page, unsigned long syscon_page); int read_channel(unsigned long adc_page, unsigned short channel); static char is_ADC_busy(unsigned long adc_page); void init_ADC(unsigned long adc_page, unsigned long syscon_page) { unsigned long val; /* set TSEN bit */ val = PEEK32(syscon_page + ADCCLKDIV_OFFSET); //unlock the software lock POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL); POKE32(syscon_page + ADCCLKDIV_OFFSET, TSEN_MASK | val); /* set ADCEN bit */ val = PEEK32(syscon_page + DEVICECFG_OFFSET); POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock POKE32(syscon_page + DEVICECFG_OFFSET, val | ADCEN_MASK); /* clear ADCPD bit */ val = PEEK32(syscon_page + DEVICECFG_OFFSET); POKE32(adc_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock POKE32(syscon_page + DEVICECFG_OFFSET, val & ~ADCPD_MASK); } int read_channel(unsigned long adc_page, unsigned short channel) { unsigned long val; POKE32(adc_page + ADCSWLOCK_OFFSET, UNLOCK_VAL); //unlock the soft lock //write ADCSwitch reg to select channel POKE32(adc_page + ADCSWITCH_OFFSET, channel); while(is_ADC_busy(adc_page)); //poll ADCResult //read result from data regisyyter val = PEEK32(adc_page + DATA_OFFSET) ; val = val & DATA_MASK; return val; } static char is_ADC_busy(unsigned long adc_page) { unsigned long val; val = PEEK32(adc_page + ADCRESULT_OFFSET); if((val & SDR_MASK) == SDR_MASK) return TRUE; return FALSE; } hamlib-4.6.5/rotators/ts7400/include/test7400ADC.c0000664000175000017500000002741715056640443014676 #include #include #include #include #include #include #include #include "peekpoke.h" #include "ep93xx_adc.h" #define DATA_PAGE 0x12C00000 #define CALIB_LOC 2027 //location of calibration values #define NUM_SAMPLES 5 #define NUM_CHANNELS 4 /* globals */ static unsigned long adc_page, syscon_page; char *dr_page; /*Calculate the adc value corresponding to 0V*/ //val1 is the ADC val corresponding to 0.833V //val2 is the ADC val corresponding to 2.5V int calcZeroVal(int val1, int val2) { val2 += 0x10000; return (int)(val1 - (((val2 - val1) / (2.5 - 0.833)) * 0.833)); } //return value of 1 indicates the board has no calibration values //return value of 0 indicates the board has calibration values int read_calibration(int buf[NUM_CHANNELS][2]) { int i, j, k = 0; unsigned short cal[NUM_CHANNELS * 2]; // read 16 calibration bytes into buffer FILE *f = fopen("/etc/ADC-calibration.dat", "r"); if (!f) { goto empty_calibration; } printf("Non-virgin board detected, evaluating stored " "calibration values\n"); printf("Stored Calibration values ["); if (fread(cal, NUM_CHANNELS * 4, 1, f) == 1) { fclose(f); for (j = 0; j < 2; j++) for (i = 0; i < NUM_CHANNELS; i++) { printf("0x%x", cal[k]); buf[i][j] = cal[k]; k++; if (k < NUM_CHANNELS * 2 - 1) { printf(", "); } } printf("]\n"); return 1; } empty_calibration: printf("/etc/ADC-calibration.dat not found or it's not readable\n"); fclose(f); return 0; } void write_calibration(int cal[NUM_CHANNELS][2]) { unsigned short buf[16]; int i, j, k = 0; FILE *f = fopen("/etc/ADC-calibration.dat", "w"); //Convert 32 bit vals to 16 bit vals for (j = 0; j < 2; j++) for (i = 0; i < NUM_CHANNELS; i++) { buf[k] = (unsigned short)cal[i][j]; k++; } if (!f) { goto unwrite_calibration; } if (fwrite(buf, NUM_CHANNELS * 4, 1, f) == 1) { return; } unwrite_calibration: printf("Problem writing /etc/ADC-calibration.dat: %m\n"); } static void erase_calibration() { printf("Erasing calibration values...\n"); unlink("/etc/ADC-calibration.dat"); } int check_calibration(int cal[NUM_CHANNELS][2], int stored_cal[NUM_CHANNELS][2], int state) { double pcnt_diff; int i, j, erase_cal = 0; int failure = 0; if (state == 0) //no calibration values { printf("Virgin board detected...\n"); for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { if (j == 0) pcnt_diff = (((double)abs(0xa000 - cal[i][j])) / 0xa000) * 100; else pcnt_diff = (((double)abs(0x3300 - cal[i][j])) / 0x3300) * 100; if (pcnt_diff > 10) { printf("Calculated calibration " "values out of range...\n"); exit(-1); } } } write_calibration(cal); } else //calibration values read { for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { pcnt_diff = (((double)abs(stored_cal[i][j] - cal[i][j])) / stored_cal[i][j]) * 100; if (pcnt_diff > 0.25) { if (!failure) { printf("Calibration values out" "of range\n"); failure = 1; erase_cal = 1; } printf("\tChannel %d: %3.3f%%\n", i , pcnt_diff); } } } } if (erase_cal) { erase_calibration(); } if (failure) { return 0; } return 1; } void setDR(char *x, int n, int val) { if (n < 0 || n > 8) { return; } x[0] = (x[0] & ~(1 << n)) | (val ? (1 << n) : 0); } void setD(char *x, int n, int val) { if (n < 0 || n > 8) { return; } x[2] = (x[2] & ~(1 << n)) | (val ? (1 << n) : 0); } double get_volts(int val, int zero, int range) { if (val <= 0x7000) { val = val + 0x10000; } val = val - zero; return ((double)val * 3.3) / range; } void calc_calibration(int calibration[NUM_CHANNELS][2], int adc_result_1[NUM_CHANNELS][NUM_SAMPLES], int adc_result_2[NUM_CHANNELS][NUM_SAMPLES]) { int i, j; /* zero out our calibration values */ for (i = 0; i < NUM_CHANNELS; i++) for (j = 0; j < 2; j++) { calibration[i][j] = 0; } //convert 0.833V vals to 0V vals for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { if (i % 2) //odd channels adc_result_1[i][j] = calcZeroVal(adc_result_1[i][j], adc_result_1[0][j]); else adc_result_2[i][j] = calcZeroVal(adc_result_2[i][j], adc_result_2[1][j]); } } //sum the readings for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { if (i % 2 == 0) { //0.833 volt values calibration[i][0] = adc_result_2[i][j] + calibration[i][0]; //2.5 volt values calibration[i][1] = adc_result_1[i][j] + calibration[i][1]; } else { //0.833 volt values calibration[i][0] = adc_result_1[i][j] + calibration[i][0]; //2.5 volt values calibration[i][1] = adc_result_2[i][j] + calibration[i][1]; } } } printf("Calculated Calibration values ["); for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { calibration[i][j] = (calibration[i][j] / NUM_SAMPLES); printf("0x%x", calibration[i][j]); if ((i == NUM_CHANNELS - 1) && (j == 1)) { printf("]\n"); } else { printf(", "); } } } } /************************************************************************ *DESCRIPTION: Read the EP93xx onboard ADC. Discard the first *two samples then save the next NUM_SAMPLES. ***********************************************************************/ static void read_7xxx_adc(int adc_result[NUM_CHANNELS][NUM_SAMPLES]) { int i, j, cur_ch; for (i = 0; i < NUM_CHANNELS; i++) { switch (i) { case 0: cur_ch = ADC_CH0; break; case 1: cur_ch = ADC_CH1; break; case 2: cur_ch = ADC_CH2; break; case 3: cur_ch = ADC_CH3; break; case 4: cur_ch = ADC_CH4; break; } //discard first two samples read_channel(adc_page, cur_ch); read_channel(adc_page, cur_ch); //read more samples for (j = 0; j < NUM_SAMPLES; j++) { hl_usleep(10000); adc_result[i][j] = read_channel(adc_page, cur_ch); } } } int test_ADC(int calibration[NUM_CHANNELS][2]) { int adc_result_1[NUM_CHANNELS][NUM_SAMPLES]; int adc_result_2[NUM_CHANNELS][NUM_SAMPLES]; int i, j, return_val; int failure = 0; double voltage; setD(dr_page, 0, 1); //ADC1 = ADC3 = 0.833V setD(dr_page, 2, 1); //ADC0 = ADC2 = 2.5V read_7xxx_adc(adc_result_1); setD(dr_page, 0, 0); //ADC1 = ADC3 = 2.5V setD(dr_page, 2, 1); //ADC0 = ADC2 = 0.833V read_7xxx_adc(adc_result_2); //verify results are within range for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { //use the datasheet values voltage = get_volts(adc_result_1[i][j], 0x9E58, 0xC350); //even channels 2.5V(+-150mV) if (i % 2 == 0 && (voltage < 2.35 || voltage > 2.65)) { if (!failure) { failure = 1; printf("EP93XX ADC out of range\n"); } printf("\tChannel %d: %3.3fV" "(expected 2.5V +- 150mV)\n", i, voltage); //odd channels 0.833(+-50mV) } else if (i % 2 == 1 && (voltage < 0.333 || voltage > 1.333)) { if (!failure) { failure = 1; printf("EP93xx ADC out of range\n"); } printf("\tChannel %d: %3.3fV" "(expected 0.833V +- 50mV)\n", i, voltage); } //use the datasheet values voltage = get_volts(adc_result_2[i][j], 0x9E58, 0xC350); //odd channels 2.5V(+-150mV) if (i % 2 == 1 && (voltage < 2.35 || voltage > 2.65)) { if (!failure) { failure = 1; printf("EP93XX ADC out of range\n"); } printf("\tChannel %d: %3.3fV" "(expected 2.5V +- 150mV)\n", i, voltage); //even channels 0.833(+-50mV) } else if (i % 2 == 0 && (voltage < 0.333 || voltage > 1.333)) { if (!failure) { failure = 1; printf("EP93xx ADC out of range\n"); } printf("\tChannel %d: %3.3fV" "(expected 0.833V +- 50mV)\n", i, voltage); } } } calc_calibration(calibration, adc_result_1, adc_result_2); if (failure) { return_val = 0; } else { return_val = 1; } return return_val; } int main(void) { int calibration[NUM_CHANNELS][2]; int ret_val; int devmem = open("/dev/mem", O_RDWR | O_SYNC); assert(devmem != -1); dr_page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, devmem, DATA_PAGE); assert(&dr_page != MAP_FAILED); adc_page = (unsigned long)mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, devmem, ADC_PAGE); assert(&adc_page != MAP_FAILED); syscon_page = (unsigned long)mmap(0, getpagesize(), PROT_READ | PROT_WRITE , MAP_SHARED, devmem, SYSCON_PAGE); assert(&syscon_page != MAP_FAILED); init_ADC(adc_page, syscon_page); setDR(dr_page, 0, 1); setDR(dr_page, 1, 0); setDR(dr_page, 2, 1); setDR(dr_page, 3, 0); if (test_ADC(calibration)) { int state; int stored_calibration[NUM_CHANNELS][2]; printf("ADC tested ok(data sheet values)\n"); state = read_calibration(stored_calibration); if (check_calibration(calibration, stored_calibration, state)) { ret_val = 0; } else { ret_val = 1; } } else { ret_val = 1; } close(devmem); return ret_val; } hamlib-4.6.5/rotators/ts7400/include/peekpoke.c0000664000175000017500000000616515056640443014674 #include #include #include #include #include unsigned int parseBinary(char *str) { unsigned int val = 0; if (*str == 'b') { str++; while (*str) { if (*str == '0') { val <<= 1; } else if (*str == '1') { val = (val << 1) + 1; } else { goto binaryError; } } } return val; binaryError: fprintf(stderr, "Unrecognized numeric value: %s\n", str); exit(0); } unsigned int parseNumber(char *str) { unsigned int addr = 0; if (!sscanf(str, "0x%x", &addr)) { if (!sscanf(str, "%u", &addr)) { addr = parseBinary(str); } } return addr; } /* Features that the old peekXX/pokeXX did not have: 1. Support for 8/16/32 bit READ/WRITE in one function 2. Support for decimal and binary values 3. The value return is returned (to become the status code) */ int main(int argc, char **argv) { off_t addr, page; int fd, bits, dowrite = 0, doread = 1; unsigned char *start; unsigned short *shortdat, shortval; unsigned int *intdat, intval; if (argc < 3 || argc > 5) { fprintf(stderr, "Usage: peekpoke BIT_WIDTH ADDRESS >\n"); fprintf(stderr, " can be anything; suppresses read-back on write\n"); return 0; } sscanf(argv[1], "%d", &bits); if (bits != 8 && bits != 16 && bits != 32) { fprintf(stderr, "Error: BIT_WIDTH must be 8, 16, or 32\n"); return 0; } addr = parseNumber(argv[2]); if (argc > 3) // peekpoke BITS ADDRESS VALUE x { intval = parseNumber(argv[3]); if (argc > 4) { doread = 0; } dowrite = 1; } fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) { perror("open(/dev/mem):"); return 0; } page = addr & 0xfffff000; start = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, page); if (start == MAP_FAILED) { perror("mmap:"); close(fd); return 0; } if (bits == 8) { unsigned char *chardat, charval; charval = (unsigned char)intval; chardat = start + (addr & 0xfff); if (dowrite) { *chardat = charval; } if (doread) { intval = (unsigned int) * chardat; } } else if (bits == 16) { shortval = (unsigned short)intval; shortdat = (unsigned short *)(start + (addr & 0xfff)); if (dowrite) { *shortdat = shortval; } if (doread) { intval = (unsigned int) * shortdat; } } else // bits == 32 { intdat = (unsigned int *)(start + (addr & 0xfff)); if (dowrite) { *intdat = intval; } if (doread) { intval = *intdat; } } if (doread) { printf("0x%X\n", intval); } close(fd); return intval; } hamlib-4.6.5/rotators/ts7400/include/readADC.c0000664000175000017500000003010315056640443014301 #include #include #include #include #include #include #include #include "peekpoke.h" #include "ep93xx_adc.h" #define DATA_PAGE 0x12C00000 #define CALIB_LOC 2027 //location of calibration values #define NUM_SAMPLES 5 #define NUM_CHANNELS 4 /* globals */ static unsigned long adc_page, syscon_page; char *dr_page; double el, az; /*Calculate the adc value corresponding to 0V*/ //val1 is the ADC val corresponding to 0.833V //val2 is the ADC val corresponding to 2.5V int calcZeroVal(int val1, int val2) { val2 += 0x10000; return (int)(val1 - (((val2 - val1) / (2.5 - 0.833)) * 0.833)); } //return value of 1 indicates the board has no calibration values //return value of 0 indicates the board has calibration values int read_calibration(int buf[NUM_CHANNELS][2]) { int i, j, k = 0; unsigned short cal[NUM_CHANNELS * 2]; // read 16 calibration bytes into buffer FILE *f = fopen("/etc/ADC-calibration.dat", "r"); if (!f) { goto empty_calibration; } printf("Non-virgin board detected, evaluating stored " "calibration values\n"); printf("Stored Calibration values ["); if (fread(cal, NUM_CHANNELS * 4, 1, f) == 1) { fclose(f); for (j = 0; j < 2; j++) for (i = 0; i < NUM_CHANNELS; i++) { printf("0x%x", cal[k]); buf[i][j] = cal[k]; k++; if (k < NUM_CHANNELS * 2 - 1) { printf(", "); } } printf("]\n"); return 1; } empty_calibration: fclose(f); printf("/etc/ADC-calibration.dat not found or it's not readable\n"); return 0; } void write_calibration(int cal[NUM_CHANNELS][2]) { unsigned short buf[16]; int i, j, k = 0; FILE *f = fopen("/etc/ADC-calibration.dat", "w"); //Convert 32 bit vals to 16 bit vals for (j = 0; j < 2; j++) for (i = 0; i < NUM_CHANNELS; i++) { buf[k] = (unsigned short)cal[i][j]; k++; } if (!f) { goto unwrite_calibration; } if (fwrite(buf, NUM_CHANNELS * 4, 1, f) == 1) { return; } unwrite_calibration: printf("Problem writing /etc/ADC-calibration.dat: %m\n"); } static void erase_calibration() { printf("Erasing calibration values...\n"); unlink("/etc/ADC-calibration.dat"); } int check_calibration(int cal[NUM_CHANNELS][2], int stored_cal[NUM_CHANNELS][2], int state) { double pcnt_diff; int i, j, erase_cal = 0; int failure = 0; if (state == 0) //no calibration values { printf("Virgin board detected...\n"); for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { if (j == 0) pcnt_diff = (((double)abs(0xa000 - cal[i][j])) / 0xa000) * 100; else pcnt_diff = (((double)abs(0x3300 - cal[i][j])) / 0x3300) * 100; if (pcnt_diff > 10) { printf("Calculated calibration " "values out of range...\n"); exit(-1); } } } write_calibration(cal); } else //calibration values read { for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { pcnt_diff = (((double)abs(stored_cal[i][j] - cal[i][j])) / stored_cal[i][j]) * 100; if (pcnt_diff > 0.25) { if (!failure) { printf("Calibration values out" "of range\n"); failure = 1; erase_cal = 1; } printf("\tChannel %d: %3.3f%%\n", i , pcnt_diff); } } } } if (erase_cal) { erase_calibration(); } if (failure) { return 0; } return 1; } void setDR(char *x, int n, int val) { if (n < 0 || n > 8) { return; } x[0] = (x[0] & ~(1 << n)) | (val ? (1 << n) : 0); } void setD(char *x, int n, int val) { if (n < 0 || n > 8) { return; } x[2] = (x[2] & ~(1 << n)) | (val ? (1 << n) : 0); } double get_volts(int val, int zero, int range) { if (val <= 0x7000) { val = val + 0x10000; } val = val - zero; return ((double)val * 3.3) / range; } void calc_calibration(int calibration[NUM_CHANNELS][2], int adc_result_1[NUM_CHANNELS][NUM_SAMPLES], int adc_result_2[NUM_CHANNELS][NUM_SAMPLES]) { int i, j; /* zero out our calibration values */ for (i = 0; i < NUM_CHANNELS; i++) for (j = 0; j < 2; j++) { calibration[i][j] = 0; } //convert 0.833V vals to 0V vals for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { if (i % 2) //odd channels adc_result_1[i][j] = calcZeroVal(adc_result_1[i][j], adc_result_1[0][j]); else adc_result_2[i][j] = calcZeroVal(adc_result_2[i][j], adc_result_2[1][j]); } } //sum the readings for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { if (i % 2 == 0) { //0.833 volt values calibration[i][0] = adc_result_2[i][j] + calibration[i][0]; //2.5 volt values calibration[i][1] = adc_result_1[i][j] + calibration[i][1]; } else { //0.833 volt values calibration[i][0] = adc_result_1[i][j] + calibration[i][0]; //2.5 volt values calibration[i][1] = adc_result_2[i][j] + calibration[i][1]; } } } //printf("Calculated Calibration values ["); for (j = 0; j < 2; j++) { for (i = 0; i < NUM_CHANNELS; i++) { calibration[i][j] = (calibration[i][j] / NUM_SAMPLES); //printf("0x%x", calibration[i][j]); //if((i == NUM_CHANNELS-1) && (j == 1)) //printf("]\n"); //else //printf(", "); } } } /************************************************************************ *DESCRIPTION: Read the EP93xx onboard ADC. Discard the first *two samples then save the next NUM_SAMPLES. ***********************************************************************/ static void read_7xxx_adc(int adc_result[NUM_CHANNELS][NUM_SAMPLES]) { int i, j, cur_ch; for (i = 0; i < NUM_CHANNELS; i++) { switch (i) { case 0: cur_ch = ADC_CH0; break; case 1: cur_ch = ADC_CH1; break; case 2: cur_ch = ADC_CH2; break; case 3: cur_ch = ADC_CH3; break; case 4: cur_ch = ADC_CH4; break; } //discard first two samples read_channel(adc_page, cur_ch); read_channel(adc_page, cur_ch); //read more samples for (j = 0; j < NUM_SAMPLES; j++) { hl_usleep(10000); adc_result[i][j] = read_channel(adc_page, cur_ch); } } } int test_ADC(int calibration[NUM_CHANNELS][2]) { int adc_result_1[NUM_CHANNELS][NUM_SAMPLES]; int adc_result_2[NUM_CHANNELS][NUM_SAMPLES]; int i, j, return_val; int failure = 0; //double voltage,el,az; double voltage; setD(dr_page, 0, 1); //ADC1 = ADC3 = 0.833V setD(dr_page, 2, 1); //ADC0 = ADC2 = 2.5V read_7xxx_adc(adc_result_1); setD(dr_page, 0, 0); //ADC1 = ADC3 = 2.5V setD(dr_page, 2, 1); //ADC0 = ADC2 = 0.833V read_7xxx_adc(adc_result_2); el = get_volts(adc_result_1[0][0], 0x9E58, 0xC350); az = get_volts(adc_result_1[1][0], 0x9E58, 0xC350); el = (el / 3.3) * 180; az = (az / 3.3) * 360; //printf("\t El.: %3.1f Az.: %3.1f \n", el, az); //verify results are within range for (i = 0; i < NUM_CHANNELS; i++) { for (j = 0; j < NUM_SAMPLES; j++) { //use the datasheet values voltage = get_volts(adc_result_1[i][j], 0x9E58, 0xC350); //printf("\tChannel %d: %3.1f \n", i, voltage); //even channels 2.5V(+-150mV) if (i % 2 == 0 && (voltage < 2.35 || voltage > 2.65)) { if (!failure) { failure = 1; //printf("EP93XX ADC out of range\n"); } //printf("\tChannel %d: %3.3fV" //"(expected 2.5V +- 150mV)\n", i, voltage); //odd channels 0.833(+-50mV) } else if (i % 2 == 1 && (voltage < 0.333 || voltage > 1.333)) { if (!failure) { failure = 1; //printf( "EP93xx ADC out of range\n"); } //printf("\tChannel %d: %3.3fV" // "(expected 0.833V +- 50mV)\n", i, voltage); } //use the datasheet values voltage = get_volts(adc_result_2[i][j], 0x9E58, 0xC350); //odd channels 2.5V(+-150mV) if (i % 2 == 1 && (voltage < 2.35 || voltage > 2.65)) { if (!failure) { failure = 1; //printf("EP93XX ADC out of range\n"); } //printf("\tChannel %d: %3.3fV" //"(expected 2.5V +- 150mV)\n", i, voltage); //even channels 0.833(+-50mV) } else if (i % 2 == 0 && (voltage < 0.333 || voltage > 1.333)) { if (!failure) { failure = 1; //printf( "EP93xx ADC out of range\n"); } ///printf("\tChannel %d: %3.3fV" "(expected 0.833V +- 50mV)\n", i, voltage); } } } calc_calibration(calibration, adc_result_1, adc_result_2); if (failure) { return_val = 0; } else { return_val = 1; } return return_val; } int main(void) { int calibration[NUM_CHANNELS][2]; int ret_val; int devmem = open("/dev/mem", O_RDWR | O_SYNC); assert(devmem != -1); dr_page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, devmem, DATA_PAGE); assert(&dr_page != MAP_FAILED); adc_page = (unsigned long)mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, devmem, ADC_PAGE); assert(&adc_page != MAP_FAILED); syscon_page = (unsigned long)mmap(0, getpagesize(), PROT_READ | PROT_WRITE , MAP_SHARED, devmem, SYSCON_PAGE); assert(&syscon_page != MAP_FAILED); init_ADC(adc_page, syscon_page); setDR(dr_page, 0, 1); setDR(dr_page, 1, 0); setDR(dr_page, 2, 1); setDR(dr_page, 3, 0); if (test_ADC(calibration)) { int state; int stored_calibration[NUM_CHANNELS][2]; printf("ADC tested ok(data sheet values)\n"); state = read_calibration(stored_calibration); if (check_calibration(calibration, stored_calibration, state)) { ret_val = 0; } else { ret_val = 1; } } else { ret_val = 1; } printf("\t El.: %3.1f Az.: %3.1f \n", el, az); close(devmem); return ret_val; } hamlib-4.6.5/rotators/ts7400/ts7400.c0000664000175000017500000001556315056640443012411 /* * Hamlib ts7400 backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "ts7400.h" struct ts7400_rot_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; }; static int ts7400_rot_init(ROT *rot) { struct ts7400_rot_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ROTSTATE(rot)->priv = (struct ts7400_rot_priv_data *) calloc(1, sizeof(struct ts7400_rot_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; ROTPORT(rot)->type.rig = RIG_PORT_NONE; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; return RIG_OK; } static int ts7400_rot_cleanup(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ROTSTATE(rot)->priv) { free(ROTSTATE(rot)->priv); } ROTSTATE(rot)->priv = NULL; return RIG_OK; } static int ts7400_rot_open(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int ts7400_rot_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int ts7400_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct ts7400_rot_priv_data *priv = (struct ts7400_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); priv->target_az = az; priv->target_el = el; gettimeofday(&priv->tv, NULL); return RIG_OK; } /* * Get position of rotor, simulating slow rotation */ static int ts7400_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { struct ts7400_rot_priv_data *priv = (struct ts7400_rot_priv_data *) ROTSTATE(rot)->priv; struct timeval tv; unsigned elapsed; /* ms */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (priv->az == priv->target_az && priv->el == priv->target_el) { *az = priv->az; *el = priv->el; return RIG_OK; } gettimeofday(&tv, NULL); elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 + (tv.tv_usec - priv->tv.tv_usec) / 1000; /* * Simulate rotation speed of 360 deg per minute */ #define DEG_PER_MS (360./60/1000) if (fabs(priv->target_az - priv->az) / DEG_PER_MS <= elapsed) { /* target reached */ priv->az = priv->target_az; } else { if (priv->az < priv->target_az) { priv->az += (azimuth_t)elapsed * DEG_PER_MS; } else { priv->az -= (azimuth_t)elapsed * DEG_PER_MS; } } if (fabs(priv->target_el - priv->el) / DEG_PER_MS <= elapsed) { /* target reached */ priv->el = priv->target_el; } else { if (priv->el < priv->target_el) { priv->el += (elevation_t)elapsed * DEG_PER_MS; } else { priv->el -= (elevation_t)elapsed * DEG_PER_MS; } } *az = priv->az; *el = priv->el; priv->tv = tv; return RIG_OK; } static int ts7400_rot_stop(ROT *rot) { struct ts7400_rot_priv_data *priv = (struct ts7400_rot_priv_data *) ROTSTATE(rot)->priv; azimuth_t az; elevation_t el; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ts7400_rot_get_position(rot, &az, &el); priv->target_az = priv->az = az; priv->target_el = priv->el = el; return RIG_OK; } static int ts7400_rot_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume home is 0,0 */ ts7400_rot_set_position(rot, 0, 0); return RIG_OK; } static int ts7400_rot_reset(ROT *rot, rot_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int ts7400_rot_move(ROT *rot, int direction, int speed) { struct ts7400_rot_priv_data const *priv = (struct ts7400_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_UP: return ts7400_rot_set_position(rot, priv->target_az, 90); case ROT_MOVE_DOWN: return ts7400_rot_set_position(rot, priv->target_az, 0); case ROT_MOVE_CCW: return ts7400_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_CW: return ts7400_rot_set_position(rot, 180, priv->target_el); default: return -RIG_EINVAL; } return RIG_OK; } static const char *ts7400_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "ts7400 rotator"; } /* * ts7400 rotator capabilities. */ const struct rot_caps ts7400_rot_caps = { ROT_MODEL(ROT_MODEL_TS7400), .model_name = "ts7400", .mfg_name = "LA7LKA", .version = "20200113.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_NONE, .min_az = -180., .max_az = 180., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .rot_init = ts7400_rot_init, .rot_cleanup = ts7400_rot_cleanup, .rot_open = ts7400_rot_open, .rot_close = ts7400_rot_close, .set_position = ts7400_rot_set_position, .get_position = ts7400_rot_get_position, .park = ts7400_rot_park, .stop = ts7400_rot_stop, .reset = ts7400_rot_reset, .move = ts7400_rot_move, .get_info = ts7400_rot_get_info, }; DECLARE_INITROT_BACKEND(ts7400) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&ts7400_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/ts7400/Makefile.am0000664000175000017500000000035115056640443013325 noinst_LTLIBRARIES = libhamlib-ts7400.la libhamlib_ts7400_la_SOURCES = ts7400.c ts7400.h EXTRA_DIST = include/ep93xx_adc.h include/peekpoke.h \ include/io.c include/peekpoke.c include/readADC.c \ include/test7400ADC.c Android.mk hamlib-4.6.5/rotators/cnctrk/0000775000175000017500000000000015056640501011670 5hamlib-4.6.5/rotators/cnctrk/Android.mk0000664000175000017500000000037215056640443013530 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := cnctrk.c LOCAL_MODULE := cnctrk LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/cnctrk/Makefile.in0000664000175000017500000005232215056640453013667 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/cnctrk ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_cnctrk_la_LIBADD = am_libhamlib_cnctrk_la_OBJECTS = cnctrk.lo libhamlib_cnctrk_la_OBJECTS = $(am_libhamlib_cnctrk_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/cnctrk.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_cnctrk_la_SOURCES) DIST_SOURCES = $(libhamlib_cnctrk_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-cnctrk.la libhamlib_cnctrk_la_SOURCES = cnctrk.c EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/cnctrk/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/cnctrk/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-cnctrk.la: $(libhamlib_cnctrk_la_OBJECTS) $(libhamlib_cnctrk_la_DEPENDENCIES) $(EXTRA_libhamlib_cnctrk_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_cnctrk_la_OBJECTS) $(libhamlib_cnctrk_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cnctrk.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/cnctrk.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/cnctrk.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/cnctrk/cnctrk.c0000664000175000017500000000442515056640443013252 /* * Hamlib Rotator backend - LinuxCNC no hardware port * Copyright (c) 2015 by Robert Freeman * Adapted from AMSAT code by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_SYS_IOCTL_H #include #endif #include "hamlib/rotator.h" #include "register.h" char axcmd[512]; static int cnctrk_set_position(ROT *rot, azimuth_t az, elevation_t el) { int retval; retval = system("/usr/bin/axis-remote --ping"); if (retval != 0) { return retval; } SNPRINTF(axcmd, sizeof(axcmd), "/usr/bin/axis-remote --mdi 'G00 X %6.2f Y %6.2f' \n", az, el); return system(axcmd); } /** CNCTRK implements essentially only the set position function. it assumes there is a LinuxCNC running with the Axis GUI */ const struct rot_caps cnctrk_rot_caps = { ROT_MODEL(ROT_MODEL_CNCTRK), .model_name = "CNCTRK", .mfg_name = "CNCTRK", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 360, .min_el = -20, .max_el = 180, .set_position = cnctrk_set_position, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(cnctrk) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&cnctrk_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/cnctrk/Makefile.am0000664000175000017500000000015215056640443013647 noinst_LTLIBRARIES = libhamlib-cnctrk.la libhamlib_cnctrk_la_SOURCES = cnctrk.c EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/apex/0000775000175000017500000000000015056640501011341 5hamlib-4.6.5/rotators/apex/sharedloop.c0000664000175000017500000000437315056640443013601 /* Apex Shared Loop Controller */ #include #include "hamlib/rotator.h" #include "iofunc.h" #include "apex.h" int apex_shared_loop_get_position(ROT *rot, float *az, float *el) { int loop = 10; while (--loop > 0 && apex_azimuth < 0) { hl_usleep(250 * 1000); }; *az = apex_azimuth; *el = 0; return RIG_OK; } int apex_shared_loop_set_position(ROT *rot, float az, float dummy) { char cmdstr[16]; int retval; hamlib_port_t *rotp = ROTPORT(rot); int remainder = lround(az + 22.5) % 45; int apex_az = lround(az + 22.5) - remainder; // default to 0 degrees snprintf(cmdstr, sizeof(cmdstr), "[R99T4AM10]\r\n"); switch (apex_az) { case 45: cmdstr[9] = '1'; break; case 90: cmdstr[9] = '2'; break; case 135: cmdstr[9] = '3'; break; case 180: cmdstr[9] = '4'; break; case 225: cmdstr[9] = '5'; break; case 270: cmdstr[9] = '6'; break; case 315: cmdstr[9] = '7'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown az=%d\n", __func__, apex_az); return -RIG_EINTERNAL; } rig_flush(rotp); apex_azimuth = -1; retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block error - %s\n", __func__, rigerror(retval)); return retval; } return RIG_OK; } const struct rot_caps apex_shared_loop_rot_caps = { ROT_MODEL(ROT_MODEL_APEX_SHARED_LOOP), .model_name = "Shared Loop", .mfg_name = "Apex", .version = "20231013.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 4000, .retry = 2, .min_az = 0.0, .max_az = 360.0, .rot_open = apex_open, .get_info = apex_get_info, .get_position = apex_shared_loop_get_position, .set_position = apex_shared_loop_set_position, }; hamlib-4.6.5/rotators/apex/apex.h0000664000175000017500000000206315056640443012375 /* * Hamlib Rotator backend - Apex rotators * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_APEX_H #define _ROT_APEX_H 1 #include "rotator.h" extern const struct rot_caps apex_shared_loop_rot_caps; extern float apex_azimuth; extern int apex_open(ROT *rot); extern const char *apex_get_info(ROT *rot); #endif /* _ROT_APEX_H */ hamlib-4.6.5/rotators/apex/Android.mk0000664000175000017500000000041215056640443013174 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := apex.c apex.h sharedloop.c LOCAL_MODULE := apex LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/apex/Makefile.in0000664000175000017500000005260715056640453013346 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/apex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_apex_la_LIBADD = am_libhamlib_apex_la_OBJECTS = apex.lo sharedloop.lo libhamlib_apex_la_OBJECTS = $(am_libhamlib_apex_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/apex.Plo ./$(DEPDIR)/sharedloop.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_apex_la_SOURCES) DIST_SOURCES = $(libhamlib_apex_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-apex.la libhamlib_apex_la_SOURCES = apex.c apex.h sharedloop.c EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/apex/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/apex/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-apex.la: $(libhamlib_apex_la_OBJECTS) $(libhamlib_apex_la_DEPENDENCIES) $(EXTRA_libhamlib_apex_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_apex_la_OBJECTS) $(libhamlib_apex_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sharedloop.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/apex.Plo -rm -f ./$(DEPDIR)/sharedloop.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/apex.Plo -rm -f ./$(DEPDIR)/sharedloop.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/apex/apex.c0000664000175000017500000000605415056640443012374 #include #include #include "iofunc.h" #include "register.h" #include "apex.h" float apex_azimuth; char apex_info[65]; static pthread_t apex_read_thread; // We only have two strings to get // one is 18 chars and the other may be variable // [T4BRFA99H00M010#] Unidirectional // xxxxxxxxxx // So we'll read 5 chars and use the to determine how to read the rest static int apex_get_string(ROT *rot, char *s, int maxlen) { int retval = 0; char buf[64]; memset(s, 0, maxlen); retval = read_string(ROTPORT(rot), (unsigned char *)buf, sizeof(buf), "\n", strlen("\n"), sizeof(buf), 1); strncpy(s, buf, 64); strtok(s, "\r\n"); // truncate any CR/LF rig_debug(RIG_DEBUG_VERBOSE, "%s: %d bytes '%s'\n", __func__, retval, s); if (retval <= 0) { return -RIG_EPROTO; } return RIG_OK; } // Expecting # from 0-7 // [T4BRFA99H00M010#] Unidirectional // Or // [T4BRFA99H00M020#] Bidirectional static void *apex_read(void *arg) { ROT *rot = arg; int retval = 0; char data[64]; int expected_return_length = 63; while (1) { retval = apex_get_string(rot, data, expected_return_length); if (strstr(data, "")) { strncpy(apex_info, data, sizeof(apex_info)); rig_debug(RIG_DEBUG_TRACE, "%s: apex_info=%s\n", __func__, apex_info); continue; } if (retval != 0 || strstr(data, "[T4BRFA99") == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unknown apex status message=%s\n", __func__, data); continue; } rig_debug(RIG_DEBUG_VERBOSE, "%s: data='%s'\n", __func__, data); switch (data[16]) { case '0': apex_azimuth = 45; break; case '1': apex_azimuth = 90; break; case '2': apex_azimuth = 135; break; case '3': apex_azimuth = 180; break; case '4': apex_azimuth = 225; break; case '5': apex_azimuth = 270; break; case '6': apex_azimuth = 315; break; case '7': apex_azimuth = 0; break; } // printf("az=%f\n", apex_azimuth); } return NULL; } int apex_open(ROT *rot) { int retval; char *cmdstr = "[GETVER]\r"; // does this work on all Apex controllers? hamlib_port_t *rotp = ROTPORT(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s: entered\n", __func__); apex_azimuth = -1; // we check to see if we've seen azimuth at least one time rig_flush(rotp); retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block failed - %s\n", __func__, rigerror(retval)); return retval; } pthread_create(&apex_read_thread, NULL, apex_read, rot); return RIG_OK; } const char *apex_get_info(ROT *rot) { return apex_info; } DECLARE_INITROT_BACKEND(apex) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&apex_shared_loop_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/apex/Makefile.am0000664000175000017500000000017015056640443013320 noinst_LTLIBRARIES = libhamlib-apex.la libhamlib_apex_la_SOURCES = apex.c apex.h sharedloop.c EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/flir/0000775000175000017500000000000015056640501011340 5hamlib-4.6.5/rotators/flir/README.md0000664000175000017500000000352015056640443012544 # FLIR/DirectedPerception PTU Rotor Module This module interfaces FLIR and DirectedPerception rotor using the PTU protocol via serial. This includes: * PTU-D48(E) * PTU-E46 * PTU-D100(E) * PTU-D300(E) Tested only with PTU-D48 yet and with one rotor per chain only. ## Usage 1. Connect the rotor via serial (RS232 or RS485) 2. Power up the rotor 3. The rotor must be calibrated after each power up. This can be accived either using the rotctl `Reset` command (R) or manually via serial terminal sending the `R\n` command. 4. To enable the rotor to fully turn +/- 180°, the softlock must be disabled. This is included in the rotctl `Reset` command or manually via serial terminal seinden the command `LD\n`. **WARNING:** Send this command only after the rotor is calibrated, or you risk damage running into the hard endstops (at about +/-190°) 5. Start `rotctl` or `rotctld` with the arguments `-m 2501 -r ` Have Fun. ### Hints 1. Setup the max. velocity, power and acceleration according to your antenna load. This must be done via serial terminal, as the functions are not implemented yet. 2. Never use the maximum hold power, only use the low or off. If you use max or regular, the rotor may easily overheat! ## PTU Protocol * [Protocol Version 3.02 (2011)](https://flir.netx.net/file/asset/11556/original/attachment) ## Current Status The current status is **ALPHA**. It is tested with DirectedPercepiton PTU-D48 (Firmware v2.13.4r0(D48-C14/E)) Linux with `rotctl` and `gpredict`. ### Implemented so far: * init * cleanup * open * close * set_position * get_position * park * stop * reset * move * info ### Needs to be implemented: #### Parameters * velocity * acceleration * velocity profile * user soft-limits * power commands (move and hold) * step mode * reset on startup #### Functions * usage of chained rotors via RS485 hamlib-4.6.5/rotators/flir/flir.h0000664000175000017500000000301015056640443012364 /* * Hamlib FLIR PTU rotor backend - main header * Copyright (c) 2022 by Andreas Mueller (DC1MIL) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_FLIR_H #define _ROT_FLIR_H 1 #include "rotator.h" #include "token.h" /* backend conf */ #define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) #define MAXBUF 64 extern struct rot_caps flir_caps; extern struct rot_caps netrotctl_caps; #endif /* _ROT_FLIR_H */ hamlib-4.6.5/rotators/flir/flir.c0000664000175000017500000003545015056640443012374 /* * Hamlib FLIR PTU rotor backend - main file * Copyright (c) 2022 by Andreas Mueller (DC1MIL) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include #include #include "hamlib/rotator.h" #include "register.h" #include "idx_builtin.h" #include "serial.h" #include "flir.h" #define FLIR_FUNC 0 #define FLIR_LEVEL ROT_LEVEL_SPEED #define FLIR_PARM 0 #define FLIR_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) struct flir_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; rot_status_t status; setting_t funcs; value_t levels[RIG_SETTING_MAX]; value_t parms[RIG_SETTING_MAX]; char info[256]; struct ext_list *ext_funcs; struct ext_list *ext_levels; struct ext_list *ext_parms; char *magic_conf; double resolution_pp; double resolution_tp; }; static int flir_request(ROT *rot, char *request, char *response, int resp_size) { int return_value = -RIG_EINVAL; hamlib_port_t *rotp = ROTPORT(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rotp); if (request) { return_value = write_block(rotp, (unsigned char *)request, strlen(request)); if (return_value != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s request not OK\n", __func__); return return_value; } } //Is a direct response expected? if (response != NULL) { int retry_read = 0; int read_char; while (retry_read < rotp->retry) { memset(response, 0, (size_t)resp_size); read_char = read_string(rotp, (unsigned char *)response, resp_size, "\r\n", sizeof("\r\n"), 0, 1); if (read_char > 0) { if (response[0] == '*') { rig_debug(RIG_DEBUG_VERBOSE, "accepted command %s\n", request); return RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "NOT accepted command %s\n", request); return -RIG_ERJCTED; } } retry_read++; } response[0] = 0; rig_debug(RIG_DEBUG_VERBOSE, "timeout for command %s\n", request); return -RIG_ETIMEOUT; } return return_value; }; static int flir_init(ROT *rot) { struct flir_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ROTSTATE(rot)->priv = (struct flir_priv_data *) calloc(1, sizeof(struct flir_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; priv->magic_conf = strdup("ROTATOR"); priv->resolution_pp = 92.5714; priv->resolution_tp = 46.2857; return RIG_OK; } static int flir_cleanup(ROT *rot) { struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(priv->ext_funcs); free(priv->ext_levels); free(priv->ext_parms); free(priv->magic_conf); free(ROTSTATE(rot)->priv); ROTSTATE(rot)->priv = NULL; return RIG_OK; } static int flir_open(ROT *rot) { struct flir_priv_data *priv; char return_str[MAXBUF]; double resolution_pp, resolution_tp; int return_value = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = ROTSTATE(rot)->priv; // Disable ECHO return_value = flir_request(rot, "ED\n", NULL, MAXBUF); if (return_value != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ED: %s\n", __func__, rigerror(return_value)); return return_value; } // Disable Verbose Mode return_value = flir_request(rot, "FT\n", return_str, MAXBUF); if (return_value != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: FT: %s\n", __func__, rigerror(return_value)); return return_value; } // Get PAN resolution in arcsecs if (flir_request(rot, "PR\n", return_str, MAXBUF) == RIG_OK) { sscanf(return_str, "* %lf", &resolution_pp); rig_debug(RIG_DEBUG_VERBOSE, "PAN resolution: %lf arcsecs per position\n", resolution_pp); priv->resolution_pp = resolution_pp; } else { return_value = -RIG_EPROTO; } // Get TILT resolution in arcsecs if (flir_request(rot, "TR\n", return_str, MAXBUF) == RIG_OK) { sscanf(return_str, "* %lf", &resolution_tp); rig_debug(RIG_DEBUG_VERBOSE, "TILT resolution: %lf arcsecs per position\n", resolution_tp); priv->resolution_tp = resolution_tp; } else { return_value = -RIG_EPROTO; } return return_value; } static int flir_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int flir_set_conf(ROT *rot, hamlib_token_t token, const char *val) { return -RIG_ENIMPL; } static int flir_get_conf(ROT *rot, hamlib_token_t token, char *val) { return -RIG_ENIMPL; } static int flir_set_position(ROT *rot, azimuth_t az, elevation_t el) { int32_t t_pan_positions, t_tilt_positions; char return_str[MAXBUF]; char cmd_str[MAXBUF]; struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); priv->target_az = az; priv->target_el = el; t_pan_positions = (az * 3600) / priv->resolution_pp; t_tilt_positions = - ((90.0 - el) * 3600) / priv->resolution_tp; sprintf(cmd_str, "PP%d TP%d\n", t_pan_positions, t_tilt_positions); return flir_request(rot, cmd_str, return_str, MAXBUF); } /* * Get position of rotor */ static int flir_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { int return_value = RIG_OK; char return_str[MAXBUF]; int32_t pan_positions, tilt_positions; struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (flir_request(rot, "PP\n", return_str, MAXBUF) == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "PP Return String: %s\n", return_str); sscanf(return_str, "* %d", &pan_positions); priv->az = (pan_positions * priv->resolution_pp) / 3600; *az = priv->az; } else { rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str); return_value = -RIG_EPROTO; } if (flir_request(rot, "TP\n", return_str, MAXBUF) == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "TP Return String: %s\n", return_str); sscanf(return_str, "* %d", &tilt_positions); priv->el = 90.0 + ((tilt_positions * priv->resolution_tp) / 3600); *el = priv->el; } else { rig_debug(RIG_DEBUG_VERBOSE, "PP Wrong Return String: %s\n", return_str); return_value = -RIG_EPROTO; } return return_value; } static int flir_stop(ROT *rot) { int return_value = RIG_OK; struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; azimuth_t az; elevation_t el; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return_value = flir_request(rot, "H\n", NULL, MAXBUF); if (return_value != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: H: %s\n", __func__, rigerror(return_value)); return return_value; } // Wait 2s until rotor has stopped (Needs to be refactored) hl_usleep(2000000); return_value = flir_get_position(rot, &az, &el); if (return_value != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_get_position: %s\n", __func__, rigerror(return_value)); return return_value; } priv->target_az = priv->az = az; priv->target_el = priv->el = el; return return_value; } static int flir_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume park Position is 0,90 */ flir_set_position(rot, 0, 90); return RIG_OK; } static int flir_reset(ROT *rot, rot_reset_t reset) { int return_value = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (reset != 0) { return_value = flir_request(rot, "r\n", NULL, 0); // After Reset: Disable Hard Limits if (return_value == RIG_OK) { return_value = flir_request(rot, "LD\n", NULL, MAXBUF); } } return return_value; } static int flir_move(ROT *rot, int direction, int speed) { struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_UP: return flir_set_position(rot, priv->target_az, 90); case ROT_MOVE_DOWN: return flir_set_position(rot, priv->target_az, 0); case ROT_MOVE_CCW: return flir_set_position(rot, -180, priv->target_el); case ROT_MOVE_CW: return flir_set_position(rot, 180, priv->target_el); default: return -RIG_EINVAL; } return RIG_OK; } static const char *flir_get_info(ROT *rot) { char firmware_str[121]; char info_str[101]; struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; sprintf(priv->info, "No Info"); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (flir_request(rot, "V\n", firmware_str, 120) != RIG_OK) { return "No Info available"; } hl_usleep(500000); if (flir_request(rot, "O\n", info_str, 100) != RIG_OK) { return "No Info available"; } sprintf(priv->info, "Firmware: %s\nPower: %s", firmware_str, info_str); return priv->info; } static int flir_set_func(ROT *rot, setting_t func, int status) { return -RIG_ENIMPL; } static int flir_get_func(ROT *rot, setting_t func, int *status) { return -RIG_ENIMPL; } static int flir_set_level(ROT *rot, setting_t level, value_t val) { return -RIG_ENIMPL; } static int flir_get_level(ROT *rot, setting_t level, value_t *val) { return -RIG_ENIMPL; } static int flir_set_ext_level(ROT *rot, hamlib_token_t token, value_t val) { return -RIG_ENIMPL; } static int flir_get_ext_level(ROT *rot, hamlib_token_t token, value_t *val) { return -RIG_ENIMPL; } static int flir_set_ext_func(ROT *rot, hamlib_token_t token, int status) { return -RIG_ENIMPL; } static int flir_get_ext_func(ROT *rot, hamlib_token_t token, int *status) { return -RIG_ENIMPL; } static int flir_set_parm(ROT *rot, setting_t parm, value_t val) { return -RIG_ENIMPL; } static int flir_get_parm(ROT *rot, setting_t parm, value_t *val) { return -RIG_ENIMPL; } static int flir_set_ext_parm(ROT *rot, hamlib_token_t token, value_t val) { return -RIG_ENIMPL; } static int flir_get_ext_parm(ROT *rot, hamlib_token_t token, value_t *val) { return -RIG_ENIMPL; } static int flir_get_status(ROT *rot, rot_status_t *status) { const struct flir_priv_data *priv = (struct flir_priv_data *) ROTSTATE(rot)->priv; *status = priv->status; return RIG_OK; } /* * flir rotator capabilities. */ struct rot_caps flir_caps = { ROT_MODEL(ROT_MODEL_FLIR), .model_name = "PTU Serial", .mfg_name = "FLIR", .version = "20240818.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 300, .timeout = 400, .retry = 3, .min_az = -180., .max_az = 180., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .has_get_func = FLIR_FUNC, .has_set_func = FLIR_FUNC, .has_get_level = FLIR_LEVEL, .has_set_level = ROT_LEVEL_SET(FLIR_LEVEL), .has_get_parm = FLIR_PARM, .has_set_parm = ROT_PARM_SET(FLIR_PARM), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .has_status = FLIR_STATUS, .rot_init = flir_init, .rot_cleanup = flir_cleanup, .rot_open = flir_open, .rot_close = flir_close, .set_conf = flir_set_conf, .get_conf = flir_get_conf, .set_position = flir_set_position, .get_position = flir_get_position, .park = flir_park, .stop = flir_stop, .reset = flir_reset, .move = flir_move, .set_func = flir_set_func, .get_func = flir_get_func, .set_level = flir_set_level, .get_level = flir_get_level, .set_parm = flir_set_parm, .get_parm = flir_get_parm, .set_ext_func = flir_set_ext_func, .get_ext_func = flir_get_ext_func, .set_ext_level = flir_set_ext_level, .get_ext_level = flir_get_ext_level, .set_ext_parm = flir_set_ext_parm, .get_ext_parm = flir_get_ext_parm, .get_info = flir_get_info, .get_status = flir_get_status, }; DECLARE_INITROT_BACKEND(flir) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&flir_caps); rot_register(&netrotctl_caps); return RIG_OK; } hamlib-4.6.5/rotators/flir/Android.mk0000664000175000017500000000036615056640443013203 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := flir.c LOCAL_MODULE := flir LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/flir/Makefile.in0000664000175000017500000005236515056640453013346 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/flir ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_flir_la_LIBADD = am__objects_1 = flir.lo am_libhamlib_flir_la_OBJECTS = $(am__objects_1) libhamlib_flir_la_OBJECTS = $(am_libhamlib_flir_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/flir.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_flir_la_SOURCES) DIST_SOURCES = $(libhamlib_flir_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ FLIRSRC = flir.c flir.h noinst_LTLIBRARIES = libhamlib-flir.la libhamlib_flir_la_SOURCES = $(FLIRSRC) EXTRA_DIST = README.md Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/flir/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/flir/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-flir.la: $(libhamlib_flir_la_OBJECTS) $(libhamlib_flir_la_DEPENDENCIES) $(EXTRA_libhamlib_flir_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_flir_la_OBJECTS) $(libhamlib_flir_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flir.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/flir.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/flir.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/flir/Makefile.am0000664000175000017500000000021115056640443013313 FLIRSRC = flir.c flir.h noinst_LTLIBRARIES = libhamlib-flir.la libhamlib_flir_la_SOURCES = $(FLIRSRC) EXTRA_DIST = README.md Android.mkhamlib-4.6.5/rotators/saebrtrack/0000775000175000017500000000000015056640502012526 5hamlib-4.6.5/rotators/saebrtrack/saebrtrack.h0000664000175000017500000000361215056640443014746 /* * Hamlib Rotator backend - SAEBRTrack interface protocol * Copyright (c) 2023 by Matthew J Wolf * Contributed by Matthew J Wolf * * Hamlib Rotator backend - Easycomm interface protocol * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_SABEBRTRACK_H #define _ROT_SABEBRTRACK_H 1 #include "rotator.h" #include "token.h" extern const struct rot_caps saebrtrack_rot_caps; // extern const struct rot_caps easycomm2_rot_caps; // extern const struct rot_caps easycomm3_rot_caps; /* * Tokens used by rotorez_rot_set_conf and get_conf and the 'C' command in rotctl * and rotctld. */ #define TOK_GET_CONFIG TOKEN_BACKEND(1) #define TOK_SET_CONFIG TOKEN_BACKEND(2) #define TOK_GET_STATUS TOKEN_BACKEND(3) #define TOK_GET_ERRORS TOKEN_BACKEND(4) #define TOK_GET_VERSION TOKEN_BACKEND(5) #define TOK_GET_INPUT TOKEN_BACKEND(6) #define TOK_SET_OUTPUT TOKEN_BACKEND(7) #define TOK_GET_ANALOG_INPUT TOKEN_BACKEND(8) #endif /* _ROT_SABEBRTRACK_H */ hamlib-4.6.5/rotators/saebrtrack/saebrtrack.txt0000664000175000017500000000345715056640443015345 10-AUG-2020 Matthew J. Wolf Email: mwolf at speciosus.net I wanted to use Hamlib with my Amsat Tricked-Out WRAPS satellite antenna rotator [1],[2] with Hamlib and gpredict. During testing I discovered that the WARPS implementation of EASYCOMM I rotator protocol is not correct. The EASYCOMM I specification states "The Az and El values (aaa.a and eee.e) are not fixed width." The WRAPS EASYCOMM implementation is FIXED WIDTH! The WRAPS does not work with Hamlib's correct implementation of the EASYCOMM protocol. WARPS is expecting a zero padded number for the Az and El values. Leading zeros need to be added. Example for Az of 99 and El of 10: WARPS: AZ099.0 EL010.0 UP000 XXX DN000 XXX EASYCOMM I: AZ99.0 EL10.0 UP000 XXX DN000 XXX The SAEBRTrack rotator backend is a hack of the Hamlib EASYCOMM rotator backend. I copied EASYCOMM backend and removed what was not needed. I named the Hamlib rotator backend SAEBRTrack because that is the rotator protocol that is used with the WRAPS in the Microsoft windows pcsat32 program. The SAEBRTrack rotator backend only supports changing the rotor's Az and El. I have tested the rotator backend for Az and El changes with my Amsat WRAPS. The backend should work with original SAEBRTrack [3] and derivatives. The specification of EASYCOMM I protocol the are in the easycomm.txt file in the EASYCOMM rotator backend source directory References: [1] M. Spencer. WRAPS Rotor Enhancements Add a Second Beam and Circular Polarization". The AMSAT Journal. vol. 37, no. 3, pp. 25 to 31. 2014. [2] Amsat.org, 2020. [Online]. Available: https://www.amsat.org/wordpress/xtra/WRAPSArticlewithStoreAd.pdf. [Accessed: 10 Aug 2020]. [1]"saebrtrack - marklhammond", Sites.google.com, 2020. [Online]. Available: https://sites.google.com/site/marklhammond/saebrtrack. [Accessed: 10 Aug 2020]. hamlib-4.6.5/rotators/saebrtrack/Android.mk0000664000175000017500000000040115056640443014356 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := saebrtrack.c LOCAL_MODULE := saebrtrack LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/saebrtrack/Makefile.in0000664000175000017500000005251615056640453014531 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/saebrtrack ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_saebrtrack_la_LIBADD = am_libhamlib_saebrtrack_la_OBJECTS = saebrtrack.lo libhamlib_saebrtrack_la_OBJECTS = \ $(am_libhamlib_saebrtrack_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/saebrtrack.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_saebrtrack_la_SOURCES) DIST_SOURCES = $(libhamlib_saebrtrack_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-saebrtrack.la libhamlib_saebrtrack_la_SOURCES = saebrtrack.c saebrtrack.h EXTRA_DIST = saebrtrack.txt Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/saebrtrack/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/saebrtrack/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-saebrtrack.la: $(libhamlib_saebrtrack_la_OBJECTS) $(libhamlib_saebrtrack_la_DEPENDENCIES) $(EXTRA_libhamlib_saebrtrack_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_saebrtrack_la_OBJECTS) $(libhamlib_saebrtrack_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saebrtrack.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/saebrtrack.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/saebrtrack.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/saebrtrack/saebrtrack.c0000664000175000017500000001175715056640443014752 /* * Hamlib Rotator backend - SAEBRTrack * Copyright (c) 2023 by Matthew J Wolf * Contributed by Matthew J Wolf * * Hamlib Rotator backend - Easycom * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "saebrtrack.h" /* ************************************************************************* */ /** * saebrtrack_transaction * * Assumes rot!=NULL and cmdstr!=NULL * * cmdstr - string to send to rotator * data - buffer for reply string * data_len - (input) Maximum size of buffer * (output) Number of bytes read. */ static int saebrtrack_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %s\n", __func__, cmdstr); if (!rot) { return -RIG_EINVAL; } rig_flush(rotp); retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } if (data == NULL) { return RIG_OK; /* don't want a reply */ } retval = read_string(rotp, (unsigned char *) data, data_len, "\n", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_TRACE, "%s read_string failed with status %d\n", __func__, retval); goto transaction_quit; } else { rig_debug(RIG_DEBUG_TRACE, "%s read_string: %s\n", __func__, data); retval = RIG_OK; } transaction_quit: return retval; } /* ************************************************************************* */ static int saebrtrack_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); /* Non Easycom standard */ SNPRINTF(cmdstr, sizeof(cmdstr), "AZ%05.1f EL%05.1f UP000 XXX DN000 XXX\n", az, el); retval = saebrtrack_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } /* TODO: Error processing */ return RIG_OK; } /* * Get Info * returns the model name string */ // cppcheck-suppress constParameterCallback static const char *saebrtrack_rot_get_info(ROT *rot) { const struct rot_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return (const char *) - RIG_EINVAL; } rc = rot->caps; return rc->model_name; } /* ************************************************************************* */ /* * saebrtrack rotator capabilities. */ /** saebrtrackI implement essentially only the set position function, but * I included the stop command too. The radio control tags is only included * as dummy entries because the spec require them. */ const struct rot_caps saebrtrack_rot_caps = { ROT_MODEL(ROT_MODEL_SAEBRTRACK), .model_name = "SAEBRTrack", .mfg_name = "Hamlib", .version = "20200810.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .priv = NULL, /* priv */ .set_position = saebrtrack_rot_set_position, .get_info = saebrtrack_rot_get_info, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(saebrtrack) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&saebrtrack_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/saebrtrack/Makefile.am0000664000175000017500000000022315056640443014503 noinst_LTLIBRARIES = libhamlib-saebrtrack.la libhamlib_saebrtrack_la_SOURCES = saebrtrack.c saebrtrack.h EXTRA_DIST = saebrtrack.txt Android.mk hamlib-4.6.5/rotators/grbltrk/0000775000175000017500000000000015056640501012053 5hamlib-4.6.5/rotators/grbltrk/Android.mk0000775000175000017500000000040015056640443013706 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := grbltrk.c LOCAL_MODULE := grbltrk LOCAL_CFLAGS := -DHAVE_CONFIG_H LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/armeabi include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/grbltrk/Makefile.in0000664000175000017500000005235115056640453014054 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/grbltrk ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_grbltrk_la_LIBADD = am_libhamlib_grbltrk_la_OBJECTS = grbltrk.lo libhamlib_grbltrk_la_OBJECTS = $(am_libhamlib_grbltrk_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/grbltrk.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_grbltrk_la_SOURCES) DIST_SOURCES = $(libhamlib_grbltrk_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-grbltrk.la libhamlib_grbltrk_la_SOURCES = grbltrk.c EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/grbltrk/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/grbltrk/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-grbltrk.la: $(libhamlib_grbltrk_la_OBJECTS) $(libhamlib_grbltrk_la_DEPENDENCIES) $(EXTRA_libhamlib_grbltrk_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_grbltrk_la_OBJECTS) $(libhamlib_grbltrk_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grbltrk.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/grbltrk.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/grbltrk.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/grbltrk/grbltrk.c0000664000175000017500000003706515056640443013626 /* * Hamlib Rotator backend - LinuxCNC no hardware port * Copyright (c) 2015 by Robert Freeman * Adapted from AMSAT code by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #ifdef HAVE_SYS_IOCTL_H #include #endif #include "hamlib/rotator.h" #include "hamlib/rig.h" #include "misc.h" #include "serial.h" #include "token.h" #include "register.h" #define RSIZE (1024) #define XDEGREE2MM(d) ((d)/9.0) // 42-gear-22 #define YDEGREE2MM(d) ((d)/9.0) //#define YDEGREE2MM(d) ((d) * ((1710) / (77*9))) //#define YDEGREE2MM(d) ((d) * ((190) / (77))) /* $0=10 (step pulse, usec) $1=25 (step idle delay, msec) $2=0 (step port invert mask:00000000) $3=0 (dir port invert mask:00000000) $4=0 (step enable invert, bool) $5=0 (limit pins invert, bool) $6=0 (probe pin invert, bool) $10=3 (status report mask:00000011) $11=0.010 (junction deviation, mm) $12=0.002 (arc tolerance, mm) $13=0 (report inches, bool) $20=0 (soft limits, bool) $21=0 (hard limits, bool) $22=0 (homing cycle, bool) $23=0 (homing dir invert mask:00000000) $24=25.000 (homing feed, mm/min) $25=500.000 (homing seek, mm/min) $26=250 (homing debounce, msec) $27=1.000 (homing pull-off, mm) $30=1000. (rpm max) $31=0. (rpm min) $32=0 (motor lock bool) $33=7 (motor mode mask:00000111) $100=80.000 (x, step/mm) $101=80.000 (y, step/mm) $102=80.000 (z, step/mm) $110=10000.000 (x max rate, mm/min) $111=10000.000 (y max rate, mm/min) $112=10000.000 (z max rate, mm/min) $120=250.000 (x accel, mm/sec^2) $121=250.000 (y accel, mm/sec^2) $122=250.000 (z accel, mm/sec^2) $130=500.000 (x max travel, mm) $131=500.000 (y max travel, mm) $132=500.000 (z max travel, mm) */ char *grbl_get_config = "$$\r\n"; char *grbl_get_pos = "?\r\n"; char *grbl_init_list[] = { "$1=255\r\n", /* lock motors */ "$3=3\r\n", /* invert X and Y direction */ //"$100=80\r\n", /* axis-x a4988 16 microstep */ "$100=1776\r\n", /* axis-x a4988 16 microstep 42-gear-motor-22-(1710/77) (80*1710)/77 */ //"$101=160\n", /* axis-y drv8825 32 microstep */ //"$101=80\n", /* axis-y a4988 16 microstep */ "$101=1776\r\n", /* axis-y a4988 16 microstep 42-gear-motor-22-(1710/77) (80*1710)/77 */ "$110=50\r\n", "$111=50\r\n", "$120=25\r\n", "$121=25\r\n", "G90\r\n", "G0 X0 Y0\r\n", }; static int grbl_request(ROT *rot, char *request, uint32_t req_size, char *response, uint32_t *resp_size) { static int fail_count = 0; hamlib_port_t *rotp = ROTPORT(rot); rot_debug(RIG_DEBUG_ERR, "req: [%s][%d]\n", request, fail_count); if (rot->caps->rot_model == ROT_MODEL_GRBLTRK_SER || rot->caps->rot_model == ROT_MODEL_GRBLTRK_NET) { int retval; //fprintf(stderr, "ctrl by serial/network\n"); if ((retval = write_block(rotp, (unsigned char *)request, req_size)) != RIG_OK) { rot_debug(RIG_DEBUG_ERR, "%s write_block fail!\n", __func__); //exit(-1); fail_count++; //return RIG_EIO; } else { fail_count = 0; } rig_flush(rotp); usleep(300000); if ((retval = read_string(rotp, (unsigned char *)response, 1024, "\n", 1, 0, 1)) < 0) { rot_debug(RIG_DEBUG_ERR, "%s read_string fail! (%d) \n", __func__, retval); //exit(-1); fail_count++; //return RIG_EIO; } else { fail_count = 0; } if (fail_count >= 10) { rot_debug(RIG_DEBUG_ERR, "%s too much xfer fail! exit\n", __func__); return -RIG_EPROTO; } rig_flush(rotp); rot_debug(RIG_DEBUG_ERR, "rsp: [%s]\n", response); //fprintf(stderr, "rsp: [%s]\n", response); *resp_size = retval; } return RIG_OK; } static int grbl_init(ROT *rot) { int i; uint32_t init_count; char rsp[RSIZE]; uint32_t resp_size; /* get total config */ grbl_request(rot, grbl_get_config, strlen(grbl_get_config), rsp, &resp_size); if (strstr(rsp, grbl_init_list[0]) != NULL) { rot_debug(RIG_DEBUG_ERR, "%s: grbl already configured\n", __func__); return RIG_OK; } init_count = sizeof(grbl_init_list) / sizeof(grbl_init_list[0]); for (i = 0; i < init_count; i++) { int retval; rot_debug(RIG_DEBUG_ERR, "grbl_request [%s] ", grbl_init_list[i]); retval = grbl_request(rot, grbl_init_list[i], strlen(grbl_init_list[i]), rsp, &resp_size); //fprintf(stderr, "done\n"); if (retval != RIG_OK) { rot_debug(RIG_DEBUG_ERR, "grbl_request [%s] fail\n", grbl_init_list[i]); return RIG_EIO; } } return RIG_OK; } static int grbltrk_rot_set_position(ROT *rot, azimuth_t curr_az, elevation_t curr_el) { int i; int retval; static float prev_az, prev_el; static float prev_x, curr_x; float x[3], delta[3]; float y; char req[RSIZE] = {0}; char rsp[RSIZE] = {0}; uint32_t rsp_size; float min_value; int min_index; /* az:x: 0 - 360 */ /* el:y: 0 - 90 */ rot_debug(RIG_DEBUG_ERR, "%s: (prev_x) = (%.3f); (prev_az) = (%.3f); (prev_el) = (%.3f); (curr_az, curr_el) = (%.3f, %.3f)\n", __func__, prev_x, prev_az, prev_el, curr_az, curr_el); /* convert degree to mm, 360 degree = 40mm, 1 degree = 0.111mm */ //x = az * 0.111; //y = el * 0.111; /* 360 -> 0 */ if ((prev_az > 270 && prev_az < 360) && (curr_az > 0 && curr_az < 90)) { rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); if (prev_x >= XDEGREE2MM(270)) { curr_x = XDEGREE2MM(curr_az) + XDEGREE2MM(360); } else { curr_x = XDEGREE2MM(curr_az); } /* 0 -> 360 */ } else if ((prev_az > 0 && prev_az < 90) && (curr_az > 270 && curr_az < 360)) { rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); if (prev_x >= XDEGREE2MM(360)) { curr_x = XDEGREE2MM(curr_az); } else { curr_x = XDEGREE2MM(curr_az) - XDEGREE2MM(360); } /* reset */ } else if (curr_az == 0 && curr_el == 0) { rot_debug(RIG_DEBUG_ERR, "%s: reset\n", __func__); curr_x = 0; } else { rot_debug(RIG_DEBUG_ERR, "%s:%d prev_x: %.3f\n", __func__, __LINE__, prev_x); x[0] = XDEGREE2MM(curr_az) - XDEGREE2MM(360); x[1] = XDEGREE2MM(curr_az); x[2] = XDEGREE2MM(curr_az) + XDEGREE2MM(360); delta[0] = prev_x - x[0]; delta[1] = prev_x - x[1]; delta[2] = prev_x - x[2]; if (delta[0] < 0) { delta[0] = -1 * delta[0]; } if (delta[1] < 0) { delta[1] = -1 * delta[1]; } if (delta[2] < 0) { delta[2] = -1 * delta[2]; } min_value = delta[0]; min_index = 0; for (i = 0; i < 3; i++) { if (delta[i] <= min_value) { min_value = delta[i]; min_index = i; } } curr_x = x[min_index]; rot_debug(RIG_DEBUG_ERR, "min_index: %d; curr_x: %.3f\n", min_index, curr_x); } y = YDEGREE2MM(curr_el); /**/ snprintf(req, sizeof(req), "G0 X%.3f Y%.3f\n", curr_x, y); retval = grbl_request(rot, req, strlen(req), rsp, &rsp_size); if (retval != RIG_OK) { return retval; } prev_az = curr_az; prev_el = curr_el; prev_x = curr_x; return RIG_OK; } static int grbltrk_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { //static char req[RSIZE]; static char rsp[RSIZE]; uint32_t rsp_size; float mpos[3]; char dummy0[256]; char dummy1[256]; int i; rot_debug(RIG_DEBUG_ERR, "%s called\n", __func__); //snprintf(req, sizeof(req), "?\r\n"); for (i = 0; i < 5; i++) { int retval; retval = grbl_request(rot, grbl_get_pos, strlen(grbl_get_pos), rsp, &rsp_size); /*FIXME: X Y safe check */ if (retval != RIG_OK) { return retval; } if (strstr(rsp, "MPos") == NULL) { rot_debug(RIG_DEBUG_ERR, "%s no MPos found, continue\n", __func__); continue; } /* grbl 0.9 mega328p */ /* */ //sscanf(rsp, "%[^','],MPos:%f,%f,%f,WPos:%f,%f,%f,%s", &dummy[0], &mpos[0], &mpos[1], &mpos[2], &wpos[0], &wpos[1], &wpos[2], &dummy[1]); /* grbl 1.3a esp32 */ // sscanf(rsp, "%[^'|']|MPos:%f,%f,%255s", dummy0, &mpos[0], &mpos[1], dummy1); //rot_debug(RIG_DEBUG_ERR, "%s: (%.3f, %.3f) (%.3f, %.3f)\n", __func__, mpos[0], mpos[1], wpos[0], wpos[1]); //*az = (azimuth_t) mpos[0] / 0.111; //*el = (elevation_t) mpos[1] / 0.111; *az = (azimuth_t) mpos[0] * 9; *el = (elevation_t) mpos[1] * 9; if ((*az) < 0) { (*az) = (*az) + 360; } //rot_debug(RIG_DEBUG_ERR, "%s: (az, el) = (%.3f, %.3f)\n", __func__, *az, *el); rot_debug(RIG_DEBUG_ERR, "%s: (az, el) = (%.3f, %.3f)\n", __func__, *az, *el); return RIG_OK; } *az = (azimuth_t) 0; *el = (elevation_t) 0; return RIG_OK; } static int grbltrk_rot_set_conf(ROT *rot, hamlib_token_t token, const char *val) { uint32_t resp_size, len; rot_debug(RIG_DEBUG_ERR, "token: %ld; value: [%s]\n", token, val); len = strlen(val); if ((len != 0) && (val[0] == 'G')) { int i, retval; char req[RSIZE] = {0}; char rsp[RSIZE]; if (!ROTSTATE(rot)->comm_state) { return queue_deferred_config(&ROTSTATE(rot)->config_queue, token, val); } for (i = 0; i < len; i++) { if (val[i] == '@') { req[i] = ' '; } else { req[i] = val[i]; } } req[i] = '\n'; len = strlen(req); rot_debug(RIG_DEBUG_ERR, "send gcode [%s]\n", req); retval = grbl_request(rot, req, len, rsp, &resp_size); if (retval < 0) { rot_debug(RIG_DEBUG_ERR, "grbl_request [%s] fail\n", val); return RIG_EIO; } } return RIG_OK; } static int grbltrk_rot_init(ROT *rot) { int r = RIG_OK; rot_debug(RIG_DEBUG_ERR, "%s:%d rot->caps->rot_model: %d\n", __func__, __LINE__, rot->caps->rot_model); return r; } static int grbl_net_open(ROT *rot, int port) { //network_open(ROTPORT(rot), port); //rot_debug(RIG_DEBUG_ERR, "%s:%d network_fd: %d\n", __func__, __LINE__, ROTPORT(rot)->fd); rot_debug(RIG_DEBUG_ERR, "%s:%d \n", __func__, __LINE__); return 0; } static int grbltrk_rot_open(ROT *rot) { int r = RIG_OK; char host[128] = {0}; //char ip[32]; //int port; //rot_debug(RIG_DEBUG_ERR, "%s:%d rot->caps->rot_model: %d\n", __func__, __LINE__, rot->caps->rot_model); if (rot->caps->rot_model == ROT_MODEL_GRBLTRK_SER) { rot_debug(RIG_DEBUG_ERR, "%s:%d ctrl via serial\n", __func__, __LINE__); } else if (rot->caps->rot_model == ROT_MODEL_GRBLTRK_NET) { rot_get_conf(rot, TOK_PATHNAME, host); rot_debug(RIG_DEBUG_ERR, "%s:%d ctrl via net, host [%s]\n", __func__, __LINE__, host); grbl_net_open(rot, 23); #if 0 if (sscanf(host, "%[^:]:%d", ip, &port) == 2) { grbl_net_open(rot, ip, port); } else { grbl_net_open(rot, NULL, 0); /* use default ip & port */ } #endif } grbl_init(rot); //rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); return r; } static void grbl_net_close(ROT *rot) { port_close(ROTPORT(rot), RIG_PORT_NETWORK); } static int grbltrk_rot_close(ROT *rot) { int r = RIG_OK; if (rot->caps->rot_model == ROT_MODEL_GRBLTRK_SER) { rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); } else if (rot->caps->rot_model == ROT_MODEL_GRBLTRK_NET) { rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); grbl_net_close(rot); } rot_debug(RIG_DEBUG_ERR, "%s:%d\n", __func__, __LINE__); return r; } /** CNCTRK implements essentially only the set position function. it assumes there is a LinuxCNC running with the Axis GUI */ const struct rot_caps grbltrk_serial_rot_caps = { ROT_MODEL(ROT_MODEL_GRBLTRK_SER), .model_name = "GRBLTRK via Serial", .mfg_name = "BG5DIW", .version = "20220515.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 0, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 90, .rot_init = grbltrk_rot_init, .rot_open = grbltrk_rot_open, .set_position = grbltrk_rot_set_position, .get_position = grbltrk_rot_get_position, .set_conf = grbltrk_rot_set_conf, }; const struct rot_caps grbltrk_net_rot_caps = { ROT_MODEL(ROT_MODEL_GRBLTRK_NET), .model_name = "GRBLTRK via Net", .mfg_name = "BG5DIW", .version = "20220515.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, /* RIG_PORT_NONE */ //.port_type = RIG_PORT_NONE, /* RIG_PORT_NONE */ .write_delay = 0, .post_write_delay = 0, .timeout = 300, .retry = 0, //.retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 90, .rot_init = grbltrk_rot_init, .rot_open = grbltrk_rot_open, .rot_close = grbltrk_rot_close, .set_position = grbltrk_rot_set_position, .get_position = grbltrk_rot_get_position, .set_conf = grbltrk_rot_set_conf, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(grbltrk) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); //rot_debug(RIG_DEBUG_ERR, "%s: _init called\n", __func__); rot_register(&grbltrk_serial_rot_caps); rot_register(&grbltrk_net_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/grbltrk/Makefile.am0000775000175000017500000000015515056640443014040 noinst_LTLIBRARIES = libhamlib-grbltrk.la libhamlib_grbltrk_la_SOURCES = grbltrk.c EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/m2/0000775000175000017500000000000015056640502010723 5hamlib-4.6.5/rotators/m2/rc2800.c0000664000175000017500000003054215056640443011735 /* * Hamlib Rotator backend - M2 RC2800 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rotator.h" #include "serial.h" #include "misc.h" #include "register.h" #include "num_stdio.h" #include "rc2800.h" #define CR "\r" #define LF "\x0a" #define BUFSZ 128 /* The continuous output of some of the RC2800 models can be a nuisance. Even if we flush the input stream before sending the command, there may be partial sentence in the stream ahead of the data we want. */ /* rc2800_parse Parse output from the rotator controller We want to recognize the following sentences: A ERR= E ERR= A P= S= E P= S= A= S= E= S= */ static int rc2800_parse(char *s, char *device, float *value) { int msgtype = 0, errcode = 0; int len; rig_debug(RIG_DEBUG_TRACE, "%s: device return->%s", __func__, s); len = strlen(s); if (len == 0) { return -RIG_EPROTO; } if (len > 7) { if (*s == 'A' || *s == 'E') { int i; *device = *s; if (!strncmp(s + 2, "ERR=", 4)) { msgtype = 1; i = sscanf(s + 6, "%d", &errcode); if (i == EOF) { return -RIG_EINVAL; } } else if (!strncmp(s + 2, "P=", 2)) { msgtype = 2; i = num_sscanf(s + 5, "%f", value); if (i == EOF) { return -RIG_EINVAL; } } else if (s[1] == '=') { msgtype = 2; i = num_sscanf(s + 2, "%f", value); if (i == EOF) { return -RIG_EINVAL; } } } } if (msgtype == 2) { rig_debug(RIG_DEBUG_TRACE, "%s: device=%c value=%3.1f\n", __func__, *device, *value); return RIG_OK; } else if (msgtype == 1) { rig_debug(RIG_DEBUG_TRACE, "%s: driver error code %d\n", __func__, errcode); *device = ' '; return RIG_OK; } return -RIG_EPROTO; } #if 0 int testmain() { rc2800_parse("A P= 98.1 S=9 MV"); rc2800_parse("A P= 100.0 S=9 MV"); rc2800_parse("E=43.7 S=9 M"); rc2800_parse("E=42.8 S=9 S"); rc2800_parse("E ERR=05"); return 0; } #endif /** * rc2800_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. */ static int rc2800_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; char replybuf[BUFSZ]; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to know whether the cmd went OK */ if (!data) { data = replybuf; } if (!data_len) { data_len = BUFSZ; } /* then comes the answer */ memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, CR LF, strlen(CR LF), 0, 1); // some models seem to echo -- so we'll check and read again if echoed // skip last char in case the reply is terminated with LF instead of CR if (cmdstr && strncmp(data, cmdstr, strlen(data) - 1) == 0) { memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, CR LF, strlen(CR LF), 0, 1); } // some models uses both CR + LF -- so we'll check and discard the additional one if (strlen(data) == 1) { memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, CR LF, strlen(CR LF), 0, 1); } if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } retval = RIG_OK; transaction_quit: return retval; } static int rc2800_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval1, retval2 = RIG_OK; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); if (rot->caps->rot_model == ROT_MODEL_RC2800) // new protocol { // does the new protocol use decimal points? // we'll assume no for now num_sprintf(cmdstr, "A%.0f"CR, az); } else // old protocol (both AZ and AZEL) { // we have to switch modes and then send azimuth // an extra CR gives us a response to expect num_sprintf(cmdstr, "A\r%.0f\r\r", az); } retval1 = rc2800_transaction(rot, cmdstr, NULL, 0); if (rot->caps->rot_type == ROT_TYPE_AZIMUTH) { return retval1; } /* do not overwhelm the MCU? */ hl_usleep(200 * 1000); if (rot->caps->rot_model == ROT_MODEL_RC2800) // new protocol { num_sprintf(cmdstr, "E%.0f"CR, el); } else // old protocol (both AZ and AZEL) { // we have to switch modes and then send azimuth // an extra CR gives us a response to expect num_sprintf(cmdstr, "E\r%.0f\r\r", el); } retval2 = rc2800_transaction(rot, cmdstr, NULL, 0); if (retval1 == retval2) { return retval1; } return (retval1 != RIG_OK ? retval1 : retval2); } static int rc2800_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; int retval; char device; float value; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *el = 0; retval = rc2800_transaction(rot, "A" CR, posbuf, sizeof(posbuf)); if (retval != RIG_OK || strlen(posbuf) < 5) { return retval < 0 ? retval : -RIG_EPROTO; } if (rc2800_parse(posbuf, &device, &value) == RIG_OK) { if (device == 'A') { *az = (azimuth_t) value; } else { return -RIG_EPROTO; } } if (rot->caps->rot_type == ROT_TYPE_AZIMUTH) { rig_debug(RIG_DEBUG_TRACE, "%s: (az) = (%.1f)\n", __func__, *az); return RIG_OK; } /* do not overwhelm the MCU? */ hl_usleep(200 * 1000); retval = rc2800_transaction(rot, "E" CR, posbuf, sizeof(posbuf)); if (retval != RIG_OK || strlen(posbuf) < 5) { return retval < 0 ? retval : -RIG_EPROTO; } if (rc2800_parse(posbuf, &device, &value) == RIG_OK) { if (device == 'E') { *el = (elevation_t) value; } else { return -RIG_EPROTO; } } rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int rc2800_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* TODO: check each return value (do we care?) */ /* Stop AZ*/ retval = rc2800_transaction(rot, "A" CR, NULL, 0); /* select AZ */ if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: A command failed?\n", __func__); } retval = rc2800_transaction(rot, "S" CR, NULL, 0); /* STOP */ if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: az S command failed?\n", __func__); } if (rot->caps->rot_type == ROT_TYPE_AZIMUTH) { return retval; } /* do not overwhelm the MCU? */ hl_usleep(200 * 1000); /* Stop EL*/ retval = rc2800_transaction(rot, "E" CR, NULL, 0); /* select EL */ if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: E command failed?\n", __func__); } retval = rc2800_transaction(rot, "S" CR, NULL, 0); /* STOP */ if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: el S command failed?\n", __func__); } return retval; } /* ************************************************************************* */ /* * M2 RC2800 rotator capabilities. * * Protocol documentation: http://www.confluentdesigns.com/files/PdfFiles/devguide_24.pdf */ const struct rot_caps rc2800_rot_caps = { ROT_MODEL(ROT_MODEL_RC2800), .model_name = "RC2800", .mfg_name = "M2", .version = "20230123", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .get_position = rc2800_rot_get_position, .set_position = rc2800_rot_set_position, .stop = rc2800_rot_stop, }; // below tested on RC2800P-A const struct rot_caps rc2800az_rot_caps = { ROT_MODEL(ROT_MODEL_RC2800_EARLY_AZ), .model_name = "RC2800_EARLY_AZ", .mfg_name = "M2", .version = "20230123", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .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 = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .get_position = rc2800_rot_get_position, .set_position = rc2800_rot_set_position, .stop = rc2800_rot_stop, }; const struct rot_caps rc2800azel_rot_caps = { ROT_MODEL(ROT_MODEL_RC2800_EARLY_AZEL), .model_name = "RC2800_EARLY_AZEL", .mfg_name = "M2", .version = "20230123", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .get_position = rc2800_rot_get_position, .set_position = rc2800_rot_set_position, .stop = rc2800_rot_stop, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(m2) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&rc2800_rot_caps); rot_register(&rc2800az_rot_caps); rot_register(&rc2800azel_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/m2/rc2800.h0000664000175000017500000000172515056640443011743 /* * Hamlib Rotator backend - M2 RC2800 interface protocol * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_RC2800_H #define _ROT_RC2800_H 1 #include "rotator.h" extern const struct rot_caps rc2800_rot_caps; #endif /* _ROT_RC2800_H */ hamlib-4.6.5/rotators/m2/Android.mk0000664000175000017500000000036615056640443012565 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := rc2800.c LOCAL_MODULE := m2 LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/m2/Makefile.in0000664000175000017500000005222715056640453012725 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/m2 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_m2_la_LIBADD = am_libhamlib_m2_la_OBJECTS = rc2800.lo libhamlib_m2_la_OBJECTS = $(am_libhamlib_m2_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/rc2800.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_m2_la_SOURCES) DIST_SOURCES = $(libhamlib_m2_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-m2.la libhamlib_m2_la_SOURCES = rc2800.c rc2800.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/m2/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/m2/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-m2.la: $(libhamlib_m2_la_OBJECTS) $(libhamlib_m2_la_DEPENDENCIES) $(EXTRA_libhamlib_m2_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_m2_la_OBJECTS) $(libhamlib_m2_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc2800.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/rc2800.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/rc2800.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/m2/Makefile.am0000664000175000017500000000015315056640443012702 noinst_LTLIBRARIES = libhamlib-m2.la libhamlib_m2_la_SOURCES = rc2800.c rc2800.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/spid/0000775000175000017500000000000015056640502011344 5hamlib-4.6.5/rotators/spid/spid.h0000664000175000017500000000214715056640443012404 /* * Hamlib Rotator backend - SPID Rot2Prog * Copyright (c) 2009 by Norvald H. Ryeng, LA6YKA * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_SPID_H #define _ROT_SPID_H 1 #include "rotator.h" extern const struct rot_caps spid_rot1prog_rot_caps; extern const struct rot_caps spid_rot2prog_rot_caps; extern const struct rot_caps spid_md01_rot2prog_rot_caps; #endif /* _ROT_SPID_H */ hamlib-4.6.5/rotators/spid/spid.c0000664000175000017500000005316715056640443012407 /* * Hamlib Rotator backend - SPID Rot1Prog & Rot2Prog * Copyright (c) 2009-2011 by Norvald H. Ryeng, LA6YKA * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "spid.h" #define TOK_AZRES 1 #define TOK_ELRES 2 struct spid_rot2prog_priv_data { int az_resolution; int el_resolution; int dir; // current direction }; enum spid_rot2prog_framemagic { ROT2PROG_FRAME_START_BYTE = 'W', ROT2PROG_FRAME_END_BYTE = ' ', }; enum r2p_frame_parser_state { ROT2PROG_PARSER_EXPECT_FRAME_START, ROT2PROG_PARSER_EXPECT_CR, ROT2PROG_PARSER_EXPECT_LF, ROT2PROG_PARSER_EXPECT_FRAME_END, }; static int read_r2p_frame(hamlib_port_t *port, unsigned char *rxbuffer, size_t count) { // Some MD-01 firmware can apparently print debug messages to the same // serial port that is used for the control protocol. This awkwardly // intersperses the normal fixed-size frame response with a line-based // logs. Theoretically, a valid response frame will not actually be emitted // in the middle of a log message. // // Log messages are of the format : \r\n, where // is a unix-ish timestamp (inasmuch as it is an integer) and // is an ASCII string. // Due to poor(?) design decisions by the protocol designers, the frame // start and end bytes are both printable ASCII characters ('W' and ' ' // respectively) and the MD-01 response frame contains no other validation // information (such as a CRC), which means that a valid log line can // contain a character sequence that is indistinguishable from a valid // response frame, without actually being a valid response frame. // However, since the log messages appear to be reasonably strictly // structured, we can make a small number of assumptions that will allow us // to reliably separate response frames from log lines without having to // fall back on a heuristic-based parsing strategy. These assumptions are // as follows: // 1. A log line will always begin with an ASCII character in the range // [0-9], none of which are the frame start byte. // 2. A log line will never contain \r\n in the middle of the line (i.e. // multi-line log messages do not exist). This means a log "frame" will // always be of the form [0-9]\r\n. // 3. The controller will not emit a response frame in the middle of a log // line. // 4. The operating system's serial port read buffer is large enough that we // won't lose data while accumulating log messages between commands. // Provided the above assumptions are true, a simple state machine can be // used to parse the response by treating the log lines as a different type // of frame. This could be made much more robust by applying additional // heuristics for specific packets (e.g. get_position has some reasonably // strict numerical bounds that could be used to sanity check the contents // of the reply frame). int res = 0; unsigned char peek = 0; enum r2p_frame_parser_state pstate = ROT2PROG_PARSER_EXPECT_FRAME_START; // This will loop infinitely in the case of a badly-behaved serial device // that is producing log-like frames faster than we can consume them. // However, this is not expected to be a practical possibility, and there's // no concrete loop bounds we can use. while (1) { switch (pstate) { case ROT2PROG_PARSER_EXPECT_FRAME_START: res = read_block(port, &peek, 1); if (res < 0) { return res; } switch (peek) { case ROT2PROG_FRAME_START_BYTE: rxbuffer[0] = peek; pstate = ROT2PROG_PARSER_EXPECT_FRAME_END; break; default: pstate = ROT2PROG_PARSER_EXPECT_CR; break; } break; case ROT2PROG_PARSER_EXPECT_CR: res = read_block(port, &peek, 1); if (res < 0) { return res; } if (peek == '\r') { pstate = ROT2PROG_PARSER_EXPECT_LF; } break; case ROT2PROG_PARSER_EXPECT_LF: res = read_block(port, &peek, 1); if (res < 0) { return res; } if (peek == '\n') { pstate = ROT2PROG_PARSER_EXPECT_FRAME_START; } else { // we have stumbled across a \r that is not immediately // followed by \n. We could assume this is a weirdly formed // log message, but I think it makes more sense to be // defensive here and assume it is invalid for this to // happen. return -RIG_EPROTO; } break; case ROT2PROG_PARSER_EXPECT_FRAME_END: // we already read the frame start byte res = read_block(port, rxbuffer + 1, count - 1); if (res < 0) { return res; } if (rxbuffer[count - 1] != ROT2PROG_FRAME_END_BYTE) { return -RIG_EPROTO; } // account for the already-read start byte here return res + 1; default: return -RIG_EINTERNAL; } } } static int spid_write(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { int ret = rig_flush(p); if (ret < 0) { return ret; } return write_block(p, txbuffer, count); } static int spid_rot_init(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (!rot || !rot->caps) { return -RIG_EINVAL; } if (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_ROT1PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { struct spid_rot2prog_priv_data *priv; priv = (struct spid_rot2prog_priv_data *)calloc(1, sizeof(struct spid_rot2prog_priv_data)); if (!priv) { return -RIG_ENOMEM; } ROTSTATE(rot)->priv = (void *)priv; priv->az_resolution = 0; priv->el_resolution = 0; priv->dir = 0; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown SPID model=%s\n", __func__, rot->caps->model_name); } return RIG_OK; } static int spid_rot_cleanup(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (ROTSTATE(rot)->priv && (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG)) { free(ROTSTATE(rot)->priv); } ROTSTATE(rot)->priv = NULL; return RIG_OK; } static int spid_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { const struct spid_rot2prog_priv_data *priv = (struct spid_rot2prog_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_TRACE, "%s called %d\n", __func__, (int)token); if (rot->caps->rot_model != ROT_MODEL_SPID_ROT2PROG && rot->caps->rot_model != ROT_MODEL_SPID_MD01_ROT2PROG) { return -RIG_EINVAL; } switch (token) { case TOK_AZRES: SNPRINTF(val, val_len, "%d", priv->az_resolution); break; case TOK_ELRES: SNPRINTF(val, val_len, "%d", priv->el_resolution); break; default: return -RIG_EINVAL; } return RIG_OK; } static int spid_get_conf(ROT *rot, hamlib_token_t token, char *val) { return spid_get_conf2(rot, token, val, 128); } static int spid_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct spid_rot2prog_priv_data *priv = (struct spid_rot2prog_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called %d=%s\n", __func__, (int)token, val); if (rot->caps->rot_model != ROT_MODEL_SPID_ROT2PROG && rot->caps->rot_model != ROT_MODEL_SPID_MD01_ROT2PROG) { return -RIG_EINVAL; } switch (token) { case TOK_AZRES: priv->az_resolution = atoi(val); break; case TOK_ELRES: priv->el_resolution = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } static int spid_rot1prog_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { int retval; char cmdstr[13]; unsigned int u_az; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); u_az = 360 + az; cmdstr[0] = 0x57; /* S */ cmdstr[1] = 0x30 + u_az / 100; /* H1 */ cmdstr[2] = 0x30 + (u_az % 100) / 10; /* H2 */ cmdstr[3] = 0x30 + (u_az % 10); /* H3 */ cmdstr[4] = 0x30; /* H4 */ cmdstr[5] = 0x00; /* PH */ cmdstr[6] = 0x00; /* V1 */ cmdstr[7] = 0x00; /* V2 */ cmdstr[8] = 0x00; /* V3 */ cmdstr[9] = 0x00; /* V4 */ cmdstr[10] = 0x00; /* PV */ cmdstr[11] = 0x2F; /* K */ cmdstr[12] = 0x20; /* END */ retval = spid_write(ROTPORT(rot), (unsigned char *) cmdstr, 13); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int spid_rot2prog_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct rot_state *rs = ROTSTATE(rot); hamlib_port_t *rotp = ROTPORT(rot); const struct spid_rot2prog_priv_data *priv = (struct spid_rot2prog_priv_data *) rs->priv; int retval; int retry_read = 0; char cmdstr[13]; unsigned int u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); if (!priv->az_resolution || !priv->el_resolution) { do { retval = spid_write(rotp, (unsigned char *) "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\x20", 13); if (retval != RIG_OK) { return retval; } memset(cmdstr, 0, 12); retval = read_r2p_frame(rotp, (unsigned char *) cmdstr, 12); } while (retval < 0 && retry_read++ < rotp->retry); if (retval < 0) { return retval; } } else { cmdstr[5] = priv->az_resolution; /* PH */ cmdstr[10] = priv->el_resolution; /* PV */ } u_az = cmdstr[5] * (360 + az); u_el = cmdstr[10] * (360 + el); cmdstr[0] = 0x57; /* S */ cmdstr[1] = 0x30 + u_az / 1000; /* H1 */ cmdstr[2] = 0x30 + (u_az % 1000) / 100; /* H2 */ cmdstr[3] = 0x30 + (u_az % 100) / 10; /* H3 */ cmdstr[4] = 0x30 + (u_az % 10); /* H4 */ cmdstr[6] = 0x30 + u_el / 1000; /* V1 */ cmdstr[7] = 0x30 + (u_el % 1000) / 100; /* V2 */ cmdstr[8] = 0x30 + (u_el % 100) / 10; /* V3 */ cmdstr[9] = 0x30 + (u_el % 10); /* V4 */ cmdstr[11] = 0x2F; /* K */ cmdstr[12] = 0x20; /* END */ retval = spid_write(rotp, (unsigned char *) cmdstr, 13); if (retval != RIG_OK) { return retval; } /* Unlike the original Rot2Prog, MD-01 and MD-02 return the position after receiving the set position command. */ if (rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { retry_read = 0; do { retval = read_r2p_frame(rotp, (unsigned char *) cmdstr, 12); } while ((retval < 0) && (retry_read++ < rotp->retry)); } return RIG_OK; } static int spid_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; char posbuf[12]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); do { retval = spid_write(rotp, (unsigned char *) "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\x20", 13); if (retval != RIG_OK) { return retval; } memset(posbuf, 0, 12); if (rot->caps->rot_model == ROT_MODEL_SPID_ROT1PROG) { retval = read_r2p_frame(rotp, (unsigned char *) posbuf, 5); } else if (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { retval = read_r2p_frame(rotp, (unsigned char *) posbuf, 12); } else { retval = -RIG_EINVAL; } } while (retval < 0 && retry_read++ < rotp->retry); if (retval < 0) { return retval; } *az = posbuf[1] * 100; *az += posbuf[2] * 10; *az += posbuf[3]; if (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { *az += posbuf[4] / 10.0; } *az -= 360; *el = 0.0; if (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { *el = posbuf[6] * 100; *el += posbuf[7] * 10; *el += posbuf[8]; *el += posbuf[9] / 10.0; *el -= 360; } rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int spid_rot_stop(ROT *rot) { struct spid_rot2prog_priv_data *priv = (struct spid_rot2prog_priv_data *) ROTSTATE(rot)->priv; hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; char posbuf[12]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); do { retval = spid_write(rotp, (unsigned char *) "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x20", 13); if (retval != RIG_OK) { return retval; } memset(posbuf, 0, 12); if (rot->caps->rot_model == ROT_MODEL_SPID_ROT1PROG) { retval = read_r2p_frame(rotp, (unsigned char *) posbuf, 5); } else if (rot->caps->rot_model == ROT_MODEL_SPID_ROT2PROG || rot->caps->rot_model == ROT_MODEL_SPID_MD01_ROT2PROG) { retval = read_r2p_frame(rotp, (unsigned char *) posbuf, 12); } } while (retval < 0 && retry_read++ < rotp->retry); if (retval < 0) { return retval; } if (priv) { priv->dir = 0; } return RIG_OK; } static int spid_md01_rot2prog_rot_move(ROT *rot, int direction, int speed) { struct spid_rot2prog_priv_data *priv = (struct spid_rot2prog_priv_data *) ROTSTATE(rot)->priv; char dir = 0x00; int retval; char cmdstr[13]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); dir = priv->dir; switch (direction) { case ROT_MOVE_UP: if (dir != 0x01 && dir != 0x02) { dir = 0; } dir |= 0x04; break; case ROT_MOVE_DOWN: if (dir != 0x01 && dir != 0x02) { dir = 0; } dir = 0x08; break; case ROT_MOVE_LEFT: if (dir != 0x04 && dir != 0x08) { dir = 0; } dir = 0x01; break; case ROT_MOVE_RIGHT: if (dir != 0x04 && dir != 0x08) { dir = 0; } dir = 0x02; break; case ROT_MOVE_UP_RIGHT: dir = 0x06; break; case ROT_MOVE_DOWN_RIGHT: dir = 0x0a; break; case ROT_MOVE_UP_LEFT: dir = 0x05; break; case ROT_MOVE_DOWN_LEFT: dir = 0x09; break; } priv->dir = dir; cmdstr[0] = 0x57; /* S */ cmdstr[1] = dir; /* H1 */ cmdstr[2] = 0x00; /* H2 */ cmdstr[3] = 0x00; /* H3 */ cmdstr[4] = 0x00; /* H4 */ cmdstr[6] = 0x00; /* V1 */ cmdstr[7] = 0x00; /* V2 */ cmdstr[8] = 0x00; /* V3 */ cmdstr[9] = 0x00; /* V4 */ cmdstr[11] = 0x14; /* K */ cmdstr[12] = 0x20; /* END */ /* The rotator must be stopped before changing directions. Since we don't know which direction we're already moving in (if moving at all), always send the stop command first. */ spid_rot_stop(rot); retval = spid_write(ROTPORT(rot), (unsigned char *) cmdstr, 13); return retval; } const struct confparams spid_cfg_params[] = { { TOK_AZRES, "az_resolution", "Azimuth resolution", "Number of pulses per degree, 0 = auto sense", "0", RIG_CONF_NUMERIC, { .n = { 0, 0xff, 1 } } }, { TOK_ELRES, "el_resolution", "Elevation resolution", "Number of pulses per degree, 0 = auto sense", "0", RIG_CONF_NUMERIC, { .n = { 0, 0xff, 1 } } }, { RIG_CONF_END, NULL, } }; const struct rot_caps spid_rot1prog_rot_caps = { ROT_MODEL(ROT_MODEL_SPID_ROT1PROG), .model_name = "Rot1Prog", .mfg_name = "SPID", .version = "20240815.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 540.0, .min_el = 0.0, .max_el = 0.0, .cfgparams = spid_cfg_params, .get_conf = spid_get_conf, .get_conf2 = spid_get_conf2, .set_conf = spid_set_conf, .rot_init = spid_rot_init, .rot_cleanup = spid_rot_cleanup, .get_position = spid_rot_get_position, .set_position = spid_rot1prog_rot_set_position, .stop = spid_rot_stop, }; const struct rot_caps spid_rot2prog_rot_caps = { ROT_MODEL(ROT_MODEL_SPID_ROT2PROG), .model_name = "Rot2Prog", .mfg_name = "SPID", .version = "20240815.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 600, .serial_rate_max = 600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 540.0, .min_el = -20.0, .max_el = 210.0, .cfgparams = spid_cfg_params, .get_conf = spid_get_conf, .set_conf = spid_set_conf, .get_conf2 = spid_get_conf2, .rot_init = spid_rot_init, .rot_cleanup = spid_rot_cleanup, .get_position = spid_rot_get_position, .set_position = spid_rot2prog_rot_set_position, .stop = spid_rot_stop, }; const struct rot_caps spid_md01_rot2prog_rot_caps = { ROT_MODEL(ROT_MODEL_SPID_MD01_ROT2PROG), .model_name = "MD-01/02 (ROT2 mode)", .mfg_name = "SPID", .version = "20240815.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 600, .serial_rate_max = 460800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 540.0, .min_el = -20.0, .max_el = 210.0, .cfgparams = spid_cfg_params, .get_conf = spid_get_conf, .get_conf2 = spid_get_conf2, .set_conf = spid_set_conf, .rot_init = spid_rot_init, .rot_cleanup = spid_rot_cleanup, .get_position = spid_rot_get_position, .set_position = spid_rot2prog_rot_set_position, .move = spid_md01_rot2prog_rot_move, .stop = spid_rot_stop, }; DECLARE_INITROT_BACKEND(spid) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&spid_rot1prog_rot_caps); rot_register(&spid_rot2prog_rot_caps); rot_register(&spid_md01_rot2prog_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/spid/Android.mk0000664000175000017500000000036615056640443013206 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := spid.c LOCAL_MODULE := spid LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/spid/Makefile.in0000664000175000017500000005226415056640453013347 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/spid ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_spid_la_LIBADD = am_libhamlib_spid_la_OBJECTS = spid.lo libhamlib_spid_la_OBJECTS = $(am_libhamlib_spid_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/spid.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_spid_la_SOURCES) DIST_SOURCES = $(libhamlib_spid_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-spid.la libhamlib_spid_la_SOURCES = spid.c spid.h EXTRA_DIST = spid.txt Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/spid/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/spid/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-spid.la: $(libhamlib_spid_la_OBJECTS) $(libhamlib_spid_la_DEPENDENCIES) $(EXTRA_libhamlib_spid_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_spid_la_OBJECTS) $(libhamlib_spid_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spid.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/spid.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/spid.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/spid/spid.txt0000664000175000017500000002050115056640443012766 SPID Rot1Prog & Rot2Prog Protocol ================================= This is an attempt at documenting the protocol of the Rot1Prog and Rot2Prog rotator controller from SPID Elektronik (spid@alpha.pl). Rot1Prog controls only azimuth, while Rot2Prog controls both azimuth and elevation. GENERAL INFO ------------ The SPID protocol supports 3 commands: stop, status and set. The stop command stops the rotator in its current position. The status command returns the current position of the rotator, and the set command tells the rotator to rotate to a given position. The rotator controller communicates with the PC using a serial port. Communication parameters are 1200 bps (Rot1Prog) or 600 bps (Rot2Prog), 8 bits, no parity and 1 stop bit. All commands are issued as 13 byte packets, and responses are received as 5 byte packets (Rot1Prog) or 12 byte packets (Rot2Prog). COMMAND PACKETS --------------- Command packets are 13 byte long. Byte: 0 1 2 3 4 5 6 7 8 9 10 11 12 ----------------------------------------------------------------- Field: | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END | ----------------------------------------------------------------- Value: 57 3x 3x 3x 3x 0x 3x 3x 3x 3x 0x xF 20 (hex) S: Start byte. This is always 0x57 ('W') H1-H4: Azimuth as ASCII characters 0-9 PH: Azimuth resolution in pulses per degree (ignored!) V1-V4: Elevation as ASCII characters 0-9 PV: Elevation resolution in pulses per degree (ignored!) K: Command (0x0F=stop, 0x1F=status, 0x2F=set) END: End byte. This is always 0x20 (space) Positions are encoded as number of pulses in ASCII numbers '0000'-'9999' (see set command for formula). Rot1Prog does not control elevation and does not support different resolutions, so V1-V4, PH and PV are set to 0x00. Also, since only whole degrees are supported, H4 is always set to 0x30 (0 tenths of degrees). RESPONSE PACKETS ---------------- Rot1Prog response packets are 5 bytes long. Byte: 0 1 2 3 4 -------------------------- Field: | S | H1 | H2 | H3 | END | -------------------------- Value: 57 0x 0x 0x 20 (hex) S: Start byte. This is always 0x57 ('W') H1-H3: Azimuth as byte values END: End byte. This is always 0x20 (space) Positions are decoded using the following formula: az = H1 * 100 + H2 * 10 + H3 - 360 Rot2Prog response packets are 12 bytes long. Byte: 0 1 2 3 4 5 6 7 8 9 10 11 ------------------------------------------------------------- Field: | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END | ------------------------------------------------------------- Value: 57 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 20 (hex) S: Start byte. This is always 0x57 ('W') H1-H4: Azimuth as byte values PH: Azimuth resolution in pulses per degree (controller setting) V1-V4: Elevation as byte values PV: Elevation resolution in pulses per degree (controller setting) END: End byte. This is always 0x20 (space) Positions are decoded using the following formulas: az = H1 * 100 + H2 * 10 + H3 + H4 / 10 - 360 el = V1 * 100 + V2 * 10 + V3 + V4 / 10 - 360 The PH and PV values in the response packet reflect the settings of the rotator controller. The Rot2Prog supports the following resolutions (always the same for azimuth and elevation): 1 deg/pulse: PH=0x01, PV=0x01 0.5 deg/pulse: PH=0x02, PV=0x02 0.25 deg/pulse: PH=0x04, PV=0x04 STOP COMMAND ------------ The stop command stops the rotator immediately in the current position and returns the current position. (The position returned does not seem to be entirely correct, often off by a degree or two.) The H1-H4, PH, V1-V4 and PV fields are ignored, so only the S, K and END fields are used. E.g.: Command: ----------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END | ----------------------------------------------------------------- | 57| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 0F| 20 | (hex) ----------------------------------------------------------------- Rotator stops Rot1Prog response: -------------------------- | S | H1 | H2 | H3 | END | -------------------------- | 57| 03 | 07 | 02 | 20 | (hex) -------------------------- az=372-360=12 Rot2Prog response: ------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END | ------------------------------------------------------------- | 57| 03 | 07 | 02 | 05 | 02 | 03 | 09 | 04 | 00 | 02 | 20 | (hex) ------------------------------------------------------------- az=372.5-360=12.5, el=394.0-360=34.0 PH=PV=0x02 (pulse for each 0.5 deg) STATUS COMMAND -------------- The status command returns the current position of the antenna. The H1-H4, PH, V1-V4 and PV fields are ignored, so only the S, K and END fields are used. E.g.: Command: ----------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END | ----------------------------------------------------------------- | 57| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 1F| 20 | (hex) ----------------------------------------------------------------- Rot1Prog response: -------------------------- | S | H1 | H2 | H3 | END | -------------------------- | 57| 03 | 07 | 02 | 20 | (hex) -------------------------- az=372-360=12 Rot2Prog response: ------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END | ------------------------------------------------------------- | 57| 03 | 07 | 02 | 05 | 02 | 03 | 09 | 04 | 00 | 02 | 20 | (hex) ------------------------------------------------------------- az=372.5-360=12.5, el=394.0-360=34.0 PH=PV=0x02 (pulse for each 0.5 deg) Status commands can be issued while the rotator is moving and will always return the current position. SET COMMAND ----------- The set command tells the rotator to turn to a specific position. The controller does not send a response to this command. Azimuth and elevation is calculated as number of pulses, with a +360 degree offset (so that negative position can be encoded with positive numbers). Rot1Prog supports only whole degree positions: H = 360 + az Rot2Prog supports different resolutions: H = PH * (360 + az) V = PV * (360 + el) H1-H4 and V1-V4 are these numbers encoded as ASCII (0x30-0x39, i.e. '0'-'9'). E.g., when pointing a Rot1Prog to azimuth 123: H = 360 + 123 = 483 ----------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END | ----------------------------------------------------------------- | 57| 34 | 38 | 33 | 30 | 00 | 00 | 00 | 00 | 00 | 00 | 2F| 20 | (hex) ----------------------------------------------------------------- Note that H4 is not used and always set to 0x30. E.g., when pointing a Rot2Prog to azimuth 123.5, elevation 77.0 when the rotator sends one pulse per 0.5 degree (PH=PV=2): H = 2 * (360 + 123.5) = 967 V = 2 * (360 + 77.0) = 874 ----------------------------------------------------------------- | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END | ----------------------------------------------------------------- | 57| 30 | 39 | 36 | 37 | 02 | 30 | 38 | 37 | 34 | 02 | 2F| 20 | (hex) ----------------------------------------------------------------- The PH and PV values sent are ignored. The values used by the rotator control unit are set by choosing resolution in the setup menu. Luckily, these values can be read using the status command (Rot2Prog only). Note that H1-H4 is interpreted differently by Rot1Prog and Rot2Prog in the set command: Rot1Prog Rot2Prog H1 *100 *1000 H2 *10 *100 H3 *1 *10 H4 *0 *1 Rot1Prog does not use H4 and uses H1 for houndres, while Rot2Prog uses H4 for ones and H1 for thousands. SEE ALSO -------- http://alfaradio.ca/downloads/program_info/ AUTHOR ------ Norvald H. Ryeng, LA6YKA norvald@ryeng.name 2009-05-21, updated 2011-01-29 hamlib-4.6.5/rotators/spid/Makefile.am0000664000175000017500000000016415056640443013325 noinst_LTLIBRARIES = libhamlib-spid.la libhamlib_spid_la_SOURCES = spid.c spid.h EXTRA_DIST = spid.txt Android.mk hamlib-4.6.5/rotators/meade/0000775000175000017500000000000015056640502011460 5hamlib-4.6.5/rotators/meade/README.md0000664000175000017500000000454615056640443012674 # Meade Telescope Rotator Module This module interfaces Meade telescope rotator via the LX200 serial protocol. These rotators can easily be modified to carry antennas instead of telescopes. ## Usage 1. Set the telescope manually to show to north with 0 degree elevation 2. Connect the Autostar and the serial cable with the telescope and control PC 3. Turn on telescope rotator 4. Press `Speed` on the Autostar to accept "Don't look into the sun" warning 5. Press `Mode` a couple of times until the Autostar display shows `Object` 6. Start `rotctl` or `rotctld` with the arguments `-m 1801 -s ` Have Fun. ### Hints 1. The rotator has no lock on 360 degree azimuth. For example, if you go from 359 degrees to 002 degrees, it will go the short way. That means it is possible to make several rotations in the same directions. Please have a kind look on your cables and don't use the rotator unattended! 2. If a new position gets sent to the rotor while it is in movement, it moves immediately to the new position, but stores the old one and moves again to the old one after the new position is reached. To avoid this, a `Stop all movement` command gets executed if a position update reaches the rotator while in movement. That can cause a choppy movement when going to a new position which is far away. ## LX200 Protocol * [2003 Protocol Version](https://www.meade.com/support/LX200CommandSet.pdf) * [2010 Protocol Version](https://www.meade.com/support/TelescopeProtocol_2010-10.pdf) ## Current Status The current status is **ALPHA**. It is tested with Meade DS-2000 with Autostar 494 (2003 Firmware) and Meade 506 i2c to RS232 interface cable, tested under Linux with `rotctl` and `gpredict`. ### What works good: * `set_position` works for azimuth and elevation (0-360,0-90 degree), high frequent update (<2s) can cause sometimes unexpected behavior. * `get_position` works mostly fine, sometime the elevation gets not read properly * `init`, `cleanup`, `get_info` work as expected * `open` sends all setup commands needed for now * `close` stops all movement of the rotor * `meade_stop` stops fine * `park`, `reset` move the rotor to home position (north, elevation 0) ### What works with some problems: * `move` works fine for elevation, but for azimuth it will sometimes move in the wrong direction caused by the short way movement. hamlib-4.6.5/rotators/meade/Android.mk0000664000175000017500000000037015056640443013315 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := meade.c LOCAL_MODULE := meade LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/meade/Makefile.in0000664000175000017500000005241715056640453013463 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/meade ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_meade_la_LIBADD = am__objects_1 = meade.lo am_libhamlib_meade_la_OBJECTS = $(am__objects_1) libhamlib_meade_la_OBJECTS = $(am_libhamlib_meade_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/meade.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_meade_la_SOURCES) DIST_SOURCES = $(libhamlib_meade_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MEADESRC = meade.c meade.h noinst_LTLIBRARIES = libhamlib-meade.la libhamlib_meade_la_SOURCES = $(MEADESRC) EXTRA_DIST = README.md Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/meade/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/meade/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-meade.la: $(libhamlib_meade_la_OBJECTS) $(libhamlib_meade_la_DEPENDENCIES) $(EXTRA_libhamlib_meade_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_meade_la_OBJECTS) $(libhamlib_meade_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meade.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/meade.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/meade.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/meade/meade.h0000664000175000017500000000205015056640443012625 /* * Hamlib Meade telescope rotor backend - main header * Copyright (c) 2018 by Andreas Mueller (DC1MIL) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _MEADE_H #define _MEADE_H 1 #include "rotator.h" #define BUFSIZE 128 #define CR "\r" #define LF "\x0a" extern const struct rot_caps meade_caps; #endif /* _MEADE_H */ hamlib-4.6.5/rotators/meade/meade.c0000664000175000017500000003534315056640443012633 /* * Hamlib Meade telescope rotor backend - main file * Copyright (c) 2018 by Andreas Mueller (DC1MIL) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include #include #include "serial.h" #include "register.h" #include "meade.h" struct meade_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; char product_name[32]; }; /** * Command list: * See https://www.meade.com/support/LX200CommandSet.pdf * and https://www.meade.com/support/TelescopeProtocol_2010-10.pdf for newer * Firmware Versions * * Not the full set of available commands is used, the list here shows * only the commands of the telescope used by hamlib * * All used Commands are supported by Meade Telescopes with LX-200 protocol * (e.g. DS-2000 with Autostar) and should also work with the LX16 and * LX200GPS. * Tested only with DS-2000 and AutoStar 494 together with Meade 506 i2c to * Serial cable. But should also work with other AutoStars and the regular * Serial Cable. * * | Command | Attribute | Return value | Description | * --------------------------------------------------------------------- * | :Me# | - | - | Moves telescope east | * | :Mn# | - | - | Moves telescope north | * | :Ms# | - | - | Moves telescope south | * | :Mw# | - | - | Moves telescope west | * | :AL# | - | - | Set to Land mode | * | :Sz DDD*MM# | D,M | 1' == OK | Set Target azimuth | * | :SasDD*MM# | s,D,M | 1' == OK | Set Target elevation | * | :Mw# | - | - | Moves telescope west | * | :Q# | - | - | Halt all slewing | * | :SoDD# | D | '1' == OK | Set minimal elevation | * | :ShDD# | D | '1' == OK | Set maximal elevation | * | :MA# | - | '0' == OK | GoTo Target | * | :D# | - | 0x7F == YES | Check if active movement | * */ /** * meade_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. */ static int meade_transaction(ROT *rot, const char *cmdstr, char *data, size_t *data_len, size_t expected_return_length) { hamlib_port_t *rotp = ROTPORT(rot); int return_value; int retry_read = 0; while (1) { transaction: rig_flush(rotp); if (cmdstr) { return_value = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (return_value != RIG_OK) { *data_len = 0; return return_value; } } /* Not all commands will send a return value, so use data = NULL if no return value is expected, Strings end with '#' */ if (data != NULL) { return_value = read_string(rotp, (unsigned char *) data, expected_return_length + 1, "\r\n", strlen("\r\n"), 0, 1); if (return_value > 0) { *data_len = return_value; return RIG_OK; } else { if (retry_read++ >= rotp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error %s\n", __func__, rigerror(return_value)); *data_len = 0; return -RIG_ETIMEOUT; } else { goto transaction; } } } else { return RIG_OK; } } } /* * Initialization */ static int meade_init(ROT *rot) { struct meade_priv_data *priv; ROTSTATE(rot)->priv = (struct meade_priv_data *) calloc(1, sizeof(struct meade_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called version %s\n", __func__, rot->caps->version); ROTPORT(rot)->type.rig = RIG_PORT_SERIAL; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; return RIG_OK; } /* * Cleanup */ static int meade_cleanup(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ROTSTATE(rot)->priv) { free(ROTSTATE(rot)->priv); } ROTSTATE(rot)->priv = NULL; return RIG_OK; } /* * Opens the Port and sets all needed parameters for operation */ static int meade_open(ROT *rot) { char return_str[BUFSIZE]; size_t return_str_size = 0; struct meade_priv_data *priv = (struct meade_priv_data *)ROTSTATE(rot)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Get our product name for any custom things we need to do // The LX200 does not have :GVP# so no response will default to LX200 retval = meade_transaction(rot, ":GVP#", return_str, &return_str_size, sizeof(return_str)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: meade_transaction %s\n", __func__, rigerror(retval)); } if (return_str_size > 0) { strtok(return_str, "#"); } strcpy(priv->product_name, return_str_size > 0 ? return_str : "LX200 Assumed"); rig_debug(RIG_DEBUG_VERBOSE, "%s product_name=%s\n", __func__, priv->product_name); /* Set Telescope to Land alignment mode to deactivate sloping */ /* Allow 0-90 Degree Elevation */ if (strcmp(priv->product_name, "Autostar")) // if we're not an audiostar { retval = meade_transaction(rot, ":AL#:So00#:Sh90#", NULL, 0, 0); } else { // Audiostar elevation is in arcminutes retval = meade_transaction(rot, ":So00#:Sh5400#", NULL, 0, 0); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: meade_transaction %s\n", __func__, rigerror(retval)); } return RIG_OK; } /* * Closes the port and stops all movement */ static int meade_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Stop all Movement */ return meade_transaction(rot, ":Q#", NULL, 0, 0); } /* * Sets the target position and starts movement * * az: Target azimuth * el: Target elevation */ static int meade_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct meade_priv_data *priv = (struct meade_priv_data *)ROTSTATE(rot)->priv; char cmd_str[BUFSIZE]; char return_str[BUFSIZE]; size_t return_str_size; float az_degrees, az_minutes, el_degrees, el_minutes; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); az_degrees = floor(az); az_minutes = (az - az_degrees) * 60; el_degrees = floor(el); el_minutes = (el - el_degrees) * 60; // LX200 won't do 180 degrees exactly...so we fudge everybody if (strstr(priv->product_name, "LX200") && az_degrees == 180 && az_minutes == 0) { az_degrees = 179; az_minutes = 59; } /* Check if there is an active movement and stop it */ /* Undesirable behavior if stopped can happen */ /* So we just ignore commands while moving */ /* Should we return RIG_OK or an error though? */ meade_transaction(rot, ":D#", return_str, &return_str_size, sizeof(return_str)); // LX200 return 0xff bytes and Autostart returns 0x7f if (return_str_size > 0 && ((return_str[0] & 0x7f) == 0x7f)) { rig_debug(RIG_DEBUG_WARN, "%s: rotor is moving...ignoring move\n", __func__); return RIG_OK; // we don't give an error -- just ignore it } priv->target_az = az; priv->target_el = el; num_sprintf(cmd_str, ":Sz %03.0f*%02.0f#:Sa+%02.0f*%02.0f#:MA#", az_degrees, az_minutes, el_degrees, el_minutes); meade_transaction(rot, cmd_str, return_str, &return_str_size, 3); /* '1' == Azimuth accepted '1' == Elevation accepted '0' == No error */ /* MA command may return 1=Lower than or 2=Higher than min/max elevation */ if (return_str_size > 0 && strstr(return_str, "110") != NULL) { return RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: expected 110, got %s\n", __func__, return_str); return RIG_EINVAL; } } /* * Get position of rotor, simulating slow rotation */ static int meade_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char return_str[BUFSIZE]; char eom; size_t return_str_size; int az_degrees, az_minutes, az_seconds, el_degrees, el_minutes, el_seconds; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); meade_transaction(rot, ":GZ#:GA#", return_str, &return_str_size, BUFSIZE); rig_debug(RIG_DEBUG_VERBOSE, "%s: returned '%s'\n", __func__, return_str); // GZ returns DDD*MM# or DDD*MM'SS# // GA returns sDD*MM# or sDD*MM'SS# n = sscanf(return_str, "%d%*c%d:%d#%d%*c%d:%d%c", &az_degrees, &az_minutes, &az_seconds, &el_degrees, &el_minutes, &el_seconds, &eom); if (n != 7 || eom != '#') { rig_debug(RIG_DEBUG_VERBOSE, "%s: not 6 args in '%s'\nTrying low precision\n", __func__, return_str); az_seconds = el_seconds = 0; n = sscanf(return_str, "%d%*c%d#%d%*c%d%c", &az_degrees, &az_minutes, &el_degrees, &el_minutes, &eom); if (n != 5 || eom != '#') { rig_debug(RIG_DEBUG_ERR, "%s: not 4 args in '%s', parsing failed\n", __func__, return_str); return -RIG_EPROTO; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: az=%03d:%02d:%02d, el=%03d:%02d:%02d\n", __func__, az_degrees, az_minutes, az_seconds, el_degrees, el_minutes, el_seconds); *az = dmmm2dec(az_degrees, az_minutes, az_seconds, az_seconds); *el = dmmm2dec(el_degrees, el_minutes, el_seconds, el_seconds); return RIG_OK; } /* * Stops all movement */ static int meade_stop(ROT *rot) { struct meade_priv_data *priv = (struct meade_priv_data *)ROTSTATE(rot)->priv; azimuth_t az; elevation_t el; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); meade_transaction(rot, ":Q#", NULL, 0, 0); meade_get_position(rot, &az, &el); priv->target_az = priv->az = az; priv->target_el = priv->el = el; return RIG_OK; } /* * Moves to Home Position */ static int meade_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume home is 0,0 */ meade_set_position(rot, 0, 0); return RIG_OK; } /* * Reset: Nothing to do except parking */ static int meade_reset(ROT *rot, rot_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); meade_park(rot); return RIG_OK; } /* * Movement to direction */ static int meade_move(ROT *rot, int direction, int speed) { const struct meade_priv_data *priv = (struct meade_priv_data *)ROTSTATE( rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_UP: return meade_set_position(rot, priv->target_az, 90); case ROT_MOVE_DOWN: return meade_set_position(rot, priv->target_az, 0); case ROT_MOVE_CCW: return meade_set_position(rot, -180, priv->target_el); case ROT_MOVE_CW: return meade_set_position(rot, 180, priv->target_el); default: return -RIG_EINVAL; } return RIG_OK; } static const char *meade_get_info(ROT *rot) { static char buf[256]; // this is not thread-safe but not important either const struct meade_priv_data *priv = (struct meade_priv_data *)ROTSTATE( rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "Meade telescope rotator with LX200 protocol.\nModel: %s", priv->product_name); return buf; } /* * Meade telescope rotator capabilities. */ const struct rot_caps meade_caps = { ROT_MODEL(ROT_MODEL_MEADE), .model_name = "LX200/Autostar", .mfg_name = "Meade", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 200, .timeout = 400, .retry = 2, .min_az = 0., .max_az = 360., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .rot_init = meade_init, .rot_cleanup = meade_cleanup, .rot_open = meade_open, .rot_close = meade_close, .set_position = meade_set_position, .get_position = meade_get_position, .park = meade_park, .stop = meade_stop, .reset = meade_reset, .move = meade_move, .get_info = meade_get_info, }; DECLARE_INITROT_BACKEND(meade) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&meade_caps); return RIG_OK; } hamlib-4.6.5/rotators/meade/Makefile.am0000664000175000017500000000021715056640443013440 MEADESRC = meade.c meade.h noinst_LTLIBRARIES = libhamlib-meade.la libhamlib_meade_la_SOURCES = $(MEADESRC) EXTRA_DIST = README.md Android.mkhamlib-4.6.5/rotators/heathkit/0000775000175000017500000000000015056640502012206 5hamlib-4.6.5/rotators/heathkit/hd1780.h0000664000175000017500000000302515056640443013216 /* * Hamlib backend library for the Heathkit HD 1780 Intellirotor command set. * * hd1780.h - (C) Nate Bargmann 2003 (n0nb at arrl.net) * (C) Rob Frohne 2008 (kl7na at arrl.net) * * This shared library provides an API for communicating * via serial interface to a Heathkit Intellirotor HD 1780 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_HD1780_H #define _ROT_HD1780_H 1 #include "rotator.h" #define AZ_READ_LEN 6 extern const struct rot_caps hd1780_rot_caps; /* * API local implementation * */ static int hd1780_rot_init(ROT *rot); static int hd1780_rot_cleanup(ROT *rot); static int hd1780_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation); static int hd1780_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation); #endif /* _ROT_HD1780_H */ hamlib-4.6.5/rotators/heathkit/Android.mk0000664000175000017500000000037415056640443014047 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := hd1780.c LOCAL_MODULE := heathkit LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/heathkit/Makefile.in0000664000175000017500000005237515056640453014214 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/heathkit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_heathkit_la_LIBADD = am_libhamlib_heathkit_la_OBJECTS = hd1780.lo libhamlib_heathkit_la_OBJECTS = $(am_libhamlib_heathkit_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/hd1780.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_heathkit_la_SOURCES) DIST_SOURCES = $(libhamlib_heathkit_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-heathkit.la libhamlib_heathkit_la_SOURCES = hd1780.c hd1780.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/heathkit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/heathkit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-heathkit.la: $(libhamlib_heathkit_la_OBJECTS) $(libhamlib_heathkit_la_DEPENDENCIES) $(EXTRA_libhamlib_heathkit_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_heathkit_la_OBJECTS) $(libhamlib_heathkit_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hd1780.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/hd1780.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/hd1780.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/heathkit/hd1780.c0000664000175000017500000001645315056640443013222 /* * Hamlib backend library for the HD 1780 Intellirotor command set. * * hd1780.c - (C) Nate Bargmann 2003 (n0nb at arrl.net) * (C) Rob Frohne 2008 (kl7na at arrl.net) * * This shared library provides an API for communicating * via serial interface to a Heathkit HD 1780 Intellirotor. * * Heathkit is a trademark of Heath Company * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* Standard library definitions */ #include /* String function definitions */ #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "hd1780.h" /* * Private data structure */ struct hd1780_rot_priv_data { azimuth_t az; }; /* * Private helper function prototypes */ static int hd1780_send_priv_cmd(ROT *rot, const char *cmd); /* * HD 1780 Intellirotor rotor capabilities */ const struct rot_caps hd1780_rot_caps = { ROT_MODEL(ROT_MODEL_HD1780), .model_name = "HD 1780 Intellirotor", .mfg_name = "Heathkit", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 10, .post_write_delay = 500, .timeout = 60000, .retry = 0, .min_az = -180, .max_az = 180, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .rot_init = hd1780_rot_init, .rot_cleanup = hd1780_rot_cleanup, .set_position = hd1780_rot_set_position, .get_position = hd1780_rot_get_position, }; /* ************************************ * * API functions * * ************************************ */ /* * Initialize data structures */ static int hd1780_rot_init(ROT *rot) { struct hd1780_rot_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } ROTSTATE(rot)->priv = (struct hd1780_rot_priv_data *) calloc(1, sizeof(struct hd1780_rot_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; ROTPORT(rot)->type.rig = RIG_PORT_SERIAL; priv->az = 0; return RIG_OK; } /* * Clean up allocated memory structures */ static int hd1780_rot_cleanup(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (ROTSTATE(rot)->priv) { free(ROTSTATE(rot)->priv); } ROTSTATE(rot)->priv = NULL; return RIG_OK; } /* * Set position * HD 1780 protocol supports azimuth only--elevation is ignored * Range is converted to an integer string, 0 to 360 degrees */ static int hd1780_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation) { char cmdstr[8]; const char execstr[5] = "\r", ok[3]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (azimuth < hd1780_rot_caps.min_az || azimuth > hd1780_rot_caps.max_az) { return -RIG_EINVAL; } if (azimuth < 0) { azimuth = azimuth + 360; } SNPRINTF(cmdstr, sizeof(cmdstr), "%03.0f", azimuth); /* Target bearing */ err = hd1780_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } err = hd1780_send_priv_cmd(rot, execstr); /* Execute command */ if (err != RIG_OK) { return err; } /* We need to look for the + to signify that everything finished. The HD 1780 * sends a when it is finished rotating. */ err = read_block(ROTPORT(rot), (unsigned char *) ok, 2); if (err != 2) { return -RIG_ETRUNC; } if ((ok[0] != '\r') || (ok[1] != '\n')) { return -RIG_ETRUNC; } return RIG_OK; } /* * Get position * Returns current azimuth position in whole degrees. * Range returned from Rotor-EZ is an integer, 0 to 359 degrees * Elevation is set to 0 */ static int hd1780_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation) { const char cmdstr[3] = "b\r"; char az[7]; /* read azimuth string */ char *p; azimuth_t tmp = 0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = hd1780_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } err = read_block(ROTPORT(rot), (unsigned char *) az, AZ_READ_LEN); if (err != AZ_READ_LEN) { return -RIG_ETRUNC; } /* * HD 1780 returns a four octet string consisting of * three octets containing the rotor's position in degrees followed by a * space and a and a . The * space is ignored when passing the string to atof(). */ az[4] = 0x00; /* NULL terminated string */ p = az; /* for hd1780 */ tmp = (azimuth_t)atof(p); rig_debug(RIG_DEBUG_TRACE, "%s: \"%s\" after conversion = %.1f\n", __func__, p, tmp); if (tmp < 0 || tmp > 359) { return -RIG_EINVAL; } *azimuth = tmp; *elevation = 0; /* assume aiming at the horizon */ rig_debug(RIG_DEBUG_TRACE, "%s: azimuth = %.1f deg; elevation = %.1f deg\n", __func__, *azimuth, *elevation); return RIG_OK; } /* * Send command string to rotor. * * To make sure that the rotor is ready to take a command, we send it a and * it will normally reply with a ? . If you don't do this, using the * w: command of rotctl it is possible to get it out of sequence. This kind of * resets its command buffer before sending the command. */ static int hd1780_send_priv_cmd(ROT *rot, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = write_block(ROTPORT(rot), (unsigned char *) cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Initialize backend */ DECLARE_INITROT_BACKEND(heathkit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&hd1780_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/heathkit/Makefile.am0000664000175000017500000000016715056640443014172 noinst_LTLIBRARIES = libhamlib-heathkit.la libhamlib_heathkit_la_SOURCES = hd1780.c hd1780.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/amsat/0000775000175000017500000000000015056640501011511 5hamlib-4.6.5/rotators/amsat/if100.c0000664000175000017500000000644715056640443012434 /* * Hamlib Rotator backend - IF-100 parallel port * Copyright (c) 2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_SYS_IOCTL_H # include #endif #include #include "parallel.h" #include "register.h" static int if100_set_position(ROT *rot, azimuth_t az, elevation_t el) { hamlib_port_t *port = ROTPORT(rot); struct rot_state *rs = ROTSTATE(rot); int retval; int az_i; int el_i; int dataout, i; double az_scale, el_scale; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); az_scale = 255. / (rs->max_az - rs->min_az); el_scale = 255. / 180; az_i = (int)round((az - rs->min_az) * az_scale); el_i = (int)round(el * el_scale); rig_debug(RIG_DEBUG_TRACE, "%s output az: %d el: %d\n", __func__, az_i, el_i); dataout = ((el_i & 0xff) << 8) + (az_i & 0xff); #define DAT0 0x01 #define CLK 0x02 #define TRACK 0x08 rig_debug(RIG_DEBUG_TRACE, "%s: shifting dataout 0x%04x to parallel port\n", __func__, dataout); retval = par_lock(port); if (retval != RIG_OK) { return retval; } for (i = 0; i < 16; i++) { if (dataout & 0x8000) { par_write_data(port, TRACK | DAT0); par_write_data(port, TRACK | DAT0 | CLK); par_write_data(port, TRACK | DAT0); } else { par_write_data(port, TRACK); par_write_data(port, TRACK | CLK); par_write_data(port, TRACK); } dataout = (dataout << 1) & 0xffff; } par_write_data(port, TRACK); par_unlock(port); return RIG_OK; } /** IF-100 implements essentially only the set position function. */ const struct rot_caps if100_rot_caps = { ROT_MODEL(ROT_MODEL_IF100), .model_name = "IF-100", .mfg_name = "AMSAT", .version = "20110531.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 180, .set_position = if100_set_position, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(amsat) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&if100_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/amsat/Android.mk0000664000175000017500000000037015056640443013347 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := if100.c LOCAL_MODULE := amsat LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/amsat/Makefile.in0000664000175000017500000005227315056640453013515 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/amsat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_amsat_la_LIBADD = am_libhamlib_amsat_la_OBJECTS = if100.lo libhamlib_amsat_la_OBJECTS = $(am_libhamlib_amsat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/if100.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_amsat_la_SOURCES) DIST_SOURCES = $(libhamlib_amsat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-amsat.la libhamlib_amsat_la_SOURCES = if100.c EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/amsat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/amsat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-amsat.la: $(libhamlib_amsat_la_OBJECTS) $(libhamlib_amsat_la_DEPENDENCIES) $(EXTRA_libhamlib_amsat_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_amsat_la_OBJECTS) $(libhamlib_amsat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if100.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/if100.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/if100.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/amsat/Makefile.am0000664000175000017500000000014715056640443013474 noinst_LTLIBRARIES = libhamlib-amsat.la libhamlib_amsat_la_SOURCES = if100.c EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/gs232a/0000775000175000017500000000000015056640501011405 5hamlib-4.6.5/rotators/gs232a/gs232b.c0000664000175000017500000003243615056640443012510 /* * Hamlib Rotator backend - GS-232B * Copyright (c) 2001-2012 by Stephane Fillod * (c) 2010 by Kobus Botha * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * #include #include "hamlib/rotator.h" #include "serial.h" #include "misc.h" #include "idx_builtin.h" #define EOM "\r" #define REPLY_EOM "\r\n" #define BUFSZ 64 #define GS232B_LEVELS ROT_LEVEL_SPEED /** * gs232b_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ static int gs232b_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len, int no_reply) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } if (!data) { write_block(rotp, (unsigned char *) EOM, strlen(EOM)); } } if (no_reply) { return RIG_OK; } // nothing expected so return /* If no data requested just return */ if (!data) { return RIG_OK; } if (!data_len) { data_len = BUFSZ; } memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, REPLY_EOM, strlen(REPLY_EOM), 0, 1); if (strncmp(data, "\r\n", 2) == 0 || strchr(data, '>')) { rig_debug(RIG_DEBUG_ERR, "%s: Invalid response for '%s': '%s' (length=%d)\n", __func__, cmdstr, data, (int) strlen(data)); dump_hex((unsigned char *)data, strlen(data)); retval = -RIG_EPROTO; // force retry } if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } #if 0 /* Check that command termination is correct */ if (strchr(REPLY_EOM, data[strlen(data) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rotp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } #endif #if 0 https://github.com/Hamlib/Hamlib/issues/272 // If asked for we will check for connection // we don't expect a reply...just a prompt return // Seems some GS232B's only echo the CR if ((strncmp(data, "?>", 2) != 0) && data[0] != 0x0d) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Expected '?>' but got '%s' from cmd '%s'\n", __func__, data, cmdstr); return -RIG_EPROTO; } #endif if (data[0] == '?') { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s': '%s'\n", __func__, cmdstr, data); retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: return retval; } static int gs232b_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval; unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: az=%.02f el=%.02f\n", __func__, az, el); if (az < 0.0) { az = az + 360.0; } u_az = (unsigned) rint(az); u_el = (unsigned) rint(el); SNPRINTF(cmdstr, sizeof(cmdstr), "W%03u %03u" EOM, u_az, u_el); #if 0 // do any GS232B models need a reply to the W command? retval = gs232b_transaction(rot, cmdstr, buf, sizeof(buf), 0); #else retval = gs232b_transaction(rot, cmdstr, NULL, 0, 0); if (retval != RIG_OK) { return retval; } #endif return RIG_OK; } static int gs232b_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; int retval, int_az = 0, int_el = 0; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = gs232b_transaction(rot, "C2" EOM, posbuf, sizeof(posbuf), 0); if (retval != RIG_OK || strlen(posbuf) < 10) { return retval < 0 ? retval : -RIG_EPROTO; } /* parse "AZ=aaa EL=eee" */ /* With the format string containing a space character as one of the * directives, any amount of space is matched, including none in the input. */ // There's a 12PR1A rotor that only returns AZ so we may only get AZ=xxx if (sscanf(posbuf, "AZ=%d EL=%d", &int_az, &int_el) <= 0) { // only give error if we didn't parse anything rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s', expected AZ=xxx EL=xxx\n", __func__, posbuf); return -RIG_EPROTO; } *az = (azimuth_t) int_az; *el = (elevation_t) int_el; rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.0f, %.0f)\n", __func__, *az, *el); return RIG_OK; } static int gs232b_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* All Stop */ retval = gs232b_transaction(rot, "S" EOM, NULL, 0, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232b_rot_get_level(ROT *rot, setting_t level, value_t *val) { const struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: val->i = rs->current_speed; break; default: return -RIG_ENAVAIL; } return RIG_OK; } static int gs232b_rot_set_level(ROT *rot, setting_t level, value_t val) { struct rot_state *rs = ROTSTATE(rot); char cmdstr[24]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { int retval; case ROT_LEVEL_SPEED: { int speed = val.i; if (speed < 1) { speed = 1; } else if (speed > 4) { speed = 4; } /* between 1 (slowest) and 4 (fastest) */ SNPRINTF(cmdstr, sizeof(cmdstr), "X%u" EOM, speed); retval = gs232b_transaction(rot, cmdstr, NULL, 0, 1); if (retval != RIG_OK) { return retval; } rs->current_speed = speed; break; } default: return -RIG_ENAVAIL; } return RIG_OK; } static int gs232b_rot_move(ROT *rot, int direction, int speed) { char cmdstr[24]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called %d %d\n", __func__, direction, speed); if (speed != ROT_SPEED_NOCHANGE) { value_t gs232b_speed; if (speed < 1 || speed > 100) { rig_debug(RIG_DEBUG_ERR, "%s: Invalid speed value (1-100)! (%d)\n", __func__, speed); return -RIG_EINVAL; } gs232b_speed.i = (3 * speed) / 100 + 1; retval = gs232b_rot_set_level(rot, ROT_LEVEL_SPEED, gs232b_speed); if (retval != RIG_OK) { return retval; } } switch (direction) { case ROT_MOVE_UP: /* Elevation increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "U" EOM); break; case ROT_MOVE_DOWN: /* Elevation decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "D" EOM); break; case ROT_MOVE_LEFT: /* Azimuth decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "L" EOM); break; case ROT_MOVE_RIGHT: /* Azimuth increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "R" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid direction value! (%d)\n", __func__, direction); return -RIG_EINVAL; } retval = gs232b_transaction(rot, cmdstr, NULL, 0, 1); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232b_rot_init(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Set default speed to half of maximum rs->current_speed = 3; return RIG_OK; } /* ************************************************************************* */ /* * Generic GS232B rotator capabilities. */ const struct rot_caps gs232b_rot_caps = { ROT_MODEL(ROT_MODEL_GS232B), .model_name = "GS-232B", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ .has_get_level = GS232B_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232B_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232b_rot_init, .get_position = gs232b_rot_get_position, .set_position = gs232b_rot_set_position, .stop = gs232b_rot_stop, .move = gs232b_rot_move, .get_level = gs232b_rot_get_level, .set_level = gs232b_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232B azimuth rotator capabilities. */ const struct rot_caps gs232b_az_rot_caps = { ROT_MODEL(ROT_MODEL_GS232B_AZ), .model_name = "GS-232B azimuth", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 0.0, .has_get_level = GS232B_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232B_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232b_rot_init, .get_position = gs232b_rot_get_position, .set_position = gs232b_rot_set_position, .stop = gs232b_rot_stop, .move = gs232b_rot_move, .get_level = gs232b_rot_get_level, .set_level = gs232b_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232B elevation rotator capabilities. */ const struct rot_caps gs232b_el_rot_caps = { ROT_MODEL(ROT_MODEL_GS232B_EL), .model_name = "GS-232B elevation", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_ELEVATION, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = 0.0, .max_az = 0.0, .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ .has_get_level = GS232B_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232B_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232b_rot_init, .get_position = gs232b_rot_get_position, .set_position = gs232b_rot_set_position, .stop = gs232b_rot_stop, .move = gs232b_rot_move, .get_level = gs232b_rot_get_level, .set_level = gs232b_rot_set_level, }; /* end of file */ hamlib-4.6.5/rotators/gs232a/gs232a.c0000664000175000017500000004236215056640443012506 /* * Hamlib Rotator backend - GS-232A * Copyright (c) 2001-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * // cppcheck-suppress * #include #include "hamlib/rotator.h" #include "serial.h" #include "misc.h" #include "register.h" #include "idx_builtin.h" #include "gs232a.h" #define EOM "\r" #define REPLY_EOM "\n" #define BUFSZ 64 #define GS232A_LEVELS ROT_LEVEL_SPEED /** * gs232a_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ static int gs232a_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len, int no_reply) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* If no data requested just return */ if (!data) { return RIG_OK; } if (!data_len) { data_len = BUFSZ; } if (!no_reply) { memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, REPLY_EOM, strlen(REPLY_EOM), 0, 1); if (strncmp(data, "\r\n", 2) == 0 || strchr(data, '>')) { rig_debug(RIG_DEBUG_ERR, "%s: wrong response nbytes=%d\n", __func__, (int)strlen(data)); dump_hex((unsigned char *)data, strlen(data)); retval = -1; // force retry } if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } } #ifdef XXREMOVEDXX /* Check that command termination is correct */ if (strchr(REPLY_EOM, data[strlen(data) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rotp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } #endif if (data[0] == '?') { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s': '%s'\n", __func__, cmdstr, data); retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: return retval; } static int gs232a_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval; unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %.02f %.02f\n", __func__, az, el); if (az < 0.0) { az = az + 360.0; } u_az = (unsigned)rint(az); u_el = (unsigned)rint(el); SNPRINTF(cmdstr, sizeof(cmdstr), "W%03u %03u" EOM, u_az, u_el); retval = gs232a_transaction(rot, cmdstr, NULL, 0, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232a_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; int retval, int_az, int_el = 0; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = gs232a_transaction(rot, "C2" EOM, posbuf, sizeof(posbuf), 0); if (retval != RIG_OK) { return retval; } // parse "+0aaa+0eee" and expect both arguments if (sscanf(posbuf, "+0%d+0%d", &int_az, &int_el) != 2) { rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s', not +0xxx+0xxx format?\n", __func__, posbuf); return -RIG_EPROTO; } *az = (azimuth_t) int_az; *el = (elevation_t) int_el; rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int gs232a_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* All Stop */ retval = gs232a_transaction(rot, "S" EOM, NULL, 0, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232a_rot_get_level(ROT *rot, setting_t level, value_t *val) { const struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: val->i = rs->current_speed; break; default: return -RIG_ENAVAIL; } return RIG_OK; } static int gs232a_rot_set_level(ROT *rot, setting_t level, value_t val) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: { char cmdstr[24]; int retval; int speed = val.i; if (speed < 1) { speed = 1; } else if (speed > 4) { speed = 4; } /* between 1 (slowest) and 4 (fastest) */ SNPRINTF(cmdstr, sizeof(cmdstr), "X%u" EOM, speed); retval = gs232a_transaction(rot, cmdstr, NULL, 0, 1); if (retval != RIG_OK) { return retval; } rs->current_speed = speed; break; } default: return -RIG_ENAVAIL; } return RIG_OK; } static int gs232a_rot_move(ROT *rot, int direction, int speed) { char cmdstr[24]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called %d %d\n", __func__, direction, speed); if (speed != ROT_SPEED_NOCHANGE) { value_t gs232a_speed; if (speed < 1 || speed > 100) { rig_debug(RIG_DEBUG_ERR, "%s: Invalid speed value (1-100)! (%d)\n", __func__, speed); return -RIG_EINVAL; } gs232a_speed.i = (3 * speed) / 100 + 1; retval = gs232a_rot_set_level(rot, ROT_LEVEL_SPEED, gs232a_speed); if (retval != RIG_OK) { return retval; } } switch (direction) { case ROT_MOVE_UP: /* Elevation increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "U" EOM); break; case ROT_MOVE_DOWN: /* Elevation decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "D" EOM); break; case ROT_MOVE_LEFT: /* Azimuth decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "L" EOM); break; case ROT_MOVE_RIGHT: /* Azimuth increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "R" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid direction value! (%d)\n", __func__, direction); return -RIG_EINVAL; } retval = gs232a_transaction(rot, cmdstr, NULL, 0, 1); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232a_rot_init(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Set default speed to half of maximum rs->current_speed = 3; return RIG_OK; } /* ************************************************************************* */ /* * Generic GS23 rotator capabilities. */ const struct rot_caps gs23_rot_caps = { ROT_MODEL(ROT_MODEL_GS23), .model_name = "GS-23", .mfg_name = "Yaesu/Kenpro", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232a_rot_init, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS23 azimuth rotator capabilities. */ const struct rot_caps gs23_az_rot_caps = { ROT_MODEL(ROT_MODEL_GS23_AZ), .model_name = "GS-23 azimuth", .mfg_name = "Yaesu/Kenpro", .version = "20220527.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 0.0, .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232a_rot_init, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232 rotator capabilities. */ const struct rot_caps gs232_rot_caps = { ROT_MODEL(ROT_MODEL_GS232), .model_name = "GS-232", .mfg_name = "Yaesu/Kenpro", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232a_rot_init, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232A rotator capabilities. */ const struct rot_caps gs232a_rot_caps = { ROT_MODEL(ROT_MODEL_GS232A), .model_name = "GS-232A", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232a_rot_init, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .move = gs232a_rot_move, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232A azimuth rotator capabilities. */ const struct rot_caps gs232a_az_rot_caps = { ROT_MODEL(ROT_MODEL_GS232A_AZ), .model_name = "GS-232A azimuth", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 0.0, .rot_init = gs232a_rot_init, .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .move = gs232a_rot_move, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ /* * Generic GS232A elevation rotator capabilities. */ const struct rot_caps gs232a_el_rot_caps = { ROT_MODEL(ROT_MODEL_GS232A_EL), .model_name = "GS-232A elevation", .mfg_name = "Yaesu", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_ELEVATION, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 400, .retry = 3, .min_az = 0.0, .max_az = 0.0, .min_el = 0.0, .max_el = 180.0, /* requires G-5400B, G-5600B, G-5500, or G-500/G-550 */ .has_get_level = GS232A_LEVELS, .has_set_level = ROT_LEVEL_SET(GS232A_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .rot_init = gs232a_rot_init, .get_position = gs232a_rot_get_position, .set_position = gs232a_rot_set_position, .stop = gs232a_rot_stop, .move = gs232a_rot_move, .get_level = gs232a_rot_get_level, .set_level = gs232a_rot_set_level, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(gs232a) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&gs232a_rot_caps); rot_register(&gs232a_az_rot_caps); rot_register(&gs232a_el_rot_caps); rot_register(&gs232_generic_rot_caps); rot_register(&gs232b_rot_caps); rot_register(&gs232b_az_rot_caps); rot_register(&gs232b_el_rot_caps); rot_register(&f1tetracker_rot_caps); rot_register(&gs23_rot_caps); rot_register(&gs232_rot_caps); rot_register(&amsat_lvb_rot_caps); rot_register(&st2_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/gs232a/gs232.c0000664000175000017500000002405215056640443012341 /* * Hamlib Rotator backend - GS-232 * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2009 by Jason Winningham * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include "hamlib/rotator.h" #include "serial.h" #define EOM "\r" #define REPLY_EOM "\r" #define BUFSZ 64 /** * gs232_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ static int gs232_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to know whether the cmd went OK */ if (!data) { return RIG_OK; } if (!data_len) { data_len = BUFSZ; } memset(data, 0, data_len); retval = read_string(rotp, (unsigned char *) data, data_len, REPLY_EOM, strlen(REPLY_EOM), 0, 1); if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } #ifdef XXREMOVEDXX /* Check that command termination is correct */ if (strchr(REPLY_EOM, data[strlen(data) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rotp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } #endif if (data[0] == '?') { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s': '%s'\n", __func__, cmdstr, data); retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: return retval; } /* * write-only transaction, no data returned by controller */ static int gs232_wo_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { return write_block(ROTPORT(rot), (unsigned char *) cmdstr, strlen(cmdstr)); } static int gs232_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval; unsigned u_az, u_el; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); if (az < 0.0) { az = az + 360.0; } u_az = (unsigned)rint(az); u_el = (unsigned)rint(el); SNPRINTF(cmdstr, sizeof(cmdstr), "W%03u %03u" EOM, u_az, u_el); retval = gs232_wo_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int gs232_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char posbuf[32]; // these really shouldn't be static but it's fixing faulty firmware -- see below static int expected = 12; static int expected_flag = 0; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (expected_flag == 0) { ROTPORT(rot)->retry = 0; expected_flag = 1; } retval = gs232_transaction(rot, "C2" EOM, posbuf, expected); if (strlen(posbuf) < 10) { return retval; } // AF6SA WRC - Wifi Rotator Controller does not provide EOM byte so we allow timeout // Still returns 10 chars though if (strlen(posbuf) == 10 && expected == 12) { rig_debug(RIG_DEBUG_WARN, "%s: rotor didn't send CR...assuming it won't in the future\n", __func__); retval = RIG_OK; expected = 11; // we won't expect the CR ROTPORT(rot)->retry = 3; } /* parse */ if (sscanf(posbuf + 2, "%f", az) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s'\n", __func__, posbuf); return -RIG_EPROTO; } if (sscanf(posbuf + 7, "%f", el) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong reply '%s'\n", __func__, posbuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n", __func__, *az, *el); return RIG_OK; } static int gs232_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* All Stop */ retval = gs232_wo_transaction(rot, "S" EOM, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* ************************************************************************* */ /* * Generic GS232 Protocol (including those not correctly implemented) rotator capabilities. */ const struct rot_caps gs232_generic_rot_caps = { ROT_MODEL(ROT_MODEL_GS232_GENERIC), .model_name = "GS-232 Generic", .mfg_name = "Various", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 1, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .get_position = gs232_rot_get_position, .set_position = gs232_rot_set_position, .stop = gs232_rot_stop, }; /* ************************************************************************* */ /* * Generic AMSAT LVB Tracker rotator capabilities. */ const struct rot_caps amsat_lvb_rot_caps = { ROT_MODEL(ROT_MODEL_LVB), .model_name = "LVB Tracker", .mfg_name = "AMSAT", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .get_position = gs232_rot_get_position, .set_position = gs232_rot_set_position, .stop = gs232_rot_stop, }; /* ************************************************************************* */ /* * Generic FoxDelta ST2 rotator capabilities. */ const struct rot_caps st2_rot_caps = { ROT_MODEL(ROT_MODEL_ST2), .model_name = "GS232/ST2", .mfg_name = "FoxDelta", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .min_az = -180.0, .max_az = 450.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .get_position = gs232_rot_get_position, .set_position = gs232_rot_set_position, .stop = gs232_rot_stop, }; /* ************************************************************************* */ /* * F1TE Tracker, GS232 without position feedback * * http://www.f1te.org/index.php?option=com_content&view=article&id=19&Itemid=39 */ const struct rot_caps f1tetracker_rot_caps = { ROT_MODEL(ROT_MODEL_F1TETRACKER), .model_name = "GS232/F1TE Tracker", .mfg_name = "F1TE", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 150, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 0, .min_az = -180.0, .max_az = 360.0, /* vary according to rotator type */ .min_el = 0.0, .max_el = 180.0, .get_position = NULL, /* no position feedback available */ .set_position = gs232_rot_set_position, #ifdef XXREMOVEDXX .stop = gs232_rot_stop, #endif }; hamlib-4.6.5/rotators/gs232a/Android.mk0000664000175000017500000000041315056640443013241 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := gs232a.c gs232b.c gs232.c LOCAL_MODULE := gs232a LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/gs232a/Makefile.in0000664000175000017500000005314015056640453013403 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/gs232a ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_gs232a_la_LIBADD = am_libhamlib_gs232a_la_OBJECTS = gs232a.lo gs232b.lo gs232.lo libhamlib_gs232a_la_OBJECTS = $(am_libhamlib_gs232a_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gs232.Plo ./$(DEPDIR)/gs232a.Plo \ ./$(DEPDIR)/gs232b.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_gs232a_la_SOURCES) DIST_SOURCES = $(libhamlib_gs232a_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-gs232a.la libhamlib_gs232a_la_SOURCES = gs232a.c gs232a.h gs232b.c gs232.c EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/gs232a/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/gs232a/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-gs232a.la: $(libhamlib_gs232a_la_OBJECTS) $(libhamlib_gs232a_la_DEPENDENCIES) $(EXTRA_libhamlib_gs232a_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_gs232a_la_OBJECTS) $(libhamlib_gs232a_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs232.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs232a.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs232b.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gs232.Plo -rm -f ./$(DEPDIR)/gs232a.Plo -rm -f ./$(DEPDIR)/gs232b.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gs232.Plo -rm -f ./$(DEPDIR)/gs232a.Plo -rm -f ./$(DEPDIR)/gs232b.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/gs232a/gs232a.h0000664000175000017500000000307715056640443012513 /* * Hamlib Rotator backend - GS-232 interface protocol * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_GS232A_H #define _ROT_GS232A_H 1 #include "rotator.h" extern const struct rot_caps gs232a_rot_caps; extern const struct rot_caps gs232a_az_rot_caps; extern const struct rot_caps gs232a_el_rot_caps; extern const struct rot_caps gs232_generic_rot_caps; extern const struct rot_caps gs232b_rot_caps; extern const struct rot_caps gs232b_az_rot_caps; extern const struct rot_caps gs232b_el_rot_caps; extern const struct rot_caps f1tetracker_rot_caps; extern const struct rot_caps gs23_rot_caps; extern const struct rot_caps gs23_az_rot_caps; extern const struct rot_caps gs232_rot_caps; extern const struct rot_caps amsat_lvb_rot_caps; extern const struct rot_caps st2_rot_caps; #endif /* _ROT_GS232A_H */ hamlib-4.6.5/rotators/gs232a/Makefile.am0000664000175000017500000000020415056640443013362 noinst_LTLIBRARIES = libhamlib-gs232a.la libhamlib_gs232a_la_SOURCES = gs232a.c gs232a.h gs232b.c gs232.c EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/ars/0000775000175000017500000000000015056640501011171 5hamlib-4.6.5/rotators/ars/Android.mk0000664000175000017500000000036415056640443013032 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ars.c LOCAL_MODULE := ars LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/ars/Makefile.in0000664000175000017500000005263415056640453013176 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/ars ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_ars_la_LIBADD = am_libhamlib_ars_la_OBJECTS = ars.lo libhamlib_ars_la_OBJECTS = $(am_libhamlib_ars_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libhamlib_ars_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libhamlib_ars_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ars.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_ars_la_SOURCES) DIST_SOURCES = $(libhamlib_ars_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ $(PTHREAD_CFLAGS) AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-ars.la libhamlib_ars_la_SOURCES = ars.c ars.h libhamlib_ars_la_LDFLAGS = $(PTHREAD_LIBS) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/ars/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/ars/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-ars.la: $(libhamlib_ars_la_OBJECTS) $(libhamlib_ars_la_DEPENDENCIES) $(EXTRA_libhamlib_ars_la_DEPENDENCIES) $(AM_V_CCLD)$(libhamlib_ars_la_LINK) $(libhamlib_ars_la_OBJECTS) $(libhamlib_ars_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ars.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ars.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ars.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/ars/ars.h0000664000175000017500000000246015056640443012056 /* * Hamlib Rotator backend - ARS interface protocol * Copyright (c) 2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_ARS_H #define _ROT_ARS_H 1 #include "hamlib/rig.h" struct ars_priv_data { unsigned adc_res; int brake_off; int curr_move; unsigned char pp_control; unsigned char pp_data; #ifdef HAVE_PTHREAD pthread_t thread; int set_pos_active; azimuth_t target_az; elevation_t target_el; #endif }; extern const struct rot_caps rci_az_rot_caps; extern const struct rot_caps rci_azel_rot_caps; #endif /* _ROT_ARS_H */ hamlib-4.6.5/rotators/ars/ars.c0000664000175000017500000005201315056640443012050 /* * Hamlib Rotator backend - ARS parallel port backend * Copyright (c) 2010 by Stephane Fillod * This code is inspired by work from Pablo GARCIA - EA4TX * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_PTHREAD #include #endif #include "hamlib/rotator.h" #include "parallel.h" #include "misc.h" #include "register.h" #include "ars.h" #define CTL_PIN_CS PARPORT_CONTROL_AUTOFD /* pin14: Control Linefeed */ #define CTL_PIN_CLK PARPORT_CONTROL_STROBE /* pin01: Control /Strobe */ #define STA_PIN_D0 PARPORT_STATUS_BUSY /* pin11: Status Busy */ #define STA_PIN_D1 PARPORT_STATUS_ERROR /* pin15: Status /Error */ #define DTA_PIN02 0x01 /* Data0 */ #define DTA_PIN03 0x02 /* Data1 */ #define DTA_PIN04 0x04 /* Data2 */ #define DTA_PIN05 0x08 /* Data3 */ #define DTA_PIN06 0x10 /* Data4 */ #define DTA_PIN07 0x20 /* Data5 */ #define DTA_PIN08 0x40 /* Data6 */ #define DTA_PIN09 0x80 /* Data7 */ #define CTL_PIN16 PARPORT_CONTROL_INIT #define CTL_PIN17 PARPORT_CONTROL_SELECT #define ARS_BRAKE_DELAY (100*1000) /* usecs */ #define ARS_SETTLE_DELAY (500*1000) /* usecs */ #define PP_IO_PERIOD (25) /* usecs */ #define NUM_SAMPLES 3 /* TODO: take into account ADC res (8 bits -> 1.4 deg at 360 deg) * Rem: at 360 deg/mn, that's 6 deg/sec. */ #define AZ_RANGE 3. #define EL_RANGE 2. /* Check return value, with appropriate unlocking upon error. * Assumes "rot" variable is current ROT pointer. */ #define CHKPPRET(a) \ do { int _retval = a; if (_retval != RIG_OK) \ {par_unlock (ROTPORT(rot));return _retval; }} while(0) static int ars_init(ROT *rot); static int ars_cleanup(ROT *rot); static int ars_open(ROT *rot); static int ars_close(ROT *rot); static int ars_stop(ROT *rot); static int ars_move(ROT *rot, int direction, int speed); static int ars_set_position_sync(ROT *rot, azimuth_t az, elevation_t el); static int ars_set_position(ROT *rot, azimuth_t az, elevation_t el); static int ars_get_position(ROT *rot, azimuth_t *az, elevation_t *el); #ifdef HAVE_PTHREAD static void *handle_set_position(void *); #endif /* ************************************************************************* */ static int ars_clear_ctrl_pin(ROT *rot, unsigned char pin) { hamlib_port_t *pport = ROTPORT(rot); struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; priv->pp_control &= ~pin; return par_write_control(pport, priv->pp_control); } static int ars_set_ctrl_pin(ROT *rot, unsigned char pin) { hamlib_port_t *pport = ROTPORT(rot); struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; priv->pp_control |= pin; return par_write_control(pport, priv->pp_control); } static int ars_clear_data_pin(ROT *rot, unsigned char pin) { hamlib_port_t *pport = ROTPORT(rot); struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; priv->pp_data &= ~pin; return par_write_data(pport, priv->pp_data); } static int ars_set_data_pin(ROT *rot, unsigned char pin) { hamlib_port_t *pport = ROTPORT(rot); struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; priv->pp_data |= pin; return par_write_data(pport, priv->pp_data); } static int ars_has_el(const ROT *rot) { return (rot->caps->rot_type & ROT_FLAG_ELEVATION); } /* ************************************************************************* */ int ars_init(ROT *rot) { struct ars_priv_data *priv; if (!rot) { return -RIG_EINVAL; } ROTSTATE(rot)->priv = (struct ars_priv_data *)calloc(1, sizeof(struct ars_priv_data)); if (!ROTSTATE(rot)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; priv->pp_control = 0; priv->pp_data = 0; /* Always use 10 bit resolution, which supports also 8 bits * at the cost of 2 potentially wrong lsb */ priv->adc_res = 10; /* 8 bits vs. 10 bits ADC */ priv->brake_off = 0; /* i.e. brake is ON */ priv->curr_move = 0; return RIG_OK; } int ars_cleanup(ROT *rot) { if (!rot) { return -RIG_EINVAL; } if (ROTSTATE(rot)->priv) { free(ROTSTATE(rot)->priv); ROTSTATE(rot)->priv = NULL; } return RIG_OK; } int ars_open(ROT *rot) { /* make it idle, and known state */ ars_stop(rot); #ifdef HAVE_PTHREAD { struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; pthread_attr_t attr; int retcode; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); /* create behind-the-scene thread doing the ars_set_position_sync() */ retcode = pthread_create(&priv->thread, &attr, handle_set_position, rot); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create: %s\n", __func__, strerror(retcode)); return -RIG_ENOMEM; } } #endif return RIG_OK; } int ars_close(ROT *rot) { #ifdef HAVE_PTHREAD struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; pthread_cancel(priv->thread); #endif /* leave it in safe state */ ars_stop(rot); return RIG_OK; } int ars_stop(ROT *rot) { struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; hamlib_port_t *pport = ROTPORT(rot); rig_debug(RIG_DEBUG_TRACE, "%s called, brake was %s\n", __func__, priv->brake_off ? "OFF" : "ON"); #ifdef HAVE_PTHREAD priv->set_pos_active = 0; #endif par_lock(pport); priv->brake_off = 0; priv->curr_move = 0; // Relay AUX -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN08)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17 | CTL_PIN16)); // Elevation Relays -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN07)); par_unlock(pport); return RIG_OK; } int ars_move(ROT *rot, int direction, int speed) { struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; hamlib_port_t *pport = ROTPORT(rot); int need_settle_delay = 0; rig_debug(RIG_DEBUG_TRACE, "%s called%s%s%s%s%s\n", __func__, (direction & ROT_MOVE_LEFT) ? " LEFT" : "", (direction & ROT_MOVE_RIGHT) ? " RIGHT" : "", (direction & ROT_MOVE_UP) ? " UP" : "", (direction & ROT_MOVE_DOWN) ? " DOWN" : "", (direction == 0) ? " STOP" : ""); par_lock(pport); /* Allow the rotator to settle down when changing direction */ if (((priv->curr_move & ROT_MOVE_LEFT) && (direction & ROT_MOVE_RIGHT)) || ((priv->curr_move & ROT_MOVE_RIGHT) && (direction & ROT_MOVE_LEFT))) { // Relay AUX -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN08)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17 | CTL_PIN16)); need_settle_delay = 1; priv->brake_off = 0; } if (ars_has_el(rot) && (((priv->curr_move & ROT_MOVE_UP) && (direction & ROT_MOVE_DOWN)) || ((priv->curr_move & ROT_MOVE_DOWN) && (direction & ROT_MOVE_UP)))) { // Elevation Relays -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN07)); need_settle_delay = 1; } if (need_settle_delay) { rig_debug(RIG_DEBUG_TRACE, "%s need settling delay\n", __func__); hl_usleep(ARS_SETTLE_DELAY); } priv->curr_move = direction; /* Brake handling, only for AZ */ if (!priv->brake_off && (direction & (ROT_MOVE_LEFT | ROT_MOVE_RIGHT))) { /* release the brake */ if (ars_has_el(rot)) { // RCI Model Azim & Elev // Deactivated CCW/CW relays CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17 | CTL_PIN16)); // Relay Aux CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06 | DTA_PIN08)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN09)); } else { // RCI Model Azimuth only // Deactivated CCW/CW relays CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17 | CTL_PIN16)); // Relay Aux CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06 | DTA_PIN07 | DTA_PIN08 | DTA_PIN09)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN05)); } priv->brake_off = 1; hl_usleep(ARS_BRAKE_DELAY); } if (ars_has_el(rot)) { if (direction & ROT_MOVE_UP) { /* UP */ CHKPPRET(ars_set_data_pin(rot, DTA_PIN03 | DTA_PIN06 | DTA_PIN07)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN05 | DTA_PIN09)); } else if (direction & ROT_MOVE_DOWN) { CHKPPRET(ars_set_data_pin(rot, DTA_PIN03 | DTA_PIN05 | DTA_PIN06 | DTA_PIN07)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN09)); } else { // Elevation Relays -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN07)); } } if (direction & ROT_MOVE_LEFT) { // Relay Left if (ars_has_el(rot)) { // RCI Model Azim & Elev CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06)); CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN16)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN09)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17)); } else { // RCI Model Azimuth only CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06 | DTA_PIN07 | DTA_PIN08)); CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN16)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN05)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17)); } } else if (direction & ROT_MOVE_RIGHT) { // Relay Right if (ars_has_el(rot)) { // RCI Model Azim & Elev CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06)); CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN17)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN09)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN16)); } else { // RCI Model Azimuth only CHKPPRET(ars_set_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN06 | DTA_PIN07 | DTA_PIN08)); CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN17)); CHKPPRET(ars_clear_data_pin(rot, DTA_PIN03 | DTA_PIN05)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN16)); } } else { // Relay AUX -> Off CHKPPRET(ars_clear_data_pin(rot, DTA_PIN02 | DTA_PIN04 | DTA_PIN08)); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN17 | CTL_PIN16)); // AZ stop } par_unlock(pport); return RIG_OK; } static int angle_in_range(float angle, float angle_base, float range) { return (angle >= angle_base - range && angle <= angle_base + range); } /* * Thread handler */ #ifdef HAVE_PTHREAD static void *handle_set_position(void *arg) { ROT *rot = (ROT *) arg; struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; int retcode; while (1) { if (!priv->set_pos_active) { /* TODO: replace polling period by cond var */ hl_usleep(100 * 1000 - 1); continue; } retcode = ars_set_position_sync(rot, priv->target_az, priv->target_el); priv->set_pos_active = 0; if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: ars_set_position_sync() failed: %s\n", __func__, rigerror(retcode)); hl_usleep(1000 * 1000); continue; } } return NULL; } #endif /* * ars_set_position_sync() is synchronous. * See handle_set_position_async() for asynchronous thread handler, * with wait loop in background */ int ars_set_position_sync(ROT *rot, azimuth_t az, elevation_t el) { azimuth_t curr_az, prev_az; elevation_t curr_el, prev_el; int retval; int az_move, el_move; struct timeval last_pos_az_tv, last_pos_el_tv; rig_debug(RIG_DEBUG_TRACE, "%s called: %.1f %.1f\n", __func__, az, el); ars_stop(rot); retval = ars_get_position(rot, &curr_az, &curr_el); if (retval != RIG_OK) { return retval; } /* watchdog init */ prev_az = curr_az; prev_el = curr_el; gettimeofday(&last_pos_az_tv, NULL); last_pos_el_tv = last_pos_az_tv; while (!angle_in_range(curr_az, az, AZ_RANGE) || (ars_has_el(rot) && !angle_in_range(curr_el, el, EL_RANGE)) ) { if (curr_az < (az - AZ_RANGE)) { az_move = ROT_MOVE_RIGHT; } else if (curr_az > (az + AZ_RANGE)) { az_move = ROT_MOVE_LEFT; } else { az_move = 0; } if (ars_has_el(rot)) { if (curr_el < (el - EL_RANGE)) { el_move = ROT_MOVE_UP; } else if (curr_el > (el + EL_RANGE)) { el_move = ROT_MOVE_DOWN; } else { el_move = 0; } } else { el_move = 0; } retval = ars_move(rot, az_move | el_move, 0); if (retval != RIG_OK) { ars_stop(rot); return retval; } /* wait a little */ hl_usleep(10 * 1000); retval = ars_get_position(rot, &curr_az, &curr_el); if (retval != RIG_OK) { ars_stop(rot); return retval; } /* Watchdog detecting when rotor is blocked unexpectedly */ #define AZ_WATCHDOG 5000 /* ms */ #define EL_WATCHDOG 5000 /* ms */ if (az_move != 0 && angle_in_range(curr_az, prev_az, AZ_RANGE)) { if (rig_check_cache_timeout(&last_pos_az_tv, AZ_WATCHDOG)) { ars_stop(rot); return -RIG_ETIMEOUT; } } else { prev_az = curr_az; gettimeofday(&last_pos_az_tv, NULL); } if (el_move != 0 && ars_has_el(rot) && angle_in_range(curr_el, prev_el, EL_RANGE)) { if (rig_check_cache_timeout(&last_pos_el_tv, EL_WATCHDOG)) { ars_stop(rot); return -RIG_ETIMEOUT; } } else { prev_el = curr_el; gettimeofday(&last_pos_el_tv, NULL); } } return ars_stop(rot); } int ars_set_position(ROT *rot, azimuth_t az, elevation_t el) { #ifdef HAVE_PTHREAD struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; /* will be picked by handle_set_position() next polling tick */ priv->target_az = az; priv->target_el = el; priv->set_pos_active = 1; return RIG_OK; #else return ars_set_position_sync(rot, az, el); #endif } static int comparunsigned(const void *a, const void *b) { const unsigned ua = *(const unsigned *)a, ub = *(const unsigned *)b; return ua == ub ? 0 : ua < ub ? -1 : 1; } int ars_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { const struct ars_priv_data *priv = (struct ars_priv_data *)ROTSTATE(rot)->priv; struct rot_state *rs = ROTSTATE(rot); hamlib_port_t *pport = ROTPORT(rot); int i, num_sample; unsigned az_samples[NUM_SAMPLES], az_value; unsigned el_samples[NUM_SAMPLES], el_value; unsigned char status; par_lock(pport); /* flush last sampled value, with a dummy read */ CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CS)); hl_usleep(PP_IO_PERIOD); for (i = 0; i < priv->adc_res; i++) { CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); } CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN_CS)); /* end of dummy read */ for (num_sample = 0; num_sample < NUM_SAMPLES; num_sample++) { /* read ADC value TLC(1)549 (8/10 bits), by SPI bitbanging */ hl_usleep(PP_IO_PERIOD); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CS)); hl_usleep(PP_IO_PERIOD); az_samples[num_sample] = 0; el_samples[num_sample] = 0; for (i = 0; i < priv->adc_res; i++) { CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); CHKPPRET(par_read_status(pport, &status)); az_samples[num_sample] <<= 1; az_samples[num_sample] |= (status & STA_PIN_D0) ? 1 : 0; el_samples[num_sample] <<= 1; el_samples[num_sample] |= (status & STA_PIN_D1) ? 1 : 0; CHKPPRET(ars_clear_ctrl_pin(rot, CTL_PIN_CLK)); hl_usleep(PP_IO_PERIOD); } CHKPPRET(ars_set_ctrl_pin(rot, CTL_PIN_CS)); rig_debug(RIG_DEBUG_TRACE, "%s: raw samples: az %u, el %u\n", __func__, az_samples[num_sample], el_samples[num_sample]); hl_usleep(PP_IO_PERIOD); } par_unlock(pport); qsort(az_samples, NUM_SAMPLES, sizeof(unsigned), comparunsigned); qsort(el_samples, NUM_SAMPLES, sizeof(unsigned), comparunsigned); /* select median value in order to rule out glitches */ az_value = az_samples[NUM_SAMPLES / 2]; el_value = el_samples[NUM_SAMPLES / 2]; *az = rs->min_az + ((float)az_value * (rs->max_az - rs->min_az)) / (( 1 << priv->adc_res) - 1); *el = rs->min_el + ((float)el_value * (rs->max_el - rs->min_el)) / (( 1 << priv->adc_res) - 1); rig_debug(RIG_DEBUG_TRACE, "%s: az=%.1f el=%.1f\n", __func__, *az, *el); return RIG_OK; } /* ************************************************************************* */ /* * ARS rotator capabilities. */ /* * RCI/RCI-SE, with Elevation daugtherboard/unit. */ const struct rot_caps rci_azel_rot_caps = { ROT_MODEL(ROT_MODEL_RCI_AZEL), .model_name = "ARS RCI AZ&EL", .mfg_name = "EA4TX", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, /* AZ&EL units */ .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 10, .timeout = 0, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 180, /* TBC */ .rot_init = ars_init, .rot_cleanup = ars_cleanup, .rot_open = ars_open, .rot_close = ars_close, .set_position = ars_set_position, .get_position = ars_get_position, .stop = ars_stop, .move = ars_move, }; /* * RCI/RCI-SE, without Elevation daugtherboard/unit. * Azimuth only */ const struct rot_caps rci_az_rot_caps = { ROT_MODEL(ROT_MODEL_RCI_AZ), .model_name = "ARS RCI AZ", .mfg_name = "EA4TX", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, /* AZ-only unit */ .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 10, .timeout = 0, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 180, /* TBC */ .rot_init = ars_init, .rot_cleanup = ars_cleanup, .rot_open = ars_open, .rot_close = ars_close, .set_position = ars_set_position, .get_position = ars_get_position, .stop = ars_stop, .move = ars_move, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(ars) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&rci_az_rot_caps); rot_register(&rci_azel_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/ars/Makefile.am0000664000175000017500000000026115056640443013151 AM_CFLAGS += $(PTHREAD_CFLAGS) noinst_LTLIBRARIES = libhamlib-ars.la libhamlib_ars_la_SOURCES = ars.c ars.h libhamlib_ars_la_LDFLAGS = $(PTHREAD_LIBS) EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/prosistel/0000775000175000017500000000000015056640502012431 5hamlib-4.6.5/rotators/prosistel/prosistel.c0000664000175000017500000003645315056640443014560 /* * Hamlib Prosistel backend * Copyright (c) 2015 by Dario Ventura IZ7CRX * Copyright (c) 2020 by Mikael Nousiainen OH3BHX * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "num_stdio.h" #include "prosistel.h" #define BUFSZ 128 #define CR "\r" #define STX "\x02" struct prosistel_rot_priv_caps { float angle_multiplier; char azimuth_id; char elevation_id; int stop_angle; }; /** * prosistel_transaction * * cmdstr - Command to be sent to the rig. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed, but answer will still be read. * data_len - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_EPROTO - if a the response does not follow Prosistel protocol * RIG_ETIMEOUT - if timeout expires without any characters received. */ static int prosistel_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry_read = 0; char replybuf[BUFSZ]; transaction_write: rig_flush(rotp); if (cmdstr) { retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to know whether the cmd went OK */ if (!data) { data = replybuf; } if (!data_len) { data_len = BUFSZ; } // Remember to check for STXA,G,R or STXA,?,XXX,R 10 bytes retval = read_string(rotp, (unsigned char *) data, 20, CR, strlen(CR), 0, 1); if (retval < 0) { if (retry_read++ < rotp->retry) { goto transaction_write; } goto transaction_quit; } // Check if reply matches issued command if (cmdstr && data[0] == 0x02 && data[3] == cmdstr[2]) { rig_debug(RIG_DEBUG_VERBOSE, "%s Command %c reply received\n", __func__, data[3]); retval = RIG_OK; } else if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error Command issued: %c doesn't match reply %c\n", __func__, cmdstr[2], data[3]); retval = -RIG_EPROTO; } transaction_quit: return retval; } static int prosistel_rot_open(ROT *rot) { const struct prosistel_rot_priv_caps *priv_caps = (struct prosistel_rot_priv_caps *) rot->caps->priv; char cmdstr[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Disable CPM mode - CPM stands for Continuous Position Monitor operating mode // The rotator controller sends position data continuously when CPM is enabled // Disable CPM for azimuth if the rotator has an azimuth rotator if (rot->caps->rot_type == ROT_TYPE_AZIMUTH || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cS"CR, priv_caps->azimuth_id); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } // Disable CPM for elevation if the rotator has an elevation rotator if (rot->caps->rot_type == ROT_TYPE_ELEVATION || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cS"CR, priv_caps->elevation_id); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } static int prosistel_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { const struct prosistel_rot_priv_caps *priv_caps = (struct prosistel_rot_priv_caps *) rot->caps->priv; char cmdstr[64]; int retval = -RIG_EINTERNAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.1f %.1f\n", __func__, az, el); // Leading zeros in angle values are optional according to Prosistel protocol documentation // Set azimuth only if the rotator has the capability to do so // It is an error to set azimuth if it's not supported by the rotator controller if (rot->caps->rot_type == ROT_TYPE_AZIMUTH || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cG%.0f"CR, priv_caps->azimuth_id, az * priv_caps->angle_multiplier); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } // Set elevation only if the rotator has the capability to do so // It is an error to set elevation if it's not supported by the rotator controller if (rot->caps->rot_type == ROT_TYPE_ELEVATION || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cG%.0f"CR, priv_caps->elevation_id, el * priv_caps->angle_multiplier); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } return retval; } static int prosistel_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { const struct prosistel_rot_priv_caps *priv_caps = (struct prosistel_rot_priv_caps *) rot->caps->priv; char cmdstr[64]; char data[20]; float posval; int retval = RIG_OK; int n; // Query azimuth only if the rotator has the capability to do so // It is an error to query for azimuth if it's not supported by the rotator controller if (rot->caps->rot_type == ROT_TYPE_AZIMUTH || rot->caps->rot_type == ROT_TYPE_AZEL) { char rot_id; num_sprintf(cmdstr, STX"%c?"CR, priv_caps->azimuth_id); retval = prosistel_transaction(rot, cmdstr, data, sizeof(data)); if (retval != RIG_OK) { return retval; } // Example response of 290 degree azimuth with 3 digits // 02 41 2c 3f 2c 32 39 30 2c 52 0d .A,?,290,R. // Example response of 100 degree azimuth with 4 digits // 02 41 2c 3f 2c 31 30 30 30 2c 52 0d .A,?,1000,R. n = sscanf(data, "%*c%c,?,%f,%*c.", &rot_id, &posval); if (n != 2 || rot_id != priv_caps->azimuth_id) { rig_debug(RIG_DEBUG_ERR, "%s failed to parse azimuth '%s'\n", __func__, data); return -RIG_EPROTO; } posval /= priv_caps->angle_multiplier; rig_debug(RIG_DEBUG_VERBOSE, "%s got position from '%s' converted to %f\n", __func__, data, posval); *az = (azimuth_t) posval; } else { *az = 0; } // Query elevation only if the rotator has the capability to do so // It is an error to query for elevation if it's not supported by the rotator controller if (rot->caps->rot_type == ROT_TYPE_ELEVATION || rot->caps->rot_type == ROT_TYPE_AZEL) { char rot_id; num_sprintf(cmdstr, STX"%c?"CR, priv_caps->elevation_id); retval = prosistel_transaction(rot, cmdstr, data, sizeof(data)); if (retval != RIG_OK) { return retval; } // Example response of 90 degree elevation with 4 digits // 02 42 2c 3f 2c 30 39 30 30 2c 52 0d .B,?,0900,R. // The response will be an error if no elevation is available // 02 42 2c 3f 2c 45 2c 30 30 30 30 33 0d .B,?,E,00003. n = sscanf(data, "%*c%c,?,%f,%*c.", &rot_id, &posval); if (n != 2 || rot_id != priv_caps->elevation_id) { rig_debug(RIG_DEBUG_ERR, "%s failed to parse elevation '%s'\n", __func__, data); return -RIG_EPROTO; } posval /= priv_caps->angle_multiplier; rig_debug(RIG_DEBUG_VERBOSE, "%s got position from '%s' converted to %f\n", __func__, data, posval); *el = (elevation_t) posval; } else { *el = 0; } return retval; } static int prosistel_rot_stop(ROT *rot) { const struct prosistel_rot_priv_caps *priv_caps = (struct prosistel_rot_priv_caps *) rot->caps->priv; char cmdstr[64]; int retval = -RIG_EINTERNAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Stop azimuth only if the rotator has the capability to do so if (rot->caps->rot_type == ROT_TYPE_AZIMUTH || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cG%d"CR, priv_caps->azimuth_id, priv_caps->stop_angle); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } // Stop elevation only if the rotator has the capability to do so if (rot->caps->rot_type == ROT_TYPE_ELEVATION || rot->caps->rot_type == ROT_TYPE_AZEL) { num_sprintf(cmdstr, STX"%cG%d"CR, priv_caps->elevation_id, priv_caps->stop_angle); retval = prosistel_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } } return retval; } static const struct prosistel_rot_priv_caps prosistel_rot_az_or_el_priv_caps = { .angle_multiplier = 1.0f, /** * Angle 977 = soft stop, stops the rotator using using PWM if PWM mode is enabled, otherwise results in a fast stop * Angle 999 = fast stop, stops the rotator immediately */ .stop_angle = 997, .azimuth_id = 'A', .elevation_id = 'E', }; /* * The Prosistel Combi-Track azimuth + elevation controllers use angle values multiplied by 10 and have * two "units" with identifier A and B (instead of A and E). */ static const struct prosistel_rot_priv_caps prosistel_rot_combitrack_priv_caps = { .angle_multiplier = 10.0f, /** * Angle 9777 = soft stop, stops the rotator using using PWM if PWM mode is enabled, otherwise results in a fast stop * Angle 9999 = fast stop, stops the rotator immediately */ .stop_angle = 9777, .azimuth_id = 'A', .elevation_id = 'B', }; // Elevation rotator with Control box D using azimuth logic static const struct prosistel_rot_priv_caps prosistel_rot_el_cboxaz = { .angle_multiplier = 1.0f, .stop_angle = 997, .elevation_id = 'A', }; /* * Prosistel rotator capabilities */ const struct rot_caps prosistel_d_az_rot_caps = { ROT_MODEL(ROT_MODEL_PROSISTEL_D_AZ), .model_name = "D azimuth", .mfg_name = "Prosistel", .version = "20201215.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZIMUTH, .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 = 0, .post_write_delay = 0, .timeout = 3000, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 0.0, .priv = &prosistel_rot_az_or_el_priv_caps, .rot_open = prosistel_rot_open, .stop = prosistel_rot_stop, .set_position = prosistel_rot_set_position, .get_position = prosistel_rot_get_position, }; const struct rot_caps prosistel_d_el_rot_caps = { ROT_MODEL(ROT_MODEL_PROSISTEL_D_EL), .model_name = "D elevation", .mfg_name = "Prosistel", .version = "20201215.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_ELEVATION, .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 = 0, .post_write_delay = 0, .timeout = 3000, .retry = 3, .min_az = 0.0, .max_az = 0.0, .min_el = 0.0, .max_el = 90.0, .priv = &prosistel_rot_az_or_el_priv_caps, .rot_open = prosistel_rot_open, .stop = prosistel_rot_stop, .set_position = prosistel_rot_set_position, .get_position = prosistel_rot_get_position, }; const struct rot_caps prosistel_combi_track_azel_rot_caps = { ROT_MODEL(ROT_MODEL_PROSISTEL_COMBI_TRACK_AZEL), .model_name = "Combi-Track az+el", .mfg_name = "Prosistel", .version = "20201215.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .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 = 0, .post_write_delay = 0, .timeout = 3000, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 90.0, .priv = &prosistel_rot_combitrack_priv_caps, .rot_open = prosistel_rot_open, .stop = prosistel_rot_stop, .set_position = prosistel_rot_set_position, .get_position = prosistel_rot_get_position, }; // Elevation rotator with Control box D using azimuth logic const struct rot_caps prosistel_d_el_cboxaz_rot_caps = { ROT_MODEL(ROT_MODEL_PROSISTEL_D_EL_CBOXAZ), .model_name = "D elevation CBOX az", .mfg_name = "Prosistel", .version = "20221215.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_ELEVATION, .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 = 0, .post_write_delay = 0, .timeout = 3000, .retry = 3, .min_az = 0.0, .max_az = 0.0, .min_el = 0.0, .max_el = 90.0, .priv = &prosistel_rot_el_cboxaz, .rot_open = prosistel_rot_open, .stop = prosistel_rot_stop, .set_position = prosistel_rot_set_position, .get_position = prosistel_rot_get_position, }; DECLARE_INITROT_BACKEND(prosistel) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&prosistel_d_az_rot_caps); rot_register(&prosistel_d_el_rot_caps); rot_register(&prosistel_combi_track_azel_rot_caps); rot_register(&prosistel_d_el_cboxaz_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/prosistel/Android.mk0000664000175000017500000000040015056640443014260 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := prosistel.c LOCAL_MODULE := prosistel LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/prosistel/Makefile.in0000664000175000017500000005244315056640453014433 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/prosistel ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_prosistel_la_LIBADD = am_libhamlib_prosistel_la_OBJECTS = prosistel.lo libhamlib_prosistel_la_OBJECTS = $(am_libhamlib_prosistel_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/prosistel.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_prosistel_la_SOURCES) DIST_SOURCES = $(libhamlib_prosistel_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-prosistel.la libhamlib_prosistel_la_SOURCES = prosistel.c prosistel.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/prosistel/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/prosistel/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-prosistel.la: $(libhamlib_prosistel_la_OBJECTS) $(libhamlib_prosistel_la_DEPENDENCIES) $(EXTRA_libhamlib_prosistel_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_prosistel_la_OBJECTS) $(libhamlib_prosistel_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prosistel.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/prosistel.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/prosistel.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/prosistel/prosistel.h0000664000175000017500000000226715056640443014561 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_PROSISTEL_H #define _ROT_PROSISTEL_H 1 #include "rotator.h" extern const struct rot_caps prosistel_d_az_rot_caps; extern const struct rot_caps prosistel_d_el_rot_caps; extern const struct rot_caps prosistel_combi_track_azel_rot_caps; extern const struct rot_caps prosistel_d_el_cboxaz_rot_caps; #endif /* _ROT_PROSISTEL_H */ hamlib-4.6.5/rotators/prosistel/Makefile.am0000664000175000017500000000017615056640443014415 noinst_LTLIBRARIES = libhamlib-prosistel.la libhamlib_prosistel_la_SOURCES = prosistel.c prosistel.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/easycomm/0000775000175000017500000000000015056640501012221 5hamlib-4.6.5/rotators/easycomm/easycomm.c0000664000175000017500000004132115056640443014130 /* * Hamlib Rotator backend - Easycom * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "misc.h" #include "easycomm.h" #define EASYCOMM3_LEVELS ROT_LEVEL_SPEED /* ************************************************************************* */ /** * easycomm_transaction * * Assumes rot!=NULL and cmdstr!=NULL * * cmdstr - string to send to rotator * data - buffer for reply string * data_len - (input) Maximum size of buffer * (output) Number of bytes read. */ static int easycomm_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; int retry = rot->caps->retry; rig_debug(RIG_DEBUG_TRACE, "%s called: %s\n", __func__, cmdstr); if (!rot) { return -RIG_EINVAL; } do { rig_flush(rotp); retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } if (data == NULL) { return RIG_OK; /* don't want a reply */ } retval = read_string(rotp, (unsigned char *) data, data_len, "\n", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_TRACE, "%s read_string failed with status %d:%s\n", __func__, retval, strerror(retval)); goto transaction_quit; } else { rig_debug(RIG_DEBUG_TRACE, "%s read_string: %s\n", __func__, data); retval = RIG_OK; } } while (--retry && retval != RIG_OK); transaction_quit: return retval; } /* ************************************************************************* */ static int easycomm_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[64]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); if (rot->caps->rot_model == ROT_MODEL_EASYCOMM1) { SNPRINTF(cmdstr, sizeof(cmdstr), "AZ%.1f EL%.1f UP000 XXX DN000 XXX\n", az, el); } else // for easycomm 2 & 3 and upwards { SNPRINTF(cmdstr, sizeof(cmdstr), "AZ%.1f EL%.1f\n", az, el); } retval = easycomm_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } /* TODO: Error processing */ return RIG_OK; } static int easycomm_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char cmdstr[16], ackbuf[32]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(cmdstr, sizeof(cmdstr), "AZ\n"); retval = easycomm_transaction(rot, cmdstr, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s got error: %d\n", __func__, retval); return retval; } /* Parse parse string to extract AZ values */ rig_debug(RIG_DEBUG_TRACE, "%s got response: %s\n", __func__, ackbuf); retval = sscanf(ackbuf, "AZ%f", az); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown response (%s)\n", __func__, ackbuf); return -RIG_ERJCTED; } SNPRINTF(cmdstr, sizeof(cmdstr), "EL\n"); retval = easycomm_transaction(rot, cmdstr, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s got error: %d\n", __func__, retval); return retval; } /* Parse parse string to extract EL values */ rig_debug(RIG_DEBUG_TRACE, "%s got response: %s\n", __func__, ackbuf); retval = sscanf(ackbuf, "EL%f", el); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown response (%s)\n", __func__, ackbuf); return -RIG_ERJCTED; } return RIG_OK; } static int easycomm_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = easycomm_transaction(rot, "SA SE \n", NULL, 0); if (retval != RIG_OK) { return retval; } /* TODO: error processing */ return RIG_OK; } static int easycomm_rot_reset(ROT *rot, rot_reset_t rst) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = easycomm_transaction(rot, "RESET\n", NULL, 0); if (retval != RIG_OK) /* Custom command (not in Easycomm) */ { return retval; } return RIG_OK; } static int easycomm_rot_park(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = easycomm_transaction(rot, "PARK\n", NULL, 0); if (retval != RIG_OK) /* Custom command (not in Easycomm) */ { return retval; } return RIG_OK; } static int easycomm_rot_move(ROT *rot, int direction, int speed) { char cmdstr[24]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* For EasyComm 1/2/3 */ switch (direction) { case ROT_MOVE_UP: /* Elevation increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "MU\n"); break; case ROT_MOVE_DOWN: /* Elevation decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "MD\n"); break; case ROT_MOVE_LEFT: /* Azimuth decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "ML\n"); break; case ROT_MOVE_RIGHT: /* Azimuth increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "MR\n"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid direction value! (%d)\n", __func__, direction); return -RIG_EINVAL; } retval = easycomm_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int easycomm_rot_move_velocity(ROT *rot, int direction, int speed) { struct rot_state *rs = ROTSTATE(rot); char cmdstr[24]; int retval; int easycomm_speed; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (speed == ROT_SPEED_NOCHANGE) { easycomm_speed = rs->current_speed; } else { if (speed < 1 || speed > 100) { rig_debug(RIG_DEBUG_ERR, "%s: Invalid speed value (1-100)! (%d)\n", __func__, speed); return -RIG_EINVAL; } easycomm_speed = ((speed - 1) * 100); rs->current_speed = easycomm_speed; } /* Speed for EasyComm 3 */ switch (direction) { case ROT_MOVE_UP: /* Elevation increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "VU%04d\n", easycomm_speed); break; case ROT_MOVE_DOWN: /* Elevation decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "VD%04d\n", easycomm_speed); break; case ROT_MOVE_LEFT: /* Azimuth decrease */ SNPRINTF(cmdstr, sizeof(cmdstr), "VL%04d\n", easycomm_speed); break; case ROT_MOVE_RIGHT: /* Azimuth increase */ SNPRINTF(cmdstr, sizeof(cmdstr), "VR%04d\n", easycomm_speed); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid direction value! (%d)\n", __func__, direction); return -RIG_EINVAL; } retval = easycomm_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int easycomm_rot_get_level(ROT *rot, setting_t level, value_t *val) { const struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: val->i = rs->current_speed; break; default: return -RIG_ENAVAIL; } return RIG_OK; } static int easycomm_rot_set_level(ROT *rot, setting_t level, value_t val) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: { int speed = val.i; if (speed < 0) { speed = 0; } else if (speed > 9999) { speed = 9999; } rs->current_speed = speed; break; } default: return -RIG_ENAVAIL; } return RIG_OK; } /* * Get Info * returns the model name string */ // cppcheck-suppress constParameterCallback static const char *easycomm_rot_get_info(ROT *rot) { const struct rot_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return (const char *) - RIG_EINVAL; } rc = rot->caps; return rc->model_name; } /* * Receive status / configuration / output * * For configuration registers, *val must contain string of register e.g. '0'-'f' */ static int easycomm_rot_get_conf(ROT *rot, hamlib_token_t token, char *val) { char cmdstr[16], ackbuf[32]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: token = %d", __func__, (int)token); if (!rot) { return -RIG_EINVAL; } switch (token) { case TOK_GET_STATUS: SNPRINTF(cmdstr, sizeof(cmdstr), "GS\n;"); break; case TOK_GET_ERRORS: SNPRINTF(cmdstr, sizeof(cmdstr), "GE\n;"); break; case TOK_GET_INPUT: SNPRINTF(cmdstr, sizeof(cmdstr), "IP\n;"); break; case TOK_GET_ANALOG_INPUT: SNPRINTF(cmdstr, sizeof(cmdstr), "AN\n;"); break; case TOK_GET_VERSION: SNPRINTF(cmdstr, sizeof(cmdstr), "VE\n;"); break; case TOK_GET_CONFIG: SNPRINTF(cmdstr, sizeof(cmdstr), "CR %c\n;", *val); break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s, *val = %c\n", __func__, cmdstr, *val); retval = easycomm_transaction(rot, cmdstr, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s got error: %d\n", __func__, retval); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s got response: %s\n", __func__, ackbuf); /* Return given string at correct position*/ memcpy(val, ackbuf + 2, sizeof(ackbuf) - 2); /* CCxxxxxx */ return RIG_OK; } /* * Set configuration * * For configuration registers, *val must contain char of register e.g. '0'-'f' followed by setting * e.g. x,yyyyy */ static int easycomm_rot_set_conf(ROT *rot, hamlib_token_t token, const char *val) { char cmdstr[16]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: token = %d", __func__, (int)token); if (!rot) { return -RIG_EINVAL; } switch (token) { case TOK_SET_CONFIG: SNPRINTF(cmdstr, sizeof(cmdstr), "CW%s\n;", val); break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s, *val = %c\n", __func__, cmdstr, *val); if (!ROTSTATE(rot)->comm_state) { return queue_deferred_config(&ROTSTATE(rot)->config_queue, token, val); } retval = easycomm_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s got error: %d\n", __func__, retval); return retval; } return RIG_OK; } static int easycomm_rot_init(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Set default speed to half of maximum rs->current_speed = 5000; return RIG_OK; } /* ************************************************************************* */ /* * Easycomm rotator capabilities. */ /** EasycommI implement essentially only the set position function, but * I included the stop command too. The radio control tags is only included * as dummy entries because the spec require them. */ const struct rot_caps easycomm1_rot_caps = { ROT_MODEL(ROT_MODEL_EASYCOMM1), .model_name = "EasycommI", .mfg_name = "Hamlib", .version = "20231219.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .priv = NULL, /* priv */ .set_position = easycomm_rot_set_position, .stop = easycomm_rot_stop, .get_info = easycomm_rot_get_info, }; /* EasycommII implement most of the functions. Again the radio tags * is only dummy values. */ const struct rot_caps easycomm2_rot_caps = { ROT_MODEL(ROT_MODEL_EASYCOMM2), .model_name = "EasycommII", .mfg_name = "Hamlib", .version = "20231218.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .priv = NULL, /* priv */ .rot_init = NULL, .rot_cleanup = NULL, .rot_open = NULL, .rot_close = NULL, .get_position = easycomm_rot_get_position, .set_position = easycomm_rot_set_position, .stop = easycomm_rot_stop, .park = easycomm_rot_park, .reset = easycomm_rot_reset, .move = easycomm_rot_move, .set_conf = easycomm_rot_set_conf, .get_conf = easycomm_rot_get_conf, .get_info = easycomm_rot_get_info, }; /* EasycommIII provides changes Moving functions and info. */ const struct rot_caps easycomm3_rot_caps = { ROT_MODEL(ROT_MODEL_EASYCOMM3), .model_name = "EasycommIII", .mfg_name = "Hamlib", .version = "2022312180", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .priv = NULL, /* priv */ .has_get_level = EASYCOMM3_LEVELS, .has_set_level = ROT_LEVEL_SET(EASYCOMM3_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 0 }, .max = { .i = 9999 }, .step = { .i = 1 } } }, .rot_init = easycomm_rot_init, .rot_cleanup = NULL, .rot_open = NULL, .rot_close = NULL, .get_position = easycomm_rot_get_position, .set_position = easycomm_rot_set_position, .stop = easycomm_rot_stop, .park = easycomm_rot_park, .reset = easycomm_rot_reset, .move = easycomm_rot_move_velocity, .get_level = easycomm_rot_get_level, .set_level = easycomm_rot_set_level, .set_conf = easycomm_rot_set_conf, .get_conf = easycomm_rot_get_conf, .get_info = easycomm_rot_get_info, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(easycomm) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&easycomm1_rot_caps); rot_register(&easycomm2_rot_caps); rot_register(&easycomm3_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/easycomm/easycomm.txt0000664000175000017500000000757115056640443014536 The following are the specifications for the EasyComm interfaces which are available with the WiSP programs. The EasyComm interfaces are for use by those who wish to design their own radio and rotor controllers. EASYCOMM I Standard ------------------- The EasyComm 1 standard is a simple ASCII character based standard for controlling antennas and rotators. The host PC issues a single line command as follows -: AZaaa.a ELeee.e UPuuuuuuuuu UUU DNddddddddd DDD The Az and El values (aaa.a and eee.e) are not fixed width. They are in degrees and include 1 decimal place. The Up and Dn frequencies are in Hz. UUU and DDD are the uplink and downlink mode. EASYCOMM II Standard -------------------- The EasyComm 2 standard is an enhanced protocol to allow full station control and also feedback from external systems. The host PC issues commands to the controller by sending a 2 character command identifier followed by the command value. Commands are separated by either a space or carriage return or linefeed. Not all commands need to be implemented, and the most basic system may only decode the rotator control commands. The Host PC can issue the following commands -: Command Meaning Parameters ------- ------- ---------- AZ Azimuth number - 1 decimal place [deg] EL Elevation number - 1 decimal place [deg] UP Uplink freq in Hertz DN Downlink freq in Hertz DM Downlink Mode ascii, eg SSB, FM UM Uplink Mode ascii, eg SSB, FM DR Downlink Radio number UR Uplink Radio number ML Move Left MR Move Right MU Move Up MD Move Down SA Stop azimuth moving SE Stop elevation moving AO AOS LO LOS OP Set output number IP Read an input number AN Read analogue input number ST Set time YY:MM:DD:HH:MM:SS VE Request Version For those commands that require a response, the response is an echo of the command followed by the response. If the command specifies a field number (eq. AN or IP), then the two numbers are delimited with a comma. eg. To read an analogue value, the host sends ANx where x is the analogue channel number. In response the controller will reply with ANx,yyy where yyy is the value read on the analogue port. eg. To find the controller version number, the host sends VE. In response the controller sends VExxx where xxx is an ascii string containing the version number. All strings sent in either direction are not of fixed length. The controller can also send unsolicited information back to the host. This information may be used by the host for alarms or just control feedback. All of the above commands may be sent by the controller for information, and in addition the following may also be sent ALxxx Alarm, where xxxx is an ascii string with the alarm info. Chris Jackson, G7UPN EASYCOMM III Standard -------------------- The EasyComm 3 standard is an extension of the version 2 with the additional features: Command Meaning Parameters Hamlib Config Token ------- ------- ---------- ------------------- VL Velocity Left number [mdeg/s] VR Velocity Right number [mdeg/s] VU Velocity Up number [mdeg/s] VD Velocity Down number [mdeg/s] CR Read config register [0-x] 1 CW Write config register [0-x] 2 GS Get status register 3 GE Get error register 4 VE Request Version 5 IP Read an input number 6 OP Set output number 7 AN Read analogue input number 8 >Several status and error bits can combined. Proposed mapping: Status Meaning ------- ------- 1 Idle 2 Moving 4 Pointing 8 Error Error Meaning ------- ------- 1 Sensor Error 2 Jam 4 Homing Error >Proposed mapping of configuration registers: Register Meaning Value ------- ------- ---------- 0 MaxSpeed number a Overshoot 0/1/- b Jamming 0/1/- c Endpoints 0/1/- d Unstick 0/1/- 73, Alexander Schultze hamlib-4.6.5/rotators/easycomm/Android.mk0000664000175000017500000000037515056640443014064 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := easycomm.c LOCAL_MODULE := easycomm LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/easycomm/Makefile.in0000664000175000017500000005243015056640453014220 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/easycomm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_easycomm_la_LIBADD = am_libhamlib_easycomm_la_OBJECTS = easycomm.lo libhamlib_easycomm_la_OBJECTS = $(am_libhamlib_easycomm_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/easycomm.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_easycomm_la_SOURCES) DIST_SOURCES = $(libhamlib_easycomm_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-easycomm.la libhamlib_easycomm_la_SOURCES = easycomm.c easycomm.h EXTRA_DIST = easycomm.txt Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/easycomm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/easycomm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-easycomm.la: $(libhamlib_easycomm_la_OBJECTS) $(libhamlib_easycomm_la_DEPENDENCIES) $(EXTRA_libhamlib_easycomm_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_easycomm_la_OBJECTS) $(libhamlib_easycomm_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/easycomm.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/easycomm.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/easycomm.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/easycomm/easycomm.h0000664000175000017500000000333415056640443014137 /* * Hamlib Rotator backend - Easycomm interface protocol * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_EASYCOMM_H #define _ROT_EASYCOMM_H 1 #include "rotator.h" #include "token.h" extern const struct rot_caps easycomm1_rot_caps; extern const struct rot_caps easycomm2_rot_caps; extern const struct rot_caps easycomm3_rot_caps; /* * Tokens used by rotorez_rot_set_conf and get_conf and the 'C' command in rotctl * and rotctld. */ #define TOK_GET_CONFIG TOKEN_BACKEND(1) #define TOK_SET_CONFIG TOKEN_BACKEND(2) #define TOK_GET_STATUS TOKEN_BACKEND(3) #define TOK_GET_ERRORS TOKEN_BACKEND(4) #define TOK_GET_VERSION TOKEN_BACKEND(5) #define TOK_GET_INPUT TOKEN_BACKEND(6) #define TOK_SET_OUTPUT TOKEN_BACKEND(7) #define TOK_GET_ANALOG_INPUT TOKEN_BACKEND(8) #endif /* _ROT_EASYCOMM_H */ hamlib-4.6.5/rotators/easycomm/Makefile.am0000664000175000017500000000021015056640443014173 noinst_LTLIBRARIES = libhamlib-easycomm.la libhamlib_easycomm_la_SOURCES = easycomm.c easycomm.h EXTRA_DIST = easycomm.txt Android.mk hamlib-4.6.5/rotators/sartek/0000775000175000017500000000000015056640502011676 5hamlib-4.6.5/rotators/sartek/Android.mk0000664000175000017500000000037215056640443013535 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := sartek.c LOCAL_MODULE := sartek LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/sartek/Makefile.in0000664000175000017500000005233315056640453013676 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/sartek ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_sartek_la_LIBADD = am_libhamlib_sartek_la_OBJECTS = sartek.lo libhamlib_sartek_la_OBJECTS = $(am_libhamlib_sartek_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/sartek.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_sartek_la_SOURCES) DIST_SOURCES = $(libhamlib_sartek_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-sartek.la libhamlib_sartek_la_SOURCES = sartek.c sartek.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/sartek/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/sartek/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-sartek.la: $(libhamlib_sartek_la_OBJECTS) $(libhamlib_sartek_la_DEPENDENCIES) $(EXTRA_libhamlib_sartek_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_sartek_la_OBJECTS) $(libhamlib_sartek_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sartek.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/sartek.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sartek.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/sartek/sartek.c0000664000175000017500000000714515056640443013266 /* * Hamlib backend library for the SARtek rotor command set. * * sartek.c - (C) Stephane Fillod 2003 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "sartek.h" /* ************************************* * * Separate model capabilities * * ************************************* */ /* * SARtek rotor capabilities * * Documentation from: * http://www.hosenose.com/sartek/ifcspecs.htm */ const struct rot_caps sartek_rot_caps = { ROT_MODEL(ROT_MODEL_SARTEK1), .model_name = "SARtek-1", .mfg_name = "SARtek", .version = "20061007.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .set_position = sartek_rot_set_position, .stop = sartek_rot_stop, }; /* ************************************ * * API functions * * ************************************ */ /* * Set position * SARtek protocol supports azimuth only--elevation is ignored * Range is converted to an integer string, 0 to 360 degrees */ static int sartek_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation) { char cmdstr[8]; int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (azimuth < 0 || azimuth > 360) { return -RIG_EINVAL; } if (azimuth < 2) { azimuth = 2; } else if (azimuth > 358) { azimuth = 358; } SNPRINTF(cmdstr, sizeof(cmdstr), "P%c", (int)((azimuth * 255) / 360)); err = write_block(ROTPORT(rot), (unsigned char *) cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Stop rotation */ static int sartek_rot_stop(ROT *rot) { int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); err = write_block(ROTPORT(rot), (unsigned char *) "P\0", 2); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Initialize backend */ DECLARE_INITROT_BACKEND(sartek) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&sartek_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/sartek/Makefile.am0000664000175000017500000000016315056640443013656 noinst_LTLIBRARIES = libhamlib-sartek.la libhamlib_sartek_la_SOURCES = sartek.c sartek.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/sartek/sartek.h0000664000175000017500000000230115056640443013260 /* * Hamlib backend library for the SARtek rotor command set. * * sartek.h - (C) Stephane Fillod 2003 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_SARTEK_H #define _ROT_SARTEK_H 1 #include "rotator.h" #define AZ_READ_LEN 4 extern const struct rot_caps sartek_rot_caps; /* * API local implementation * */ static int sartek_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation); static int sartek_rot_stop(ROT *rot); #endif /* _ROT_SARTEK_H */ hamlib-4.6.5/rotators/rotorez/0000775000175000017500000000000015056640502012111 5hamlib-4.6.5/rotators/rotorez/rotorez.h0000664000175000017500000000352215056640443013714 /* * Hamlib backend library for the DCU rotor command set. * * rotorez.h - (C) Nate Bargmann 2003,2009,2010 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to a Hy-Gain or Yaesu rotor using * the Idiom Press Rotor-EZ or RotorCard interface. It also * supports the Hy-Gain DCU-1. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_ROTOREZ_H #define _ROT_ROTOREZ_H 1 #include "rotator.h" #include "token.h" #define AZ_READ_LEN 4 #define RT21_AZ_LEN 6 extern const struct rot_caps rotorez_rot_caps; extern const struct rot_caps rotorcard_rot_caps; extern const struct rot_caps dcu_rot_caps; extern const struct rot_caps erc_rot_caps; extern const struct rot_caps rt21_rot_caps; extern const struct rot_caps yrc1_rot_caps; /* * Tokens used by rotorez_rot_set_conf and the 'C' command in rotctl * and rotctld followed by a value of '0' to disable a Rotor-EZ option * and '1' to enable it. */ #define TOK_ENDPT TOKEN_BACKEND(1) #define TOK_JAM TOKEN_BACKEND(2) #define TOK_OVRSHT TOKEN_BACKEND(3) #define TOK_UNSTICK TOKEN_BACKEND(4) #endif /* _ROT_ROTOREZ_H */ hamlib-4.6.5/rotators/rotorez/rotorez.c0000664000175000017500000007362115056640443013716 /* * Hamlib backend library for the DCU rotor command set. * * rotorez.c - (C) Nate Bargmann 2003,2009,2010 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to a Hy-Gain or Yaesu rotor using * the Idiom Press Rotor-EZ or RotorCard interface. It also * supports the Hy-Gain DCU-1, and DF9GR ERC. * * Rotor-EZ is a trademark of Idiom Press * Hy-Gain is a trademark of MFJ Enterprises * * Tested on a HAM-IV with the Rotor-EZ V1.4S interface installed. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include /* Standard library definitions */ #include /* String function definitions */ #include /* for isdigit function */ #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "iofunc.h" #include "misc.h" #include "rotorez.h" /* * API local implementation * */ static int rotorez_rot_init(ROT *rot); static int rotorez_rot_cleanup(ROT *rot); static int rotorez_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation); static int rotorez_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation); static int rotorez_park(ROT *rot); static int erc_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation); static int rt21_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation); static int rt21_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation); static int rotorez_rot_reset(ROT *rot, rot_reset_t reset); static int rotorez_rot_stop(ROT *rot); static int dcu1_rot_stop(ROT *rot); static int rotorez_rot_set_conf(ROT *rot, hamlib_token_t token, const char *val); static const char *rotorez_rot_get_info(ROT *rot); /* * Private data structure */ struct rotorez_rot_priv_data { azimuth_t az; }; /* * Private helper function prototypes */ static int rotorez_send_priv_cmd(ROT *rot, const char *cmd); static int rotorez_send_priv_cmd2(ROT *rot, const char *cmd); static int rotorez_flush_buffer(ROT *rot); /* * local configuration parameters */ static const struct confparams rotorez_cfg_params[] = { { TOK_ENDPT, "endpt", "Endpoint option", "Endpoint option", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_JAM, "jam", "Jam protection", "Jam protection", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_OVRSHT, "oversht", "Overshoot option", "Overshoot option", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_UNSTICK, "unstick", "Unstick option", "Unstick option", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /* ************************************* * * Separate model capabilities * * ************************************* */ /* * Idiom Press Rotor-EZ enhanced rotor capabilities for * Hy-Gain CD45, Ham-II, Ham-III, Ham IV and all TailTwister rotors */ const struct rot_caps rotorez_rot_caps = { ROT_MODEL(ROT_MODEL_ROTOREZ), .model_name = "Rotor-EZ", .mfg_name = "Idiom Press", .version = "20230328.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .cfgparams = rotorez_cfg_params, .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rotorez_rot_set_position, .get_position = rotorez_rot_get_position, .park = rotorez_park, .stop = rotorez_rot_stop, .set_conf = rotorez_rot_set_conf, .get_info = rotorez_rot_get_info, }; /* * Idiom Press RotorCard enhanced rotor capabilities for * Yaesu SDX and DXA series rotors */ const struct rot_caps rotorcard_rot_caps = { ROT_MODEL(ROT_MODEL_ROTORCARD), .model_name = "RotorCard", .mfg_name = "Idiom Press", .version = "20230328.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .cfgparams = rotorez_cfg_params, .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rotorez_rot_set_position, .get_position = rotorez_rot_get_position, .park = rotorez_park, .stop = rotorez_rot_stop, .set_conf = rotorez_rot_set_conf, .get_info = rotorez_rot_get_info, }; /* * Hy-Gain DCU-1/DCU-1X rotor capabilities */ const struct rot_caps dcu_rot_caps = { ROT_MODEL(ROT_MODEL_DCU), .model_name = "DCU-1/DCU-1X", .mfg_name = "Hy-Gain", .version = "20230328.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rotorez_rot_set_position, .stop = dcu1_rot_stop, .reset = rotorez_rot_reset, .get_info = rotorez_rot_get_info, }; /* * Rotor capabilities for DF9GR ERC * * TODO: Learn of additional capabilities of the ERC */ const struct rot_caps erc_rot_caps = { ROT_MODEL(ROT_MODEL_ERC), .model_name = "ERC", .mfg_name = "DF9GR", .version = "20230328.2", /* second revision on 23 Aug 2010 */ .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ // .cfgparams = rotorez_cfg_params, .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rotorez_rot_set_position, .get_position = erc_rot_get_position, .park = rotorez_park, .stop = dcu1_rot_stop, .reset = rotorez_rot_reset, // .stop = rotorez_rot_stop, // .set_conf = rotorez_rot_set_conf, .get_info = rotorez_rot_get_info, }; /* * Rotor capabilities for Hy-Gain YRC-1 compatible with DF9GR ERC * * TODO: Learn of additional capabilities of the ERC */ const struct rot_caps yrc1_rot_caps = { ROT_MODEL(ROT_MODEL_YRC1), .model_name = "DCU2/DCU3/YRC-1", .mfg_name = "Hy-Gain", .version = "20230328.2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ // .cfgparams = rotorez_cfg_params, .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rotorez_rot_set_position, .get_position = erc_rot_get_position, .park = rotorez_park, .stop = dcu1_rot_stop, .reset = rotorez_rot_reset, // .stop = rotorez_rot_stop, // .set_conf = rotorez_rot_set_conf, .get_info = rotorez_rot_get_info, }; const struct rot_caps rt21_rot_caps = { ROT_MODEL(ROT_MODEL_RT21), .model_name = "RT-21", .mfg_name = "Green Heron", .version = "20230507.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 500, .timeout = 1500, .retry = 2, .min_az = 0, .max_az = 359.9, .min_el = 0, .max_el = 90, .priv = NULL, /* priv */ // .cfgparams = rotorez_cfg_params, .rot_init = rotorez_rot_init, .rot_cleanup = rotorez_rot_cleanup, .set_position = rt21_rot_set_position, .get_position = rt21_rot_get_position, .park = rotorez_park, .stop = rotorez_rot_stop, // .set_conf = rotorez_rot_set_conf, // .get_info = rotorez_rot_get_info, }; /* ************************************ * * API functions * * ************************************ */ /* * Initialize data structures */ static int rotorez_rot_init(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } ROTSTATE(rot)->priv = (struct rotorez_rot_priv_data *) calloc(1, sizeof(struct rotorez_rot_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } ROTPORT(rot)->type.rig = RIG_PORT_SERIAL; ((struct rotorez_rot_priv_data *)ROTSTATE(rot)->priv)->az = 0; return RIG_OK; } /* * Clean up allocated memory structures */ static int rotorez_rot_cleanup(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (ROTSTATE(rot)->priv) { free(ROTSTATE(rot)->priv); } ROTSTATE(rot)->priv = NULL; return RIG_OK; } /* * Set position * DCU protocol supports azimuth only--elevation is ignored * Range is converted to an integer string, 0 to 360 degrees */ static int rotorez_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation) { char cmdstr[8]; const char execstr[5] = "AM1;"; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (azimuth < 0 || azimuth > 360) { return -RIG_EINVAL; } if (azimuth > 359.4999) /* DCU-1 compatibility */ { azimuth = 0; } SNPRINTF(cmdstr, sizeof(cmdstr), "AP1%03.0f;", azimuth); /* Target bearing */ err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } err = rotorez_send_priv_cmd(rot, execstr); /* Execute command */ if (err != RIG_OK) { return err; } return RIG_OK; } /* * RT-21 Set position. * * RT-21 has a custom command to set azimuth to a precision of 1/10 of a * degree--"AP1XXX.Y\r;". XXX must be zero padded. The '\r' causes the * command to be executed immediately (no need to send "AM1;"). */ static int rt21_rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation) { char cmdstr[16]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } if (azimuth < 0 || azimuth > 360) { return -RIG_EINVAL; } SNPRINTF(cmdstr, sizeof(cmdstr), "AP1%05.1f\r;", azimuth); /* Total field width of 5 chars */ err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } if (ROTPORT2(rot)->pathname[0] != 0) { SNPRINTF(cmdstr, sizeof(cmdstr), "AP1%05.1f\r;", elevation); /* Total field width of 5 chars */ err = rotorez_send_priv_cmd2(rot, cmdstr); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * Get position * Returns current azimuth position in whole degrees. * Range returned from Rotor-EZ is an integer, 0 to 359 degrees * Elevation is set to 0 */ static int rotorez_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation) { hamlib_port_t *rotp; hamlib_port_t *rotp2; const char cmdstr[5] = "AI1;"; char az[5]; /* read azimuth string */ char *p; azimuth_t tmp = 0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } rotp = ROTPORT(rot); rotp2 = ROTPORT2(rot); do { err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } err = read_block(rotp, (unsigned char *) az, AZ_READ_LEN); if (err != AZ_READ_LEN) { return -RIG_ETRUNC; } /* The azimuth string should be ';xxx' beginning at offset 0. If the * ';' is not there, it's likely the RotorEZ has received an invalid * command and the buffer needs to be flushed. See * rotorez_flush_buffer() definition below for a complete description. */ if (az[0] != ';') { err = rotorez_flush_buffer(rot); if (err == -RIG_EIO) { return err; } else { err = -RIG_EINVAL; } } else if (err == AZ_READ_LEN) { /* Check if remaining chars are digits if az[0] == ';' */ for (p = az + 1; p < az + 4; p++) if (isdigit((int)*p)) { continue; } else { err = -RIG_EINVAL; } } } while (err == -RIG_EINVAL); /* * Rotor-EZ returns a four octet string consisting of a ';' followed * by three octets containing the rotor's position in degrees. The * semi-colon is ignored when passing the string to atof(). */ az[4] = 0x00; /* NULL terminated string */ p = az + 1; /* advance past leading ';' */ tmp = (azimuth_t)atof(p); rig_debug(RIG_DEBUG_TRACE, "%s: \"%s\" after conversion = %.1f\n", __func__, p, tmp); if (tmp == 360) { tmp = 0; } else if (tmp < 0 || tmp > 359) { return -RIG_EINVAL; } *azimuth = tmp; if (strlen(rotp2->pathname) > 0) { do { err = rotorez_send_priv_cmd2(rot, cmdstr); if (err != RIG_OK) { return err; } //TODO: Should this be rotp or rotp2???? //err = read_block(&rs->rotport, (unsigned char *) az, AZ_READ_LEN); err = read_block(rotp2, (unsigned char *) az, AZ_READ_LEN); if (err != AZ_READ_LEN) { return -RIG_ETRUNC; } /* The elevation string should be ';xxx' beginning at offset 0. If the * ';' is not there, it's likely the RotorEZ has received an invalid * command and the buffer needs to be flushed. See * rotorez_flush_buffer() definition below for a complete description. */ if (az[0] != ';') { err = rotorez_flush_buffer(rot); if (err == -RIG_EIO) { return err; } else { err = -RIG_EINVAL; } } else if (err == AZ_READ_LEN) { /* Check if remaining chars are digits if az[0] == ';' */ for (p = az + 1; p < az + 4; p++) if (isdigit((int)*p)) { continue; } else { err = -RIG_EINVAL; } } } while (err == -RIG_EINVAL); sscanf(az, ";%f", elevation); } else { *elevation = 0; /* RotorEZ does not support elevation */ } rig_debug(RIG_DEBUG_TRACE, "%s: azimuth = %.1f deg; elevation = %.1f deg\n", __func__, *azimuth, *elevation); return RIG_OK; } /* * Get position for ERC * Returns current azimuth position in whole degrees. * Range returned from ERC is an integer, 0 to 359 degrees * Elevation is set to 0 */ static int erc_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation) { const char cmdstr[5] = "AI1;"; char az[5]; /* read azimuth string */ char *p; azimuth_t tmp = 0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } do { err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } err = read_block(ROTPORT(rot), (unsigned char *) az, AZ_READ_LEN); if (err != AZ_READ_LEN) { return -RIG_ETRUNC; } /* * The azimuth string returned by the ERC should be 'xxx;' * beginning at offset 0. A new version may implement the * Idiom PRess format, hence the test for ';xxx'. */ /* Check if remaining chars are digits if az[3] == ';' */ if (az[3] == ';') { for (p = az; p < az + 3; p++) if (isdigit((int)*p)) { continue; } else { err = -RIG_EINVAL; } } else if (az[0] == ';') { /* Check if remaining chars are digits if az[0] == ';' */ for (p = az + 1; p < az + 4; p++) if (isdigit((int)*p)) { continue; } else { err = -RIG_EINVAL; } } } while (err == -RIG_EINVAL); /* * Old ERC returns a four octet string consisting of three octets * followed by ';' ('xxx;') containing the rotor's position in degrees. * A new version will implement Idiom Press format of ';xxx'. * * We test for either case and pass a string of only digits to atof() */ az[4] = 0x00; /* NULL terminated string */ p = az; if (*p == ';') { p++; } else { az[3] = 0x00; /* truncate trailing ';' */ } tmp = (azimuth_t)atof(p); rig_debug(RIG_DEBUG_TRACE, "%s: \"%s\" after conversion = %.1f\n", __func__, p, tmp); if (tmp == 360) { tmp = 0; } else if (tmp < 0 || tmp > 359) { return -RIG_EINVAL; } *azimuth = tmp; *elevation = 0; /* ERC does not support elevation */ rig_debug(RIG_DEBUG_TRACE, "%s: azimuth = %.1f deg; elevation = %.1f deg\n", __func__, *azimuth, *elevation); return RIG_OK; } /* * Get position from Green Heron RT-21 series of controllers Returns * current azimuth position in degrees and tenths. Range returned from * RT-21 is a float, 0.0 to 359.9 degrees Elevation is set to 0 */ static int rt21_rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation) { hamlib_port_t *rotp; hamlib_port_t *rotp2; char az[8]; /* read azimuth string */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } rotp = ROTPORT(rot); rotp2 = ROTPORT2(rot); /* 'BI1' is an RT-21 specific command that queries for a floating * point position (to the tenth of a degree). */ err = rotorez_send_priv_cmd(rot, "BI1;"); if (err != RIG_OK) { return err; } err = read_string(rotp, (unsigned char *) az, RT21_AZ_LEN + 1, ";", strlen(";"), 0, 1); if (err < 0) /* read_string returns negative on error. */ { return err; } /* RT-21 returns a five to six octet string consisting of one to * three octets containing the rotor's position in degrees, one * octet containing a decimal '.', one octet containing the rotor's * position in tenths of a degree, and one octet with the * terminating ';' with a leading space as padding--'[xx| ]x.y;'. * Seems as though at least five characters are returned and a * space is used as a leading pad character if needed. */ if ((isdigit((int)az[0])) || (isspace((int)az[0]))) { azimuth_t tmp = strtof(az, NULL); rig_debug(RIG_DEBUG_TRACE, "%s: \"%s\" after conversion = %.1f\n", __func__, az, tmp); if (tmp == 360.0) { tmp = 0; } else if (tmp < 0.0 || tmp > 359.9) { return -RIG_EINVAL; } *azimuth = tmp; if (rotp2 && strlen(rotp2->pathname) > 0) { err = rotorez_send_priv_cmd2(rot, "BI1;"); if (err != RIG_OK) { return err; } err = read_string(rotp2, (unsigned char *) az, RT21_AZ_LEN + 1, ";", strlen(";"), 0, 1); if (err < 0) /* read_string returns negative on error. */ { return err; } sscanf(az, "%f", elevation); } else { *elevation = 0.0; /* RT-21 backend does not support el at this time. */ } rig_debug(RIG_DEBUG_TRACE, "%s: azimuth = %.1f deg; elevation = %.1f deg\n", __func__, *azimuth, *elevation); } else { return -RIG_EINVAL; } return RIG_OK; } /* * Stop rotation on RotorEZ, reset on DCU-1 * * Sending the ";" string will stop rotation on the RotorEZ and reset the DCU-1 */ static int rotorez_rot_stop(ROT *rot) { const char cmdstr[2] = ";"; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } return RIG_OK; } static int rotorez_rot_reset(ROT *rot, rot_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return rotorez_rot_stop(rot); } /* * Stop rotation on DCU-1 */ static int dcu1_rot_stop(ROT *rot) { const char cmdstr[5] = "AS1;"; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Send configuration character * * Rotor-EZ interface will act on these commands immediately -- * no other command or command terminator is needed. Expects token * define in rotorez.h and *val of '1' or '0' (enable/disable). */ static int rotorez_rot_set_conf(ROT *rot, hamlib_token_t token, const char *val) { char cmdstr[2]; char c; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: token = %d, *val = %c\n", __func__, (int)token, *val); if (!rot) { return -RIG_EINVAL; } if (*val < '0' || *val > '1') { return -RIG_EINVAL; } switch (token) { case TOK_ENDPT: /* Endpoint option */ if (*val == '1') { c = 'E'; } else { c = 'e'; } break; case TOK_JAM: /* Jam protection */ if (*val == '1') { c = 'J'; } else { c = 'j'; } break; case TOK_OVRSHT: /* Overshoot option */ if (*val == '1') { c = 'O'; } else { c = 'o'; } break; case TOK_UNSTICK: /* Unstick option */ if (*val == '1') { c = 'S'; } else { c = 's'; } break; default: return -RIG_EINVAL; } SNPRINTF(cmdstr, sizeof(cmdstr), "%c", c); rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s, *val = %c\n", __func__, cmdstr, *val); /* * We cannot send anything to the rotator if it isn't open yet. * Queue any set_conf commands and let rot_open reprocess them * after it has done it's job. */ if (!ROTSTATE(rot)->comm_state) { err = queue_deferred_config(&ROTSTATE(rot)->config_queue, token, val); return err; } err = rotorez_send_priv_cmd(rot, cmdstr); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Get Info * returns the model name string */ static const char *rotorez_rot_get_info(ROT *rot) { const struct rot_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return (const char *) - RIG_EINVAL; } rc = rot->caps; return rc->model_name; } /* * Send command string to rotor */ static int rotorez_send_priv_cmd(ROT *rot, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = write_block(ROTPORT(rot), (unsigned char *) cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } // send command to 2nd rotator port static int rotorez_send_priv_cmd2(ROT *rot, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } err = write_block(ROTPORT2(rot), (unsigned char *) cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Flush the serial input buffer * * If the RotorEZ should receive an invalid command, such as an the ';' * character while the rotor is not in motion, as sent by the rotorez_rot_stop * function or the 'S' command from 'rotctl', it will output the following * string, "C2000 IDIOM V1.4S " into the input buffer. This function flushes * the buffer by reading it until a timeout occurs. Once the timeout occurs, * this function returns and the buffer is presumed to be empty. */ static int rotorez_flush_buffer(ROT *rot) { char garbage[32]; /* read buffer */ int err = 0; size_t MAX = 31; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot) { return -RIG_EINVAL; } do { err = read_block(ROTPORT(rot), (unsigned char *) garbage, MAX); /* Oops! An IO error was encountered. Bail out! */ if (err == -RIG_EIO) { return -RIG_EIO; } } while (err != -RIG_ETIMEOUT); return RIG_OK; } /* * Moves to Home Position */ static int rotorez_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume home is 0,0 */ rotorez_rot_set_position(rot, 0, 0); return RIG_OK; } /* * Initialize backend */ DECLARE_INITROT_BACKEND(rotorez) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&rotorez_rot_caps); rot_register(&rotorcard_rot_caps); rot_register(&dcu_rot_caps); rot_register(&erc_rot_caps); rot_register(&rt21_rot_caps); rot_register(&yrc1_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/rotorez/Android.mk0000664000175000017500000000037415056640443013752 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := rotorez.c LOCAL_MODULE := rotorez LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/rotorez/rotorez.txt0000664000175000017500000001240215056640443014301 January 17, 2009: As of version 0.5 of the rotorez backend, the serial timeout has been shortened to 1500 mS and the retry count reduced to 2 to speed up recovery when flushing the buffer as described below. Also, four tokens have been defined in rotorez.h for the set_conf function used by 'rotctl' and 'rotctld'. They are: ENDPT, JAM, OVRSHT, UNSTICK and have the integer values of 1-4 respectively. Until tokens are more completely developed in the Hamlib frontend, passing the integers to 'rotcrl' and 'rotctld' will be necessary. The 'value' given to 'rotclt' and 'rotctld' is the character '0' or '1' to disable or enable the function. For example, to disable Endpoint Protection give the command 'C 1 0' and to enable it again use 'C 1 1'. ----- Further testing has revealed that the RotorEZ interface will place undocumented characters into the serial buffer. Additions to the rotorez backend now take this into account and test for a valid azimuth reply and flush the buffer if necessary. When the unit is first powered on, it appears as though at least one character is placed into the buffer. I have seen this as 0xE0 although it is possible some other character could be placed there. If the RotorEZ should receive an invalid command, such as an the ';' character while the rotor is not in motion, as sent by the rotorez_rot_stop function ('S' command from 'rotctl'), it will output the following string, "C2000 IDIOM V1.4S " into the input buffer. A new function, rotorez_flush_buffer, flushes the buffer by reading it until a timeout occurs. Once the timeout occurs, this function returns and the buffer is presumed to be empty. Should read_block return an IO error, it is passed back to the application. Flushing the buffer is done by reading the buffer until the read_block function times out. By necessity, this means that the delay could be up to a few seconds before the rotorez_rot_get_position function returns a valid azimuth. ======================================================================= January 12, 2003: The following email describes the command set used by the Rotor-EZ interface for Hy-Gain rotors and the RotorCard interface for Yaesu rotors manufactured and sold by Idiom Press, http://www.idiompres.com The Hy-Gain DCU-1/DCU-1X Digital Control Unit supports a subset of these commands--AP1XXX; and AM1; The DCU-1/DCU-1X is manufactured and sold by Hy-Gain, http://www.hy-gain.com From: "sales@idiompress.com" To: "Nate Bargmann" Subject: Re: Rotor Card and Rotor-EZ command reference Date: Fri, 10 Jan 2003 09:38:52 -0800 Here you go: Important note: The program you are using must insert leading zeros into bearing commands, such as "009" degrees, instead of "9" degrees. Most programs are already configured this way, but some are not in their default mode, and in such cases you must change the default setting or the RS-232 portion of Rotor-EZ will not work properly. Rotor-EZ can also be commanded from any terminal having RS232 output, using the following configuration: 4800 baud, 8,N,1 Note that upper case/lower case must be used as listed for the commands below to work: "AP1xxx" sets target bearing to "xxx" degrees where xxx are three digits between 000 and 360, and executes. A typical command to rotate to 080 degrees would be AP1080 Note that the is often labeled on many keyboards. "AP1xxx;" sets the target bearing but does not execute. "AM1;" executes rotation to the bearing set by the "AP1xxx;" command "AI1;" inquires current bearing; and responds with (000-359) degrees ";" terminates rotation "E" enable endpoint option - effective immediately "e" disable endpoint option - effective immediately "O" enable overshoot option - effective immediately "o" disable overshoot option - effective immediately "S" enable unstick option - effective immediately "s" disable unstick option - effective immediately "V" reports version number "J" enable jam protection - effective immediately "j" disable jam protection - effective immediately - NOT recommended! Note that during any rotation initiated by an RS232 command, the rotation can be halted and further rotation cancelled by a momentary press of the Brake paddle. Also, an RS232 operation can be overridden by using the pointing control during rotation; when the control is moved rotation will cease and the control will wait for a new command after the five second brake delay is completed. 73 ----- Original Message ----- From: Nate Bargmann To: Sent: Friday, January 10, 2003 8:23 AM Subject: Rotor Card and Rotor-EZ command reference > Hi! > > I am working with a software project called Hamlib > http://hamlib.sourceforge.net and I would like to add support for the > Rotor Card and Rotor-EZ into our library. In the course of several Web > searches I have downloaded the Hy-Gain DCU-1 manual from their site and > I've also visited the Digital Audio Rotor-EZ troubleshooting site. > Between the two I have found a couple of discrepancies in the command > set. If possible, I would like a copy of the complete command set and > their syntax for these two boards for our project. > > Thanks! > > 73, de Nate >> > hamlib-4.6.5/rotators/rotorez/Makefile.in0000664000175000017500000005241615056640453014113 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/rotorez ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_rotorez_la_LIBADD = am_libhamlib_rotorez_la_OBJECTS = rotorez.lo libhamlib_rotorez_la_OBJECTS = $(am_libhamlib_rotorez_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/rotorez.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_rotorez_la_SOURCES) DIST_SOURCES = $(libhamlib_rotorez_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-rotorez.la libhamlib_rotorez_la_SOURCES = rotorez.c rotorez.h EXTRA_DIST = README.rotorez rotorez.txt Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/rotorez/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/rotorez/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-rotorez.la: $(libhamlib_rotorez_la_OBJECTS) $(libhamlib_rotorez_la_DEPENDENCIES) $(EXTRA_libhamlib_rotorez_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_rotorez_la_OBJECTS) $(libhamlib_rotorez_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotorez.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/rotorez.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/rotorez.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/rotorez/README.rotorez0000664000175000017500000000310515056640443014417 Quirks, known bugs, and other notes. ==================================== In this document I'll try to describe the behavior of the Idiom Press Rotor-EZ and RotorCard interfaces as well as the HyGain DCU-1/DCU-1X control units with Hamlib. For background information see rotorez/rotorez.txt. The Idiom Press interfaces are the most capable of the units supported by this backend and all available commands are supported by these units at this time. The HyGain control units only support a subset of the command set involving rotor positioning. This document is organized by Hamlib function calls and documents observed behavior with each call. rot_set_position * Fractional values passed for azimuth are dropped. i.e. 180.6 becomes 180 while a value greater than 359.4999 is converted to 0 for DCU1/ DCU-1X compatibility. * Allowed range for azimuth is 0 to 360. * Values passed for elevation are ignored. The protocol only supports azimuthal positioning rot_get_position * Position reading is returned in whole degrees from 0 to 359. * Not supported by DCU-1/DCU-1X. rotorez_rot_stop * Causes immediate cessation of rotor positioning. * Not supported by DCU-1/DCU-1X. rot_set_conf * Accepts one of E, e, J, j, O, o, S, and s (see rotorez/rotorez.txt) in *val. * The value in token is not used by the backend and may be safely set to TOK_BACKEND_NONE. * Not supported by DCU-1/DCU-1X. BUGS Please report all bugs to Nate Bargmann n0nb at arrl.net hamlib-4.6.5/rotators/rotorez/Makefile.am0000664000175000017500000000022215056640443014065 noinst_LTLIBRARIES = libhamlib-rotorez.la libhamlib_rotorez_la_SOURCES = rotorez.c rotorez.h EXTRA_DIST = README.rotorez rotorez.txt Android.mk hamlib-4.6.5/rotators/radant/0000775000175000017500000000000015056640502011656 5hamlib-4.6.5/rotators/radant/radant.txt0000664000175000017500000000133215056640443013613 Standard protocol for both El and Az axes. Working with russian Radant version 1.0 - 1.4: Радант AZV-1 Serial port mode 9600 8N1. ------------ Main commands ----------------- means carriage return - Set desired angle: "Qaaa.a eee.e", where aaa.a - azimuth angle value with floating point, eee.e - elevation angle with floating point. - After receiving command 'Q' rotator will send message "ACK" if rotator received correct command, or "ERR", if there were any mistakes. - After reaching destination angle rotator will send "OKaaa.a[.]eee.e" - Request current axes angle command: "Y" without parameters - Rotator will reply: "OKaaa.a[.]eee.e" Command for stop positioning: "S" hamlib-4.6.5/rotators/radant/Makefile.in0000664000175000017500000005233315056640453013656 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/radant ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_radant_la_LIBADD = am_libhamlib_radant_la_OBJECTS = radant.lo libhamlib_radant_la_OBJECTS = $(am_libhamlib_radant_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/radant.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_radant_la_SOURCES) DIST_SOURCES = $(libhamlib_radant_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-radant.la libhamlib_radant_la_SOURCES = radant.c radant.h EXTRA_DIST = radant.txt all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/radant/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/radant/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-radant.la: $(libhamlib_radant_la_OBJECTS) $(libhamlib_radant_la_DEPENDENCIES) $(EXTRA_libhamlib_radant_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_radant_la_OBJECTS) $(libhamlib_radant_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radant.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/radant.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/radant.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/radant/radant.h0000664000175000017500000000313415056640443013225 /* * Hamlib Rotator backend - Easycomm interface protocol * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_RADANT_H #define _ROT_RADANT_H 1 #include "token.h" extern const struct rot_caps radant_rot_caps; /* * Tokens used by rotorez_rot_set_conf and get_conf and the 'C' command in rotctl * and rotctld. */ #define TOK_GET_CONFIG TOKEN_BACKEND(1) #define TOK_SET_CONFIG TOKEN_BACKEND(2) #define TOK_GET_STATUS TOKEN_BACKEND(3) #define TOK_GET_ERRORS TOKEN_BACKEND(4) #define TOK_GET_VERSION TOKEN_BACKEND(5) #define TOK_GET_INPUT TOKEN_BACKEND(6) #define TOK_SET_OUTPUT TOKEN_BACKEND(7) #define TOK_GET_ANALOG_INPUT TOKEN_BACKEND(8) #endif /* _ROT_RADANT_H */ hamlib-4.6.5/rotators/radant/radant.c0000664000175000017500000001257415056640443013230 /* * Hamlib Rotator backend - Radant * Copyright (c) 2001-2003 by Stephane Fillod * Contributed by Francois Retief * Copyright (c) 2014 by Alexander Schultze * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "serial.h" #include "misc.h" #include "register.h" #include "idx_builtin.h" #include "radant.h" //#define EASYCOMM3_LEVELS ROT_LEVEL_SPEED /* ************************************************************************* */ /** * radant_transaction * * Assumes rot!=NULL and cmdstr!=NULL * * cmdstr - string to send to rotator * data - buffer for reply string * data_len - (input) Maximum size of buffer * (output) Number of bytes read. */ static int radant_transaction(ROT *rot, const char *cmdstr, char *data, size_t data_len) { hamlib_port_t *rotp = ROTPORT(rot); int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %s\n", __func__, cmdstr); if (!rot) { return -RIG_EINVAL; } rig_flush(rotp); retval = write_block(rotp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } if (data == NULL) { return RIG_OK; /* don't want a reply */ } retval = read_string(rotp, (unsigned char *) data, data_len, "\n", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_TRACE, "%s read_string failed with status %d\n", __func__, retval); goto transaction_quit; } else { rig_debug(RIG_DEBUG_TRACE, "%s read_string: %s\n", __func__, data); retval = RIG_OK; } transaction_quit: return retval; } /* ************************************************************************* */ static int radant_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdstr[32]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); SNPRINTF(cmdstr, sizeof(cmdstr), "Q%.1f %1.f\r", az, el); retval = radant_transaction(rot, cmdstr, NULL, 0); if (retval != RIG_OK) { return retval; } /* TODO: Error processing */ return RIG_OK; } static int radant_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { char cmdstr[4], ackbuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(cmdstr, sizeof(cmdstr), "Y\r"); retval = radant_transaction(rot, cmdstr, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s got error: %d\n", __func__, retval); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s got response: %s\n", __func__, ackbuf); retval = sscanf(ackbuf, "OK%f %f\r", az, el); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: unknown response (%s)\n", __func__, ackbuf); return -RIG_ERJCTED; } return RIG_OK; } static int radant_rot_stop(ROT *rot) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = radant_transaction(rot, "S\r", NULL, 0); if (retval != RIG_OK) { return retval; } /* TODO: error processing */ return RIG_OK; } /* ************************************************************************* */ /* * Radant rotator capabilities. */ /** Radant implement set and get position function and stop, but * there is no velocity and other configurations functions */ const struct rot_caps radant_rot_caps = { ROT_MODEL(ROT_MODEL_RADANT), .model_name = "AZ-1/AZV-1", .mfg_name = "Radant", .version = "20210508.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .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 = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0.0, .max_az = 360.0, .min_el = 0.0, .max_el = 180.0, .priv = NULL, /* priv */ .set_position = radant_rot_set_position, .get_position = radant_rot_get_position, .stop = radant_rot_stop, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(radant) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&radant_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/radant/Makefile.am0000664000175000017500000000016315056640443013636 noinst_LTLIBRARIES = libhamlib-radant.la libhamlib_radant_la_SOURCES = radant.c radant.h EXTRA_DIST = radant.txt hamlib-4.6.5/rotators/ether6/0000775000175000017500000000000015056640501011601 5hamlib-4.6.5/rotators/ether6/ether6.txt0000664000175000017500000000046715056640443013473 jro@sunny:~ $ socat stdio tcp4:etherrape:2701 rotor status cw az=-87 el=88 v=50 ad0=370 rotor cw rotor ccw rotor stop rotor park rotor state -180/180 0/90 .... all commands rotor move rotor status rotor state rotor cw rotor ccw rotor stop rotor park rotor setparkpos rotor calibrate rotor get calibrate hamlib-4.6.5/rotators/ether6/ether6.h0000664000175000017500000000211715056640443013075 /* * Hamlib Ether6 backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * Copyright (c) 2013 by Jonny Röker * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_ETHER6_H #define _ROT_ETHER6_H 1 #include "rotator.h" #define ROTORCTL_RET "OK" extern const struct rot_caps ether6_rot_caps; #endif /* _ROT_ETHER6_H */ hamlib-4.6.5/rotators/ether6/Android.mk0000664000175000017500000000037215056640443013441 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ether6.c LOCAL_MODULE := ether6 LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/ether6/Makefile.in0000664000175000017500000005236415056640453013606 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/ether6 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_ether6_la_LIBADD = am_libhamlib_ether6_la_OBJECTS = ether6.lo libhamlib_ether6_la_OBJECTS = $(am_libhamlib_ether6_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ether6.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_ether6_la_SOURCES) DIST_SOURCES = $(libhamlib_ether6_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-ether6.la libhamlib_ether6_la_SOURCES = ether6.c ether6.h EXTRA_DIST = README.ether6 ether6.txt Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/ether6/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/ether6/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-ether6.la: $(libhamlib_ether6_la_OBJECTS) $(libhamlib_ether6_la_DEPENDENCIES) $(EXTRA_libhamlib_ether6_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_ether6_la_OBJECTS) $(libhamlib_ether6_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ether6.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ether6.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ether6.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/ether6/README.ether60000664000175000017500000000231315056640443013601 Quirks, known bugs, and other notes. ==================================== In this document I will try to describe the operation of the rotor Ethersex interfaces. The project Ethersex (www.ethersex.de) provides a simple linking against its own projects. The software runs on Atmel AVR processors. The rotor control I realized for the following AVR boards: * etherrape http://www.lochraster.org/etherrape/ and * AVR-NET-IO http://www.pollin.de/shop/dt/MTQ5OTgxOTk-/Bausaetze_Module/Bausaetze/Bausatz_AVR_NET_IO.html The functioning of the etersex rotor control is easy. A voltage of 0 - 5 V indicates the direction of rotation. One output for CW, CCW and, if necessary, the brake control. When creating the software (Ethersex) can be adjusted by a more detailed configuration menu. The controller supports only a subset of the command set of rotor position. * set position * get position * park * stop * move (turn cw or ccw) A detailed description of the software can be found at Ethersex: http://www.ethersex.de/index.php/Rotor_(Deutsch) An example of the direct control via the command found in the File ether6.txt Does anyone have any suggestions or comments send an e mail to dg9oaa@darc.de hamlib-4.6.5/rotators/ether6/ether6.c0000664000175000017500000002262415056640443013075 /* * Hamlib Ether6 backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * Copyright (c) 2013 by Jonny Röker * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "ether6.h" #define CMD_MAX 32 #define BUF_MAX 64 #define ETHER_LEVELS ROT_LEVEL_SPEED /* * Helper function with protocol return code parsing */ static int ether_transaction(ROT *rot, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rotp = ROTPORT(rot); ret = write_block(rotp, (unsigned char *) cmd, len); rig_debug(RIG_DEBUG_VERBOSE, "function %s(1): ret=%d || send=%s\n", __func__, ret, cmd); if (ret != RIG_OK) { return ret; } ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "function %s(2): ret=%d || receive=%s\n", __func__, ret, buf); if (ret < 0) { return ret; } if (!memcmp(buf, ROTORCTL_RET, strlen(ROTORCTL_RET))) { rig_debug(RIG_DEBUG_VERBOSE, "function %s(2a): receive=%s\n", __func__, buf); return RIG_OK; } if (!memcmp(buf, NETROTCTL_RET, strlen(NETROTCTL_RET))) { int rv = atoi(buf + strlen(NETROTCTL_RET)); rig_debug(RIG_DEBUG_VERBOSE, "function %s(2): ret=%d || receive=%d\n", __func__, ret, rv); return atoi(buf + strlen(NETROTCTL_RET)); } return ret; } static int ether_rot_open(ROT *rot) { int ret; int sval; float min_az, max_az, min_el, max_el; struct rot_state *rs = ROTSTATE(rot); char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* elevation not need */ SNPRINTF(cmd, sizeof(cmd), "rotor state\n"); /*-180/180 0/90*/ ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } sval = sscanf(buf, "%f/%f %f/%f", &min_az, &max_az, &min_el, &max_el); rs->min_az = min_az; rs->max_az = max_az; rs->min_el = min_el; rs->max_el = max_el; rig_debug(RIG_DEBUG_VERBOSE, "ret(%d)%f/%f %f/%f\n", sval, rs->min_az, rs->max_az, rs->min_el, rs->max_el); return RIG_OK; } static int ether_rot_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(ROTPORT(rot), (unsigned char *) "\n", 1); return RIG_OK; } static int ether_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %f %f\n", __func__, az, el); SNPRINTF(cmd, sizeof(cmd), "rotor move %d %d\n", (int)az, (int)el); ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int ether_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { int ret, sval, speed, adv; char cmd[CMD_MAX]; char buf[BUF_MAX]; char mv[5]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "rotor status\n"); ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } // example "hold,az=87,el=0,v=8,ad0=346" sval = sscanf(buf, "%4s az=%f el=%f v=%d ad0=%d", mv, az, el, &speed, &adv); rig_debug(RIG_DEBUG_VERBOSE, "az=%f el=%f mv=%s ad(az)=%d\n", *az, *el, mv, adv); if (sval == 5) { return RIG_OK; } else { return -RIG_EPROTO; } } /** * stop the rotor */ static int ether_rot_stop(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "rotor stop\n"); ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } /** * park the rotor */ static int ether_rot_park(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "rotor park\n"); ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int ether_rot_reset(ROT *rot, rot_reset_t reset) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "reset\n"); ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } /** * call rotor cw or rotor ccw * if direction value 0 turn cw and if direction value 1 turn ccw */ static int ether_rot_move(ROT *rot, int direction, int speed) { struct rot_state *rs = ROTSTATE(rot); int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; int ether_speed; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (speed == ROT_SPEED_NOCHANGE) { ether_speed = rs->current_speed; } else { if (speed < 1 || speed > 100) { rig_debug(RIG_DEBUG_ERR, "%s: Invalid speed value (1-100)! (%d)\n", __func__, speed); return -RIG_EINVAL; } rs->current_speed = speed; ether_speed = speed; } if (direction == 0) { SNPRINTF(cmd, sizeof(cmd), "rotor cw %d\n", ether_speed); } else { SNPRINTF(cmd, sizeof(cmd), "rotor ccw %d\n", ether_speed); } ret = ether_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int ether_rot_get_level(ROT *rot, setting_t level, value_t *val) { const struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: val->i = rs->current_speed; break; default: return -RIG_ENAVAIL; } return RIG_OK; } static int ether_rot_set_level(ROT *rot, setting_t level, value_t val) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); switch (level) { case ROT_LEVEL_SPEED: { int speed = val.i; if (speed < 1) { speed = 1; } else if (speed > 100) { speed = 100; } rs->current_speed = speed; break; } default: return -RIG_ENAVAIL; } return RIG_OK; } static const char *ether_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "ip rotator via ethersex"; } static int ether_rot_init(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Set default speed to half of maximum rs->current_speed = 00; return RIG_OK; } /* * Dummy rotator capabilities. */ const struct rot_caps ether6_rot_caps = { ROT_MODEL(ROT_MODEL_ETHER6), .model_name = "Ether6 (via ethernet)", .mfg_name = "DG9OAA", .version = "20220109.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_FLAG_AZIMUTH, .port_type = RIG_PORT_NETWORK, .timeout = 5000, .retry = 3, .min_az = 0., .max_az = 360, .min_el = 0, .max_el = 90, .priv = NULL, /* priv */ .has_get_level = ETHER_LEVELS, .has_set_level = ROT_LEVEL_SET(ETHER_LEVELS), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 0 }, .max = { .i = 9999 }, .step = { .i = 1 } } }, .rot_init = ether_rot_init, .rot_cleanup = NULL, .rot_open = ether_rot_open, .rot_close = ether_rot_close, .set_position = ether_rot_set_position, .get_position = ether_rot_get_position, .park = ether_rot_park, .stop = ether_rot_stop, .reset = ether_rot_reset, .move = ether_rot_move, .get_level = ether_rot_get_level, .set_level = ether_rot_set_level, .get_info = ether_rot_get_info, }; DECLARE_INITROT_BACKEND(ether6) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(ðer6_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/ether6/Makefile.am0000664000175000017500000000021415056640443013557 noinst_LTLIBRARIES = libhamlib-ether6.la libhamlib_ether6_la_SOURCES = ether6.c ether6.h EXTRA_DIST = README.ether6 ether6.txt Android.mk hamlib-4.6.5/rotators/indi/0000775000175000017500000000000015056640475011341 5hamlib-4.6.5/rotators/indi/indi_wrapper.cpp0000664000175000017500000003726115056640443014454 /* * Hamlib Rotator backend - INDI integration * Copyright (c) 2020 by Norbert Varga HA2NON * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "indi_wrapper.hpp" #include #include #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) static std::unique_ptr indi_wrapper_client(new RotINDIClient()); int RotINDIClient::setSpeed(int speedPercent) { if (!mTelescope || !mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_SLEW_RATE"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_SLEW_RATE switch\n"); return -RIG_EPROTO; } if (speedPercent < 0) { speedPercent = 0; } if (speedPercent > 100) { speedPercent = 100; } unsigned int speed = DIV_ROUND_UP(speedPercent, 10); for (unsigned int i = 1; i <= 10; i++) { char switchName[4]; snprintf(switchName, sizeof(switchName), "%ux", i); ISwitch *slewrate = IUFindSwitch(switchVector, switchName); if (slewrate) { if (speed == i) { rig_debug(RIG_DEBUG_VERBOSE, "indi: setting speed %s\n", switchName); slewrate->s = ISS_ON; } else { slewrate->s = ISS_OFF; } } else { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member %s\n", switchName); return -RIG_EPROTO; } } sendNewSwitch(switchVector); return RIG_OK; } int RotINDIClient::move(int direction, int speedPercent) { if (!mTelescope || !mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } int err = setSpeed(speedPercent); if (err != RIG_OK) { return err; } ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_MOTION_NS"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_MOTION_NS switch\n"); return -RIG_EPROTO; } ISwitch *motion_north = IUFindSwitch(switchVector, "MOTION_NORTH"); if (!motion_north) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_NORTH\n"); return -RIG_EPROTO; } if (direction & ROT_MOVE_UP) { rig_debug(RIG_DEBUG_VERBOSE, "indi: moving up\n"); motion_north->s = ISS_ON; } else { motion_north->s = ISS_OFF; } ISwitch *motion_south = IUFindSwitch(switchVector, "MOTION_SOUTH"); if (!motion_south) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_SOUTH\n"); return -RIG_EPROTO; } if (direction & ROT_MOVE_DOWN) { rig_debug(RIG_DEBUG_VERBOSE, "indi: moving down\n"); motion_south->s = ISS_ON; } else { motion_south->s = ISS_OFF; } sendNewSwitch(switchVector); switchVector = mTelescope->getSwitch("TELESCOPE_MOTION_WE"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_MOTION_WE switch\n"); return -RIG_EPROTO; } ISwitch *motion_west = IUFindSwitch(switchVector, "MOTION_WEST"); if (!motion_west) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_WEST\n"); return -RIG_EPROTO; } if (direction & ROT_MOVE_LEFT) { rig_debug(RIG_DEBUG_VERBOSE, "indi: moving left\n"); motion_west->s = ISS_ON; } else { motion_west->s = ISS_OFF; } ISwitch *motion_east = IUFindSwitch(switchVector, "MOTION_EAST"); if (!motion_east) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_RIGHT\n"); return -RIG_EPROTO; } if (direction & ROT_MOVE_RIGHT) { rig_debug(RIG_DEBUG_VERBOSE, "indi: moving right\n"); motion_east->s = ISS_ON; } else { motion_east->s = ISS_OFF; } sendNewSwitch(switchVector); return RIG_OK; } int RotINDIClient::stop() { if (!mTelescope || !mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_ABORT_MOTION"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_ABORT_MOTION switch\n"); return -RIG_EPROTO; } ISwitch *sw = IUFindSwitch(switchVector, "ABORT"); if (!sw) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member ABORT_MOTION\n"); return -RIG_EPROTO; } sw->s = ISS_ON; sendNewSwitch(switchVector); return RIG_OK; } int RotINDIClient::park() { if (!mTelescope) { return -RIG_EIO; } if (!mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_PARK"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_PARK switch\n"); return -RIG_EPROTO; } ISwitch *unpark = IUFindSwitch(switchVector, "UNPARK"); if (!unpark) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member UNPARK\n"); return -RIG_EPROTO; } unpark->s = ISS_OFF; ISwitch *park = IUFindSwitch(switchVector, "PARK"); if (!park) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member PARK\n"); return -RIG_EPROTO; } park->s = ISS_ON; sendNewSwitch(switchVector); return RIG_OK; } int RotINDIClient::unPark() { if (!mTelescope || !mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_PARK"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or TELESCOPE_PARK switch\n"); return -RIG_EPROTO; } ISwitch *park2 = IUFindSwitch(switchVector, "PARK"); if (!park2) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member PARK\n"); return -RIG_EPROTO; } park2->s = ISS_OFF; ISwitch *unpark = IUFindSwitch(switchVector, "UNPARK"); if (!unpark) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member UNPARK\n"); return -RIG_EPROTO; } unpark->s = ISS_ON; sendNewSwitch(switchVector); return RIG_OK; } void RotINDIClient::position(azimuth_t *az, elevation_t *el) { *az = mAz; *el = mEl; } double RotINDIClient::getPositionDiffBetween(double deg1, double deg2) { return fabs(deg1 - deg2); } double RotINDIClient::getPositionDiffOutside(double deg1, double deg2, double minDeg, double maxDeg) { if (deg1 < deg2) { return getPositionDiffBetween(minDeg, deg1) + getPositionDiffBetween(deg2, maxDeg); } return getPositionDiffBetween(minDeg, deg2) + getPositionDiffBetween(deg1, maxDeg); } double RotINDIClient::getPositionDiff(double deg1, double deg2, double minDeg, double maxDeg) { double between = getPositionDiffBetween(deg1, deg2); double outside = getPositionDiffOutside(deg1, deg2, minDeg, maxDeg); if (between < outside) { return between; } return outside; } int RotINDIClient::setPosition(azimuth_t az, elevation_t el) { if (!mTelescope || !mTelescope->isConnected()) { rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n"); return -RIG_EIO; } if (fabs(mDstAz - az) < 0.001 && fabs(mDstEl - el) < 0.001) { rig_debug(RIG_DEBUG_VERBOSE, "indi: ignoring new position, already approaching\n"); return RIG_OK; } // Each coordinate set command stops and restarts the rotator, so we have to avoid unnecessary // set calls by defining a range of distance from the new az/el coords which we ignore until // we are closer to the new az/el coords than this value. const int quickJumpRangeDegrees = 10; double currDstNewDstAzDiff = getPositionDiff(mDstAz, az, 0, 360); double currDstNewDstElDiff = getPositionDiff(mDstEl, el, -90, 90); double currDstNewDstDistance = sqrt(pow(currDstNewDstAzDiff, 2) + pow(currDstNewDstElDiff, 2)); double currPosNewDstAzDiff = getPositionDiff(mAz, az, 0, 360); double currPosNewDstElDiff = getPositionDiff(mEl, el, -90, 90); double currPosNewDstDistance = sqrt(pow(currPosNewDstAzDiff, 2) + pow(currPosNewDstElDiff, 2)); if (currDstNewDstDistance < quickJumpRangeDegrees && currPosNewDstDistance > quickJumpRangeDegrees) { rig_debug(RIG_DEBUG_VERBOSE, "indi: ignoring new position, approaching quickly, newDst/currDst distance: %f newDst/currPos distance: %f\n", currDstNewDstDistance, currPosNewDstDistance); return RIG_OK; } rig_debug(RIG_DEBUG_VERBOSE, "indi: setting position to az: %f el: %f\n", az, el); mDstAz = az; mDstEl = el; ISwitchVectorProperty *switchVector = mTelescope->getSwitch("ON_COORD_SET"); if (!switchVector) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or ON_COORD_SET switch\n"); return -RIG_EPROTO; } ISwitch *slew = IUFindSwitch(switchVector, "SLEW"); if (!slew) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member SLEW\n"); return -RIG_EPROTO; } slew->s = ISS_OFF; ISwitch *track = IUFindSwitch(switchVector, "TRACK"); if (!track) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member TRACK\n"); return -RIG_EPROTO; } track->s = ISS_ON; ISwitch *sync = IUFindSwitch(switchVector, "SYNC"); if (!sync) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member SYNC\n"); return -RIG_EPROTO; } sync->s = ISS_OFF; sendNewSwitch(switchVector); INumberVectorProperty *property = mTelescope->getNumber("HORIZONTAL_COORD"); if (!property) { rig_debug(RIG_DEBUG_ERR, "indi: unable to find telescope or HORIZONTAL_COORD property\n"); return -RIG_EPROTO; } property->np[0].value = az; property->np[1].value = el; sendNewNumber(property); return RIG_OK; } // cppcheck-suppress unusedFunction void RotINDIClient::removeDevice(INDI::BaseDevice *dp) {} // cppcheck-suppress unusedFunction void RotINDIClient::newProperty(INDI::Property *property) { std::string name(property->getName()); if (!mTelescope && name == "TELESCOPE_INFO") { mTelescope = property->getBaseDevice(); rig_debug(RIG_DEBUG_VERBOSE, "indi: using device %s\n", mTelescope->getDeviceName()); watchDevice(mTelescope->getDeviceName()); if (!mTelescope->isConnected()) { connectDevice(mTelescope->getDeviceName()); } mDstAz = INT_MAX; mDstEl = INT_MAX; } if (name == "HORIZONTAL_COORD") { mAz = property->getNumber()->np[0].value; mEl = property->getNumber()->np[1].value; } } // cppcheck-suppress unusedFunction void RotINDIClient::removeProperty(INDI::Property *property) {} // cppcheck-suppress unusedFunction void RotINDIClient::newBLOB(IBLOB *bp) {} // cppcheck-suppress unusedFunction void RotINDIClient::newSwitch(ISwitchVectorProperty *svp) {} // cppcheck-suppress unusedFunction void RotINDIClient::newNumber(INumberVectorProperty *nvp) { std::string name(nvp->name); if (name == "HORIZONTAL_COORD") { mAz = nvp->np[0].value; mEl = nvp->np[1].value; } } // cppcheck-suppress unusedFunction void RotINDIClient::newMessage(INDI::BaseDevice *dp, int messageID) {} // cppcheck-suppress unusedFunction void RotINDIClient::newText(ITextVectorProperty *tvp) {} // cppcheck-suppress unusedFunction void RotINDIClient::newLight(ILightVectorProperty *lvp) {} // cppcheck-suppress unusedFunction void RotINDIClient::newDevice(INDI::BaseDevice *dp) {} // cppcheck-suppress unusedFunction void RotINDIClient::serverConnected() { rig_debug(RIG_DEBUG_VERBOSE, "indi: server connected\n"); } // cppcheck-suppress unusedFunction void RotINDIClient::serverDisconnected(int exit_code) { rig_debug(RIG_DEBUG_VERBOSE, "indi: server disconnected\n"); } const char *RotINDIClient::getInfo(void) { if (mTelescope && mTelescope->isConnected()) { static char info[128]; snprintf(info, sizeof(info), "using INDI device %s", mTelescope->getDeviceName()); return info; } return "no INDI device connected"; } void RotINDIClient::close(void) { if (mTelescope && mTelescope->isConnected()) { disconnectDevice(mTelescope->getDeviceName()); } disconnectServer(); } extern "C" int indi_wrapper_set_position(ROT *rot, azimuth_t az, elevation_t el) { int res; rig_debug(RIG_DEBUG_TRACE, "%s called: az=%f el=%f\n", __func__, az, el); res = indi_wrapper_client->unPark(); if (res != RIG_OK) { return res; } return indi_wrapper_client->setPosition(az, el); } extern "C" int indi_wrapper_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); indi_wrapper_client->position(az, el); return RIG_OK; } extern "C" int indi_wrapper_stop(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); return indi_wrapper_client->stop(); } extern "C" int indi_wrapper_park(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); return indi_wrapper_client->park(); } extern "C" int indi_wrapper_move(ROT *rot, int direction, int speed) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); return indi_wrapper_client->move(direction, speed); } extern "C" const char *indi_wrapper_get_info(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); return indi_wrapper_client->getInfo(); } extern "C" int indi_wrapper_open(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); indi_wrapper_client->setServer("localhost", 7624); if (!indi_wrapper_client->connectServer()) { rig_debug(RIG_DEBUG_ERR, "indi: server refused connection\n"); return -RIG_EPROTO; } return RIG_OK; } extern "C" int indi_wrapper_close(ROT *rot) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); indi_wrapper_client->close(); return RIG_OK; } hamlib-4.6.5/rotators/indi/indi.c0000664000175000017500000000410015056640443012336 /* * Hamlib Rotator backend - INDI integration * Copyright (c) 2020 by Norbert Varga HA2NON * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "indi_wrapper.h" #include #include const struct rot_caps indi_rot_caps = { ROT_MODEL(ROT_MODEL_INDI), .model_name = "INDI", .mfg_name = "INDI", .version = "0.1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 360, .min_el = -90, .max_el = 90, .set_position = indi_wrapper_set_position, .get_position = indi_wrapper_get_position, .stop = indi_wrapper_stop, .park = indi_wrapper_park, .move = indi_wrapper_move, .get_info = indi_wrapper_get_info, .rot_open = indi_wrapper_open, .rot_close = indi_wrapper_close, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(indi) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&indi_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/indi/Android.mk0000664000175000017500000000040615056640443013165 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := indi.c indi_wrapper.cpp LOCAL_MODULE := indi LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/indi/Makefile.in0000664000175000017500000005772615056640453013343 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/indi ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_indi_la_LIBADD = am_libhamlib_indi_la_OBJECTS = indi.lo indi_wrapper.lo libhamlib_indi_la_OBJECTS = $(am_libhamlib_indi_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libhamlib_indi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libhamlib_indi_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/indi.Plo \ ./$(DEPDIR)/indi_wrapper.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libhamlib_indi_la_SOURCES) DIST_SOURCES = $(libhamlib_indi_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-indi.la libhamlib_indi_la_SOURCES = indi.c indi_wrapper.cpp indi_wrapper.hpp indi_wrapper.h libhamlib_indi_la_LDFLAGS = $(INDI_LIBS) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/indi/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/indi/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-indi.la: $(libhamlib_indi_la_OBJECTS) $(libhamlib_indi_la_DEPENDENCIES) $(EXTRA_libhamlib_indi_la_DEPENDENCIES) $(AM_V_CXXLD)$(libhamlib_indi_la_LINK) $(libhamlib_indi_la_OBJECTS) $(libhamlib_indi_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indi_wrapper.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/indi.Plo -rm -f ./$(DEPDIR)/indi_wrapper.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/indi.Plo -rm -f ./$(DEPDIR)/indi_wrapper.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/indi/indi_wrapper.h0000664000175000017500000000254315056640443014114 /* * Hamlib Rotator backend - INDI integration * Copyright (c) 2020 by Norbert Varga HA2NON * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _INDI_WRAPPER_H #define _INDI_WRAPPER_H 1 #include int indi_wrapper_set_position(ROT *rot, azimuth_t az, elevation_t el); int indi_wrapper_get_position(ROT *rot, azimuth_t *az, elevation_t *el); int indi_wrapper_stop(ROT *rot); int indi_wrapper_park(ROT *rot); int indi_wrapper_move(ROT *rot, int direction, int speed); const char *indi_wrapper_get_info(ROT *rot); int indi_wrapper_open(ROT *rot); int indi_wrapper_close(ROT *rot); #endif // _INDI_WRAPPER_H hamlib-4.6.5/rotators/indi/indi_wrapper.hpp0000664000175000017500000000460315056640443014453 /* * Hamlib Rotator backend - INDI integration * Copyright (c) 2020 by Norbert Varga HA2NON * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _INDI_WRAPPER_HPP #define _INDI_WRAPPER_HPP 1 #include #include #include class RotINDIClient : public INDI::BaseClient { public: RotINDIClient() {}; int setSpeed(int speedPercent); int move(int direction, int speedPercent); int stop(); int park(); int unPark(); void position(azimuth_t *az, elevation_t *el); int setPosition(azimuth_t az, elevation_t el); const char *getInfo(); void close(void); protected: virtual void newDevice(INDI::BaseDevice *dp); virtual void removeDevice(INDI::BaseDevice *dp); virtual void newProperty(INDI::Property *property); virtual void removeProperty(INDI::Property *property); virtual void newBLOB(IBLOB *bp); virtual void newSwitch(ISwitchVectorProperty *svp); virtual void newNumber(INumberVectorProperty *nvp); virtual void newMessage(INDI::BaseDevice *dp, int messageID); virtual void newText(ITextVectorProperty *tvp); virtual void newLight(ILightVectorProperty *lvp); virtual void serverConnected(); virtual void serverDisconnected(int exit_code); private: double getPositionDiffBetween(double deg1, double deg2); double getPositionDiffOutside(double deg1, double deg2, double minDeg, double maxDeg); double getPositionDiff(double deg1, double deg2, double minDeg, double maxDeg); INDI::BaseDevice *mTelescope; azimuth_t mDstAz; elevation_t mDstEl; azimuth_t mAz; elevation_t mEl; }; #endif // _INDI_WRAPPER_HPP hamlib-4.6.5/rotators/indi/Makefile.am0000664000175000017500000000027615056640443013315 noinst_LTLIBRARIES = libhamlib-indi.la libhamlib_indi_la_SOURCES = indi.c indi_wrapper.cpp indi_wrapper.hpp indi_wrapper.h libhamlib_indi_la_LDFLAGS = $(INDI_LIBS) EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/fodtrack/0000775000175000017500000000000015056640501012201 5hamlib-4.6.5/rotators/fodtrack/fodtrack.c0000664000175000017500000001160015056640443014065 /* * Hamlib Rotator backend - Fodtrack parallel port * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_PARALLEL #ifdef HAVE_LINUX_PARPORT_H #include #endif #endif #include "hamlib/rotator.h" #include "parallel.h" #include "misc.h" #include "register.h" #include "fodtrack.h" #ifndef CP_ACTIVE_LOW_BITS #define CP_ACTIVE_LOW_BITS 0x0B #endif /* ************************************************************************* */ /** outputs an direction to the interface */ static int setDirection(hamlib_port_t *port, unsigned char outputvalue, int direction) { int retval; unsigned char outputstatus; retval = par_lock(port); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } // set the data bits retval = par_write_data(port, outputvalue); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } // autofd=true --> azimuth otherwise elevation if (direction) { outputstatus = PARPORT_CONTROL_AUTOFD; } else { outputstatus = 0; } retval = par_write_control(port, outputstatus ^ CP_ACTIVE_LOW_BITS); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } // and now the strobe impulse hl_usleep(1); if (direction) { outputstatus = PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE; } else { outputstatus = PARPORT_CONTROL_STROBE; } retval = par_write_control(port, outputstatus ^ CP_ACTIVE_LOW_BITS); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } hl_usleep(1); if (direction) { outputstatus = PARPORT_CONTROL_AUTOFD; } else { outputstatus = 0; } retval = par_write_control(port, outputstatus ^ CP_ACTIVE_LOW_BITS); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } retval = par_unlock(port); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\n", __func__, __LINE__, rigerror(retval)); return retval; } return RIG_OK; } static int fodtrack_set_position(ROT *rot, azimuth_t az, elevation_t el) { int retval; hamlib_port_t *pport; rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __func__, az, el); pport = ROTPORT(rot); retval = setDirection(pport, el / (float)ROTSTATE(rot)->max_el * 255.0, 0); if (retval != RIG_OK) { return retval; } retval = setDirection(pport, az / (float)ROTSTATE(rot)->max_az * 255.0, 1); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* ************************************************************************* */ /* * Fodtrack rotator capabilities. */ /** Fodtrack implement essentially only the set position function. */ const struct rot_caps fodtrack_rot_caps = { ROT_MODEL(ROT_MODEL_FODTRACK), .model_name = "Fodtrack", .mfg_name = "XQ2FOD", .version = "20200107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 450, .min_el = 0, .max_el = 180, .priv = NULL, /* priv */ .set_position = fodtrack_set_position, }; /* ************************************************************************* */ DECLARE_INITROT_BACKEND(fodtrack) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_register(&fodtrack_rot_caps); return RIG_OK; } /* ************************************************************************* */ /* end of file */ hamlib-4.6.5/rotators/fodtrack/Android.mk0000664000175000017500000000037615056640443014045 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := fodtrack.c LOCAL_MODULE := fodtrack LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/fodtrack/Makefile.in0000664000175000017500000005241315056640453014201 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/fodtrack ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_fodtrack_la_LIBADD = am_libhamlib_fodtrack_la_OBJECTS = fodtrack.lo libhamlib_fodtrack_la_OBJECTS = $(am_libhamlib_fodtrack_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/fodtrack.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_fodtrack_la_SOURCES) DIST_SOURCES = $(libhamlib_fodtrack_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-fodtrack.la libhamlib_fodtrack_la_SOURCES = fodtrack.c fodtrack.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/fodtrack/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/fodtrack/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-fodtrack.la: $(libhamlib_fodtrack_la_OBJECTS) $(libhamlib_fodtrack_la_DEPENDENCIES) $(EXTRA_libhamlib_fodtrack_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_fodtrack_la_OBJECTS) $(libhamlib_fodtrack_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fodtrack.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/fodtrack.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/fodtrack.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/fodtrack/fodtrack.h0000664000175000017500000000201315056640443014070 /* * Hamlib Rotator backend - Fodtrack interface protocol * Copyright (c) 2001-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_FODTRACK_H #define _ROT_FODTRACK_H 1 #include "rotator.h" extern const struct rot_caps fodtrack_rot_caps; #endif /* _ROT_FODTRACK_H */ hamlib-4.6.5/rotators/fodtrack/Makefile.am0000664000175000017500000000017315056640443014163 noinst_LTLIBRARIES = libhamlib-fodtrack.la libhamlib_fodtrack_la_SOURCES = fodtrack.c fodtrack.h EXTRA_DIST = Android.mk hamlib-4.6.5/rotators/satel/0000775000175000017500000000000015056640502011515 5hamlib-4.6.5/rotators/satel/satel.c0000664000175000017500000002051015056640443012713 /* * Hamlib SatEL backend - main file * Copyright (c) 2021 Joshua Lynch * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include #include #include #include #include #include "hamlib/rotator.h" #include "serial.h" #include "register.h" #include "satel.h" /** * Protocol documentation. * * Apparently, the system is modeled after this one: * “An Inexpensive Az-El Rotator System” * "Dec, 1999, QST article by Jim Koehler, VE5FP * * '?' - returns 'SatEL\r\n'. a good test to see if there's * connectivity. * * 'g' - enable motion. nothing happens without this enabled. * * 'z' - display rotator status. contains current Az/El among other * things. here's an example: * * Motion ENABLED * Mode 0 - azimuth break at NORTH * Time: 2001/00/00 00:00:07 * Azimuth = 000 Absolute = 000 * Elevation = 000 * * Number of stored positions: 00 * * * '*' - reset the rotator controller. * * 'pAZ EL\r\n' - tell the rotator where to point where AZ is the * integer azimuth and EL is the integer * elevation. e.g. 'p010 045\n'. the controller will * report the current pointing status after the * operation has completed. * * NOTE: The SatEL system changed a few commands as described in the * user's manual. They are not used here. You can find the manual for * this rotator here: * * http://www.codeposse.com/~jlynch/SatEL%20Az-EL.pdf * */ /** * Idiosyncrasies * * - the controller does zero input checking. you can put it into an * incredibly bad state very easily. * * - the controller doesn't accept any data whilst moving the * rotators. In fact, you can put the controller into a bad state on * occasion if you try and send it commands while its slewing the * rotators. this means we have a really long read timeout so we can * wait for the rotators to slew around before accepting any more * commands. * */ #define BUF_SIZE 256 typedef struct satel_stat satel_stat_t; struct satel_stat { bool motion_enabled; // int mode; // time_t time; // int absolute; int az; int el; }; static int satel_cmd(ROT *rot, char *cmd, int cmdlen, char *res, int reslen) { int ret; hamlib_port_t *rotp = ROTPORT(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rotp); ret = write_block(rotp, (unsigned char *) cmd, cmdlen); if (ret != RIG_OK) { return ret; } if (reslen > 0 && res != NULL) { ret = read_string(rotp, (unsigned char *) res, reslen, "\n", 1, 0, 1); if (ret < 0) { return ret; } } return RIG_OK; } static int satel_read_status(ROT *rot, satel_stat_t *stat) { char resbuf[BUF_SIZE]; char *p; int ret; hamlib_port_t *rotp = ROTPORT(rot); // read motion state ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } stat->motion_enabled = strcmp(resbuf, "Motion ENABLED") == 0 ? true : false; // XXX skip mode ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } // XXX skip time ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } // read azimuth line ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } p = resbuf + 10; p[3] = '\0'; stat->az = (int)strtof(p, NULL); // read elevation line ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } p = resbuf + 12; p[3] = '\0'; stat->el = (int)strtof(p, NULL); // skip blank line ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } // XXX skip stored position count ret = read_string(rotp, (unsigned char *) resbuf, BUF_SIZE, "\n", 1, 0, 1); if (ret < 0) { return ret; } return RIG_OK; } static int satel_get_status(ROT *rot, satel_stat_t *stat) { int ret; ret = satel_cmd(rot, "z", 1, NULL, 0); if (ret != RIG_OK) { return ret; } return satel_read_status(rot, stat); } static int satel_rot_open(ROT *rot) { char resbuf[BUF_SIZE]; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // are we connected? ret = satel_cmd(rot, "?", 1, resbuf, BUF_SIZE); if (ret != RIG_OK) { return ret; } ret = strncasecmp("SatEL", resbuf, 5); if (ret != 0) { return -RIG_EIO; } // yep, reset system ret = satel_cmd(rot, "*", 1, NULL, 0); if (ret != RIG_OK) { return ret; } return RIG_OK; } static int satel_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { char cmdbuf[BUF_SIZE]; int ret; satel_stat_t stat; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); ret = satel_get_status(rot, &stat); if (ret < 0) { return ret; } if (stat.motion_enabled == false) { ret = satel_cmd(rot, "g", 1, NULL, 0); if (ret != RIG_OK) { return ret; } } SNPRINTF(cmdbuf, BUF_SIZE, "p%d %d\r\n", (int)az, (int)el); ret = satel_cmd(rot, cmdbuf, strlen(cmdbuf), NULL, 0); if (ret != RIG_OK) { return ret; } // wait-for, read and discard the status message ret = satel_read_status(rot, &stat); if (ret < 0) { return ret; } return RIG_OK; } static int satel_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { int ret; satel_stat_t stat; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = satel_get_status(rot, &stat); if (ret < 0) { return ret; } *az = stat.az; *el = stat.el; return RIG_OK; } static int satel_rot_stop(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // send reset command return satel_cmd(rot, "*", 1, NULL, 0); } static const char *satel_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "SatEL rotator"; } /* * Satel rotator capabilities. */ const struct rot_caps satel_rot_caps = { ROT_MODEL(ROT_MODEL_SATEL), .model_name = "SatEL", .mfg_name = "SatEL", .version = "20210123.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_SERIAL, .serial_rate_max = 9600, .serial_rate_min = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 60000, .retry = 0, .min_az = 0., .max_az = 360., .min_el = 0., .max_el = 90., .rot_open = satel_rot_open, .get_position = satel_rot_get_position, .set_position = satel_rot_set_position, .stop = satel_rot_stop, .get_info = satel_rot_get_info, .priv = NULL, /* priv */ }; DECLARE_INITROT_BACKEND(satel) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&satel_rot_caps); return RIG_OK; } hamlib-4.6.5/rotators/satel/Android.mk0000664000175000017500000000037015056640443013352 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := satel.c LOCAL_MODULE := satel LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rotators/satel/Makefile.in0000664000175000017500000005237315056640453013521 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rotators/satel ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_satel_la_LIBADD = am__objects_1 = satel.lo am_libhamlib_satel_la_OBJECTS = $(am__objects_1) libhamlib_satel_la_OBJECTS = $(am_libhamlib_satel_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/satel.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_satel_la_SOURCES) DIST_SOURCES = $(libhamlib_satel_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SATELSRC = satel.c satel.h noinst_LTLIBRARIES = libhamlib-satel.la libhamlib_satel_la_SOURCES = $(SATELSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rotators/satel/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rotators/satel/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-satel.la: $(libhamlib_satel_la_OBJECTS) $(libhamlib_satel_la_DEPENDENCIES) $(EXTRA_libhamlib_satel_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_satel_la_OBJECTS) $(libhamlib_satel_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/satel.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/satel.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/satel.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rotators/satel/satel.h0000664000175000017500000000171515056640443012726 /* * Hamlib SatEL backend - main header * Copyright (c) 2021 Joshua Lynch * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_SATEL_H #define _ROT_SATEL_H 1 extern const struct rot_caps satel_rot_caps; #endif /* _ROT_SATEL_H */ hamlib-4.6.5/rotators/satel/Makefile.am0000664000175000017500000000020615056640443013473 SATELSRC = satel.c satel.h noinst_LTLIBRARIES = libhamlib-satel.la libhamlib_satel_la_SOURCES = $(SATELSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/configure.ac0000664000175000017500000007541215056640442010752 ## Process this file with autoconf to create configure. -*- autoconf -*- dnl Autoconf 2.67 is in Debian Squeeze--is an older version needed dnl for some other distribution? ## FIXME: Is this too new? ## AC_PREREQ([2.69]) ## ------------------------ ## ## Autoconf initialisation. ## ## ------------------------ ## dnl Please do not use '-' in the version number, as package managers will fail, dnl however, the use of '~' should be fine as apt (others?) will treat dnl it as an earlier version than the actual release. TNX KA6MAL dnl PACKAGE_NAME + " " + PACKAGE_VERSION must not exceed 20 chars! AC_INIT([Hamlib],[4.6.5],[hamlib-developer@lists.sourceforge.net],[hamlib],[http://www.hamlib.org]) #AC_INIT([PRODUCT_NAME], [Hamlib]) #AC_DEFINE([Hamlib], [PRODUCT_VERSION_RESOURCE]) AC_CONFIG_SRCDIR([include/hamlib/rig.h]) AC_CONFIG_MACRO_DIR([macros]) AC_CONFIG_HEADERS([include/hamlib/config.h]) dnl Place build system provided programs in this directory. AC_CONFIG_AUX_DIR([build-aux]) AC_USE_SYSTEM_EXTENSIONS ## ------------------------ ## ## Automake Initialisation. ## ## ------------------------ ## dnl Passing AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION to AM_INIT_AUTOMAKE is dnl obsolete as these values are obtained from the AC_INIT macro. AM_INIT_AUTOMAKE([-Wall subdir-objects]) dnl Clean compilation output makes compiler warnings more visible m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) ## ------------------------------ ## ## Hamlib specific configuration. ## ## ------------------------------ ## dnl AC_ARG_ENABLE([shared], dnl [AS_HELP_STRING([--enable-shared], dnl [Enable shared libraries @<:@default=yes@:>@])], dnl [enable_shared=$enableval], dnl [enable_shared=yes]) dnl AC_ARG_ENABLE([static], dnl [AS_HELP_STRING([--enable-static], dnl [Enable static libraries @<:@default=check@:>@])], dnl [enable_static=$enableval], dnl [enable_static=check]) dnl dnl AS_IF([test "x$enable_static" = "xyes"], [ dnl enable_shared=no dnl ]) dnl AS_IF([test "x$enable_static" = "xyes" && test "x$enable_shared" = "xyes"], [ dnl AC_MSG_ERROR([Both --enable-static and --enable-shared cannot be enabled at the same time.]) dnl ]) dnl New backends must be listed here! Also the new Makefile path must be dnl added to AC_CONFIG_FILES near the end of this file. See README.developer dnl Beware of duplication should a backend directory include both rig and dnl rotor definitions, e.g. "dummy". Optional backends will not be listed dnl here but will be added later, e.g. "winradio". RIG_BACKEND_LIST="rigs/adat rigs/alinco rigs/aor rigs/barrett rigs/codan rigs/dorji rigs/drake rigs/dummy rigs/elad rigs/flexradio rigs/icom rigs/icmarine rigs/jrc rigs/kachina rigs/kenwood rigs/kit rigs/lowe rigs/pcr rigs/prm80 rigs/racal rigs/rft rigs/rs rigs/skanti rigs/tapr rigs/tentec rigs/tuner rigs/uniden rigs/winradio rigs/wj rigs/yaesu rigs/gomspace rigs/mds rigs/anytone rigs/motorola rigs/commradio" ROT_BACKEND_LIST="rotators/amsat rotators/apex rotators/ars rotators/celestron rotators/cnctrk rotators/grbltrk rotators/easycomm rotators/ether6 rotators/flir rotators/fodtrack rotators/gs232a rotators/heathkit rotators/m2 rotators/meade rotators/rotorez rotators/sartek rotators/saebrtrack rotators/spid rotators/ts7400 rotators/prosistel rotators/ioptron rotators/satel rotators/skywatcher rotators/radant" # Amplifiers are all in the amplifiers directory AMP_BACKEND_LIST="amplifiers/elecraft amplifiers/gemini amplifiers/expert" dnl See README.release on setting these values # Values given to -version-info when linking. See libtool documentation. # Set them here to keep c++/Makefile and src/Makefile in sync. ABI_VERSION=4 ABI_REVISION=6 ABI_PATCH=5 ABI_AGE=0 AC_DEFINE_UNQUOTED([ABI_VERSION], [$ABI_VERSION], [Frontend ABI version]) AC_DEFINE_UNQUOTED([ABI_REVISION], [$ABI_REVISION], [Frontend ABI revision]) AC_DEFINE_UNQUOTED([ABI_AGE], [$ABI_AGE], [Frontend ABI age]) AC_DEFINE_UNQUOTED([ABI_VERSION_MAJOR], [$ABI_VERSION], [Frontend Major version]) AC_DEFINE_UNQUOTED([ABI_VERSION_MINOR], [$ABI_REVISION], [Frontend Minor version]) AC_DEFINE_UNQUOTED([ABI_VERSION_PATCH], [$ABI_PATCH], [Frontend Patch version]) AC_SUBST([ABI_VERSION]) AC_SUBST([ABI_REVISION]) AC_SUBST([ABI_AGE]) # Add Hamlib define needed to link DLLs AM_CPPFLAGS="${AM_CPPFLAGS} -DIN_HAMLIB" # Add Hamlib header include paths AM_CPPFLAGS="${AM_CPPFLAGS} -I\$(top_srcdir)/include -I\$(top_srcdir)/src -I\$(top_srcdir)/lib -I\$(top_builddir)/include -I\$(top_srcdir)/include/hamlib -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" ## --------------- ## ## Program checks ## ## --------------- ## dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_CPP AC_PROG_AWK AC_PROG_INSTALL AC_PROG_LN_S # TODO: check whether CXX is functional AC_CHECK_PROG([cf_with_cxx], ["${CXX}"], [yes], [no]) AM_CONDITIONAL([ENABLE_CXX], [test x"${cf_with_cxx}" = "xyes"]) dnl Broke on older Automake, so test for its existence. m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) ## ----------------------------------- ## ## Miscellaneous configuration macros ## ## ----------------------------------- ## AC_C_INLINE dnl Set warnings for compilation dnl CFLAGS and CXXFLAGS are reserved for user, so set their AM_* counterparts. # macros/ax_cflags_warn_all.m4 AX_CFLAGS_WARN_ALL([AM_CFLAGS]) AX_CXXFLAGS_WARN_ALL([AM_CXXFLAGS]) dnl Automake macro for rigmem compilation AM_PROG_CC_C_O ## ------------------------------------------ ## ## Various parts of Hamlib need these headers ## ## ------------------------------------------ ## AC_CHECK_HEADERS([errno.h fcntl.h getopt.h limits.h locale.h malloc.h \ netdb.h sgtty.h stddef.h termio.h termios.h values.h \ arpa/inet.h dev/ppbus/ppbconf.hdev/ppbus/ppi.h \ linux/hidraw.h linux/ioctl.h linux/parport.h linux/ppdev.h netinet/in.h \ sys/ioccom.h sys/ioctl.h sys/param.h sys/socket.h sys/stat.h sys/time.h \ sys/select.h glob.h ]) dnl set host_os variable AC_CANONICAL_HOST dnl ws2tcpip.h not provided by cygwin and its test causes a configure warning. dnl wspiapi.h provides needed freeaddrinfo function on W2k systems. AS_IF([test "${host_os}" != "cygwin"], [ AC_CHECK_HEADERS([ws2tcpip.h wspiapi.h]) ]) ## ------------------------------------ ## ## System capability and library checks ## ## ------------------------------------ ## dnl Check for Mingw (Win32 Sleep) support # macros/gr_pwin32.m4 GR_PWIN32 dnl If pthread support is found, this macro defines HAVE_PTHREAD and dnl AC_SUBST's PTHREAD_LIBS, PTHREAD_CFLAGS, and PTHREAD_CC making those dnl variables available in Makefiles. # macros/ax_pthread.m4 AX_PTHREAD AC_SYS_POSIX_TERMIOS() dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_CHECK_TYPES([siginfo_t],[],[],[[#include ]]) AC_CHECK_TYPES([sig_atomic_t],[],[],[[#include ]]) dnl Checks for libraries. # The following comes from SC_TCL_LINK_LIBS # we redefine them here because we want a separate NET_LIBS var #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. #-------------------------------------------------------------------- AC_CHECK_FUNC([sin], [MATH_LIBS=""], [MATH_LIBS="-lm"]) AC_SUBST([MATH_LIBS]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: cannot redo a check because # autoconf caches the results of the last check and will not redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # are not already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- hl_checkBoth=0 hl_oldLibs=$LIBS AC_CHECK_FUNC([connect], [hl_checkSocket=0], [hl_checkSocket=1]) AS_IF([test "$hl_checkSocket" = 1], [ AC_CHECK_LIB([socket], [main], [NET_LIBS="$NET_LIBS -lsocket"], [hl_checkBoth=1], []) ]) AS_IF([test "$hl_checkBoth" = 1], [ hl2_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC([accept], [hl_checkNsl=0], [LIBS=$hl2_oldLibs]) ]) # separate Name Service Library AC_CHECK_FUNC([gethostbyname], [], [AC_CHECK_LIB([nsl], [main], [NET_LIBS="$NET_LIBS -lnsl"], [], []) ]) # Winsock2 32 bit AC_CHECK_FUNC([gethostbyname], [], [AC_CHECK_LIB([ws2_32], [main], [NET_LIBS="$NET_LIBS -lws2_32 -liphlpapi"], [], []) ]) # Winsock2 32 bit AC_CHECK_FUNC([timeBeginPeriod], [], [AC_CHECK_LIB([winmm], [main], [NET_LIBS="$NET_LIBS -lwinmm"], [], []) ]) LIBS="$LIBS $NET_LIBS" # macros/hl_getaddrinfo.m4 HL_GETADDRINFO LIBS=$hl_oldLibs AC_SUBST([NET_LIBS]) ## End Hamlib socket test ## dnl Checks for library functions. AC_CHECK_FUNCS([cfmakeraw floor getpagesize getpagesize gettimeofday inet_ntoa \ ioctl memchr memmove memset pow rint select setitimer setlocale sigaction signal \ snprintf socket sqrt strchr strdup strerror strncasecmp strrchr strstr strtol \ glob socketpair ]) AC_FUNC_ALLOCA dnl AC_LIBOBJ replacement functions directory AC_CONFIG_LIBOBJ_DIR([lib]) dnl Use Hamlib's termios AC_LIBOBJ([termios]) dnl Assure libmisc is not empty AC_LIBOBJ([dummy]) ## ------------------------ ## ## libtool Initialisation. ## ## ------------------------ ## AR_FLAGS="cr" LT_PREREQ([2.2.6b]) dnl N.B. LT_INIT([win32-dll]) does not work for older libtool dnl so require new enough version above. LT_INIT([win32-dll]) LT_LANG([Windows Resource]) ## -------------------------- ## ## Custom host configurations ## ## -------------------------- ## dnl The host_os variable is set by the AC_CANONICAL_HOST macro above. AM_CONDITIONAL([VERSIONDLL], false) AS_CASE(["$host_os"], [freebsd*], [ AM_CPPFLAGS="${AM_CPPFLAGS} -I/usr/local/include" AM_LDFLAGS="${AM_LDFLAGS} -L/usr/local/lib" AC_SUBST([AM_LDFLAGS])], [darwin* | rhapsody*], [ # Tell the OS X linker to allocate enough space inside the # libhamlib.X.dylib shared object for install_name_tool(1) to # work. This is useful when including hamlib in an app bundle. OSXLDFLAGS="-Wl,-headerpad_max_install_names" AC_SUBST([OSXLDFLAGS])], [mingw* | pw32* | cygwin*], [ AM_CONDITIONAL([VERSIONDLL], true) WINLDFLAGS="-Wl,--output-def,libhamlib.def -Wl,--add-stdcall-alias" VERSIONDLL="version_dll.rc" AC_SUBST([WINLDFLAGS]) # Enable ld's "auto import" for executables WINEXELDFLAGS="-Wl,--enable-auto-import" AC_SUBST([WINEXELDFLAGS]) ]) ## ---------------------- ## ## External package tests ## ## ---------------------- ## dnl Check if C99 struct initializers are supported AC_MSG_CHECKING([whether C99 struct/array initializers are supported]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[struct{char a;int b;}s[8]={[3]={.b=5}};]])], [AC_MSG_RESULT(yes)], [AC_MSG_ERROR(["" "You need a C99 compliant C compiler that supports struct/array initializers." "Have you considered GCC lately?."]) ]) dnl Check for libusb, treat LIBUSB_LIBS and LIBUSB_CFLAGS as precious variables AC_MSG_CHECKING([whether to build USB dependent backends]) AC_ARG_WITH([libusb], [AS_HELP_STRING([--without-libusb], [disable USB dependent backends @<:@default=yes@:>@])], [cf_with_libusb=$with_libusb], [cf_with_libusb=yes] ) AC_MSG_RESULT([$cf_with_libusb]) AM_CONDITIONAL([HAVE_LIBUSB], [test x"${cf_with_libusb}" = "xyes"]) LIBUSB="" AC_ARG_VAR([LIBUSB_CFLAGS], [C compiler flags for libusb, overriding configure defaults]) AC_ARG_VAR([LIBUSB_LIBS], [linker flags for libusb, overriding configure check (useful for specifying static libusb-1.0.a (see INSTALL))]) AS_IF([test x"${cf_with_libusb}" = "xyes"], [ AS_IF([test -z $LIBUSB_LIBS], [AC_CHECK_LIB([usb-1.0], [libusb_init], [LIBUSB_LIBS="-lusb-1.0"], [AC_MSG_WARN([libusb_init was not found in libusb-1.0--USB backends will be disabled])] [cf_with_libusb="no"]) ], [cf_with_libusb="yes"]) AS_IF([test x"${cf_with_libusb}" = "xyes"], [AC_CHECK_HEADERS([libusb.h libusb-1.0/libusb.h]) AC_DEFINE([HAVE_LIBUSB], [1], [Define if libusb-1.0 is available]) LIBUSB="libusb-1.0"])]) # Only used in hamlib.pc.in AC_SUBST([LIBUSB]) dnl Check if readline support in rigctl/rotctl is wanted AC_MSG_CHECKING([whether to use readline in rigctl/rotctl]) AC_ARG_WITH([readline], [AS_HELP_STRING([--without-readline], [disable readline in rigctl/rotctl @<:@default=yes@:>@])], [cf_with_readline_support=$with_readline], [cf_with_readline_support=yes] ) AC_MSG_RESULT([$cf_with_readline_support]) AS_IF([test x"$cf_with_readline_support" != "xno"], [ # macros/ax_lib_readline.m4 AX_LIB_READLINE ]) AS_IF([test x"$ax_cv_lib_readline" = "xno"], [ AC_MSG_WARN([readline support not found, using internal input handling.]) cf_with_readline_support=no ]) dnl Check if INDI support in rigctl/rotctl is wanted AC_MSG_CHECKING([whether to use INDI in rigctl/rotctl]) #AS_IF([test x"${cf_with_cxx_binding}" = "xyes"], [ AC_ARG_WITH([indi], [AS_HELP_STRING([--without-indi], [disable INDI in rigctl/rotctl @<:@default=yes@:>@])], [cf_with_indi_support=$with_indi], [cf_with_indi_support=no] ) #]) AS_IF([test x"$cf_with_indi_support" != "xno"], [ # INDI support needs a C++ compiler, tested for presence above. AS_IF([test x"${cf_with_cxx}" != "xyes"], [ AC_MSG_WARN([INDI support needs a C++ compiler.]) cf_with_indi_support=no ]) ]) AS_IF([test x"$cf_with_indi_support" != "xno"], [ # macros/ax_lib_nova.m4 AX_LIB_NOVA AS_IF([test x"$ax_cv_lib_nova" = "xno"], [ AC_MSG_WARN([libnova support not found, required by INDI.]) cf_with_indi_support=no ]) AS_IF([test x"$ax_cv_lib_nova" != "xno"], [ # macros/ax_lib_indi.m4 AX_LIB_INDI AS_IF([test x"$ax_cv_lib_indi" = "xno"], [ AC_MSG_WARN([INDI support not found.]) cf_with_indi_support=no ]) AS_IF([test x"$cf_with_indi_support" != "xno"], [ ROT_BACKEND_LIST="$ROT_BACKEND_LIST rotators/indi" ]) ]) ]) dnl Check if libgd-dev is installed, so we can enable rigmatrix AC_MSG_CHECKING([whether to build HTML rig feature matrix]) AC_ARG_ENABLE([html-matrix], [AS_HELP_STRING([--disable-html-matrix], [do not generate HTML rig feature matrix (requires libgd-dev) @<:@default=check@:>@])], [cf_enable_html_matrix=$enable_html_matrix], [cf_enable_html_matrix=check] ) AS_IF([test x"$cf_enable_html_matrix" != "xno"], [AC_CHECK_HEADERS([gd.h], [AC_CHECK_LIB([gd], [gdImageCreate], [cf_enable_html_matrix=yes], [cf_enable_html_matrix=no], [-lz])], [cf_enable_html_matrix=no] ) ]) AC_MSG_RESULT([$cf_enable_html_matrix]) AM_CONDITIONAL([HTML_MATRIX], [test x"${cf_enable_html_matrix}" = "xyes"]) ## ------------------ ## ## PKG Config support ## ## ------------------ ## dnl These features rely on the external pkg-config functionality being available. dnl Test for pkg-config only when these features are enabled. # libxml2 required rigmem xml support, make it user optional AC_MSG_CHECKING([whether to build rigmem XML support]) AC_ARG_WITH([xml-support], [AS_HELP_STRING([--with-xml-support], [build rigmem with XML support @<:@default=no@:>@])], [cf_with_xml_support=$withval], [cf_with_xml_support=no]) AC_MSG_RESULT([$cf_with_xml_support]) # USRP needs a C++ compiler, tested for presence above. AS_IF([test x"${cf_with_cxx}" = "xyes"], [ AC_MSG_CHECKING([whether to build USRP backend]) AC_ARG_ENABLE([usrp], [AS_HELP_STRING([--enable-usrp], [build USRP backend @<:@default=no@:>@])], [cf_with_usrp=$enableval], [cf_with_usrp="no"]) AC_MSG_RESULT([$cf_with_usrp]) ]) dnl Only check for pkg-config when either of the dependent features are enabled. AS_IF([test x"${cf_with_xml_support}" = "xyes" || test x"${cf_with_usrp}" = "xyes"], [ dnl Check for pkg-config presence and if not installed define a dummy macro dnl to disable libxml2 and USRP use. Code borrowed from: dnl http://lists.gnu.org/archive/html/automake/2011-03/msg00008.html dnl dnl Check for pkg-config program, used for configuring some libraries. m4_define_default([PKG_PROG_PKG_CONFIG], [AC_MSG_CHECKING([pkg-config]) AC_MSG_RESULT([no])]) PKG_PROG_PKG_CONFIG dnl If the pkg-config autoconf support isn't installed, define its dnl autoconf macro to disable any packages depending on it. m4_define_default([PKG_CHECK_MODULES], [AC_MSG_CHECKING([$1]) AC_MSG_RESULT([no]) $4]) ]) AS_IF([test x"${cf_with_xml_support}" = "xyes"], [ PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], [AC_DEFINE([HAVE_XML2], [1], [Define if libxml2 is available])], [AC_MSG_WARN([libxml-2.0 pkg-config not found, XML support will be disabled]) ]) ]) AC_SUBST([LIBXML2_LIBS]) AC_SUBST([LIBXML2_CFLAGS]) ## ----------------- ## ## Language bindings ## ## ----------------- ## BINDINGS="" BINDING_ALL="" BINDING_CHECK="" BINDING_CLEAN="" BINDING_DISTCLEAN="" BINDING_DISTCHECK="" BINDING_INSTALL_EXEC="" BINDING_UNINSTALL="" BINDING_LIST="" BINDING_LIB_TARGETS="" dnl Check if cxx-binding not wanted, default is to build it # C++ binding AC_MSG_CHECKING([whether to build C++ binding]) AC_ARG_WITH([cxx-binding], [AS_HELP_STRING([--without-cxx-binding], [do not build C++ binding @<:@default=yes@:>@])], [cf_with_cxx_binding=$withval], [cf_with_cxx_binding=$cf_with_cxx]) AC_MSG_RESULT([$cf_with_cxx_binding]) AS_IF([test x"${cf_with_cxx_binding}" = "xyes"], [BINDINGS="${BINDINGS} c++"]) AM_CONDITIONAL([ENABLE_CXX], [test x"${cf_with_cxx_binding}" = "xyes"]) dnl Check if perl-binding is wanted, default is to not build it # Perl binding AC_MSG_CHECKING([whether to build perl binding]) AC_ARG_WITH([perl-binding], [AS_HELP_STRING([--with-perl-binding], [build perl binding @<:@default=no@:>@])], [cf_with_perl_binding=$withval], [cf_with_perl_binding=no]) AC_MSG_RESULT([$cf_with_perl_binding]) dnl SC_PATH_PERLINC from macros/perl.m4 AS_IF([test x"${cf_with_perl_binding}" = "xyes"],[ SC_PATH_PERLINC BINDING_LIST="${BINDING_LIST} perl" BINDING_ALL="${BINDING_ALL} all-perl" BINDING_CHECK="${BINDING_CHECK} check-perl" BINDING_CLEAN="${BINDING_CLEAN} clean-perl" BINDING_DISTCLEAN="${BINDING_DISTCLEAN} distclean-perl" BINDING_DISTCHECK="${BINDING_DISTCHECK} distcheck-perl" BINDING_INSTALL_EXEC="${BINDING_INSTALL_EXEC} install-perl" BINDING_UNINSTALL="${BINDING_UNINSTALL} uninstall-perl" ]) AM_CONDITIONAL([ENABLE_PERL], [test x"${cf_with_perl_binding}" = "xyes"]) dnl Check for python availability, so we can enable HamlibPy # Python bindings AC_MSG_CHECKING([whether to build python binding]) AC_ARG_WITH([python-binding], [AS_HELP_STRING([--with-python-binding], [build python binding @<:@default=no@:>@])], [cf_with_python_binding=$withval], [cf_with_python_binding=no]) AC_MSG_RESULT([$cf_with_python_binding]) dnl AX_PYTHON_DEVEL from macros/ax_python_devel.m4 AS_IF([test x"${cf_with_python_binding}" = "xyes"],[ dnl Order matters! AX_PYTHON_DEVEL must be first for PYTHON_VERSION to be honored. AX_PYTHON_DEVEL([>='2.1']) AM_PATH_PYTHON([2.1],, [:]) BINDING_LIST="${BINDING_LIST} python" BINDING_ALL="${BINDING_ALL} all-py" BINDING_CHECK="${BINDING_CHECK} check-py" BINDING_CLEAN="${BINDING_CLEAN} clean-py" BINDING_DISTCLEAN="${BINDING_DISTCLEAN} distclean-py" BINDING_INSTALL_EXEC="${BINDING_INSTALL_EXEC} install-py" BINDING_UNINSTALL="${BINDING_UNINSTALL} uninstall-py" BINDING_LIB_TARGETS="${BINDING_LIB_TARGETS} \$(python_ltlib)"]) AM_CONDITIONAL([ENABLE_PYTHON], [test x"${cf_with_python_binding}" = "xyes"]) dnl Determine whether to install pytest.py or py3test.py to $(docdir)/examples AM_PYTHON_CHECK_VERSION([${PYTHON}], [3.0], [pyver_3="yes"], [pyver_3="no"]) AM_CONDITIONAL([PYVER_3], [test x"${pyver_3}" = x"yes"]) # Tcl binding AC_MSG_CHECKING([Whether to build Tcl bindings]) AC_ARG_WITH([tcl-binding], [AS_HELP_STRING([--with-tcl-binding], [build Tcl binding @<:@default=no@:>@])], [build_tcl=$withval], [build_tcl=no]) AC_MSG_RESULT([$build_tcl]) dnl tcl.pc or SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG from macros/tcl.m4 AS_IF([test x"${build_tcl}" = "xyes"],[ dnl Search for and load tcl.pc or tclConfig.sh. PKG_CHECK_MODULES([TCL], [tcl], [], [ AC_MSG_WARN([Unable to find Tcl pkgconfig]) SC_PATH_TCLCONFIG SC_LOAD_TCLCONFIG tcl_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $TCL_INCLUDE_SPEC" AC_CHECK_HEADERS([tcl.h], [], [AC_MSG_ERROR([Unable to find Tcl headers])]) CPPFLAGS=$tcl_save_CPPFLAGS ]) BINDING_LIST="${BINDING_LIST} tcl" BINDING_ALL="${BINDING_ALL} all-tcl" BINDING_CHECK="${BINDING_CHECK} check-tcl" BINDING_CLEAN="${BINDING_CLEAN} clean-tcl" BINDING_DISTCLEAN="${BINDING_DISTCLEAN} distclean-tcl" BINDING_INSTALL_EXEC="${BINDING_INSTALL_EXEC} install-tcl" BINDING_UNINSTALL="${BINDING_UNINSTALL} uninstall-tcl" BINDING_LIB_TARGETS="${BINDING_LIB_TARGETS} \$(tcl_ltlib)"]) AM_CONDITIONAL([ENABLE_TCL], [test x"${build_tcl}" = "xyes"]) dnl These variables are set once tclConfig.sh is loaded. AC_SUBST([TCL_VERSION]) AC_SUBST([TCL_LIB_SPEC]) AC_SUBST([TCL_INCLUDE_SPEC]) AC_SUBST([TCL_SHLIB_SUFFIX]) dnl These variables are set once tcl.pc is found. AC_SUBST([TCL_LIBS]) AC_SUBST([TCL_CFLAGS]) dnl Check for lua availability, so we can enable HamlibLua dnl Newer ax_lua.m4 macro, at least Serial 47, requires LUAJIT be present. AM_CONDITIONAL([LUAJIT], [false]) # Lua bindings AC_MSG_CHECKING([whether to build lua binding]) AC_ARG_WITH([lua-binding], [AS_HELP_STRING([--with-lua-binding], [build lua binding @<:@default=no@:>@])], [cf_with_lua_binding=$withval], [cf_with_lua_binding=no]) AC_MSG_RESULT([$cf_with_lua_binding]) dnl AX_LUA_DEVEL from macros/ax_lua_devel.m4 AS_IF([test x"${cf_with_lua_binding}" = "xyes"],[ AX_PROG_LUA([5.2], [5.5]) AX_LUA_HEADERS AX_LUA_LIBS BINDING_LIST="${BINDING_LIST} lua" BINDING_ALL="${BINDING_ALL} all-lua" BINDING_CHECK="${BINDING_CHECK} check-lua" BINDING_CLEAN="${BINDING_CLEAN} clean-lua" BINDING_DISTCLEAN="${BINDING_DISTCLEAN} distclean-lua" BINDING_INSTALL_EXEC="${BINDING_INSTALL_EXEC} install-lua" BINDING_UNINSTALL="${BINDING_UNINSTALL} uninstall-lua" BINDING_LIB_TARGETS="${BINDING_LIB_TARGETS} \$(lua_ltlib)"]) AM_CONDITIONAL([ENABLE_LUA], [test x"${cf_with_lua_binding}" = "xyes"]) dnl Only search for Swig if one or more bindings are enabled. AS_IF([test "x${BINDING_ALL}" != "x"], [# macros/ax_pkg_swig.m4 AX_PKG_SWIG([3.0.12], [BINDINGS="${BINDINGS} bindings" cf_with_bindings="yes"], [AC_MSG_ERROR([SWIG is required to build bindings...]) ])], [cf_with_bindings="no"]) AC_MSG_CHECKING([whether to build bindings]) AC_MSG_RESULT([$cf_with_bindings]) AC_SUBST([BINDINGS]) AC_SUBST([BINDING_ALL]) AC_SUBST([BINDING_CHECK]) AC_SUBST([BINDING_CLEAN]) AC_SUBST([BINDING_DISTCLEAN]) AC_SUBST([BINDING_DISTCHECK]) AC_SUBST([BINDING_INSTALL_EXEC]) AC_SUBST([BINDING_UNINSTALL]) AC_SUBST([BINDING_LIST]) AC_SUBST([BINDING_LIB_TARGETS]) ## ----------------- ## ## Optional backends ## ## ----------------- ## dnl Winradio only under Linux (until someone ports it on other os) AC_MSG_CHECKING([whether to build winradio backend]) AC_ARG_ENABLE([winradio], [AS_HELP_STRING([--disable-winradio], [do not build winradio backend @<:@default=yes@:>@])], [cf_with_winradio="${enable_winradio}"], [cf_with_winradio="yes" ]) AS_IF([test x"${cf_with_winradio}" = "xyes"], [AC_DEFINE([HAVE_WINRADIO],[1],[Define if winradio backend is built])] ) AC_MSG_RESULT([$cf_with_winradio]) dnl Parallel port device disable AC_MSG_CHECKING([whether to build parallel port devices]) AC_ARG_ENABLE([parallel], [AS_HELP_STRING([--disable-parallel], [do not build parallel devices @<:@default=yes@:>@])], [cf_with_parallel="${enable_parallel}"], [cf_with_parallel="yes"]) AS_IF([test x"${cf_with_parallel}" = "xyes"], [AC_DEFINE([HAVE_PARALLEL],[1],[Define if parallel devices are to be built])] ) AC_MSG_RESULT([$cf_with_parallel]) DL_LIBS="" AS_IF([test x"${cf_with_winradio}" = "xyes"], [RIGS_BACKEND_LIST="$RIGS_BACKEND_LIST rigs/winradio" dnl Check for libdl and set DL_LIBS if found--used for linradio WR-G313 backend. AC_CHECK_LIB([dl], [dlopen], [DL_LIBS="-ldl"], [AC_MSG_WARN([dlopen was not found in libdl--linradio backend will be disabled])]) ]) # Still need -ldl if we have it AS_IF([test x"${cf_with_winradio}" = "xno"], [RIGS_BACKEND_LIST="$RIGS_BACKEND_LIST" dnl Check for libdl and set DL_LIBS if found--used for linradio WR-G313 backend. AC_CHECK_LIB([dl], [dlopen], [DL_LIBS="-ldl"], [AC_MSG_WARN([dlopen was not found in libdl--linradio backend will be disabled])]) ]) dnl Set conditional compilation for G-313. AS_CASE(["$host_os"], [mingw* | pw32* | cygwin ], [ AM_CONDITIONAL(G313_LINUX_GNU, false) AM_CONDITIONAL(G313_WINDOWS, true) ], dnl As g313-posix.c has a hard dependency on linux/types.h dnl via linradio/wrg313api.h, disable compilation on other POSIX. dnl (Certain systems have extra characters following "-gnu" such as dnl the Raspberry Pi which is "linux-gnueabihf"; presume that "linux-gnu" dnl is a sufficient test.) [ *linux-gnu* ], [ AM_CONDITIONAL(G313_LINUX_GNU, true) AM_CONDITIONAL(G313_WINDOWS, false) ], [ AM_CONDITIONAL(G313_LINUX_GNU, false) AM_CONDITIONAL(G313_WINDOWS, false) AC_DEFINE([OTHER_POSIX], [1], [Compilation on POSIX other than Linux]) ]) dnl If libdl is present, check for its header file. AS_IF([test x"${DL_LIBS}" = "x-ldl"], [AC_CHECK_HEADERS([dlfcn.h])]) AC_SUBST([DL_LIBS]) dnl check for c++11 AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory]) dnl stuff that requires C++ support AS_IF([test x"${cf_with_usrp}" = "xyes"],[ PKG_CHECK_MODULES([USRP], [usrp >= 0.8], [AC_DEFINE([HAVE_USRP],[1],[Define if usrp is available]) ]) ]) AM_CONDITIONAL([HAVE_USRP], [test x"${cf_with_usrp}" = "xyes"]) AM_CONDITIONAL(BUILD_OS_IS_UBUNTU, [test x"$build_os" = ubuntu]) AM_CONDITIONAL(BUILD_OS_IS_FEDORA, [test x"$build_os" = fedora]) echo Build_OS is $build_os ## -------------------------------- ## ## Prepare rig backend dependencies ## ## -------------------------------- ## dnl otherwise parallel 'make -jn' will fail for be in ${RIG_BACKEND_LIST} ; do RIGDIR=$(echo $be | awk -F "/" '{print $2}') RIG_BACKENDEPS="${RIG_BACKENDEPS} \$(top_builddir)/rigs/${RIGDIR}/libhamlib-${RIGDIR}.la" done AC_SUBST([RIG_BACKEND_LIST]) AC_SUBST([RIG_BACKENDEPS]) ## ---------------------------------- ## ## Prepare rotor backend dependencies ## ## ---------------------------------- ## # otherwise parallel 'make -jn' will fail for be in ${ROT_BACKEND_LIST} ; do ROTDIR=$(echo $be | awk -F "/" '{print $2}') ROT_BACKENDEPS="${ROT_BACKENDEPS} \$(top_builddir)/rotators/${ROTDIR}/libhamlib-${ROTDIR}.la" done AC_SUBST([ROT_BACKEND_LIST]) AC_SUBST([ROT_BACKENDEPS]) ## ---------------------------------- ## ## Prepare amplifier backend dependencies ## ## ---------------------------------- ## # otherwise parallel 'make -jn' will fail for be in ${AMP_BACKEND_LIST} ; do AMPDIR=$(echo $be | awk -F "/" '{print $2}') AMP_BACKENDEPS="${AMP_BACKENDEPS} \$(top_builddir)/amplifiers/${AMPDIR}/libhamlib-${AMPDIR}.la" done AC_SUBST([AMP_BACKEND_LIST]) AC_SUBST([AMP_BACKENDEPS]) ## ------------ ## ## Final output ## ## ------------ ## dnl Output accumulated flags to the Makefile files. AC_SUBST([AM_CPPFLAGS]) AC_SUBST([AM_CFLAGS]) AC_SUBST([AM_CXXFLAGS]) AC_CONFIG_FILES([Makefile macros/Makefile include/Makefile lib/Makefile src/Makefile security/Makefile c++/Makefile bindings/Makefile doc/Makefile doc/hamlib.cfg rotators/amsat/Makefile rotators/apex/Makefile rotators/ars/Makefile rotators/celestron/Makefile rotators/cnctrk/Makefile rotators/grbltrk/Makefile rotators/easycomm/Makefile rotators/ether6/Makefile rotators/flir/Makefile rotators/fodtrack/Makefile rotators/gs232a/Makefile rotators/heathkit/Makefile rotators/ioptron/Makefile rotators/m2/Makefile rotators/meade/Makefile rotators/prosistel/Makefile rotators/rotorez/Makefile rotators/sartek/Makefile rotators/saebrtrack/Makefile rotators/spid/Makefile rotators/ts7400/Makefile rotators/indi/Makefile rotators/satel/Makefile rotators/skywatcher/Makefile rotators/radant/Makefile rigs/adat/Makefile rigs/alinco/Makefile rigs/aor/Makefile rigs/barrett/Makefile rigs/codan/Makefile rigs/commradio/Makefile rigs/dorji/Makefile rigs/drake/Makefile rigs/dummy/Makefile rigs/elad/Makefile rigs/flexradio/Makefile rigs/icmarine/Makefile rigs/icom/Makefile rigs/jrc/Makefile rigs/kachina/Makefile rigs/kenwood/Makefile rigs/kit/Makefile rigs/lowe/Makefile rigs/pcr/Makefile rigs/prm80/Makefile rigs/racal/Makefile rigs/rft/Makefile rigs/rs/Makefile rigs/skanti/Makefile rigs/tapr/Makefile rigs/tentec/Makefile rigs/tuner/Makefile rigs/uniden/Makefile rigs/winradio/Makefile rigs/wj/Makefile rigs/yaesu/Makefile rigs/gomspace/Makefile rigs/mds/Makefile rigs/anytone/Makefile rigs/motorola/Makefile tests/Makefile scripts/Makefile android/Makefile amplifiers/elecraft/Makefile amplifiers/gemini/Makefile amplifiers/expert/Makefile simulators/Makefile hamlib.pc ]) AC_OUTPUT echo \ "---------------------------------------------------------------------- ${PACKAGE_NAME} Version ${PACKAGE_VERSION} configuration: Prefix ${prefix} Preprocessor ${CPP} ${CPPFLAGS} C Compiler ${CC} ${CFLAGS} C++ Compiler ${CXX} ${CXXFLAGS} Package features: With C++ binding ${cf_with_cxx_binding} With Perl binding ${cf_with_perl_binding} With Python binding ${cf_with_python_binding} With TCL binding ${build_tcl} With Lua binding ${cf_with_lua_binding} With rigmem XML support ${cf_with_xml_support} With Readline support ${cf_with_readline_support} With INDI support ${cf_with_indi_support} Enable HTML rig feature matrix ${cf_enable_html_matrix} Enable WinRadio ${cf_with_winradio} Enable Parallel ${cf_with_parallel} Enable USRP ${cf_with_usrp} Enable USB backends ${cf_with_libusb} Enable shared libs ${enable_shared} Enable static libs ${enable_static} -----------------------------------------------------------------------" hamlib-4.6.5/COPYING0000664000175000017500000004325415056640442007516 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. hamlib-4.6.5/src/0000775000175000017500000000000015056640474007327 5hamlib-4.6.5/src/mem.c0000664000175000017500000011656615056640443010204 /** \addtogroup rig * @{ */ /** * \file src/mem.c * \brief Memory and channel interface * \author Stephane Fillod * \date 2000-2011 * * Hamlib interface is a frontend implementing wrapper functions. * */ /* * Hamlib Interface - mem/channel calls * Copyright (c) 2000-2011 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #ifndef DOC_HIDDEN #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state) #endif /* !DOC_HIDDEN */ /** * \brief set the current memory channel number * \param rig The rig handle * \param vfo The target VFO * \param ch The memory channel number * * Sets the current memory channel number. * It is not mandatory for the radio to be in memory mode. Actually * it depends on rigs. YMMV. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mem() */ int HAMLIB_API rig_set_mem(RIG *rig, vfo_t vfo, int ch) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_mem == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_MEM) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->set_mem(rig, vfo, ch); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_mem(rig, vfo, ch); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the current memory channel number * \param rig The rig handle * \param vfo The target VFO * \param ch The location where to store the current memory channel number * * Retrieves the current memory channel number. * It is not mandatory for the radio to be in memory mode. Actually * it depends on rigs. YMMV. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_mem() */ int HAMLIB_API rig_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !ch) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_mem == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_MEM) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->get_mem(rig, vfo, ch); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_mem(rig, vfo, ch); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set the current memory bank * \param rig The rig handle * \param vfo The target VFO * \param bank The memory bank * * Sets the current memory bank number. * It is not mandatory for the radio to be in memory mode. Actually * it depends on rigs. YMMV. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_mem() */ int HAMLIB_API rig_set_bank(RIG *rig, vfo_t vfo, int bank) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_bank == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_BANK) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->set_bank(rig, vfo, bank); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_bank(rig, vfo, bank); caps->set_vfo(rig, curr_vfo); return retcode; } #ifndef DOC_HIDDEN /* * call on every ext_levels of a rig */ static int generic_retr_extl(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { channel_t *chan = (channel_t *)ptr; struct ext_list *p; if (chan->ext_levels == NULL) { p = chan->ext_levels = calloc(1, 2 * sizeof(struct ext_list)); } else { unsigned el_size = 0; for (p = chan->ext_levels; !RIG_IS_EXT_END(*p); p++) { el_size += sizeof(struct ext_list); } chan->ext_levels = realloc(chan->ext_levels, el_size + sizeof(struct ext_list)); } if (!chan->ext_levels) { rig_debug(RIG_DEBUG_ERR, "%s: %d memory allocation error!\n", __func__, __LINE__); return -RIG_ENOMEM; } p->token = cfp->token; rig_get_ext_level(rig, RIG_VFO_CURR, p->token, &p->val); p++; p->token = 0; /* RIG_EXT_END */ return 1; /* process them all */ } static const channel_cap_t mem_cap_all = { .bank_num = 1, .vfo = 1, .ant = 1, .freq = 1, .mode = 1, .width = 1, .tx_freq = 1, .tx_mode = 1, .tx_width = 1, .split = 1, .tx_vfo = 1, .rptr_shift = 1, .rptr_offs = 1, .tuning_step = 1, .rit = 1, .xit = 1, .funcs = (setting_t) - 1, .levels = (setting_t) - 1, .ctcss_tone = 1, .ctcss_sql = 1, .dcs_code = 1, .dcs_sql = 1, .scan_group = 1, .flags = 1, .channel_desc = 1, .ext_levels = 1, }; static int rig_mem_caps_empty(const channel_cap_t *mem_cap) { return !( mem_cap->bank_num || mem_cap->vfo || mem_cap->ant || mem_cap->freq || mem_cap->mode || mem_cap->width || mem_cap->tx_freq || mem_cap->tx_mode || mem_cap->tx_width || mem_cap->split || mem_cap->tx_vfo || mem_cap->rptr_shift || mem_cap->rptr_offs || mem_cap->tuning_step || mem_cap->rit || mem_cap->xit || mem_cap->funcs || mem_cap->levels || mem_cap->ctcss_tone || mem_cap->ctcss_sql || mem_cap->dcs_code || mem_cap->dcs_sql || mem_cap->scan_group || mem_cap->flags || mem_cap->channel_desc || mem_cap->ext_levels ); } /* * stores current VFO state into chan by emulating rig_get_channel */ static int generic_save_channel(RIG *rig, channel_t *chan) { int i; int chan_num; vfo_t vfo; setting_t setting; const channel_cap_t *mem_cap = NULL; value_t vdummy = {0}; chan_num = chan->channel_num; vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = chan_num; chan->vfo = vfo; if (vfo == RIG_VFO_MEM) { const chan_t *chan_cap; chan_cap = rig_lookup_mem_caps(rig, chan_num); if (chan_cap) { mem_cap = &chan_cap->mem_caps; } } /* If vfo!=RIG_VFO_MEM or incomplete backend, try all properties */ if (mem_cap == NULL || rig_mem_caps_empty(mem_cap)) { mem_cap = &mem_cap_all; } if (mem_cap->freq) { int retval = rig_get_freq(rig, RIG_VFO_CURR, &chan->freq); /* empty channel ? */ if (retval == -RIG_ENAVAIL || chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } } if (mem_cap->vfo) { rig_get_vfo(rig, &chan->vfo); } if (mem_cap->mode || mem_cap->width) { rig_get_mode(rig, RIG_VFO_CURR, &chan->mode, &chan->width); } chan->split = RIG_SPLIT_OFF; if (mem_cap->split) { rig_get_split_vfo(rig, RIG_VFO_CURR, &chan->split, &chan->tx_vfo); } if (chan->split != RIG_SPLIT_OFF) { if (mem_cap->tx_freq) { rig_get_split_freq(rig, RIG_VFO_CURR, &chan->tx_freq); } if (mem_cap->tx_mode || mem_cap->tx_width) { rig_get_split_mode(rig, RIG_VFO_CURR, &chan->tx_mode, &chan->tx_width); } } else { chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; } if (mem_cap->rptr_shift) { rig_get_rptr_shift(rig, RIG_VFO_CURR, &chan->rptr_shift); } if (mem_cap->rptr_offs) { rig_get_rptr_offs(rig, RIG_VFO_CURR, &chan->rptr_offs); } if (mem_cap->ant) { ant_t ant_tx, ant_rx; rig_get_ant(rig, RIG_VFO_CURR, RIG_ANT_CURR, &vdummy, &chan->ant, &ant_tx, &ant_rx); } if (mem_cap->tuning_step) { rig_get_ts(rig, RIG_VFO_CURR, &chan->tuning_step); } if (mem_cap->rit) { rig_get_rit(rig, RIG_VFO_CURR, &chan->rit); } if (mem_cap->xit) { rig_get_xit(rig, RIG_VFO_CURR, &chan->xit); } for (i = 0; i < RIG_SETTING_MAX; i++) { setting = rig_idx2setting(i); if ((setting & mem_cap->levels) && RIG_LEVEL_SET(setting)) { rig_get_level(rig, RIG_VFO_CURR, setting, &chan->levels[i]); } } for (i = 0; i < RIG_SETTING_MAX; i++) { int fstatus; setting = rig_idx2setting(i); if ((setting & mem_cap->funcs) && (rig_get_func(rig, RIG_VFO_CURR, setting, &fstatus) == RIG_OK)) { chan->funcs |= fstatus ? setting : 0; } } if (mem_cap->ctcss_tone) { rig_get_ctcss_tone(rig, RIG_VFO_CURR, &chan->ctcss_tone); } if (mem_cap->ctcss_sql) { rig_get_ctcss_sql(rig, RIG_VFO_CURR, &chan->ctcss_sql); } if (mem_cap->dcs_code) { rig_get_dcs_code(rig, RIG_VFO_CURR, &chan->dcs_code); } if (mem_cap->dcs_sql) { rig_get_dcs_sql(rig, RIG_VFO_CURR, &chan->dcs_sql); } /* * TODO: (missing calls) * - channel_desc * - bank_num * - scan_group * - flags */ rig_ext_level_foreach(rig, generic_retr_extl, (rig_ptr_t)chan); return RIG_OK; } /* * Restores chan into current VFO state by emulating rig_set_channel */ static int generic_restore_channel(RIG *rig, const channel_t *chan) { int i; struct ext_list *p; setting_t setting; const channel_cap_t *mem_cap = NULL; value_t vdummy = {0}; if (chan->vfo == RIG_VFO_MEM) { const chan_t *chan_cap; chan_cap = rig_lookup_mem_caps(rig, chan->channel_num); if (chan_cap) { mem_cap = &chan_cap->mem_caps; } } /* If vfo!=RIG_VFO_MEM or incomplete backend, try all properties */ if (mem_cap == NULL || rig_mem_caps_empty(mem_cap)) { mem_cap = &mem_cap_all; } rig_set_vfo(rig, chan->vfo); if (mem_cap->freq) { rig_set_freq(rig, RIG_VFO_CURR, chan->freq); } if (mem_cap->mode || mem_cap->width) { rig_set_mode(rig, RIG_VFO_CURR, chan->mode, chan->width); } rig_set_split_vfo(rig, RIG_VFO_CURR, chan->split, chan->tx_vfo); if (chan->split != RIG_SPLIT_OFF) { if (mem_cap->tx_freq) { rig_set_split_freq(rig, RIG_VFO_CURR, chan->tx_freq); } if (mem_cap->tx_mode || mem_cap->tx_width) { rig_set_split_mode(rig, RIG_VFO_CURR, chan->tx_mode, chan->tx_width); } } if (mem_cap->rptr_shift) { rig_set_rptr_shift(rig, RIG_VFO_CURR, chan->rptr_shift); } if (mem_cap->rptr_offs) { rig_set_rptr_offs(rig, RIG_VFO_CURR, chan->rptr_offs); } for (i = 0; i < RIG_SETTING_MAX; i++) { setting = rig_idx2setting(i); if (setting & mem_cap->levels) { rig_set_level(rig, RIG_VFO_CURR, setting, chan->levels[i]); } } if (mem_cap->ant) { rig_set_ant(rig, RIG_VFO_CURR, chan->ant, vdummy); } if (mem_cap->tuning_step) { rig_set_ts(rig, RIG_VFO_CURR, chan->tuning_step); } if (mem_cap->rit) { rig_set_rit(rig, RIG_VFO_CURR, chan->rit); } if (mem_cap->xit) { rig_set_xit(rig, RIG_VFO_CURR, chan->xit); } for (i = 0; i < RIG_SETTING_MAX; i++) { setting = rig_idx2setting(i); if (setting & mem_cap->funcs) rig_set_func(rig, RIG_VFO_CURR, setting, chan->funcs & rig_idx2setting(i)); } if (mem_cap->ctcss_tone) { rig_set_ctcss_tone(rig, RIG_VFO_CURR, chan->ctcss_tone); } if (mem_cap->ctcss_sql) { rig_set_ctcss_sql(rig, RIG_VFO_CURR, chan->ctcss_sql); } if (mem_cap->dcs_code) { rig_set_dcs_code(rig, RIG_VFO_CURR, chan->dcs_code); } if (mem_cap->dcs_sql) { rig_set_dcs_sql(rig, RIG_VFO_CURR, chan->dcs_sql); } /* * TODO: (missing calls) * - channel_desc * - bank_num * - scan_group * - flags */ for (p = chan->ext_levels; p && !RIG_IS_EXT_END(*p); p++) { rig_set_ext_level(rig, RIG_VFO_CURR, p->token, p->val); } return RIG_OK; } #endif /* !DOC_HIDDEN */ /** * \brief set channel data * \param rig The rig handle * \param chan The location of data to set for this channel * * Sets the data associated with a channel. This channel can either * be the state of a VFO specified by \a chan->vfo, or a memory channel * specified with \a chan->vfo = RIG_VFO_MEM and \a chan->channel_num. * See #channel_t for more information. * * The rig_set_channel is supposed to have no impact on the current VFO * and memory number selected. Depending on backend and rig capabilities, * the chan struct may not be set completely. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_channel() */ int HAMLIB_API rig_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct rig_caps *rc; int curr_chan_num = -1, get_mem_status = RIG_OK; vfo_t curr_vfo; vfo_t vfotmp; /* requested vfo */ int retcode; int can_emulate_by_vfo_mem, can_emulate_by_vfo_op; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan) { return -RIG_EINVAL; } /* * TODO: check validity of chan->channel_num */ rc = rig->caps; if (rc->set_channel) { return rc->set_channel(rig, vfo, chan); } /* * if not available, emulate it * Optional: get_vfo, set_vfo, */ vfotmp = chan->vfo; if (vfotmp == RIG_VFO_CURR) { return generic_restore_channel(rig, chan); } /* any emulation requires set_mem() */ if (vfotmp == RIG_VFO_MEM && !rc->set_mem) { return -RIG_ENAVAIL; } can_emulate_by_vfo_mem = rc->set_vfo && ((STATE(rig)->vfo_list & RIG_VFO_MEM) == RIG_VFO_MEM); can_emulate_by_vfo_op = rc->vfo_op && rig_has_vfo_op(rig, RIG_OP_FROM_VFO); if (!can_emulate_by_vfo_mem && !can_emulate_by_vfo_op) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; if (vfotmp == RIG_VFO_MEM) { get_mem_status = rig_get_mem(rig, RIG_VFO_CURR, &curr_chan_num); } if (can_emulate_by_vfo_mem && curr_vfo != vfotmp) { retcode = rig_set_vfo(rig, vfotmp); if (retcode != RIG_OK) { return retcode; } } if (vfotmp == RIG_VFO_MEM) { rig_set_mem(rig, RIG_VFO_CURR, chan->channel_num); } retcode = generic_restore_channel(rig, chan); if (!can_emulate_by_vfo_mem && can_emulate_by_vfo_op) { retcode = rig_vfo_op(rig, RIG_VFO_CURR, RIG_OP_FROM_VFO); if (retcode != RIG_OK) { return retcode; } } /* restore current memory number */ if (vfotmp == RIG_VFO_MEM && get_mem_status == RIG_OK) { rig_set_mem(rig, RIG_VFO_CURR, curr_chan_num); } if (can_emulate_by_vfo_mem) { rig_set_vfo(rig, curr_vfo); } return retcode; } /** * \brief get channel data * \param rig The rig handle * \param chan The location where to store the channel data * \param read_only if true chan info will be filled but rig will not change, if false rig will update to chan info * * Retrieves the data associated with a channel. This channel can either * be the state of a VFO specified by \a chan->vfo, or a memory channel * specified with \a chan->vfo = RIG_VFO_MEM and \a chan->channel_num. * See #channel_t for more information. * * Example: \code channel_t chan; int err; chan->vfo = RIG_VFO_MEM; chan->channel_num = 10; chan->read_only = 1; err = rig_get_channel(rig, &chan); if (err != RIG_OK) error("get_channel failed: %s", rigerror(err)); \endcode * * The rig_get_channel is supposed to have no impact on the current VFO * and memory number selected. Depending on backend and rig capabilities, * the chan struct may not be filled in completely. * * Note: chan->ext_levels is a pointer to a newly allocated memory. * This is the responsibility of the caller to manage and eventually * free it. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_channel() */ int HAMLIB_API rig_get_channel(RIG *rig, vfo_t vfox, channel_t *chan, int read_only) { struct rig_caps *rc; int curr_chan_num = -1, get_mem_status = RIG_OK; vfo_t curr_vfo; vfo_t vfotmp = RIG_VFO_NONE; /* requested vfo */ int retcode = RIG_OK; int can_emulate_by_vfo_mem, can_emulate_by_vfo_op; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan) { return -RIG_EINVAL; } /* * TODO: check validity of chan->channel_num */ rc = rig->caps; if (rc->get_channel) { return rc->get_channel(rig, vfotmp, chan, read_only); } /* * if not available, emulate it * Optional: get_vfo, set_vfo * TODO: check return codes */ vfotmp = chan->vfo; if (vfotmp == RIG_VFO_CURR) { return generic_save_channel(rig, chan); } /* any emulation requires set_mem() */ if (vfotmp == RIG_VFO_MEM && !rc->set_mem) { return -RIG_ENAVAIL; } can_emulate_by_vfo_mem = rc->set_vfo && ((STATE(rig)->vfo_list & RIG_VFO_MEM) == RIG_VFO_MEM); can_emulate_by_vfo_op = rc->vfo_op && rig_has_vfo_op(rig, RIG_OP_TO_VFO); if (!can_emulate_by_vfo_mem && !can_emulate_by_vfo_op) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; if (vfotmp == RIG_VFO_MEM) { get_mem_status = rig_get_mem(rig, RIG_VFO_CURR, &curr_chan_num); } if (!read_only) { if (can_emulate_by_vfo_mem && curr_vfo != vfotmp) { retcode = rig_set_vfo(rig, vfotmp); if (retcode != RIG_OK) { return retcode; } } if (vfotmp == RIG_VFO_MEM) { rig_set_mem(rig, RIG_VFO_CURR, chan->channel_num); } if (!can_emulate_by_vfo_mem && can_emulate_by_vfo_op) { retcode = rig_vfo_op(rig, RIG_VFO_CURR, RIG_OP_TO_VFO); if (retcode != RIG_OK) { return retcode; } } retcode = generic_save_channel(rig, chan); /* restore current memory number */ if (vfotmp == RIG_VFO_MEM && get_mem_status == RIG_OK) { rig_set_mem(rig, RIG_VFO_CURR, curr_chan_num); } if (can_emulate_by_vfo_mem) { rig_set_vfo(rig, curr_vfo); } } return retcode; } #ifndef DOC_HIDDEN int get_chan_all_cb_generic(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j; chan_t *chan_list = STATE(rig)->chan_list; channel_t *chan; for (i = 0; !RIG_IS_CHAN_END(chan_list[i]) && i < HAMLIB_CHANLSTSIZ; i++) { int retval; /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; retval = chan_cb(rig, vfo, &chan, chan_list[i].startc, chan_list, arg); if (retval != RIG_OK) { return retval; } if (chan == NULL) { return -RIG_ENOMEM; } for (j = chan_list[i].startc; j <= chan_list[i].endc; j++) { int chan_next; chan->vfo = RIG_VFO_MEM; chan->channel_num = j; /* * TODO: if doesn't have rc->get_channel, special generic */ retval = rig_get_channel(rig, vfo, chan, 1); if (retval == -RIG_ENAVAIL) { /* * empty channel * * Should it continue or call chan_cb with special arg? */ continue; } if (retval != RIG_OK) { return retval; } chan_next = j < chan_list[i].endc ? j + 1 : j; chan_cb(rig, vfo, &chan, chan_next, chan_list, arg); } } return RIG_OK; } int set_chan_all_cb_generic(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, retval; chan_t *chan_list = STATE(rig)->chan_list; channel_t *chan; for (i = 0; !RIG_IS_CHAN_END(chan_list[i]) && i < HAMLIB_CHANLSTSIZ; i++) { for (j = chan_list[i].startc; j <= chan_list[i].endc; j++) { chan_cb(rig, vfo, &chan, j, chan_list, arg); chan->vfo = RIG_VFO_MEM; retval = rig_set_channel(rig, vfo, chan); if (retval != RIG_OK) { return retval; } } } return RIG_OK; } struct map_all_s { channel_t *chans; const struct confparams *cfgps; value_t *vals; }; /* * chan_cb_t to be used for non cb get/set_all */ static int map_chan(RIG *rig, vfo_t vfo, channel_t **chan, int channel_num, const chan_t *chan_list, rig_ptr_t arg) { struct map_all_s *map_arg = (struct map_all_s *)arg; /* TODO: check channel_num within start-end of chan_list */ *chan = &map_arg->chans[channel_num]; return RIG_OK; } #endif /* DOC_HIDDEN */ /** * \brief set all channel data, by callback * \param rig The rig handle * \param chan_cb Pointer to a callback function to provide channel data * \param arg Arbitrary argument passed back to \a chan_cb * * Write the data associated with a all the memory channels. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_chan_all(), rig_get_chan_all_cb() */ int HAMLIB_API rig_set_chan_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->set_chan_all_cb) { return rc->set_chan_all_cb(rig, vfo, chan_cb, arg); } /* if not available, emulate it */ retval = set_chan_all_cb_generic(rig, vfo, chan_cb, arg); return retval; } /** * \brief get all channel data, by callback * \param rig The rig handle * \param chan_cb Pointer to a callback function to retrieve channel data * \param arg Arbitrary argument passed back to \a chan_cb * * Retrieves the data associated with a all the memory channels. * This is the preferred method to support clonable rigs. * * \a chan_cb is called first with no data in chan (chan equals NULL). * This means the application has to provide a struct where to store * future data for channel channel_num. If channel_num == chan->channel_num, * the application does not need to provide a new allocated structure. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_chan_all(), rig_set_chan_all_cb() */ int HAMLIB_API rig_get_chan_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->get_chan_all_cb) { return rc->get_chan_all_cb(rig, vfo, chan_cb, arg); } /* if not available, emulate it */ retval = get_chan_all_cb_generic(rig, vfo, chan_cb, arg); return retval; } /** * \brief set all channel data * \param rig The rig handle * \param chans The location of data to set for all channels * * Write the data associated with all the memory channels. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_chan_all_cb(), rig_get_chan_all() */ int HAMLIB_API rig_set_chan_all(RIG *rig, vfo_t vfo, const channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans) { return -RIG_EINVAL; } rc = rig->caps; memset(&map_arg, 0, sizeof(map_arg)); map_arg.chans = (channel_t *) chans; if (rc->set_chan_all_cb) { return rc->set_chan_all_cb(rig, vfo, map_chan, (rig_ptr_t)&map_arg); } /* if not available, emulate it */ retval = set_chan_all_cb_generic(rig, vfo, map_chan, (rig_ptr_t)&map_arg); return retval; } /** * \brief get all channel data * \param rig The rig handle * \param chans The location where to store all the channel data * * Retrieves the data associated with all the memory channels. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_chan_all_cb(), rig_set_chan_all() */ int HAMLIB_API rig_get_chan_all(RIG *rig, vfo_t vfo, channel_t chans[]) { struct rig_caps *rc; struct map_all_s map_arg; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans) { return -RIG_EINVAL; } rc = rig->caps; memset(&map_arg, 0, sizeof(map_arg)); map_arg.chans = chans; if (rc->get_chan_all_cb) { return rc->get_chan_all_cb(rig, vfo, map_chan, (rig_ptr_t)&map_arg); } /* * if not available, emulate it * * TODO: save_current_state, restore_current_state */ retval = get_chan_all_cb_generic(rig, vfo, map_chan, (rig_ptr_t)&map_arg); return retval; } /** * \brief copy channel structure to another channel structure * \param rig The rig handle * \param dest The destination location * \param src The source location * * Copies the data associated with one channel structure to another * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_chan_all_cb(), rig_set_chan_all() */ int HAMLIB_API rig_copy_channel(RIG *rig, channel_t *dest, const channel_t *src) { struct ext_list *saved_ext_levels; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* TODO: ext_levels[] of different sizes */ for (i = 0; !RIG_IS_EXT_END(src->ext_levels[i]) && !RIG_IS_EXT_END(dest->ext_levels[i]); i++) { dest->ext_levels[i] = src->ext_levels[i]; } saved_ext_levels = dest->ext_levels; memcpy(dest, src, sizeof(channel_t)); dest->ext_levels = saved_ext_levels; return RIG_OK; } #ifndef DOC_HIDDEN static int map_parm(RIG *rig, const struct confparams *cfgps, value_t *value, rig_ptr_t arg) { return -RIG_ENIMPL; } int get_parm_all_cb_generic(RIG *rig, vfo_t vfo, confval_cb_t parm_cb, rig_ptr_t cfgps, rig_ptr_t vals) { return -RIG_ENIMPL; } int set_parm_all_cb_generic(RIG *rig, vfo_t vfo, confval_cb_t parm_cb, rig_ptr_t cfgps, rig_ptr_t vals) { return -RIG_ENIMPL; } #endif /* DOC_HIDDEN */ /** * \brief set all channel and non-channel data by call-back * \param rig The rig handle * \param chan_cb The callback for channel data * \param parm_cb The callback for non-channel(aka parm) data * \param arg Cookie passed to \a chan_cb and \a parm_cb * * Writes the data associated with all the memory channels, * and rigs memory parameters, by callback. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mem_all_cb(), rig_set_mem_all() * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_set_mem_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, confval_cb_t parm_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->set_mem_all_cb) { return rc->set_mem_all_cb(rig, vfo, chan_cb, parm_cb, arg); } /* if not available, emulate it */ retval = rig_set_chan_all_cb(rig, vfo, chan_cb, arg); if (retval != RIG_OK) { return retval; } #if 0 retval = rig_set_parm_all_cb(rig, parm_cb, arg); if (retval != RIG_OK) { return retval; } #else return -RIG_ENIMPL; #endif return retval; } /** * \brief get all channel and non-channel data by call-back * \param rig The rig handle * \param chan_cb The callback for channel data * \param parm_cb The callback for non-channel(aka parm) data * \param arg Cookie passed to \a chan_cb and \a parm_cb * * Retrieves the data associated with all the memory channels, * and rigs memory parameters, by callback. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mem_all_cb(), rig_set_mem_all() * * \todo get all parm's * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_get_mem_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, confval_cb_t parm_cb, rig_ptr_t arg) { struct rig_caps *rc; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chan_cb) { return -RIG_EINVAL; } rc = rig->caps; if (rc->get_mem_all_cb) { return rc->get_mem_all_cb(rig, vfo, chan_cb, parm_cb, arg); } /* if not available, emulate it */ retval = rig_get_chan_all_cb(rig, vfo, chan_cb, arg); if (retval != RIG_OK) { return retval; } #if 0 retval = rig_get_parm_cb(rig, parm_cb, arg); if (retval != RIG_OK) { return retval; } #else return -RIG_ENIMPL; #endif return retval; } /** * \brief set all channel and non-channel data * \param rig The rig handle * \param chans Channel data * \param cfgps ?? * \param vals ?? * * Writes the data associated with all the memory channels, * and rigs memory parameters. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mem_all(), rig_set_mem_all_cb() * * \todo set all parm's * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_set_mem_all(RIG *rig, vfo_t vfo, const channel_t chans[], const struct confparams cfgps[], const value_t vals[]) { struct rig_caps *rc; int retval; struct map_all_s mem_all_arg; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans || !cfgps || !vals) { return -RIG_EINVAL; } rc = rig->caps; mem_all_arg.chans = (channel_t *) chans; mem_all_arg.cfgps = cfgps; mem_all_arg.vals = (value_t *) vals; if (rc->set_mem_all_cb) return rc->set_mem_all_cb(rig, vfo, map_chan, map_parm, (rig_ptr_t)&mem_all_arg); /* if not available, emulate it */ retval = rig_set_chan_all(rig, vfo, chans); if (retval != RIG_OK) { return retval; } #if 0 retval = rig_set_parm_all(rig, parms); if (retval != RIG_OK) { return retval; } #else return -RIG_ENIMPL; #endif return retval; } /** * \brief get all channel and non-channel data * \param rig The rig handle * \param chans Array of channels where to store the data * \param cfgps Array of config parameters to retrieve * \param vals Array of values where to store the data * * Retrieves the data associated with all the memory channels, * and rigs memory parameters. * This is the preferred method to support clonable rigs. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mem_all(), rig_set_mem_all_cb() * \todo finish coding and testing of mem_all functions */ int HAMLIB_API rig_get_mem_all(RIG *rig, vfo_t vfo, channel_t chans[], const struct confparams cfgps[], value_t vals[]) { struct rig_caps *rc; int retval; struct map_all_s mem_all_arg; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !chans || !cfgps || !vals) { return -RIG_EINVAL; } rc = rig->caps; mem_all_arg.chans = chans; mem_all_arg.cfgps = cfgps; mem_all_arg.vals = vals; if (rc->get_mem_all_cb) return rc->get_mem_all_cb(rig, vfo, map_chan, map_parm, (rig_ptr_t)&mem_all_arg); /* * if not available, emulate it * * TODO: save_current_state, restore_current_state */ retval = rig_get_chan_all(rig, vfo, chans); if (retval != RIG_OK) { return retval; } retval = get_parm_all_cb_generic(rig, vfo, map_parm, (rig_ptr_t)cfgps, (rig_ptr_t)vals); return retval; } /** * \brief lookup the memory type and capabilities * \param rig The rig handle * \param ch The memory channel number * * Lookup the memory type and capabilities associated with a channel number. * If \a ch equals RIG_MEM_CAPS_ALL, then a union of all the mem_caps sets * is returned (pointer to static memory). * * \return a pointer to a chan_t structure if the operation has been successful, * otherwise a NULL pointer, most probably because of incorrect channel number * or buggy backend. */ const chan_t *HAMLIB_API rig_lookup_mem_caps(RIG *rig, int ch) { chan_t *chan_list; static chan_t chan_list_all; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return NULL; } if (ch == RIG_MEM_CAPS_ALL) { memset(&chan_list_all, 0, sizeof(chan_list_all)); chan_list = STATE(rig)->chan_list; chan_list_all.startc = chan_list[0].startc; chan_list_all.type = RIG_MTYPE_NONE; /* meaningless */ for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { int j; unsigned char *p1, *p2; p1 = (unsigned char *)&chan_list_all.mem_caps; p2 = (unsigned char *)&chan_list[i].mem_caps; /* It's kind of hackish, we just want to do update set with: * chan_list_all.mem_caps |= chan_list[i].mem_caps */ for (j = 0; j < sizeof(channel_cap_t); j++) { p1[j] |= p2[j]; } /* til the end, most probably meaningless */ chan_list_all.endc = chan_list[i].endc; } return &chan_list_all; } chan_list = STATE(rig)->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (ch >= chan_list[i].startc && ch <= chan_list[i].endc) { return &chan_list[i]; } } return NULL; } // Not referenced anywhere /** * \brief get memory channel count * \param rig The rig handle * * Get the total memory channel count, computed from the rig caps * * \return the memory count */ int HAMLIB_API rig_mem_count(RIG *rig) { const chan_t *chan_list; int i, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } chan_list = STATE(rig)->chan_list; count = 0; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { count += chan_list[i].endc - chan_list[i].startc + 1; } return count; } /*! @} */ hamlib-4.6.5/src/serial.h0000664000175000017500000000351315056640443010675 /* * Hamlib Interface - serial communication header * Copyright (c) 2000-2005 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _SERIAL_H #define _SERIAL_H 1 #include #include "iofunc.h" __BEGIN_DECLS extern HAMLIB_EXPORT(int) serial_open(hamlib_port_t *rs); extern HAMLIB_EXPORT(int) serial_setup(hamlib_port_t *rs); extern HAMLIB_EXPORT(int) serial_flush(hamlib_port_t *p); /* Hamlib internal use, see rig.c */ int ser_open(hamlib_port_t *p); int ser_close(hamlib_port_t *p); extern HAMLIB_EXPORT(int) ser_set_rts(hamlib_port_t *p, int state); extern HAMLIB_EXPORT(int) ser_get_rts(hamlib_port_t *p, int *state); extern HAMLIB_EXPORT(int) ser_set_brk(const hamlib_port_t *p, int state); extern HAMLIB_EXPORT(int) ser_set_dtr(hamlib_port_t *p, int state); extern HAMLIB_EXPORT(int) ser_get_dtr(hamlib_port_t *p, int *state); extern HAMLIB_EXPORT(int) ser_get_cts(hamlib_port_t *p, int *state); extern HAMLIB_EXPORT(int) ser_get_dsr(hamlib_port_t *p, int *state); extern HAMLIB_EXPORT(int) ser_get_car(hamlib_port_t *p, int *state); __END_DECLS #endif /* _SERIAL_H */ hamlib-4.6.5/src/ext.c0000664000175000017500000002006415056640443010211 /* * Hamlib Interface - rig ext parameter interface * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig * @{ */ /** * \file ext.c * \brief Extension request parameter interface * * An open-ended set of extension parameters, functions and levels are available * for each rig, as provided in the rigcaps extparms, extfuncs and extlevels lists. * These provide a way to work with rig-specific functions that don't fit into the * basic "virtual rig" of Hamlib. See icom/ic746.c for an example. */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include "token.h" static int rig_has_ext_token(RIG *rig, hamlib_token_t token) { const int *ext_tokens = rig->caps->ext_tokens; int i; if (ext_tokens == NULL) { // Assume that all listed extfuncs/extlevels/extparms are supported if // the ext_tokens list is not defined to preserve backwards-compatibility return 1; } for (i = 0; ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (ext_tokens[i] == token) { return 1; } } return 0; } /** * \param rig The rig handle * \param cfunc callback function of each extfunc * \param data cookie to be passed to \a cfunc callback * \brief Executes cfunc on all the elements stored in the extfuncs table * * The callback \a cfunc is called until it returns a value which is not * strictly positive. A zero value means a normal end of iteration, and a * negative value an abnormal end, which will be the return value of * rig_ext_func_foreach. */ int HAMLIB_API rig_ext_func_foreach(RIG *rig, int (*cfunc)(RIG *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rig->caps->extfuncs; cfp && cfp->name; cfp++) { if (!rig_has_ext_token(rig, cfp->token)) { continue; } int ret = (*cfunc)(rig, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \param rig The rig handle * \param cfunc callback function of each extlevel * \param data cookie to be passed to \a cfunc callback * \brief Executes cfunc on all the elements stored in the extlevels table * * The callback \a cfunc is called until it returns a value which is not * strictly positive. A zero value means a normal end of iteration, and a * negative value an abnormal end, which will be the return value of * rig_ext_level_foreach. */ int HAMLIB_API rig_ext_level_foreach(RIG *rig, int (*cfunc)(RIG *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rig->caps->extlevels; cfp && cfp->name; cfp++) { if (!rig_has_ext_token(rig, cfp->token)) { continue; } int ret = (*cfunc)(rig, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \param rig The rig handle * \param cfunc callback function of each extparm * \param data cookie to be passed to \a cfunc callback * \brief Executes cfunc on all the elements stored in the extparms table * * The callback \a cfunc is called until it returns a value which is not * strictly positive. A zero value means a normal end of iteration, and a * negative value an abnormal end, which will be the return value of * rig_ext_parm_foreach. */ int HAMLIB_API rig_ext_parm_foreach(RIG *rig, int (*cfunc)(RIG *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rig->caps->extparms; cfp && cfp->name; cfp++) { if (!rig_has_ext_token(rig, cfp->token)) { continue; } int ret = (*cfunc)(rig, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \param rig * \param name * \brief lookup ext token by its name, return pointer to confparams struct. * * Lookup extlevels table, then extfuncs, then extparms. * * Returns NULL if nothing found * * TODO: should use Lex to speed it up, strcmp hurts! */ const struct confparams *HAMLIB_API rig_ext_lookup(RIG *rig, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return NULL; } for (cfp = rig->caps->extlevels; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } for (cfp = rig->caps->extfuncs; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } for (cfp = rig->caps->extparms; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } return NULL; } /** * \param rig * \param token * \brief lookup ext token, return pointer to confparams struct. * * lookup extlevels table first, then extfuncs, then fall back to extparms. * * Returns NULL if nothing found */ const struct confparams *HAMLIB_API rig_ext_lookup_tok(RIG *rig, hamlib_token_t token) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return NULL; } for (cfp = rig->caps->extlevels; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } for (cfp = rig->caps->extfuncs; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } for (cfp = rig->caps->extparms; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } return NULL; } /** * \param rig * \param name * \brief Simple lookup returning token id associated with name */ hamlib_token_t HAMLIB_API rig_ext_token_lookup(RIG *rig, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); cfp = rig_ext_lookup(rig, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** @} */ hamlib-4.6.5/src/amplifier.c0000664000175000017500000005620015056640443011362 /* * Hamlib Interface - main file * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * Copyright (C) 2019-2020 by Michael Black * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup amplifier * @{ */ /** * \file src/amplifier.c * \brief Amplifier interface * \author Stephane Fillod * \date 2000-2012 * \author Frank Singleton * \date 2000-2003 * \author Michael Black * \date 2019-2020 * * This Hamlib interface is a frontend implementing the amplifier wrapper * functions. */ /** * \page amp Amplifier interface * * An amplifier can be any kind of external power amplifier that is capable of * CAT type control. */ #include #include #include #include #include #include #include #include "serial.h" #include "parallel.h" #include "usb_port.h" #include "network.h" #include "token.h" //! @cond Doxygen_Suppress #define CHECK_AMP_ARG(r) (!(r) || !(r)->caps || !AMPSTATE(r)->comm_state) //! @endcond /* * Data structure to track the opened amp (by amp_open) */ //! @cond Doxygen_Suppress struct opened_amp_l { AMP *amp; struct opened_amp_l *next; }; //! @endcond static struct opened_amp_l *opened_amp_list = { NULL }; /* * track which amp is opened (with amp_open) * needed at least for transceive mode */ static int add_opened_amp(AMP *amp) { struct opened_amp_l *p; p = (struct opened_amp_l *)calloc(1, sizeof(struct opened_amp_l)); if (!p) { return -RIG_ENOMEM; } p->amp = amp; p->next = opened_amp_list; opened_amp_list = p; return RIG_OK; } static int remove_opened_amp(const AMP *amp) { struct opened_amp_l *p, *q; q = NULL; for (p = opened_amp_list; p; p = p->next) { if (p->amp == amp) { if (q == NULL) { opened_amp_list = opened_amp_list->next; } else { q->next = p->next; } free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* Not found in list ! */ } #ifdef XXREMOVEDXX /** * \brief Executes cfunc() on each #AMP handle. * * \param cfunc The function to be executed on each #AMP handle. * \param data Data pointer to be passed to cfunc() * * Calls cfunc() function for each #AMP handle. The contents of the opened * #AMP table is processed in random order according to a function pointed to * by \a cfunc, which is called with two arguments, the first pointing to the * #AMP handle, the second to a data pointer \a data. * * If \a data is not needed, then it can be set to NULL. The processing of * the opened amp table is stopped when cfunc() returns 0. * \internal * * \return always RIG_OK. */ int foreach_opened_amp(int (*cfunc)(AMP *, rig_ptr_t), rig_ptr_t data) { struct opened_amp_l *p; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (p = opened_amp_list; p; p = p->next) { if ((*cfunc)(p->amp, data) == 0) { return RIG_OK; } } return RIG_OK; } #endif /** * \brief Allocate a new #AMP handle. * * \param amp_model The amplifier model for this new handle. * * Allocates a new #AMP handle and initializes the associated data * for \a amp_model (see amplist.h or `ampctl -l`). * * \return Pointer to the #AMP handle otherwise NULL if memory allocation * failed or \a amp_model is unknown, e.g. backend autoload failed. * * \sa amp_cleanup(), amp_open() */ AMP *HAMLIB_API amp_init(amp_model_t amp_model) { AMP *amp; const struct amp_caps *caps; struct amp_state *rs; hamlib_port_t *ap; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); amp_check_backend(amp_model); caps = amp_get_caps(amp_model); if (!caps) { return NULL; } /* * okay, we've found it. Allocate some memory and set it to zeros, * and especially the initialize the callbacks */ amp = calloc(1, sizeof(AMP)); if (amp == NULL) { /* * FIXME: how can the caller know it's a memory shortage, * and not "amp not found" ? */ return NULL; } /* caps is const, so we need to tell compiler that we know what we are doing */ amp->caps = (struct amp_caps *) caps; /* * populate the amp->state */ /** * \todo Read the Preferences here! */ rs = AMPSTATE(amp); //TODO allocate and link new ampport // For now, use the embedded one ap = AMPPORT(amp); rs->comm_state = 0; ap->type.rig = caps->port_type; /* default from caps */ ap->write_delay = caps->write_delay; ap->post_write_delay = caps->post_write_delay; ap->timeout = caps->timeout; ap->retry = caps->retry; rs->has_get_level = caps->has_get_level; switch (caps->port_type) { case RIG_PORT_SERIAL: // Don't think we need a default port here //strncpy(ap->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); ap->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ ap->parm.serial.data_bits = caps->serial_data_bits; ap->parm.serial.stop_bits = caps->serial_stop_bits; ap->parm.serial.parity = caps->serial_parity; ap->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: strncpy(ap->pathname, "127.0.0.1:4531", HAMLIB_FILPATHLEN - 1); break; default: strncpy(ap->pathname, "", HAMLIB_FILPATHLEN - 1); } ap->fd = -1; /* * let the backend a chance to setup his private data * This must be done only once defaults are setup, * so the backend init can override amp_state. */ if (caps->amp_init != NULL) { int retcode = caps->amp_init(amp); if (retcode != RIG_OK) { amp_debug(RIG_DEBUG_VERBOSE, "%s: backend_init failed!\n", __func__); /* cleanup and exit */ free(amp); return NULL; } } // Now we have to copy our new rig state hamlib_port structure to the deprecated one // Clients built on older 4.X versions will use the old structure // Clients built on newer 4.5 versions will use the new structure memcpy(&rs->ampport_deprecated, ap, sizeof(rs->ampport_deprecated)); return amp; } /** * \brief Open the communication channel to the amplifier. * * \param amp The #AMP handle of the amplifier to be opened. * * Opens the communication channel to an amplifier for which the #AMP handle * has been passed. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Communication channel successfully opened. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * * \sa amp_init(), amp_close() */ int HAMLIB_API amp_open(AMP *amp) { const struct amp_caps *caps; struct amp_state *rs; hamlib_port_t *ap = AMPPORT(amp); int status; int net1, net2, net3, net4, port; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return -RIG_EINVAL; } caps = amp->caps; rs = AMPSTATE(amp); if (rs->comm_state) { return -RIG_EINVAL; } ap->fd = -1; // determine if we have a network address if (sscanf(ap->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, ap->pathname); ap->type.rig = RIG_PORT_NETWORK; } switch (ap->type.rig) { case RIG_PORT_SERIAL: status = serial_open(ap); if (status != 0) { return status; } break; case RIG_PORT_PARALLEL: status = par_open(ap); if (status < 0) { return status; } break; case RIG_PORT_DEVICE: status = open(ap->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } ap->fd = status; break; case RIG_PORT_USB: status = usb_port_open(ap); if (status < 0) { return status; } break; case RIG_PORT_NONE: case RIG_PORT_RPC: break; /* ez :) */ case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: /* FIXME: default port */ status = network_open(ap, 4531); if (status < 0) { return status; } break; default: return -RIG_EINVAL; } add_opened_amp(amp); rs->comm_state = 1; /* * Maybe the backend has something to initialize * In case of failure, just close down and report error code. */ if (caps->amp_open != NULL) { status = caps->amp_open(amp); if (status != RIG_OK) { memcpy(&rs->ampport_deprecated, ap, sizeof(rs->ampport_deprecated)); return status; } } if (ap->parm.serial.dtr_state == RIG_SIGNAL_ON) { ser_set_dtr(ap, 1); } else { ser_set_dtr(ap, 0); } if (ap->parm.serial.rts_state == RIG_SIGNAL_ON) { ser_set_rts(ap, 1); } else { ser_set_rts(ap, 0); } memcpy(&rs->ampport_deprecated, ap, sizeof(rs->ampport_deprecated)); return RIG_OK; } /** * \brief Close the communication channel to the amplifier. * * \param amp The #AMP handle of the amplifier to be closed. * * Closes the communication channel to an amplifier for which the #AMP * handle has been passed by argument that was previously opened with * amp_open(). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Communication channel successfully closed. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * * \sa amp_cleanup(), amp_open() */ int HAMLIB_API amp_close(AMP *amp) { const struct amp_caps *caps; struct amp_state *rs; hamlib_port_t *ap = AMPPORT(amp); amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (amp == NULL) { amp_debug(RIG_DEBUG_ERR, "%s: NULL ptr? amp=%p\n", __func__, amp); return -RIG_EINVAL; } if (amp->caps == NULL) { amp_debug(RIG_DEBUG_ERR, "%s: NULL ptr? amp->caps=%p\n", __func__, amp->caps); return -RIG_EINVAL; } caps = amp->caps; rs = AMPSTATE(amp); if (!rs->comm_state) { amp_debug(RIG_DEBUG_ERR, "%s: comm_state=0? rs=%p, rs->comm_state=%d\n", __func__, rs, rs->comm_state); return -RIG_EINVAL; } /* * Let the backend say 73s to the amp. * and ignore the return code. */ if (caps->amp_close) { caps->amp_close(amp); } if (ap->fd != -1) { switch (ap->type.rig) { case RIG_PORT_SERIAL: ser_close(ap); break; case RIG_PORT_PARALLEL: par_close(ap); break; case RIG_PORT_USB: usb_port_close(ap); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: network_close(ap); break; default: close(ap->fd); } ap->fd = -1; } remove_opened_amp(amp); rs->comm_state = 0; return RIG_OK; } /** * \brief Release an #AMP handle and free associated memory. * * \param amp The #AMP handle to be released. * * Releases an #AMP handle for which the communications channel has been * closed with amp_close(). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK #AMP handle successfully released. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * * \sa amp_init(), amp_close() */ int HAMLIB_API amp_cleanup(AMP *amp) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return -RIG_EINVAL; } /* * check if they forgot to close the amp */ if (AMPSTATE(amp)->comm_state) { amp_close(amp); } /* * basically free up the priv struct */ if (amp->caps->amp_cleanup) { amp->caps->amp_cleanup(amp); } free(amp); return RIG_OK; } /** * \brief Reset the amplifier. * * \param amp The #AMP handle. * \param reset The reset operation to perform. * * Perform a reset of the amplifier. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The reset command was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#reset() capability is not available. */ int HAMLIB_API amp_reset(AMP *amp, amp_reset_t reset) { const struct amp_caps *caps; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } caps = amp->caps; if (caps->reset == NULL) { return -RIG_ENAVAIL; } return caps->reset(amp, reset); } /** * \brief Query the operating frequency of the amplifier. * * \param amp The #AMP handle. * \param freq The variable to store the operating frequency. * * Retrieves the operating frequency from the amplifier. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_freq() capability is not available. * * \sa amp_set_freq() */ int HAMLIB_API amp_get_freq(AMP *amp, freq_t *freq) { const struct amp_caps *caps; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } caps = amp->caps; if (caps->get_freq == NULL) { return -RIG_ENAVAIL; } return caps->get_freq(amp, freq); } /** * \brief Set the operating frequency of the amplifier. * * \param amp The #AMP handle. * \param freq The operating frequency. * * Set the operating frequency of the amplifier. Depending on the amplifier * this may simply set the bandpass filters, etc. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Setting the frequency was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#set_freq() capability is not available. * * \sa amp_get_freq() */ int HAMLIB_API amp_set_freq(AMP *amp, freq_t freq) { const struct amp_caps *caps; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } caps = amp->caps; if (caps->set_freq == NULL) { return -RIG_ENAVAIL; } return caps->set_freq(amp, freq); } /** * \brief Query general information from the amplifier. * * \param amp The #AMP handle. * * Retrieves some general information from the amplifier. This can include * firmware revision, exact model name, or just nothing. * * \return A pointer to static memory containing an ASCII nul terminated * string (C string) if the operation has been successful, otherwise NULL if * \a amp is NULL or inconsistent or the amp_caps#get_info() capability is not * available. */ const char *HAMLIB_API amp_get_info(AMP *amp) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return NULL; } if (amp->caps->get_info == NULL) { return NULL; } return amp->caps->get_info(amp); } /** * \brief Set the value of a requested level. * * \param amp The #AMP handle. * \param level The requested level. * \param val The variable to store the \a level value. * * Set the \a val corresponding to the \a level. * * \note \a val can be any type defined by #value_t. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_level() capability is not available. * * \sa amp_set_ext_level() */ int HAMLIB_API amp_set_level(AMP *amp, setting_t level, value_t val) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->set_level == NULL) { return -RIG_ENAVAIL; } return amp->caps->set_level(amp, level, val); } /** * \brief Query the value of a requested level. * * \param amp The #AMP handle. * \param level The requested level. * \param val The variable to store the \a level value. * * Query the \a val corresponding to the \a level. * * \note \a val can be any type defined by #value_t. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_level() capability is not available. * * \sa amp_get_ext_level() */ int HAMLIB_API amp_get_level(AMP *amp, setting_t level, value_t *val) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->get_level == NULL) { return -RIG_ENAVAIL; } return amp->caps->get_level(amp, level, val); } /** * \brief Set the value of a requested extension levels token. * * \param amp The #AMP handle. * \param level The requested extension levels token. * \param val The variable to set the extension \a level token value. * * Query the \a val corresponding to the extension \a level token. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#set_ext_level() capability is not available. * * \sa amp_set_level() */ int HAMLIB_API amp_set_ext_level(AMP *amp, hamlib_token_t level, value_t val) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->set_ext_level == NULL) { return -RIG_ENAVAIL; } return amp->caps->set_ext_level(amp, level, val); } /** * \brief Query the value of a requested extension levels token. * * \param amp The #AMP handle. * \param level The requested extension levels token. * \param val The variable to store the extension \a level token value. * * Query the \a val corresponding to the extension \a level token. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_ext_level() capability is not available. * * \sa amp_get_level() */ int HAMLIB_API amp_get_ext_level(AMP *amp, hamlib_token_t level, value_t *val) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->get_ext_level == NULL) { return -RIG_ENAVAIL; } return amp->caps->get_ext_level(amp, level, val); } /** * \brief Turn the amplifier On or Off or toggle the Standby or Operate * status. * * \param amp The #AMP handle * \param status The #powerstat_t setting. * * Turns the amplifier On or Off or toggles the Standby or Operate status. * See #RIG_POWER_ON, #RIG_POWER_OFF and #RIG_POWER_OPERATE, * #RIG_POWER_STANDBY for the value of \a status. * * \return RIG_OK if the operation was successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The requested power/standby state was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#set_powerstat() capability is not available. * * \sa amp_get_powerstat() */ int HAMLIB_API amp_set_powerstat(AMP *amp, powerstat_t status) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->set_powerstat == NULL) { return -RIG_ENAVAIL; } return amp->caps->set_powerstat(amp, status); } /** * \brief Query the power or standby status of the amplifier. * * \param amp The #AMP handle. * \param status The variable to store the amplifier \a status. * * Query the amplifier's power or standby condition. The value stored in * \a status will be one of #RIG_POWER_ON, #RIG_POWER_OFF and * #RIG_POWER_OPERATE, #RIG_POWER_STANDBY, or #RIG_POWER_UNKNOWN. * *\return RIG_OK if the query was successful, otherwise a **negative value** * if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Querying the power/standby state was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_powerstat() capability is not available. * * \sa amp_set_powerstat() */ int HAMLIB_API amp_get_powerstat(AMP *amp, powerstat_t *status) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_AMP_ARG(amp)) { return -RIG_EINVAL; } if (amp->caps->get_powerstat == NULL) { return -RIG_ENAVAIL; } return amp->caps->get_powerstat(amp, status); } /** * \brief Get the address of amplifier data structure(s) * * \sa rig_data_pointer * */ void *HAMLIB_API amp_data_pointer(AMP *amp, rig_ptrx_t idx) { switch (idx) { case RIG_PTRX_AMPPORT: return AMPPORT(amp); case RIG_PTRX_AMPSTATE: return AMPSTATE(amp); default: amp_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); return NULL; } } /*! @} */ hamlib-4.6.5/src/sprintflst.h0000664000175000017500000000644615056640443011636 /* * Hamlib Interface - sprintf toolbox header * Copyright (c) 2003-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _SPRINTFLST_H #define _SPRINTFLST_H 1 #include #include #define SPRINTF_MAX_SIZE 2048 __BEGIN_DECLS extern HAMLIB_EXPORT( int ) rig_sprintf_mode(char *str, int len, rmode_t mode); extern HAMLIB_EXPORT( int ) rig_sprintf_vfo(char *str, int len, vfo_t vfo); extern HAMLIB_EXPORT( int ) rig_sprintf_ant(char *str, int len, ant_t ant); extern HAMLIB_EXPORT( int ) rig_sprintf_func(char *str, int len, setting_t func); extern HAMLIB_EXPORT( int ) rig_sprintf_agc_levels(RIG *rig, char *str, int len); extern HAMLIB_EXPORT( int ) rot_sprintf_func(char *str, int len, setting_t func); extern HAMLIB_EXPORT( int ) rig_sprintf_level(char *str, int len, setting_t level); extern HAMLIB_EXPORT( int ) rot_sprintf_level(char *str, int len, setting_t level); extern HAMLIB_EXPORT( int ) amp_sprintf_level(char *str, int len, setting_t level); extern HAMLIB_EXPORT( int ) sprintf_level_ext(char *str, int len, const struct confparams *extlevels); extern HAMLIB_EXPORT( int ) rig_sprintf_level_gran(char *str, int len, setting_t level, const gran_t *gran); extern HAMLIB_EXPORT( int ) rot_sprintf_level_gran(char *str, int len, setting_t level, const gran_t *gran); extern HAMLIB_EXPORT( int ) rig_sprintf_parm(char *str, int len, setting_t parm); extern HAMLIB_EXPORT( int ) rot_sprintf_parm(char *str, int len, setting_t parm); extern HAMLIB_EXPORT( int ) rig_sprintf_parm_gran(char *str, int len, setting_t parm, const gran_t *gran); extern HAMLIB_EXPORT( int ) rot_sprintf_parm_gran(char *str, int len, setting_t parm, const gran_t *gran); extern HAMLIB_EXPORT( int ) rig_sprintf_vfop(char *str, int len, vfo_op_t op); extern HAMLIB_EXPORT( int ) rig_sprintf_scan(char *str, int len, scan_t rscan); extern HAMLIB_EXPORT( int ) rot_sprintf_status(char *str, int len, rot_status_t status); extern HAMLIB_EXPORT( int ) rig_sprintf_spectrum_modes(char *str, int nlen, const enum rig_spectrum_mode_e *modes); extern HAMLIB_EXPORT( int ) rig_sprintf_spectrum_spans(char *str, int nlen, const freq_t *spans); extern HAMLIB_EXPORT( int ) rig_sprintf_spectrum_avg_modes(char *str, int nlen, const struct rig_spectrum_avg_mode *avg_modes); extern HAMLIB_EXPORT( int ) rig_sprintf_tuning_steps(char *str, int nlen, const struct tuning_step_list *tuning_step_list); extern HAMLIB_EXPORT( char *) get_rig_conf_type(enum rig_conf_e type); extern HAMLIB_EXPORT( int ) print_ext_param(const struct confparams *cfp, rig_ptr_t ptr); __END_DECLS #endif /* _SPRINTFLST_H */ hamlib-4.6.5/src/rotator.c0000664000175000017500000006545615056640443011121 /* * Hamlib Interface - main file * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup rotator * @{ */ /** * \file src/rotator.c * \brief Rotator interface * \author Frank Singleton * \date 2000-2003 * \author Stephane Fillod * \date 2000-2012 * * This Hamlib interface is a frontend implementing the rotator wrapper * functions. */ /** * \page rot Rotator interface * * A rotator can be any kind of azimuth, elevation, or azimuth and elevation * controlled antenna system or other such aiming equipment, e.g. telescopes, * etc. */ #include #include #include #include #include #include #include #include #include #include "serial.h" #include "parallel.h" #if defined(HAVE_LIB_USB_H) || defined(HAMB_LIBUSB_1_0_LIBUSB_H) #include "usb_port.h" #endif #include "network.h" #include "rot_conf.h" #include "token.h" #include "serial.h" #ifndef DOC_HIDDEN #if defined(WIN32) && !defined(__CYGWIN__) # define DEFAULT_SERIAL_PORT "\\\\.\\COM1" #elif BSD # define DEFAULT_SERIAL_PORT "/dev/cuaa0" #elif MACOSX # define DEFAULT_SERIAL_PORT "/dev/cu.usbserial" #else # define DEFAULT_SERIAL_PORT "/dev/ttyS0" #endif #if defined(WIN32) # define DEFAULT_PARALLEL_PORT "\\\\.\\$VDMLPT1" #elif defined(HAVE_DEV_PPBUS_PPI_H) # define DEFAULT_PARALLEL_PORT "/dev/ppi0" #else # define DEFAULT_PARALLEL_PORT "/dev/parport0" #endif #define CHECK_ROT_ARG(r) (!(r) || !(r)->caps || !(ROTSTATE(r)->comm_state)) /* * Data structure to track the opened rot (by rot_open) */ struct opened_rot_l { ROT *rot; struct opened_rot_l *next; }; static struct opened_rot_l *opened_rot_list = { NULL }; /* * track which rot is opened (with rot_open) * needed at least for transceive mode */ static int add_opened_rot(ROT *rot) { struct opened_rot_l *p; p = (struct opened_rot_l *)calloc(1, sizeof(struct opened_rot_l)); if (!p) { return -RIG_ENOMEM; } p->rot = rot; p->next = opened_rot_list; opened_rot_list = p; return RIG_OK; } static int remove_opened_rot(const ROT *rot) { struct opened_rot_l *p, *q; q = NULL; for (p = opened_rot_list; p; p = p->next) { if (p->rot == rot) { if (q == NULL) { opened_rot_list = opened_rot_list->next; } else { q->next = p->next; } free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* Not found in list ! */ } #endif /* !DOC_HIDDEN */ /** @} */ /* rotator definitions */ /** * \addtogroup rot_internal * @{ */ /** * \brief Executes \a cfunc on each opened #ROT. * * \param cfunc The function to be executed on each #ROT. * \param data Data pointer to be passed to \a cfunc. * * Calls \a cfunc function for each opened #ROT. The contents of the opened * #ROT table is processed in random order according to a function pointed to * by \a cfunc, which is called with two arguments, the first pointing to the * #ROT handle, the second to a data pointer \a data. * * If \a data is not needed, then it can be set to NULL. The processing of * the opened #ROT table is stopped when \a cfunc returns 0. * * \return RIG_OK in all cases. */ int foreach_opened_rot(int (*cfunc)(ROT *, rig_ptr_t), rig_ptr_t data) { struct opened_rot_l *p; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (p = opened_rot_list; p; p = p->next) { if ((*cfunc)(p->rot, data) == 0) { return RIG_OK; } } return RIG_OK; } /** @} */ /* rot_internal definitions */ /** * \addtogroup rotator * @{ */ /** * \brief Allocate a new #ROT handle. * * \param rot_model The rotator model for this new handle. * * Allocates a new #ROT handle and initializes the associated data * for \a rot_model (see rotlist.h or `rigctl -l`). * * \return a pointer to the #ROT handle otherwise NULL if memory allocation * failed or \a rot_model is unknown, e.g. backend autoload failed. * * \sa rot_cleanup(), rot_open() */ ROT *HAMLIB_API rot_init(rot_model_t rot_model) { ROT *rot; const struct rot_caps *caps; struct rot_state *rs; hamlib_port_t *rotp, *rotp2; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rot_check_backend(rot_model); caps = rot_get_caps(rot_model); if (!caps) { return NULL; } /* * okay, we've found it. Allocate some memory and set it to zeros, * and especially the initialize the callbacks */ rot = calloc(1, sizeof(ROT)); if (rot == NULL) { /* * FIXME: how can the caller know it's a memory shortage, * and not "rot not found" ? */ return NULL; } /* caps is const, so we need to tell compiler that we know what we are doing */ rot->caps = (struct rot_caps *) caps; /* * populate the rot->state */ /** * \todo Read the Preferences here! */ rs = ROTSTATE(rot); //TODO Allocate new rotport[2] // For now, use the embedded ones rotp = ROTPORT(rot); rotp2 = ROTPORT2(rot); rs->comm_state = 0; rotp->type.rig = rotp2->type.rig = caps->port_type; /* default from caps */ rotp->write_delay = rotp2->write_delay = caps->write_delay; rotp->post_write_delay = rotp2->post_write_delay = caps->post_write_delay; rotp->timeout = rotp2->timeout = caps->timeout; rotp->retry = rotp2->retry = caps->retry; switch (caps->port_type) { case RIG_PORT_SERIAL: strncpy(rotp->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); rotp->parm.serial.rate = rotp2->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ rotp->parm.serial.data_bits = rotp2->parm.serial.data_bits = caps->serial_data_bits; rotp->parm.serial.stop_bits = rotp2->parm.serial.stop_bits = caps->serial_stop_bits; rotp->parm.serial.parity = rotp2->parm.serial.parity = caps->serial_parity; rotp->parm.serial.handshake = rotp2->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_PARALLEL: strncpy(rotp->pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: strncpy(rotp->pathname, "127.0.0.1:4533", HAMLIB_FILPATHLEN - 1); break; default: strncpy(rotp->pathname, "", HAMLIB_FILPATHLEN - 1); } rs->min_el = caps->min_el; rs->max_el = caps->max_el; rs->min_az = caps->min_az; rs->max_az = caps->max_az; rs->current_speed = 50; // Set default speed to 50% rotp->fd = -1; rs->has_get_func = caps->has_get_func; rs->has_set_func = caps->has_set_func; rs->has_get_level = caps->has_get_level; rs->has_set_level = caps->has_set_level; rs->has_get_parm = caps->has_get_parm; rs->has_set_parm = caps->has_set_parm; rs->has_status = caps->has_status; memcpy(rs->level_gran, caps->level_gran, sizeof(gran_t)*RIG_SETTING_MAX); memcpy(rs->parm_gran, caps->parm_gran, sizeof(gran_t)*RIG_SETTING_MAX); /* * let the backend a chance to setup his private data * This must be done only once defaults are setup, * so the backend init can override rot_state. */ if (caps->rot_init != NULL) { int retcode = caps->rot_init(rot); if (retcode != RIG_OK) { rot_debug(RIG_DEBUG_VERBOSE, "%s: backend_init failed!\n", __func__); /* cleanup and exit */ free(rot); return NULL; } } // Now we have to copy our new rig state hamlib_port structure to the deprecated one // Clients built on older 4.X versions will use the old structure // Clients built on newer 4.5 versions will use the new structure memcpy(&rs->rotport_deprecated, rotp, sizeof(rs->rotport_deprecated)); return rot; } /** * \brief Open the communication channel to the rotator. * * \param rot The #ROT handle of the rotator to be opened. * * Opens the communication channel to a rotator for which the #ROT handle has * been passed. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Communication channel successfully opened. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENIMPL Communication port type is not implemented yet. * * \sa rot_init(), rot_close() */ int HAMLIB_API rot_open(ROT *rot) { const struct rot_caps *caps; struct rot_state *rs; hamlib_port_t *rotp = ROTPORT(rot); hamlib_port_t *rotp2 = ROTPORT2(rot); int status; int net1, net2, net3, net4, port; deferred_config_item_t *item; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return -RIG_EINVAL; } caps = rot->caps; rs = ROTSTATE(rot); if (rs->comm_state) { return -RIG_EINVAL; } rotp->fd = -1; rotp2->fd = -1; // determine if we have a network address if (sscanf(rotp->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { char *type = "TCP"; if (rot->caps->port_type == RIG_PORT_UDP_NETWORK) { rotp->type.rig = RIG_PORT_UDP_NETWORK; type = "UDP"; } else { rotp->type.rig = RIG_PORT_NETWORK; } rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s:%s\n", __func__, rotp->pathname, type); } if (sscanf(rotp2->pathname, "%d.%d.%d.%d:%d", &net1, &net2, &net3, &net4, &port) == 5) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, rotp2->pathname); if (rot->caps->port_type == RIG_PORT_UDP_NETWORK) { rotp->type.rig = RIG_PORT_UDP_NETWORK; } else { rotp->type.rig = RIG_PORT_NETWORK; } } switch (rotp->type.rig) { case RIG_PORT_SERIAL: status = serial_open(rotp); if (status != 0) { return status; } // RT21 has 2nd serial port elevation // so if a 2nd pathname is provided we'll open it if (rot->caps->rot_model == ROT_MODEL_RT21 && rotp2->pathname[0] != 0) { status = serial_open(rotp2); if (status != 0) { return status; } } break; case RIG_PORT_PARALLEL: status = par_open(rotp); if (status < 0) { return status; } break; case RIG_PORT_DEVICE: status = open(rotp->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } rotp->fd = status; // RT21 has 2nd serial port elevation // so if a 2nd pathname is provided we'll open it if (rot->caps->rot_model == ROT_MODEL_RT21 && rotp2->pathname[0] != 0) { status = open(rotp2->pathname, O_RDWR, 0); if (status < 0) { return -RIG_EIO; } rotp2->fd = status; } break; #if defined(HAVE_LIB_USB_H) || defined(HAMB_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: status = usb_port_open(rotp); if (status < 0) { return status; } break; #endif case RIG_PORT_NONE: case RIG_PORT_RPC: break; /* ez :) */ case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: /* FIXME: default port */ status = network_open(rotp, 4533); if (status < 0) { return status; } break; default: return -RIG_EINVAL; } add_opened_rot(rot); if (rotp->type.rig != RIG_PORT_NETWORK && rotp->type.rig != RIG_PORT_UDP_NETWORK) { if (rotp->parm.serial.dtr_state == RIG_SIGNAL_ON) { ser_set_dtr(rotp, 1); } else { ser_set_dtr(rotp, 0); } if (rotp->parm.serial.rts_state == RIG_SIGNAL_ON) { ser_set_rts(rotp, 1); } else { ser_set_rts(rotp, 0); } } rs->comm_state = 1; /* * Now that the rotator port is officially opened, we can * send the deferred configuration info. */ while ((item = rs->config_queue.first)) { rs->config_queue.first = item->next; status = rot_set_conf(rot, item->token, item->value); free(item->value); free(item); if (status != RIG_OK) { return status; } } /* * Maybe the backend has something to initialize * In case of failure, just close down and report error code. */ if (caps->rot_open != NULL) { status = caps->rot_open(rot); if (status != RIG_OK) { memcpy(&rs->rotport_deprecated, rotp, sizeof(rs->rotport_deprecated)); return status; } } memcpy(&rs->rotport_deprecated, rotp, sizeof(rs->rotport_deprecated)); return RIG_OK; } /** * \brief Close the communication channel to the rotator. * \param rot The #ROT handle of the rotator to be closed. * * Closes the communication channel to a rotator for which #ROT handle has * been passed by argument that was previously opened with rot_open(). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Communication channel successfully closed. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * * \sa rot_cleanup(), rot_open() */ int HAMLIB_API rot_close(ROT *rot) { const struct rot_caps *caps; struct rot_state *rs; hamlib_port_t *rotp = ROTPORT(rot); rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return -RIG_EINVAL; } caps = rot->caps; rs = ROTSTATE(rot); if (!rs->comm_state) { return -RIG_EINVAL; } /* * Let the backend say 73s to the rot. * and ignore the return code. */ if (caps->rot_close) { caps->rot_close(rot); } if (rotp->fd != -1) { switch (rotp->type.rig) { case RIG_PORT_SERIAL: ser_close(rotp); break; case RIG_PORT_PARALLEL: par_close(rotp); break; #if defined(HAVE_LIB_USB_H) || defined(HAMB_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: usb_port_close(rotp); break; #endif case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: network_close(rotp); break; default: close(rotp->fd); } rotp->fd = -1; } remove_opened_rot(rot); rs->comm_state = 0; memcpy(&rs->rotport_deprecated, rotp, sizeof(rs->rotport_deprecated)); return RIG_OK; } /** * \brief Release a #ROT handle and free associated memory. * * \param rot The #ROT handle to be released. * * Releases a #ROT handle for which the communication channel has been closed * with rot_close(). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK #ROT handle successfully released. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * * \sa rot_init(), rot_close() */ int HAMLIB_API rot_cleanup(ROT *rot) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return -RIG_EINVAL; } /* * check if they forgot to close the rot */ if (ROTSTATE(rot)->comm_state) { rot_close(rot); } /* * basically free up the priv struct */ if (rot->caps->rot_cleanup) { rot->caps->rot_cleanup(rot); } //TODO Release any allocated port structures free(rot); return RIG_OK; } /** * \brief Set the azimuth and elevation of the rotator. * * \param rot The #ROT handle. * \param azimuth The azimuth to set in decimal degrees. * \param elevation The elevation to set in decimal degrees. * * Sets the azimuth and elevation of the rotator. * * \b Note: A given rotator may be capable of setting only the azimuth or * only the elevation or both. The rotator backend will ignore the unneeded * parameter. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Either or both parameters set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent \b or either \a azimuth * or \a elevation is out of range for this rotator. * \retval RIG_ENAVAIL rot_caps#set_position() capability is not available. * * \sa rot_get_position() */ int HAMLIB_API rot_set_position(ROT *rot, azimuth_t azimuth, elevation_t elevation) { const struct rot_caps *caps; const struct rot_state *rs; rot_debug(RIG_DEBUG_VERBOSE, "%s called az=%.02f el=%.02f\n", __func__, azimuth, elevation); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; rs = ROTSTATE(rot); azimuth += rs->az_offset; elevation += rs->el_offset; rot_debug(RIG_DEBUG_VERBOSE, "%s: south_zero=%d \n", __func__, rs->south_zero); if (rs->south_zero) { azimuth += azimuth >= 180 ? -180 : 180; rot_debug(RIG_DEBUG_TRACE, "%s: south adj to az=%.2f\n", __func__, azimuth); } if (azimuth < rs->min_az || azimuth > rs->max_az || elevation < rs->min_el || elevation > rs->max_el) { rot_debug(RIG_DEBUG_TRACE, "%s: range problem az=%.02f(min=%.02f,max=%.02f), el=%02f(min=%.02f,max=%02f)\n", __func__, azimuth, rs->min_az, rs->max_az, elevation, rs->min_el, rs->max_el); return -RIG_ELIMIT; } if (caps->set_position == NULL) { return -RIG_ENAVAIL; } return caps->set_position(rot, azimuth, elevation); } /** * \brief Query the azimuth and elevation of the rotator. * * \param rot The #ROT handle. * \param azimuth The variable to store the current azimuth. * \param elevation The variable to store the current elevation * * Retrieves the current azimuth and elevation values of the rotator. The * stored values are in decimal degrees. * * \b Note: A given rotator may be capable of querying only the azimuth or * only the elevation or both. The rotator backend should store a value of 0 * in the unsupported variable. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Either or both parameters queried and stored successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_position() capability is not available. * * \sa rot_set_position() */ int HAMLIB_API rot_get_position(ROT *rot, azimuth_t *azimuth, elevation_t *elevation) { const struct rot_caps *caps; const struct rot_state *rs; azimuth_t az; elevation_t el; int retval; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !azimuth || !elevation) { return -RIG_EINVAL; } caps = rot->caps; rs = ROTSTATE(rot); if (caps->get_position == NULL) { return -RIG_ENAVAIL; } retval = caps->get_position(rot, &az, &el); if (retval != RIG_OK) { return retval; } rot_debug(RIG_DEBUG_VERBOSE, "%s: got az=%.2f, el=%.2f\n", __func__, az, el); if (rs->south_zero) { az += az >= 180 ? -180 : 180; rot_debug(RIG_DEBUG_VERBOSE, "%s: south adj to az=%.2f\n", __func__, az); } *azimuth = az - rs->az_offset; *elevation = el - rs->el_offset; return RIG_OK; } /** * \brief Park the rotator. * * \param rot The #ROT handle. * * Park the rotator in a predetermined position as implemented by the rotator * hardware. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The rotator was parked successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#park() capability is not available. * */ int HAMLIB_API rot_park(ROT *rot) { const struct rot_caps *caps; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->park == NULL) { return -RIG_ENAVAIL; } return caps->park(rot); } /** * \brief Stop the rotator. * * \param rot The #ROT handle. * * Stop the rotator. Command should be immediate. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The rotator was stopped successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#stop() capability is not available. * * \sa rot_move() */ int HAMLIB_API rot_stop(ROT *rot) { const struct rot_caps *caps; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->stop == NULL) { return -RIG_ENAVAIL; } return caps->stop(rot); } /** * \brief Reset the rotator. * * \param rot The #ROT handle. * \param reset The reset operation to perform * * Resets the rotator to a state determined by \a reset. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The rotator was reset successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#reset() capability is not available. */ int HAMLIB_API rot_reset(ROT *rot, rot_reset_t reset) { const struct rot_caps *caps; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->reset == NULL) { return -RIG_ENAVAIL; } return caps->reset(rot, reset); } /** * \brief Move the rotator in the specified direction and speed. * * \param rot The #ROT handle. * \param direction Direction of movement. * \param speed Speed of movement. * * Move the rotator in the specified direction. The \a direction is one of * #ROT_MOVE_CCW, #ROT_MOVE_CW, #ROT_MOVE_LEFT, #ROT_MOVE_RIGHT, #ROT_MOVE_UP, * #ROT_MOVE_DOWN, #ROT_MOVE_UP_LEFT, #ROT_MOVE_CCW, #ROT_MOVE_UP_RIGHT, #ROT_MOVE_UP_CW, * #ROT_MOVE_DOWN_LEFT, #ROT_MOVE_DOWN_CCW, #ROT_MOVE_DOWN_RIGHT, #ROT_MOVE_DOWN_CW. * The \a speed is a value between 1 and 100 or #ROT_SPEED_NOCHANGE. * * \retval RIG_OK The rotator move was successful. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#move() capability is not available. * * \sa rot_stop() */ int HAMLIB_API rot_move(ROT *rot, int direction, int speed) { const struct rot_caps *caps; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->move == NULL) { return -RIG_ENAVAIL; } return caps->move(rot, direction, speed); } /** * \brief Get general information from the rotator. * * \param rot The #ROT handle. * * Retrieves some general information from the rotator. This can include * firmware revision, exact model name, or just nothing. * * \return A pointer to static memory containing an ASCII nul terminated * string (C string) if the operation has been successful, otherwise NULL if * \a rot is NULL or inconsistent or the rot_caps#get_info() capability is not * available. */ const char *HAMLIB_API rot_get_info(ROT *rot) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return NULL; } if (rot->caps->get_info == NULL) { return NULL; } return rot->caps->get_info(rot); } /** * \brief Query status flags of the rotator. * * \param rot The #ROT handle. * \param status The variable where the status flags will be stored. * * Query the active status flags from the rotator. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_status() capability is not available. */ int HAMLIB_API rot_get_status(ROT *rot, rot_status_t *status) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } if (rot->caps->get_status == NULL) { return -RIG_ENAVAIL; } return rot->caps->get_status(rot, status); } /** * \brief Get the address of rotator data structure(s) * * \sa rig_data_pointer * */ void *HAMLIB_API rot_data_pointer(ROT *rot, rig_ptrx_t idx) { switch (idx) { case RIG_PTRX_ROTPORT: return ROTPORT(rot); case RIG_PTRX_ROTPORT2: return ROTPORT2(rot); case RIG_PTRX_ROTSTATE: return ROTSTATE(rot); default: rot_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); return NULL; } } /*! @} */ hamlib-4.6.5/src/tones.c0000664000175000017500000003342715056640443010550 /** * \addtogroup rig * @{ */ /** * \file src/tones.c * \brief CTCSS and DCS interface and tables * \author Stephane Fillod * \date 2000-2010 */ /* * Hamlib Interface - CTCSS and DCS interface and tables * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "tones.h" #if !defined(_WIN32) && !defined(__CYGWIN__) /** * 52 CTCSS sub-audible tones */ tone_t full_ctcss_list[] = { FULL_CTCSS_LIST }; /** * 50 CTCSS sub-audible tones, from 67.0Hz to 254.1Hz * * \note Don't even think about changing a bit of this array, several * backends depend on it. If you need to, create a copy for your * own caps. --SF */ tone_t common_ctcss_list[] = { COMMON_CTCSS_LIST }; /** * 104 DCS codes */ tone_t common_dcs_list[] = { COMMON_DCS_LIST }; /** * 106 DCS codes */ tone_t full_dcs_list[] = { FULL_DCS_LIST }; #endif #ifndef DOC_HIDDEN #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state) #endif /* !DOC_HIDDEN */ /** * \brief set CTCSS sub-tone frequency * \param rig The rig handle * \param vfo The target VFO * \param tone The tone to set to * * Sets the current Continuous Tone Controlled Squelch System (CTCSS) * sub-audible tone frequency for the transmitter only. * \note the \a tone integer is NOT in Hz, but in tenth of Hz! This way, * if you want to set a subaudible tone of 88.5 Hz for example, * then pass 885 to this function. * * NB: CTCSS encoding has to be explicitly enabled or disabled through * a call to rig_set_func() with arg RIG_FUNC_TONE, unless it is * unavailable and the \a tone arg has to be set to 0. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ctcss_tone(), rig_set_ctcss_sql() */ int HAMLIB_API rig_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_ctcss_tone == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->set_ctcss_tone(rig, vfo, tone); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_ctcss_tone(rig, vfo, tone); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the current CTCSS sub-tone frequency * \param rig The rig handle * \param vfo The target VFO * \param tone The location where to store the current tone * * Retrieves the current Continuous Tone Controlled Squelch System (CTCSS) * sub-audible tone frequency for the transmitter only. * \note the \a *tone integer is NOT in Hz, but in tenth of Hz! This way, * if the function rig_get_ctcss_tone() returns a subaudible tone of 885 * for example, then the real tone is 88.5 Hz. * Also, a value of 0 for \a *tone means the Tone encoding is disabled. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ctcss_tone(), rig_get_ctcss_sql() */ int HAMLIB_API rig_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !tone) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_ctcss_tone == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->get_ctcss_tone(rig, vfo, tone); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_ctcss_tone(rig, vfo, tone); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set the current encoding DCS code * \param rig The rig handle * \param vfo The target VFO * \param code The tone to set to * * Sets the current encoding Digitally-Coded Squelch code. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_dcs_code(), rig_set_dcs_sql() */ int HAMLIB_API rig_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_dcs_code == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->set_dcs_code(rig, vfo, code); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_dcs_code(rig, vfo, code); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the current encoding DCS code * \param rig The rig handle * \param vfo The target VFO * \param code The location where to store the current tone * * Retrieves the current encoding Digitally-Coded Squelch code. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_dcs_code(), rig_get_dcs_sql() */ int HAMLIB_API rig_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !code) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_dcs_code == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->get_dcs_code(rig, vfo, code); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_dcs_code(rig, vfo, code); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set CTCSS squelch * \param rig The rig handle * \param vfo The target VFO * \param tone The PL tone to set the squelch to * * Sets the current Continuous Tone Controlled Squelch System (CTCSS) * sub-audible *squelch* tone. * \note \a tone is NOT in Hz, but in tenth of Hz! This way, * if you want to set subaudible squelch tone of 88.5 Hz for example, * then pass 885 to this function. * * NB: the tone squelch has to be explicitly enabled or disabled through * a call to rig_set_func() with arg RIG_FUNC_TSQL, unless it is * unavailable and the \a tone arg has to be set to 0. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ctcss_sql(), rig_set_ctcss_tone() */ int HAMLIB_API rig_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_ctcss_sql == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->set_ctcss_sql(rig, vfo, tone); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_ctcss_sql(rig, vfo, tone); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the current CTCSS squelch * \param rig The rig handle * \param vfo The target VFO * \param tone The location where to store the current tone * * Retrieves the current Continuous Tone Controlled Squelch System (CTCSS) * sub-audible *squelch* tone. * \note \a *tone is NOT in Hz, but in tenth of Hz! This way, * if the function rig_get_ctcss_sql() returns a subaudible tone of 885 * for example, then the real tone is 88.5 Hz. * Also, a value of 0 for \a tone means the Tone squelch is disabled. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ctcss_sql(), rig_get_ctcss_tone() */ int HAMLIB_API rig_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !tone) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_ctcss_sql == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->get_ctcss_sql(rig, vfo, tone); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_ctcss_sql(rig, vfo, tone); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set the current DCS code * \param rig The rig handle * \param vfo The target VFO * \param code The tone to set to * * Sets the current Digitally-Coded *Squelch* code. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is set * appropriately). * * \sa rig_get_dcs_sql(), rig_set_dcs_code() */ int HAMLIB_API rig_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_dcs_sql == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->set_dcs_sql(rig, vfo, code); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_dcs_sql(rig, vfo, code); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the current DCS code * \param rig The rig handle * \param vfo The target VFO * \param code The location where to store the current tone * * Retrieves the current Digitally-Coded *Squelch* code. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_dcs_sql(), rig_get_dcs_code() */ int HAMLIB_API rig_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !code) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_dcs_sql == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_TONE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->get_dcs_sql(rig, vfo, code); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_dcs_sql(rig, vfo, code); caps->set_vfo(rig, curr_vfo); return retcode; } /*! @} */ hamlib-4.6.5/src/fifo.h0000664000175000017500000000023515056640443010337 void initFIFO(FIFO_RIG *fifo); void resetFIFO(FIFO_RIG *fifo); int push(FIFO_RIG *fifo, const char *msg); int pop(FIFO_RIG *fifo); int peek(FIFO_RIG *fifo); hamlib-4.6.5/src/hamlibdatetime.h.in0000664000175000017500000000024515056640443012773 /* This is a placeholder that will be overwritten by 'make' when * invoked in a Git working tree. */ #define HAMLIBDATETIME "from indeterminate source revision." hamlib-4.6.5/src/amp_conf.c0000664000175000017500000004277015056640443011203 /* * Hamlib Interface - amplifier configuration interface * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup amplifier * @{ */ /** * \brief Amplifier Configuration Interface * \file amp_conf.c */ #include #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include "amp_conf.h" #include "token.h" /* * Configuration options available in the amp_state struct. */ static const struct confparams ampfrontend_cfg_params[] = { { TOK_PATHNAME, "amp_pathname", "Rig path name", "Path name to the device file of the amplifier", "/dev/amplifier", RIG_CONF_STRING, }, { TOK_WRITE_DELAY, "write_delay", "Write delay", "Delay in ms between each byte sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_POST_WRITE_DELAY, "post_write_delay", "Post write delay", "Delay in ms between each command sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms", "0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } } }, { TOK_RETRY, "retry", "Retry", "Max number of retry", "0", RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { RIG_CONF_END, NULL, } }; static const struct confparams ampfrontend_serial_cfg_params[] = { #include "serial_cfg_params.h" }; /** @} */ /* amplifier definitions */ /** * \addtogroup amp_internal * @{ */ /** * \brief Set an amplifier state value from alpha input. * * \param amp The #AMP handle. * \param token TOK_... specify which value to set. * \param val Input. * * Assumes amp != NULL and val != NULL. * * \return RIG_OK or a **negative value** error. * * \retval RIG_OK TOK_... value set successfully. * \retval RIG_EINVAL TOK_.. value not set. * * \sa frontamp_get_conf() */ int frontamp_set_conf(AMP *amp, hamlib_token_t token, const char *val) { struct amp_state *rs; hamlib_port_t *ampp = AMPPORT(amp); int val_i; rs = AMPSTATE(amp); amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_PATHNAME: strncpy(ampp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->ampport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; case TOK_WRITE_DELAY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->write_delay = val_i; rs->ampport_deprecated.write_delay = val_i; break; case TOK_POST_WRITE_DELAY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->post_write_delay = val_i; rs->ampport_deprecated.post_write_delay = val_i; break; case TOK_TIMEOUT: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->timeout = val_i; rs->ampport_deprecated.timeout = val_i; break; case TOK_RETRY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->retry = val_i; rs->ampport_deprecated.retry = val_i; break; case TOK_SERIAL_SPEED: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->parm.serial.rate = val_i; rs->ampport_deprecated.parm.serial.rate = val_i; break; case TOK_DATA_BITS: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->parm.serial.data_bits = val_i; rs->ampport_deprecated.parm.serial.data_bits = val_i; break; case TOK_STOP_BITS: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } ampp->parm.serial.stop_bits = val_i; rs->ampport_deprecated.parm.serial.stop_bits = val_i; break; case TOK_PARITY: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { val_i = RIG_PARITY_NONE; } else if (!strcmp(val, "Odd")) { val_i = RIG_PARITY_ODD; } else if (!strcmp(val, "Even")) { val_i = RIG_PARITY_EVEN; } else if (!strcmp(val, "Mark")) { val_i = RIG_PARITY_MARK; } else if (!strcmp(val, "Space")) { val_i = RIG_PARITY_SPACE; } else { return -RIG_EINVAL; } ampp->parm.serial.parity = val_i; rs->ampport_deprecated.parm.serial.parity = val_i; break; case TOK_HANDSHAKE: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { val_i = RIG_HANDSHAKE_NONE; } else if (!strcmp(val, "XONXOFF")) { val_i = RIG_HANDSHAKE_XONXOFF; } else if (!strcmp(val, "Hardware")) { val_i = RIG_HANDSHAKE_HARDWARE; } else { return -RIG_EINVAL; } ampp->parm.serial.handshake = val_i; break; case TOK_RTS_STATE: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { val_i = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { val_i = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { val_i = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } ampp->parm.serial.rts_state = val_i; rs->ampport_deprecated.parm.serial.rts_state = val_i; break; case TOK_DTR_STATE: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { val_i = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { val_i = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { val_i = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } ampp->parm.serial.dtr_state = val_i; rs->ampport_deprecated.parm.serial.dtr_state = val_i; break; #if 0 case TOK_MIN_AZ: rs->min_az = atof(val); break; case TOK_MAX_AZ: rs->max_az = atof(val); break; case TOK_MIN_EL: rs->min_el = atof(val); break; case TOK_MAX_EL: rs->max_el = atof(val); break; #endif default: return -RIG_EINVAL; } return RIG_OK; } /** * \brief Query data from an amplifier state in alpha form. * * \param amp The #AMP handle. * \param token TOK_... specify which data to query. * \param val Result. * * Assumes amp != NULL and val != NULL. * * \return RIG_OK or a **negative value** on error. * * \retval RIG_OK TOK_... value queried successfully. * \retval RIG_EINVAL TOK_.. value not queried. * * \sa frontamp_set_conf() */ int frontamp_get_conf2(AMP *amp, hamlib_token_t token, char *val, int val_len) { hamlib_port_t *ampp = AMPPORT(amp); const char *s; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_PATHNAME: strncpy(val, ampp->pathname, val_len - 1); break; case TOK_WRITE_DELAY: SNPRINTF(val, val_len, "%d", ampp->write_delay); break; case TOK_POST_WRITE_DELAY: SNPRINTF(val, val_len, "%d", ampp->post_write_delay); break; case TOK_TIMEOUT: SNPRINTF(val, val_len, "%d", ampp->timeout); break; case TOK_RETRY: SNPRINTF(val, val_len, "%d", ampp->retry); break; case TOK_SERIAL_SPEED: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", ampp->parm.serial.rate); break; case TOK_DATA_BITS: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", ampp->parm.serial.data_bits); break; case TOK_STOP_BITS: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", ampp->parm.serial.stop_bits); break; case TOK_PARITY: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (ampp->parm.serial.parity) { case RIG_PARITY_NONE: s = "None"; break; case RIG_PARITY_ODD: s = "Odd"; break; case RIG_PARITY_EVEN: s = "Even"; break; case RIG_PARITY_MARK: s = "Mark"; break; case RIG_PARITY_SPACE: s = "Space"; break; default: return -RIG_EINVAL; } strncpy(val, s, val_len - 1); break; case TOK_HANDSHAKE: if (ampp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (ampp->parm.serial.handshake) { case RIG_HANDSHAKE_NONE: s = "None"; break; case RIG_HANDSHAKE_XONXOFF: s = "XONXOFF"; break; case RIG_HANDSHAKE_HARDWARE: s = "Hardware"; break; default: return -RIG_EINVAL; } strncpy(val, s, val_len); break; default: return -RIG_EINVAL; } return RIG_OK; } /** @} */ /* amp_internal definitions */ /** * \addtogroup amplifier * @{ */ /** * \brief Executes cfunc on all the elements stored in the configuration * parameters table. * * \param amp The #AMP handle. * \param cfunc Pointer to the callback function(...). * \param data Data for the callback function. * * Start first with backend configuration parameters table, then finish with * frontend configuration parameters table. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The \a cfunc action completed successfully. * \retval RIG_EINVAL \a amp is NULL or inconsistent or \a cfunc is NULL. */ int HAMLIB_API amp_token_foreach(AMP *amp, int (*cfunc)(const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = ampfrontend_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } if (amp->caps->port_type == RIG_PORT_SERIAL) { for (cfp = ampfrontend_serial_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } } for (cfp = amp->caps->cfgparams; cfp && cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } return RIG_OK; } /** * \brief Query an amplifier configuration parameter token by its name. * * \param amp The #AMP handle. * \param name Configuration parameter token name string. * * Use this function to get a pointer to the token in the #confparams * structure. Searches the backend config params table first, then falls back * to the frontend config params table. * * \return A pointer to the token in the #confparams structure or NULL if * \a amp is NULL or inconsistent or if \a name is not found (how can the * caller know which occurred?). * * \sa amp_token_lookup() * * TODO: Should use Lex to speed it up, strcmp() hurts! */ const struct confparams *HAMLIB_API amp_confparam_lookup(AMP *amp, const char *name) { const struct confparams *cfp; hamlib_token_t token; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return NULL; } /* 0 returned for invalid format */ token = strtol(name, NULL, 0); for (cfp = amp->caps->cfgparams; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } for (cfp = ampfrontend_cfg_params; cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } if (amp->caps->port_type == RIG_PORT_SERIAL) { for (cfp = ampfrontend_serial_cfg_params; cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } } return NULL; } /** * \brief Search for the token ID associated with an amplifier configuration * parameter token name. * * \param amp The #AMP handle. * \param name Configuration parameter token name string. * * Searches the backend and frontend configuration parameters tables for the * token ID. * * \return The token ID value or #RIG_CONF_END if the lookup failed. * * \sa amp_confparam_lookup() */ hamlib_token_t HAMLIB_API amp_token_lookup(AMP *amp, const char *name) { const struct confparams *cfp; amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); cfp = amp_confparam_lookup(amp, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** * \brief Set an amplifier configuration parameter. * * \param amp The #AMP handle. * \param token The token of the parameter to set. * \param val The value to set the parameter to. * * Sets an amplifier configuration parameter to \a val. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The parameter was set successfully. * \retval RIG_EINVAL \a amp is NULL or inconsistent or \a token is invalid. * \retval RIG_ENAVAIL amp_caps#set_conf() capability is not available. * * \sa amp_get_conf() */ int HAMLIB_API amp_set_conf(AMP *amp, hamlib_token_t token, const char *val) { amp_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return -RIG_EINVAL; } if (rig_need_debug(RIG_DEBUG_VERBOSE)) { const struct confparams *cfp; char tokenstr[12]; SNPRINTF(tokenstr, sizeof(tokenstr), "%ld", token); cfp = amp_confparam_lookup(amp, tokenstr); if (!cfp) { return -RIG_EINVAL; } amp_debug(RIG_DEBUG_VERBOSE, "%s: %s='%s'\n", __func__, cfp->name, val); } if (IS_TOKEN_FRONTEND(token)) { return frontamp_set_conf(amp, token, val); } if (amp->caps->set_conf == NULL) { return -RIG_ENAVAIL; } return amp->caps->set_conf(amp, token, val); } /** * \brief Query the value of an amplifier configuration parameter. * * \param amp The #AMP handle. * \param token The token of the parameter to query. * \param val The location where to store the value of the configuration \a token. * * Retrieves the value of a configuration parameter associated with \a token. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Querying the parameter was successful. * \retval RIG_EINVAL \a amp is NULL or inconsistent. * \retval RIG_ENAVAIL amp_caps#get_conf() capability is not available. * * \sa amp_set_conf() */ int HAMLIB_API amp_get_conf2(AMP *amp, hamlib_token_t token, char *val, int val_len) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps || !val) { return -RIG_EINVAL; } if (IS_TOKEN_FRONTEND(token)) { return frontamp_get_conf2(amp, token, val, val_len); } if (amp->caps->get_conf == NULL) { return -RIG_ENAVAIL; } return amp->caps->get_conf(amp, token, val); } int HAMLIB_API amp_get_conf(AMP *amp, hamlib_token_t token, char *val) { return amp_get_conf2(amp, token, val, 128); } /** @} */ hamlib-4.6.5/src/rot_conf.c0000664000175000017500000004776715056640443011245 /* * Hamlib Interface - rotator configuration interface * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup rotator * @{ */ /** * \brief Rotator Configuration Interface. * * \file rot_conf.c */ #include #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include "rot_conf.h" #include "token.h" /* * Configuration options available in the rot_state struct. */ static const struct confparams rotfrontend_cfg_params[] = { { TOK_PATHNAME, "rot_pathname", "Rig path name", "Path name to the device file of the rotator", "/dev/rotator", RIG_CONF_STRING, }, { TOK_WRITE_DELAY, "write_delay", "Write delay", "Delay in ms between each byte sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_POST_WRITE_DELAY, "post_write_delay", "Post write delay", "Delay in ms between each command sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms", "0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } } }, { TOK_RETRY, "retry", "Retry", "Max number of retry", "0", RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_FLUSHX, "flushx", "Flush with read instead of TCFLUSH", "True enables flushing serial port with read instead of TCFLUSH -- MicroHam", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_MIN_AZ, "min_az", "Minimum azimuth", "Minimum rotator azimuth in degrees", "-180", RIG_CONF_NUMERIC, { .n = { -360, 360, .001 } } }, { TOK_MAX_AZ, "max_az", "Maximum azimuth", "Maximum rotator azimuth in degrees", "180", RIG_CONF_NUMERIC, { .n = { -360, 360, .001 } } }, { TOK_MIN_EL, "min_el", "Minimum elevation", "Minimum rotator elevation in degrees", "0", RIG_CONF_NUMERIC, { .n = { -90, 180, .001 } } }, { TOK_MAX_EL, "max_el", "Maximum elevation", "Maximum rotator elevation in degrees", "90", RIG_CONF_NUMERIC, { .n = { -90, 180, .001 } } }, { TOK_SOUTH_ZERO, "south_zero", "South is zero deg", "Adjust azimuth 180 degrees for south oriented rotators", "0", RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; static const struct confparams rotfrontend_serial_cfg_params[] = { #include "serial_cfg_params.h" }; /** @} */ /* rotator definitions */ /** * \addtogroup rot_internal * @{ */ /** * \brief Set a rotator state value from alpha input. * \param rot The #ROT handle. * \param token TOK_... specify which value to set. * \param val Input. * * Assumes rot != NULL and val != NULL. * * \return RIG_OK or a **negative value** on error. * * \retval RIG_OK TOK_... value set successfully. * \retval RIG_EINVAL TOK_.. value not set. * * \sa frontrot_get_conf() */ int frontrot_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct rot_state *rs; hamlib_port_t *rotp = ROTPORT(rot); int val_i; rs = ROTSTATE(rot); rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_PATHNAME: strncpy(rotp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->rotport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; case TOK_WRITE_DELAY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->write_delay = val_i; rs->rotport_deprecated.write_delay = val_i; break; case TOK_POST_WRITE_DELAY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->post_write_delay = val_i; rs->rotport_deprecated.post_write_delay = val_i; break; case TOK_TIMEOUT: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->timeout = val_i; rs->rotport_deprecated.timeout = val_i; break; case TOK_RETRY: if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->retry = val_i; rs->rotport_deprecated.retry = val_i; break; case TOK_SERIAL_SPEED: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->parm.serial.rate = val_i; rs->rotport_deprecated.parm.serial.rate = val_i; break; case TOK_DATA_BITS: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->parm.serial.data_bits = val_i; rs->rotport_deprecated.parm.serial.data_bits = val_i; break; case TOK_STOP_BITS: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%d", &val_i)) { return -RIG_EINVAL; } rotp->parm.serial.stop_bits = val_i; rs->rotport_deprecated.parm.serial.stop_bits = val_i; break; case TOK_PARITY: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { val_i = RIG_PARITY_NONE; } else if (!strcmp(val, "Odd")) { val_i = RIG_PARITY_ODD; } else if (!strcmp(val, "Even")) { val_i = RIG_PARITY_EVEN; } else if (!strcmp(val, "Mark")) { val_i = RIG_PARITY_MARK; } else if (!strcmp(val, "Space")) { val_i = RIG_PARITY_SPACE; } else { return -RIG_EINVAL; } rotp->parm.serial.parity = val_i; rs->rotport_deprecated.parm.serial.parity = val_i; break; case TOK_HANDSHAKE: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { val_i = RIG_HANDSHAKE_NONE; } else if (!strcmp(val, "XONXOFF")) { val_i = RIG_HANDSHAKE_XONXOFF; } else if (!strcmp(val, "Hardware")) { val_i = RIG_HANDSHAKE_HARDWARE; } else { return -RIG_EINVAL; } rotp->parm.serial.handshake = val_i; rs->rotport_deprecated.parm.serial.handshake = val_i; break; case TOK_FLUSHX: rotp->flushx = atoi(val); rs->rotport_deprecated.flushx = atoi(val); break; case TOK_MIN_AZ: rs->min_az = atof(val); break; case TOK_MAX_AZ: rs->max_az = atof(val); break; case TOK_MIN_EL: rs->min_el = atof(val); break; case TOK_MAX_EL: rs->max_el = atof(val); break; case TOK_SOUTH_ZERO: rs->south_zero = atoi(val); break; case TOK_RTS_STATE: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { val_i = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { val_i = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { val_i = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } rotp->parm.serial.rts_state = val_i; rs->rotport_deprecated.parm.serial.rts_state = val_i; break; case TOK_DTR_STATE: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { val_i = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { val_i = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { val_i = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } rotp->parm.serial.dtr_state = val_i; rs->rotport_deprecated.parm.serial.dtr_state = val_i; break; default: return -RIG_EINVAL; } return RIG_OK; } /** * \brief Query data from a rotator state in alpha form. * * \param rot The #ROT handle. * \param token TOK_... specify which data to query. * \param val Result. * * Assumes rot != NULL and val != NULL. * * \return RIG_OK or a **negative value** on error. * * \retval RIG_OK TOK_... value queried successfully. * \retval RIG_EINVAL TOK_.. value not queried. * * \sa frontrot_set_conf() */ int frontrot_get_conf(ROT *rot, hamlib_token_t token, char *val, int val_len) { struct rot_state *rs; hamlib_port_t *rotp = ROTPORT(rot); const char *s; rs = ROTSTATE(rot); rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_PATHNAME: strncpy(val, rotp->pathname, val_len - 1); break; case TOK_WRITE_DELAY: SNPRINTF(val, val_len, "%d", rotp->write_delay); break; case TOK_POST_WRITE_DELAY: SNPRINTF(val, val_len, "%d", rotp->post_write_delay); break; case TOK_TIMEOUT: SNPRINTF(val, val_len, "%d", rotp->timeout); break; case TOK_RETRY: SNPRINTF(val, val_len, "%d", rotp->retry); break; case TOK_SERIAL_SPEED: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rotp->parm.serial.rate); break; case TOK_DATA_BITS: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rotp->parm.serial.data_bits); break; case TOK_STOP_BITS: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rotp->parm.serial.stop_bits); break; case TOK_PARITY: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (rotp->parm.serial.parity) { case RIG_PARITY_NONE: s = "None"; break; case RIG_PARITY_ODD: s = "Odd"; break; case RIG_PARITY_EVEN: s = "Even"; break; case RIG_PARITY_MARK: s = "Mark"; break; case RIG_PARITY_SPACE: s = "Space"; break; default: return -RIG_EINVAL; } strncpy(val, s, val_len); break; case TOK_HANDSHAKE: if (rotp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (rotp->parm.serial.handshake) { case RIG_HANDSHAKE_NONE: s = "None"; break; case RIG_HANDSHAKE_XONXOFF: s = "XONXOFF"; break; case RIG_HANDSHAKE_HARDWARE: s = "Hardware"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_MIN_AZ: SNPRINTF(val, val_len, "%f", rs->min_az); break; case TOK_MAX_AZ: SNPRINTF(val, val_len, "%f", rs->max_az); break; case TOK_MIN_EL: SNPRINTF(val, val_len, "%f", rs->min_el); break; case TOK_MAX_EL: SNPRINTF(val, val_len, "%f", rs->max_el); break; case TOK_SOUTH_ZERO: SNPRINTF(val, val_len, "%d", rs->south_zero); break; default: return -RIG_EINVAL; } return RIG_OK; } /** @} */ /* rot_internal definitions */ /** * \addtogroup rotator * @{ */ /** * \brief Executes cfunc on all the elements stored in the configuration * parameters table. * * \param rot The #ROT handle. * \param cfunc Pointer to the callback function(...). * \param data Data for the callback function. * * Start first with backend configuration parameters table, then finish with * frontend configuration parameters table. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The \a cfunc action completed successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent or \a cfunc is NULL. */ int HAMLIB_API rot_token_foreach(ROT *rot, int (*cfunc)(const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rotfrontend_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } if (rot->caps->port_type == RIG_PORT_SERIAL) { for (cfp = rotfrontend_serial_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } } for (cfp = rot->caps->cfgparams; cfp && cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } return RIG_OK; } /** * \brief Query a rotator configuration parameter token by its name. * * \param rot The #ROT handle. * \param name Configuration parameter token name string. * \return confparams or NULL * * Use this function to get a pointer to the token in the #confparams * structure. Searches the backend config params table first, then falls back * to the frontend config params table. * * \return A pointer to the token in the #confparams structure or NULL if * \a rot is NULL or inconsistent or if \a name is not found (how can the * caller know which occurred?). * * \sa rot_token_lookup() * * TODO: Should use Lex to speed it up, strcmp() hurts! */ const struct confparams *HAMLIB_API rot_confparam_lookup(ROT *rot, const char *name) { const struct confparams *cfp; hamlib_token_t token; //rot_debug(RIG_DEBUG_VERBOSE, "%s called lookup=%s\n", __func__, name); if (!rot || !rot->caps) { return NULL; } /* 0 returned for invalid format */ token = strtol(name, NULL, 0); //rig_debug(RIG_DEBUG_TRACE, "%s: token=%d\n", __func__, (int)token); for (cfp = rot->caps->cfgparams; cfp && cfp->name; cfp++) { //rig_debug(RIG_DEBUG_TRACE, "%s: name=%s cfp->name=%s cfp->token=%d, token=%d\n", __func__, name, cfp->name, (int)cfp->token, (int)token); if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } //rig_debug(RIG_DEBUG_TRACE, "%s: frontend check\n", __func__); for (cfp = rotfrontend_cfg_params; cfp->name; cfp++) { //rig_debug(RIG_DEBUG_TRACE, "%s: name=%s cfp->name=%s cfp->token=%d, token=%d\n", __func__, name, cfp->name, (int)cfp->token, (int)token); if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } if (rot->caps->port_type == RIG_PORT_SERIAL) { for (cfp = rotfrontend_serial_cfg_params; cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { return cfp; } } } return NULL; } /** * \brief Search for the token ID associated with a rotator configuration * parameter token name. * * \param rot The #ROT handle. * \param name Configuration parameter token name string. * * Searches the backend and frontend configuration parameters tables for the * token ID. * * \return The token ID value or #RIG_CONF_END if the lookup failed. * * \sa rot_confparam_lookup() */ hamlib_token_t HAMLIB_API rot_token_lookup(ROT *rot, const char *name) { const struct confparams *cfp; rot_debug(RIG_DEBUG_VERBOSE, "%s called lookup %s\n", __func__, name); cfp = rot_confparam_lookup(rot, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** * \brief Set a rotator configuration parameter. * * \param rot The #ROT handle. * \param token The token of the parameter to set. * \param val The value to set the parameter to. * * Sets a rotator configuration parameter to \a val. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The parameter was set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent or \a token is invalid. * \retval RIG_ENAVAIL rot_caps#set_conf() capability is not available. * * \sa rot_get_conf() */ int HAMLIB_API rot_set_conf(ROT *rot, hamlib_token_t token, const char *val) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return -RIG_EINVAL; } if (rig_need_debug(RIG_DEBUG_VERBOSE)) { const struct confparams *cfp; char tokenstr[32]; SNPRINTF(tokenstr, sizeof(tokenstr), "%ld", token); cfp = rot_confparam_lookup(rot, tokenstr); if (!cfp) { return -RIG_EINVAL; } rot_debug(RIG_DEBUG_VERBOSE, "%s: %s='%s'\n", __func__, cfp->name, val); } if (IS_TOKEN_FRONTEND(token)) { return frontrot_set_conf(rot, token, val); } if (rot->caps->set_conf == NULL) { return -RIG_ENAVAIL; } return rot->caps->set_conf(rot, token, val); } /** * \brief Query the value of a rotator configuration parameter. * * \param rot The #ROT handle. * \param token The token of the parameter to query. * \param val The location where to store the value of the configuration \a token. * * Retrieves the value of a configuration parameter associated with \a token. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Querying the parameter was successful. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_conf() capability is not available. * * \sa rot_set_conf() */ // This call will change in Hamlib 5.0 to pass val_len in //int HAMLIB_API rot_get_conf(ROT *rot, hamlib_token_t token, char *val, int val_len) int HAMLIB_API rot_get_conf(ROT *rot, hamlib_token_t token, char *val) { // 128 is the default size we are called with return rot_get_conf2(rot, token, val, 128); } int HAMLIB_API rot_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps || !val) { return -RIG_EINVAL; } if (IS_TOKEN_FRONTEND(token)) { return frontrot_get_conf(rot, token, val, val_len); } if (rot->caps->get_conf2) { return rot->caps->get_conf2(rot, token, val, val_len); } if (rot->caps->get_conf == NULL) { return -RIG_ENAVAIL; } return rot->caps->get_conf(rot, token, val); } /** @} */ hamlib-4.6.5/src/amp_conf.h0000664000175000017500000000220415056640443011174 /* * Hamlib Interface - configuration header * Copyright (c) 2000,2001,2002 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_CONF_H #define _AMP_CONF_H 1 #include int frontamp_set_conf(AMP *amp, hamlib_token_t token, const char *val); static int frontamp_get_conf2(AMP *amp, hamlib_token_t token, char *val, int val_len); #endif /* _AMP_CONF_H */ hamlib-4.6.5/src/misc.c0000664000175000017500000022406715056640443010355 /* * Hamlib Interface - toolbox * Copyright (c) 2000-2011 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \file misc.c * \brief Miscellaneous utility routines */ #include #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #include #include #include "misc.h" #include "serial.h" #include "network.h" #include "sprintflst.h" #include "../rigs/icom/icom.h" #if defined(_WIN32) # include # ifndef localtime_r # define localtime_r(T,Tm) (localtime_s(Tm,T) ? NULL : Tm) # endif #endif #ifdef __APPLE__ #include #if !defined(CLOCK_REALTIME) && !defined(CLOCK_MONOTONIC) // // MacOS < 10.12 does not have clock_gettime // // Contribution from github user "ra1nb0w" // #define CLOCK_REALTIME 0 #define CLOCK_MONOTONIC 6 typedef int clockid_t; #include #include static int clock_gettime(clockid_t clock_id, struct timespec *tp) { if (clock_id == CLOCK_REALTIME) { struct timeval t; if (gettimeofday(&t, NULL) != 0) { return -1; } tp->tv_sec = t.tv_sec; tp->tv_nsec = t.tv_usec * 1000; } else if (clock_id == CLOCK_MONOTONIC) { static mach_timebase_info_data_t info = { 0, 0 }; if (info.denom == 0) { mach_timebase_info(&info); } uint64_t t = mach_absolute_time() * info.numer / info.denom; tp->tv_sec = t / 1000000000; tp->tv_nsec = t % 1000000000; } else { errno = EINVAL; return -1; } return 0; } #endif // !HAVE_CLOCK_GETTIME #endif // __APPLE__ /** * \brief Convert from binary to 4-bit BCD digits, little-endian * \param bcd_data * \param freq * \param bcd_len * \return bcd_data * * Convert a long long (e.g. frequency in Hz) to 4-bit BCD digits, * packed two digits per octet, in little-endian order * (e.g. byte order 90 78 56 34 12 for 1234567890 Hz). * * bcd_len is the number of BCD digits, usually 10 or 8 in 1-Hz units, * and 6 digits in 100-Hz units for Tx offset data. * * Hope the compiler will do a good job optimizing it (esp. w/the 64bit freq) * * Returns a pointer to (unsigned char *)bcd_data. * * \sa to_bcd_be() */ unsigned char *HAMLIB_API to_bcd(unsigned char bcd_data[], unsigned long long freq, unsigned bcd_len) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* '450'/4-> 5,0;0,4 */ /* '450'/3-> 5,0;x,4 */ for (i = 0; i < bcd_len / 2; i++) { unsigned char a = freq % 10; freq /= 10; a |= (freq % 10) << 4; freq /= 10; bcd_data[i] = a; } if (bcd_len & 1) { bcd_data[i] &= 0xf0; bcd_data[i] |= freq % 10; /* NB: high nibble is left uncleared */ } return bcd_data; } /** * \brief Convert BCD digits, little-endian, to a long long (e.g. frequency in Hz) * \param bcd_data * \param bcd_len * \return binary result (e.g. frequency) * * Convert BCD digits, little-endian, (byte order 90 78 56 34 12 * for 1234567890 Hz) to a long long (e.g. frequency in Hz) * * bcd_len is the number of BCD digits. * * Hope the compiler will do a good job optimizing it (esp. w/ the 64bit freq) * * Returns frequency in Hz an unsigned long long integer. * * \sa from_bcd_be() */ unsigned long long HAMLIB_API from_bcd(const unsigned char bcd_data[], unsigned bcd_len) { int i; freq_t f = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (bcd_len & 1) { f = bcd_data[bcd_len / 2] & 0x0f; } for (i = (bcd_len / 2) - 1; i >= 0; i--) { f *= 10; f += bcd_data[i] >> 4; f *= 10; f += bcd_data[i] & 0x0f; } return f; } /** * \brief Convert from binary to 4-bit BCD digits, big-endian * \param bcd_data * \param freq * \param bcd_len * \return bcd_data * * Same as to_bcd, but in big-endian order * (e.g. byte order 12 34 56 78 90 for 1234567890 Hz) * * \sa to_bcd() */ unsigned char *HAMLIB_API to_bcd_be(unsigned char bcd_data[], unsigned long long freq, unsigned bcd_len) { int i; /* '450'/4 -> 0,4;5,0 */ /* '450'/3 -> 4,5;0,x */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (bcd_len & 1) { bcd_data[bcd_len / 2] &= 0x0f; bcd_data[bcd_len / 2] |= (freq % 10) << 4; /* NB: low nibble is left uncleared */ freq /= 10; } for (i = (bcd_len / 2) - 1; i >= 0; i--) { unsigned char a = freq % 10; freq /= 10; a |= (freq % 10) << 4; freq /= 10; bcd_data[i] = a; } return bcd_data; } /** * \brief Convert 4-bit BCD digits to binary, big-endian * \param bcd_data * \param bcd_len * \return binary result * * Same as from_bcd, but in big-endian order * (e.g. byte order 12 34 56 78 90 for 1234567890 Hz) * * \sa from_bcd() */ unsigned long long HAMLIB_API from_bcd_be(const unsigned char bcd_data[], unsigned bcd_len) { int i; freq_t f = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; i < bcd_len / 2; i++) { f *= 10; f += bcd_data[i] >> 4; f *= 10; f += bcd_data[i] & 0x0f; } if (bcd_len & 1) { f *= 10; f += bcd_data[bcd_len / 2] >> 4; } return f; } size_t HAMLIB_API to_hex(size_t source_length, const unsigned char *source_data, size_t dest_length, char *dest_data) { size_t i; size_t length = source_length; const unsigned char *source = source_data; char *dest = dest_data; if (source_length == 0 || dest_length == 0) { return 0; } if (source_length * 2 > dest_length) { length = dest_length / 2 - 1; } for (i = 0; i < length; i++) { SNPRINTF(dest, dest_length - 2 * i, "%02X", source[0]); source++; dest += 2; } return length; } /** * \brief Convert duration of one morse code dot (element) to milliseconds at the given speed. * \param wpm morse code speed in words per minute * \return double duration in milliseconds * * The morse code speed is calculated using the standard based on word PARIS. * * "If you send PARIS 5 times in a minute (5WPM) you have sent 250 elements (using correct spacing). * 250 elements into 60 seconds per minute = 240 milliseconds per element." * * Source: http://kent-engineers.com/codespeed.htm */ double morse_code_dot_to_millis(int wpm) { return 240.0 * (5.0 / (double) wpm); } /** * \brief Convert duration of tenths of morse code dots to milliseconds at the given speed. * \param dot10ths number of 1/10ths of dots * \param wpm morse code speed in words per minute * \return int duration in milliseconds * * The morse code speed is calculated using the standard based on word PARIS. */ int dot10ths_to_millis(int dot10ths, int wpm) { return ceil(morse_code_dot_to_millis(wpm) * (double) dot10ths / 10.0); } /** * \brief Convert duration in milliseconds to tenths of morse code dots at the given speed. * \param millis duration in milliseconds * \param wpm morse code speed in words per minute * \return int number of 1/10ths of dots * * The morse code speed is calculated using the standard based on word PARIS. */ int millis_to_dot10ths(int millis, int wpm) { return ceil(millis / morse_code_dot_to_millis(wpm) * 10.0); } //! @cond Doxygen_Suppress #ifndef llabs #define llabs(a) ((a)<0?-(a):(a)) #endif //! @endcond /** * \brief Pretty print a frequency * \param str for result (may need up to 17 char) * \param freq input in Hz * * rig_freq_snprintf? * pretty print frequencies * str must be long enough. max can be as long as 17 chars */ int HAMLIB_API sprintf_freq(char *str, int str_len, freq_t freq) { double f; char *hz; int decplaces = 10; int retval; // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (llabs(freq) >= GHz(1)) { hz = "GHz"; f = (double)freq / GHz(1); } else if (llabs(freq) >= MHz(1)) { hz = "MHz"; f = (double)freq / MHz(1); decplaces = 7; } else if (llabs(freq) >= kHz(1)) { hz = "kHz"; f = (double)freq / kHz(1); decplaces = 4; } else { hz = "Hz"; f = (double)freq; decplaces = 1; } SNPRINTF(str, str_len, "%.*f %s", decplaces, f, hz); retval = strlen(str); return retval; } /** * \brief Convert enum RIG_STATUS_... to printable string * \param status RIG_STATUS_?? * \return string */ const char *HAMLIB_API rig_strstatus(enum rig_status_e status) { switch (status) { case RIG_STATUS_ALPHA: return "Alpha"; case RIG_STATUS_UNTESTED: return "Untested"; case RIG_STATUS_BETA: return "Beta"; case RIG_STATUS_STABLE: return "Stable"; case RIG_STATUS_BUGGY: return "Buggy"; } return ""; } static const struct { rmode_t mode; const char *str; } mode_str[] = { { RIG_MODE_AM, "AM" }, { RIG_MODE_PKTAM, "AM-D" }, { RIG_MODE_CW, "CW" }, { RIG_MODE_USB, "USB" }, { RIG_MODE_LSB, "LSB" }, { RIG_MODE_RTTY, "RTTY" }, { RIG_MODE_FM, "FM" }, { RIG_MODE_PKTFM, "FM-D" }, { RIG_MODE_WFM, "WFM" }, { RIG_MODE_CWR, "CWR" }, { RIG_MODE_CWR, "CW-R" }, { RIG_MODE_RTTYR, "RTTYR" }, { RIG_MODE_RTTYR, "RTTY-R" }, { RIG_MODE_AMS, "AMS" }, { RIG_MODE_PKTLSB, "PKTLSB" }, { RIG_MODE_PKTUSB, "PKTUSB" }, { RIG_MODE_PKTLSB, "LSB-D" }, { RIG_MODE_PKTUSB, "USB-D" }, { RIG_MODE_PKTFM, "PKTFM" }, { RIG_MODE_PKTFMN, "PKTFMN" }, { RIG_MODE_ECSSUSB, "ECSSUSB" }, { RIG_MODE_ECSSLSB, "ECSSLSB" }, { RIG_MODE_FAX, "FAX" }, { RIG_MODE_SAM, "SAM" }, { RIG_MODE_SAL, "SAL" }, { RIG_MODE_SAH, "SAH" }, { RIG_MODE_DSB, "DSB"}, { RIG_MODE_FMN, "FMN" }, { RIG_MODE_PKTAM, "PKTAM"}, { RIG_MODE_P25, "P25"}, { RIG_MODE_DSTAR, "D-STAR"}, { RIG_MODE_DPMR, "DPMR"}, { RIG_MODE_NXDNVN, "NXDN-VN"}, { RIG_MODE_NXDN_N, "NXDN-N"}, { RIG_MODE_DCR, "DCR"}, { RIG_MODE_AMN, "AMN"}, { RIG_MODE_PSK, "PSK"}, { RIG_MODE_PSKR, "PSKR"}, { RIG_MODE_C4FM, "C4FM"}, { RIG_MODE_SPEC, "SPEC"}, { RIG_MODE_CWN, "CWN"}, { RIG_MODE_IQ, "IQ"}, { RIG_MODE_ISBUSB, "ISBUSB"}, { RIG_MODE_ISBLSB, "ISBLSB"}, { RIG_MODE_NONE, "None" }, // so we can return None when NONE is requested { -1, "" }, // need to end list }; /** * \brief Convert alpha string to enum RIG_MODE * \param s input alpha string * \return enum RIG_MODE_?? * * \sa rmode_t */ rmode_t HAMLIB_API rig_parse_mode(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; (s != NULL) && (mode_str[i].str[0] != '\0'); i++) { if (!strcmp(s, mode_str[i].str)) { return mode_str[i].mode; } } rig_debug(RIG_DEBUG_WARN, "%s: mode '%s' not found...returning RIG_MODE_NONE\n", __func__, s); return RIG_MODE_NONE; } /** * \brief Convert enum RIG_MODE to alpha string * \param mode RIG_MODE_... * \return alpha string * * \sa rmode_t */ const char *HAMLIB_API rig_strrmode(rmode_t mode) { int i; // only enable if needed for debugging -- too verbose otherwise //rig_debug(RIG_DEBUG_TRACE, "%s called mode=0x%"PRXll"\n", __func__, mode); if (mode == RIG_MODE_NONE) { return ""; } for (i = 0 ; mode_str[i].str[0] != '\0'; i++) { if (mode == mode_str[i].mode) { return mode_str[i].str; } } return ""; } /** * \brief Convert RIG_MODE or'd value to alpha string of all modes * \param modes RIG_MODE or'd value * \param buf char* of result buffer * \param buflen length of buffer * \return rig status -- RIG_ETRUNC if buffer not big enough * * \sa rmode_t */ int HAMLIB_API rig_strrmodes(rmode_t modes, char *buf, int buflen) { int i; // only enable if needed for debugging -- too verbose otherwise //rig_debug(RIG_DEBUG_TRACE, "%s called mode=0x%"PRXll"\n", __func__, mode); if (modes == RIG_MODE_NONE) { SNPRINTF(buf, buflen, "NONE"); return RIG_OK; } for (i = 0 ; mode_str[i].str[0] != '\0'; i++) { if (modes & mode_str[i].mode) { char modebuf[16]; if (strlen(buf) == 0) { SNPRINTF(modebuf, sizeof(modebuf), "%s", mode_str[i].str); } else { SNPRINTF(modebuf, sizeof(modebuf), " %s", mode_str[i].str); } strncat(buf, modebuf, buflen - strlen(buf) - 1); if (strlen(buf) > buflen - 10) { return -RIG_ETRUNC; } } } return RIG_OK; } static const struct { vfo_t vfo; const char *str; } vfo_str[] = { { RIG_VFO_A, "VFOA" }, { RIG_VFO_B, "VFOB" }, { RIG_VFO_C, "VFOC" }, { RIG_VFO_CURR, "currVFO" }, { RIG_VFO_MEM, "MEM" }, { RIG_VFO_VFO, "VFO" }, { RIG_VFO_TX, "TX" }, { RIG_VFO_RX, "RX" }, { RIG_VFO_MAIN, "Main" }, { RIG_VFO_MAIN_A, "MainA" }, { RIG_VFO_MAIN_B, "MainB" }, { RIG_VFO_MAIN_C, "MainC" }, { RIG_VFO_SUB, "Sub" }, { RIG_VFO_SUB_A, "SubA" }, { RIG_VFO_SUB_B, "SubB" }, { RIG_VFO_SUB_C, "SubC" }, { RIG_VFO_NONE, "None" }, { RIG_VFO_OTHER, "otherVFO" }, { RIG_VFO_ALL, "AllVFOs" }, { RIG_VFO_A, "1" }, // to make gpredict happy in set_toggle { 0xffffffff, "" }, }; /** * \brief Convert alpha string to enum RIG_VFO_... * \param s input alpha string * \return RIG_VFO_... * * \sa RIG_VFO_A RIG_VFO_B RIG_VFO_C RIG_VFO_MAIN RIG_VFO_MAIN_A RIG_VFO_MAIN_B RIG_VFO_SUB RIG_VFO_SUB_A RIG_VFO_SUB_B RIG_VFO_VFO RIG_VFO_CURR RIG_VFO_MEM RIG_VFO_TX RIG_VFO_RX RIG_VFO_NONE */ vfo_t HAMLIB_API rig_parse_vfo(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; vfo_str[i].str[0] != '\0'; i++) { if (!strcmp(s, vfo_str[i].str)) { rig_debug(RIG_DEBUG_CACHE, "%s: str='%s' vfo='%s'\n", __func__, vfo_str[i].str, rig_strvfo(vfo_str[i].vfo)); return vfo_str[i].vfo; } } rig_debug(RIG_DEBUG_ERR, "%s: '%s' not found so vfo='%s'\n", __func__, s, rig_strvfo(RIG_VFO_NONE)); return RIG_VFO_NONE; } /** * \brief Convert enum RIG_VFO_... to alpha string * \param vfo RIG_VFO_... * \return alpha string * * \sa RIG_VFO_A RIG_VFO_B RIG_VFO_C RIG_VFO_MAIN RIG_VFO_SUB RIG_VFO_VFO RIG_VFO_CURR RIG_VFO_MEM RIG_VFO_TX RIG_VFO_RX RIG_VFO_NONE */ const char *HAMLIB_API rig_strvfo(vfo_t vfo) { int i; //a bit too verbose //rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0 ; vfo_str[i].str[0] != '\0'; i++) { if (vfo == vfo_str[i].vfo) { //rig_debug(RIG_DEBUG_TRACE, "%s returning %s\n", __func__, vfo_str[i].str); return vfo_str[i].str; } } return ""; } static const struct { setting_t func; const char *str; } rig_func_str[] = { { RIG_FUNC_FAGC, "FAGC" }, { RIG_FUNC_NB, "NB" }, { RIG_FUNC_COMP, "COMP" }, { RIG_FUNC_VOX, "VOX" }, { RIG_FUNC_TONE, "TONE" }, { RIG_FUNC_TSQL, "TSQL" }, { RIG_FUNC_SBKIN, "SBKIN" }, { RIG_FUNC_FBKIN, "FBKIN" }, { RIG_FUNC_ANF, "ANF" }, { RIG_FUNC_NR, "NR" }, { RIG_FUNC_AIP, "AIP" }, { RIG_FUNC_APF, "APF" }, { RIG_FUNC_MON, "MON" }, { RIG_FUNC_MN, "MN" }, { RIG_FUNC_RF, "RF" }, { RIG_FUNC_ARO, "ARO" }, { RIG_FUNC_LOCK, "LOCK" }, { RIG_FUNC_MUTE, "MUTE" }, { RIG_FUNC_VSC, "VSC" }, { RIG_FUNC_REV, "REV" }, { RIG_FUNC_SQL, "SQL" }, { RIG_FUNC_ABM, "ABM" }, { RIG_FUNC_BC, "BC" }, { RIG_FUNC_MBC, "MBC" }, { RIG_FUNC_RIT, "RIT" }, { RIG_FUNC_AFC, "AFC" }, { RIG_FUNC_SATMODE, "SATMODE" }, { RIG_FUNC_SCOPE, "SCOPE" }, { RIG_FUNC_RESUME, "RESUME" }, { RIG_FUNC_TBURST, "TBURST" }, { RIG_FUNC_TUNER, "TUNER" }, { RIG_FUNC_XIT, "XIT" }, { RIG_FUNC_NB2, "NB2" }, { RIG_FUNC_DSQL, "DSQL" }, { RIG_FUNC_AFLT, "AFLT" }, { RIG_FUNC_ANL, "ANL" }, { RIG_FUNC_BC2, "BC2" }, { RIG_FUNC_DUAL_WATCH, "DUAL_WATCH"}, { RIG_FUNC_DIVERSITY, "DIVERSITY"}, { RIG_FUNC_CSQL, "CSQL" }, { RIG_FUNC_SCEN, "SCEN" }, { RIG_FUNC_TRANSCEIVE, "TRANSCEIVE" }, { RIG_FUNC_SPECTRUM, "SPECTRUM" }, { RIG_FUNC_SPECTRUM_HOLD, "SPECTRUM_HOLD" }, { RIG_FUNC_SEND_MORSE, "SEND_MORSE" }, { RIG_FUNC_SEND_VOICE_MEM, "SEND_VOICE_MEM" }, { RIG_FUNC_OVF_STATUS, "OVF_STATUS" }, { RIG_FUNC_SYNC, "SYNC" }, { RIG_FUNC_NONE, "" }, }; static const struct { setting_t bandselect; const char *str; double start, stop; } rig_bandselect_str[] = { { RIG_BANDSELECT_2200M, "BAND2200M", 135700, 137799 }, { RIG_BANDSELECT_600M, "BAND600M", 472000, 478999}, { RIG_BANDSELECT_160M, "BAND160M", 1800000, 1899999}, { RIG_BANDSELECT_80M, "BAND80M", 3400000, 4099999}, { RIG_BANDSELECT_60M, "BAND60M", 5250000, 5449999}, { RIG_BANDSELECT_40M, "BAND40M", 6900000, 7499999}, { RIG_BANDSELECT_30M, "BAND30M", 9900000, 10499999}, { RIG_BANDSELECT_20M, "BAND20M", 13900000, 14499999}, { RIG_BANDSELECT_17M, "BAND17M", 17900000, 18499999}, { RIG_BANDSELECT_15M, "BAND15M", 20900000, 21499999}, { RIG_BANDSELECT_12M, "BAND12M", 24400000, 25099999}, { RIG_BANDSELECT_10M, "BAND10M", 28000000, 29999999}, { RIG_BANDSELECT_6M, "BAND6M", 50000000, 53999999}, { RIG_BANDSELECT_WFM, "BANDWFM", 74800000, 107999999}, { RIG_BANDSELECT_MW, "BANDMW", 530000000, 1700999999}, { RIG_BANDSELECT_AIR, "BANDAIR", 108000000, 136999999}, { RIG_BANDSELECT_2M, "BAND2M", 144000000, 145999999}, { RIG_BANDSELECT_1_25M, "BAND1_25M", 219000000, 224999999}, { RIG_BANDSELECT_70CM, "BAND70CM", 420000000, 449999999}, { RIG_BANDSELECT_33CM, "BAND33CM", 902000000, 927999999}, { RIG_BANDSELECT_23CM, "BAND23CM", 1240000000, 1324999999}, { RIG_BANDSELECT_13CM, "BAND13CM", 2300000000, 2449999999}, { RIG_BANDSELECT_9CM, "BAND9CM", 3300000000, 3474999999}, { RIG_BANDSELECT_5CM, "BAND5CM", 5650000000, 5924999999}, { RIG_BANDSELECT_3CM, "BAND3CM", 10000000000, 10499999999 }, { RIG_BANDSELECT_GEN, "BANDGEN", 0, 1000000000000}, { 0, NULL, 0, 0 } }; static const struct { setting_t func; const char *str; } rot_func_str[] = { { ROT_FUNC_NONE, "" }, }; /** * utility function to convert index to bit value * */ uint64_t rig_idx2setting(int i) { return ((uint64_t)1) << i; } /** * \brief Convert alpha string to enum RIG_FUNC_... * \param s input alpha string * \return RIG_FUNC_... * * \sa rig_func_e() */ setting_t HAMLIB_API rig_parse_func(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rig_func_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rig_func_str[i].str)) { return rig_func_str[i].func; } } return RIG_FUNC_NONE; } /** * \brief Convert alpha string to enum band_select_t... * \param s input alpha string * \return RIG_FUNC_... * * \sa rig_func_e() */ // cppcheck-suppress unusedFunction setting_t HAMLIB_API rig_parse_band(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (!strcmp(s, rig_bandselect_str[i].str)) { return rig_bandselect_str[i].bandselect; } } return RIG_FUNC_NONE; } /** * \brief Convert alpha string to enum ROT_FUNC_... * \param s input alpha string * \return ROT_FUNC_... * * \sa rot_func_e() */ setting_t HAMLIB_API rot_parse_func(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rot_func_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rot_func_str[i].str)) { return rot_func_str[i].func; } } return ROT_FUNC_NONE; } /** * \brief Convert enum RIG_FUNC_... to alpha string * \param func RIG_FUNC_... * \return alpha string * * \sa rig_func_e() */ const char *HAMLIB_API rig_strfunc(setting_t func) { int i; // too verbose to keep on unless debugging this in particular //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (func == RIG_FUNC_NONE) { return ""; } for (i = 0; rig_func_str[i].str[0] != '\0'; i++) { if (func == rig_func_str[i].func) { return rig_func_str[i].str; } } return ""; } /** * \brief Convert enum ROT_FUNC_... to alpha string * \param func ROT_FUNC_... * \return alpha string * * \sa rot_func_e() */ const char *HAMLIB_API rot_strfunc(setting_t func) { int i; // too verbose to keep on unless debugging this in particular //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (func == ROT_FUNC_NONE) { return ""; } for (i = 0; rot_func_str[i].str[0] != '\0'; i++) { if (func == rot_func_str[i].func) { return rot_func_str[i].str; } } return ""; } static const struct { setting_t level; const char *str; } rig_level_str[] = { { RIG_LEVEL_PREAMP, "PREAMP" }, { RIG_LEVEL_ATT, "ATT" }, { RIG_LEVEL_VOXDELAY, "VOXDELAY" }, { RIG_LEVEL_AF, "AF" }, { RIG_LEVEL_RF, "RF" }, { RIG_LEVEL_SQL, "SQL" }, { RIG_LEVEL_IF, "IF" }, { RIG_LEVEL_APF, "APF" }, { RIG_LEVEL_NR, "NR" }, { RIG_LEVEL_PBT_IN, "PBT_IN" }, { RIG_LEVEL_PBT_OUT, "PBT_OUT" }, { RIG_LEVEL_CWPITCH, "CWPITCH" }, { RIG_LEVEL_RFPOWER, "RFPOWER" }, { RIG_LEVEL_MICGAIN, "MICGAIN" }, { RIG_LEVEL_KEYSPD, "KEYSPD" }, { RIG_LEVEL_NOTCHF, "NOTCHF" }, { RIG_LEVEL_COMP, "COMP" }, { RIG_LEVEL_AGC, "AGC" }, { RIG_LEVEL_BKINDL, "BKINDL" }, { RIG_LEVEL_BALANCE, "BAL" }, { RIG_LEVEL_METER, "METER" }, { RIG_LEVEL_VOXGAIN, "VOXGAIN" }, { RIG_LEVEL_ANTIVOX, "ANTIVOX" }, { RIG_LEVEL_SLOPE_LOW, "SLOPE_LOW" }, { RIG_LEVEL_SLOPE_HIGH, "SLOPE_HIGH" }, { RIG_LEVEL_BKIN_DLYMS, "BKIN_DLYMS" }, { RIG_LEVEL_RAWSTR, "RAWSTR" }, { RIG_LEVEL_SWR, "SWR" }, { RIG_LEVEL_ALC, "ALC" }, { RIG_LEVEL_STRENGTH, "STRENGTH" }, { RIG_LEVEL_RFPOWER_METER, "RFPOWER_METER" }, { RIG_LEVEL_COMP_METER, "COMP_METER" }, { RIG_LEVEL_VD_METER, "VD_METER" }, { RIG_LEVEL_ID_METER, "ID_METER" }, { RIG_LEVEL_NOTCHF_RAW, "NOTCHF_RAW" }, { RIG_LEVEL_MONITOR_GAIN, "MONITOR_GAIN" }, { RIG_LEVEL_NB, "NB" }, { RIG_LEVEL_RFPOWER_METER_WATTS, "RFPOWER_METER_WATTS" }, { RIG_LEVEL_SPECTRUM_MODE, "SPECTRUM_MODE" }, { RIG_LEVEL_SPECTRUM_SPAN, "SPECTRUM_SPAN" }, { RIG_LEVEL_SPECTRUM_EDGE_LOW, "SPECTRUM_EDGE_LOW" }, { RIG_LEVEL_SPECTRUM_EDGE_HIGH, "SPECTRUM_EDGE_HIGH" }, { RIG_LEVEL_SPECTRUM_SPEED, "SPECTRUM_SPEED" }, { RIG_LEVEL_SPECTRUM_REF, "SPECTRUM_REF" }, { RIG_LEVEL_SPECTRUM_AVG, "SPECTRUM_AVG" }, { RIG_LEVEL_SPECTRUM_ATT, "SPECTRUM_ATT" }, { RIG_LEVEL_TEMP_METER, "TEMP_METER" }, { RIG_LEVEL_BAND_SELECT, "BAND_SELECT" }, { RIG_LEVEL_USB_AF, "USB_AF" }, { RIG_LEVEL_USB_AF_INPUT, "USB_AF_INPUT" }, { RIG_LEVEL_AGC_TIME, "AGC_TIME" }, { RIG_LEVEL_NONE, "" }, }; static const struct { setting_t level; const char *str; } rot_level_str[] = { { ROT_LEVEL_SPEED, "SPEED" }, { ROT_LEVEL_NONE, "" }, }; static const struct { setting_t level; const char *str; } amp_level_str[] = { { AMP_LEVEL_SWR, "SWR" }, { AMP_LEVEL_NH, "NH" }, { AMP_LEVEL_PF, "PF" }, { AMP_LEVEL_PWR_INPUT, "PWRINPUT" }, { AMP_LEVEL_PWR_FWD, "PWRFORWARD" }, { AMP_LEVEL_PWR_REFLECTED, "PWRREFLECTED" }, { AMP_LEVEL_PWR_PEAK, "PWRPEAK" }, { AMP_LEVEL_FAULT, "FAULT" }, { AMP_LEVEL_NONE, "" }, }; /** * \brief check input to set_level * \param rig Pointer to rig data * \param level RIG_LEVEL_* trying to set * \param val Raw input from the caller * \param gran If not NULL, set to location of level_gran data * * \return RIG_OK if value is in range for this level, -RIG_EINVAL if not */ int check_level_param(RIG *rig, setting_t level, value_t val, gran_t **gran) { gran_t *this_gran; this_gran = &rig->caps->level_gran[rig_setting2idx(level)]; if (gran) { *gran = this_gran; } if (RIG_LEVEL_IS_FLOAT(level)) { float maxval; /* If min==max==step==0, all values are OK here */ maxval = this_gran->max.f; if (this_gran->min.f == 0.0f && maxval == 0.0f) { /* if step==0 also, we're good */ if (this_gran->step.f == 0.0f) { return RIG_OK; } /* non-zero step, check for max of 1.0 */ maxval = 1.0f; } if (val.f < this_gran->min.f || val.f > maxval) { return -RIG_EINVAL; } } else { /* If min==max==0, all values are OK here but may be checked later */ if (this_gran->min.i == 0 && this_gran->max.i == 0) { return RIG_OK; } if (val.i < this_gran->min.i || val.i > this_gran->max.i) { return -RIG_EINVAL; } } return RIG_OK; } /** * \brief Convert alpha string to enum RIG_LEVEL_... * \param s input alpha string * \return RIG_LEVEL_... * * \sa rig_level_e() */ setting_t HAMLIB_API rig_parse_level(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rig_level_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rig_level_str[i].str)) { return rig_level_str[i].level; } } return RIG_LEVEL_NONE; } /** * \brief Convert alpha string to enum ROT_LEVEL_... * \param s input alpha string * \return ROT_LEVEL_... * * \sa rot_level_e() */ setting_t HAMLIB_API rot_parse_level(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rot_level_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rot_level_str[i].str)) { return rot_level_str[i].level; } } return ROT_LEVEL_NONE; } /** * \brief Convert alpha string to enum AMP_LEVEL_... * \param s input alpha string * \return AMP_LEVEL_... * * \sa amp_level_e() */ setting_t HAMLIB_API amp_parse_level(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called level=%s\n", __func__, s); rig_debug(RIG_DEBUG_VERBOSE, "%s called str=%s\n", __func__, amp_level_str[0].str); for (i = 0 ; amp_level_str[i].str[0] != '\0'; i++) { rig_debug(RIG_DEBUG_VERBOSE, "%s called checking=%s\n", __func__, amp_level_str[i].str); if (!strcmp(s, amp_level_str[i].str)) { return amp_level_str[i].level; } } return AMP_LEVEL_NONE; } /** * \brief Convert enum RIG_LEVEL_... to alpha string * \param level RIG_LEVEL_... * \return alpha string * * \sa rig_level_e() */ const char *HAMLIB_API rig_strlevel(setting_t level) { int i; rig_debug(RIG_DEBUG_CACHE, "%s called\n", __func__); if (level == RIG_LEVEL_NONE) { return ""; } for (i = 0; rig_level_str[i].str[0] != '\0'; i++) { if (level == rig_level_str[i].level) { return rig_level_str[i].str; } } return ""; } /** * \brief Convert enum ROT_LEVEL_... to alpha string * \param level ROT_LEVEL_... * \return alpha string * * \sa rot_level_e() */ const char *HAMLIB_API rot_strlevel(setting_t level) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (level == ROT_LEVEL_NONE) { return ""; } for (i = 0; rot_level_str[i].str[0] != '\0'; i++) { if (level == rot_level_str[i].level) { return rot_level_str[i].str; } } return ""; } /** * \brief Convert enum AMP_LEVEL_... to alpha string * \param level AMP_LEVEL_... * \return alpha string * * \sa amp_level_e() */ const char *HAMLIB_API amp_strlevel(setting_t level) { int i; //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (level == AMP_LEVEL_NONE) { return ""; } for (i = 0; amp_level_str[i].str[0] != '\0'; i++) { if (level == amp_level_str[i].level) { return amp_level_str[i].str; } } return ""; } static const struct { setting_t parm; const char *str; } rig_parm_str[] = { { RIG_PARM_ANN, "ANN" }, { RIG_PARM_APO, "APO" }, { RIG_PARM_BACKLIGHT, "BACKLIGHT" }, { RIG_PARM_BEEP, "BEEP" }, { RIG_PARM_TIME, "TIME" }, { RIG_PARM_BAT, "BAT" }, { RIG_PARM_KEYLIGHT, "KEYLIGHT"}, { RIG_PARM_SCREENSAVER, "SCREENSAVER"}, { RIG_PARM_AFIF, "AFIF"}, { RIG_PARM_BANDSELECT, "BANDSELECT"}, { RIG_PARM_KEYERTYPE, "KEYERTYPE"}, { RIG_PARM_AFIF_LAN, "AFIF_LAN"}, { RIG_PARM_AFIF_WLAN, "AFIF_WLAN"}, { RIG_PARM_AFIF_ACC, "AFIF_ACC"}, { RIG_PARM_NONE, "" }, }; static const struct { setting_t parm; const char *str; } rot_parm_str[] = { { ROT_PARM_NONE, "" }, }; /** * \brief Convert alpha string to RIG_PARM_... * \param s input alpha string * \return RIG_PARM_... * * \sa rig_parm_e() */ setting_t HAMLIB_API rig_parse_parm(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rig_parm_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rig_parm_str[i].str)) { return rig_parm_str[i].parm; } } return RIG_PARM_NONE; } /** * \brief Convert alpha string to ROT_PARM_... * \param s input alpha string * \return ROT_PARM_... * * \sa rot_parm_e() */ setting_t HAMLIB_API rot_parse_parm(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; rot_parm_str[i].str[0] != '\0'; i++) { if (!strcmp(s, rot_parm_str[i].str)) { return rot_parm_str[i].parm; } } return ROT_PARM_NONE; } /** * \brief Convert enum RIG_PARM_... to alpha string * \param parm RIG_PARM_... * \return alpha string * * \sa rig_parm_e() */ const char *HAMLIB_API rig_strparm(setting_t parm) { int i; // rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (parm == RIG_PARM_NONE) { return ""; } for (i = 0; rig_parm_str[i].str[0] != '\0'; i++) { if (parm == rig_parm_str[i].parm) { return rig_parm_str[i].str; } } return ""; } /** * \brief Convert enum ROT_PARM_... to alpha string * \param parm ROT_PARM_... * \return alpha string * * \sa rot_parm_e() */ const char *HAMLIB_API rot_strparm(setting_t parm) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (parm == ROT_PARM_NONE) { return ""; } for (i = 0; rot_parm_str[i].str[0] != '\0'; i++) { if (parm == rot_parm_str[i].parm) { return rot_parm_str[i].str; } } return ""; } static const struct { enum agc_level_e level; const char *str; } rig_agc_level_str[] = { { RIG_AGC_OFF, "OFF" }, { RIG_AGC_SUPERFAST, "SUPERFAST" }, { RIG_AGC_FAST, "FAST" }, { RIG_AGC_SLOW, "SLOW" }, { RIG_AGC_USER, "USER" }, { RIG_AGC_MEDIUM, "MEDIUM" }, { RIG_AGC_AUTO, "AUTO" }, { RIG_AGC_LONG, "LONG" }, { RIG_AGC_ON, "ON" }, { RIG_AGC_NONE, "NONE" }, { -1, "" }, }; /** * \brief Convert enum RIG_AGC_... to alpha string * \param level RIG_AGC_... * \return alpha string */ const char *HAMLIB_API rig_stragclevel(enum agc_level_e level) { int i; if (level < 0) { return ""; } for (i = 0; rig_agc_level_str[i].str[0] != '\0'; i++) { if (level == rig_agc_level_str[i].level) { return rig_agc_level_str[i].str; } } return ""; } /** * \brief Convert a enum agc_level_e to value * \param agcLevel level to convert * \return agc_level_e value */ value_t rig_valueagclevel(enum agc_level_e agcLevel) { value_t value; if (agcLevel == RIG_AGC_OFF) { value.i = 0; } else if (agcLevel == RIG_AGC_SUPERFAST) { value.i = 1; } else if (agcLevel == RIG_AGC_FAST) { value.i = 2; } else if (agcLevel == RIG_AGC_SLOW) { value.i = 3; } else if (agcLevel == RIG_AGC_USER) { value.i = 4; } else if (agcLevel == RIG_AGC_MEDIUM) { value.i = 5; } else { value.i = 6; } //RIG_AGC_AUTO return value; } /** * \brief Convert a value to agc_level_e -- constrains the range * \param agcValue value to convert * \return agc_level_e */ enum agc_level_e rig_levelagcvalue(int agcValue) { enum agc_level_e agcLevel; switch (agcValue) { case 0: agcLevel = RIG_AGC_OFF; break; case 1: agcLevel = RIG_AGC_SUPERFAST; break; case 2: agcLevel = RIG_AGC_FAST; break; case 3: agcLevel = RIG_AGC_SLOW; break; case 4: agcLevel = RIG_AGC_USER; break; case 5: agcLevel = RIG_AGC_MEDIUM; break; case 6: agcLevel = RIG_AGC_AUTO; break; default: agcLevel = RIG_AGC_AUTO; break; } return agcLevel; } /** * \brief Convert AGC string... to agc_level_e * \param agcString AGC string to convert * \return agc_level_e */ enum agc_level_e rig_levelagcstr(const char *agcString) { enum agc_level_e agcLevel; if (strcmp(agcString, "OFF") == 0) { agcLevel = RIG_AGC_OFF; } else if (strcmp(agcString, "SUPERFAST") == 0) { agcLevel = RIG_AGC_SUPERFAST; } else if (strcmp(agcString, "FAST") == 0) { agcLevel = RIG_AGC_FAST; } else if (strcmp(agcString, "SLOW") == 0) { agcLevel = RIG_AGC_SLOW; } else if (strcmp(agcString, "USER") == 0) { agcLevel = RIG_AGC_USER; } else if (strcmp(agcString, "MEDIUM") == 0) { agcLevel = RIG_AGC_MEDIUM; } else { agcLevel = RIG_AGC_AUTO; } return agcLevel; } static const struct { vfo_op_t vfo_op; const char *str; } vfo_op_str[] = { { RIG_OP_CPY, "CPY" }, { RIG_OP_XCHG, "XCHG" }, { RIG_OP_FROM_VFO, "FROM_VFO" }, { RIG_OP_TO_VFO, "TO_VFO" }, { RIG_OP_MCL, "MCL" }, { RIG_OP_UP, "UP" }, { RIG_OP_DOWN, "DOWN" }, { RIG_OP_BAND_UP, "BAND_UP" }, { RIG_OP_BAND_DOWN, "BAND_DOWN" }, { RIG_OP_LEFT, "LEFT" }, { RIG_OP_RIGHT, "RIGHT" }, { RIG_OP_TUNE, "TUNE" }, { RIG_OP_TOGGLE, "TOGGLE" }, { RIG_OP_NONE, "" }, }; /** * \brief Convert alpha string to enum RIG_OP_... * \param s alpha string * \return RIG_OP_... * * \sa vfo_op_t() */ vfo_op_t HAMLIB_API rig_parse_vfo_op(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; vfo_op_str[i].str[0] != '\0'; i++) { if (!strcmp(s, vfo_op_str[i].str)) { return vfo_op_str[i].vfo_op; } } return RIG_OP_NONE; } /** * \brief Convert enum RIG_OP_... to alpha string * \param op RIG_OP_... * \return alpha string * * \sa vfo_op_t() */ const char *HAMLIB_API rig_strvfop(vfo_op_t op) { int i; // too verbose // rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; vfo_op_str[i].str[0] != '\0'; i++) { if (op == vfo_op_str[i].vfo_op) { return vfo_op_str[i].str; } } return ""; } static const struct { scan_t rscan; const char *str; } scan_str[] = { { RIG_SCAN_STOP, "STOP" }, { RIG_SCAN_MEM, "MEM" }, { RIG_SCAN_SLCT, "SLCT" }, { RIG_SCAN_PRIO, "PRIO" }, { RIG_SCAN_PROG, "PROG" }, { RIG_SCAN_DELTA, "DELTA" }, { RIG_SCAN_VFO, "VFO" }, { RIG_SCAN_PLT, "PLT" }, { RIG_SCAN_NONE, "" }, { -1, NULL } }; /** * \brief Convert alpha string to enum RIG_SCAN_... * \param s alpha string * \return RIG_SCAN_... * * \sa scan_t() */ scan_t HAMLIB_API rig_parse_scan(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; scan_str[i].str[0] != '\0'; i++) { if (strcmp(s, scan_str[i].str) == 0) { return scan_str[i].rscan; } } return RIG_SCAN_NONE; } /** * \brief Convert enum RIG_SCAN_... to alpha string * \param rscan RIG_SCAN_... * \return alpha string * * \sa scan_t() */ const char *HAMLIB_API rig_strscan(scan_t rscan) { int i; // too verbose // rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rscan == RIG_SCAN_NONE) { return ""; } for (i = 0; scan_str[i].str[0] != '\0'; i++) { if (rscan == scan_str[i].rscan) { return scan_str[i].str; } } return ""; } /** * \brief convert enum RIG_RPT_SHIFT_... to printable character * \param shift RIG_RPT_SHIFT_?? * \return alpha character */ const char *HAMLIB_API rig_strptrshift(rptr_shift_t shift) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (shift) { case RIG_RPT_SHIFT_MINUS: return "-"; case RIG_RPT_SHIFT_PLUS: return "+"; case RIG_RPT_SHIFT_NONE: return "None"; } return NULL; } /** * \brief Convert alpha char to enum RIG_RPT_SHIFT_... * \param s alpha char * \return RIG_RPT_SHIFT_... */ rptr_shift_t HAMLIB_API rig_parse_rptr_shift(const char *s) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (strcmp(s, "+") == 0) { return RIG_RPT_SHIFT_PLUS; } else if (strcmp(s, "-") == 0) { return RIG_RPT_SHIFT_MINUS; } else { return RIG_RPT_SHIFT_NONE; } } static const struct { chan_type_t mtype; const char *str; } mtype_str[] = { { RIG_MTYPE_MEM, "MEM" }, { RIG_MTYPE_EDGE, "EDGE" }, { RIG_MTYPE_CALL, "CALL" }, { RIG_MTYPE_MEMOPAD, "MEMOPAD" }, { RIG_MTYPE_SAT, "SAT" }, { RIG_MTYPE_BAND, "BAND" }, { RIG_MTYPE_PRIO, "PRIO" }, { RIG_MTYPE_VOICE, "VOICE" }, { RIG_MTYPE_MORSE, "MORSE" }, { RIG_MTYPE_SPLIT, "SPLIT" }, { RIG_MTYPE_NONE, "" }, }; /** * \brief Convert alpha string to enum RIG_MTYPE_... * \param s alpha string * \return RIG_MTYPE_... * * \sa chan_type_t() */ chan_type_t HAMLIB_API rig_parse_mtype(const char *s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0 ; mtype_str[i].str[0] != '\0'; i++) { if (strcmp(s, mtype_str[i].str) == 0) { return mtype_str[i].mtype; } } return RIG_MTYPE_NONE; } /** * \brief Convert enum RIG_MTYPE_... to alpha string * \param mtype RIG_MTYPE_... * \return alpha string * * \sa chan_type_t() */ const char *HAMLIB_API rig_strmtype(chan_type_t mtype) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mtype == RIG_MTYPE_NONE) { return ""; } for (i = 0; mtype_str[i].str[0] != '\0'; i++) { if (mtype == mtype_str[i].mtype) { return mtype_str[i].str; } } return ""; } static const struct { enum rig_spectrum_mode_e mode; const char *str; } rig_spectrum_mode_str[] = { { RIG_SPECTRUM_MODE_CENTER, "CENTER" }, { RIG_SPECTRUM_MODE_FIXED, "FIXED" }, { RIG_SPECTRUM_MODE_CENTER_SCROLL, "CENTER_SCROLL" }, { RIG_SPECTRUM_MODE_FIXED_SCROLL, "FIXED_SCROLL" }, { RIG_SPECTRUM_MODE_NONE, "" }, }; /** * \brief Convert enum RIG_SPECTRUM_MODE_... to alpha string * \param mode RIG_SPECTRUM_MODE_... * \return alpha string */ const char *HAMLIB_API rig_strspectrummode(enum rig_spectrum_mode_e mode) { int i; if (mode == RIG_SPECTRUM_MODE_NONE) { return ""; } for (i = 0; rig_spectrum_mode_str[i].str[0] != '\0'; i++) { if (mode == rig_spectrum_mode_str[i].mode) { return rig_spectrum_mode_str[i].str; } } return ""; } static long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } /** * \brief Helper for checking cache timeout * \param tv pointer to timeval, date of cache * \param timeout duration of cache validity, in millisec * \return 1 when timed out, 0 when cache shall be used */ int HAMLIB_API rig_check_cache_timeout(const struct timeval *tv, int timeout) { struct timeval curr; long t; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: forced cache timeout\n", __func__); return 1; } gettimeofday(&curr, NULL); t = timediff(&curr, tv); if (t < timeout) { rig_debug(RIG_DEBUG_VERBOSE, "%s: using cache (%ld ms)\n", __func__, t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache timed out (%ld ms)\n", __func__, t); return 1; } } /** * \brief Helper for forcing cache timeout next call * * This function is typically to be called in backend_set_* functions, * so that a sequence: * \code rig_get_freq(); rig_set_freq(); rig_get_freq(); \endcode * * doesn't return a bogus (cached) value in the last rig_get_freq(). * * \param tv pointer to timeval to be reset */ void HAMLIB_API rig_force_cache_timeout(struct timeval *tv) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); tv->tv_sec = 0; tv->tv_usec = 0; } //! @cond Doxygen_Suppress int no_restore_ai; //! @endcond //! @cond Doxygen_Suppress void HAMLIB_API rig_no_restore_ai() { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); no_restore_ai = -1; } //! @endcond //! @cond Doxygen_Suppress double HAMLIB_API elapsed_ms(struct timespec *start, int option) { // If option then we are starting the timing, else we get elapsed struct timespec stop; double elapsed_msec; if (option == HAMLIB_ELAPSED_SET) { start->tv_sec = start->tv_nsec = 0; } stop = *start; // just to suppress some compiler warnings //rig_debug(RIG_DEBUG_TRACE, "%s: start = %ld,%ld\n", __func__, // (long)start->tv_sec, (long)start->tv_nsec); switch (option) { case HAMLIB_ELAPSED_GET: if (start->tv_nsec == 0) // if we haven't done SET yet { clock_gettime(CLOCK_REALTIME, start); return 1000 * 1000; } clock_gettime(CLOCK_REALTIME, &stop); break; case HAMLIB_ELAPSED_SET: clock_gettime(CLOCK_REALTIME, start); //rig_debug(RIG_DEBUG_TRACE, "%s: after gettime, start = %ld,%ld\n", __func__, // (long)start->tv_sec, (long)start->tv_nsec); return 999 * 1000; // so we can tell the difference in debug where we came from break; case HAMLIB_ELAPSED_INVALIDATE: clock_gettime(CLOCK_REALTIME, start); stop = *start; start->tv_sec -= 10; // ten seconds should be more than enough break; } elapsed_msec = ((stop.tv_sec - start->tv_sec) + (stop.tv_nsec / 1e9 - start->tv_nsec / 1e9)) * 1e3; //rig_debug(RIG_DEBUG_TRACE, "%s: elapsed_msecs=%.0f\n", __func__, elapsed_msec); if (elapsed_msec < 0 || option == HAMLIB_ELAPSED_INVALIDATE) { return 1000000; } return elapsed_msec; } //! @endcond int HAMLIB_API rig_get_cache_timeout_ms(RIG *rig, hamlib_cache_t selection) { rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d\n", __func__, selection); return CACHE(rig)->timeout_ms; } int HAMLIB_API rig_set_cache_timeout_ms(RIG *rig, hamlib_cache_t selection, int ms) { rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d, ms=%d\n", __func__, selection, ms); CACHE(rig)->timeout_ms = ms; return RIG_OK; } static char *funcname = "Unknown"; static int linenum = 0; #undef vfo_fixup vfo_t HAMLIB_API vfo_fixup2a(RIG *rig, vfo_t vfo, split_t split, const char *func, int line) { funcname = (char *)func; linenum = (int)line; return vfo_fixup(rig, vfo, split); } // we're mapping our VFO here to work with either VFO A/B rigs or Main/Sub // Hamlib uses VFO_A and VFO_B as TX/RX as of 2021-04-13 // So we map these to Main/Sub as required // We need to add some exceptions to this like the ID-5100 vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo, split_t split) { struct rig_state *rs = STATE(rig); vfo_t currvfo = rs->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s:(from %s:%d) vfo=%s, vfo_curr=%s, split=%d\n", __func__, funcname, linenum, rig_strvfo(vfo), rig_strvfo(currvfo), split); if (rig->caps->rig_model == RIG_MODEL_ID5100 || rig->caps->rig_model == RIG_MODEL_IC9700) { // dualwatch on ID5100 is TX=Main, RX=Sub if (rig->caps->rig_model == RIG_MODEL_ID5100 && rs->dual_watch) { if (vfo == RIG_VFO_TX || vfo == RIG_VFO_MAIN) { return RIG_VFO_MAIN; } return RIG_VFO_SUB; } return vfo; // no change to requested vfo } else if (RIG_IS_IC9700) { if (vfo == RIG_VFO_A && (currvfo == RIG_VFO_MAIN || currvfo == RIG_VFO_MAIN_A)) { vfo = RIG_VFO_MAIN_A; // only have Main/Sub when in satmode if (CACHE(rig)->satmode) { vfo = RIG_VFO_MAIN; } } else if (vfo == RIG_VFO_B && (currvfo == RIG_VFO_MAIN || currvfo == RIG_VFO_MAIN_A)) { vfo = RIG_VFO_MAIN_B; } else if (vfo == RIG_VFO_A && (currvfo == RIG_VFO_SUB || currvfo == RIG_VFO_SUB_A || currvfo == RIG_VFO_SUB_B)) { vfo = RIG_VFO_SUB_A; } else if (vfo == RIG_VFO_B && (currvfo == RIG_VFO_SUB || currvfo == RIG_VFO_SUB_A || currvfo == RIG_VFO_SUB_B)) { vfo = RIG_VFO_SUB_B; } } if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) { rig_debug(RIG_DEBUG_TRACE, "%s: Leaving currVFO alone\n", __func__); return vfo; // don't modify vfo for RIG_VFO_CURR } if (vfo == RIG_VFO_OTHER) { switch (rs->current_vfo) { case RIG_VFO_A: return RIG_VFO_B; case RIG_VFO_MAIN: return RIG_VFO_SUB; case RIG_VFO_B: return RIG_VFO_A; case RIG_VFO_SUB: return RIG_VFO_MAIN; case RIG_VFO_SUB_A: return RIG_VFO_SUB_B; case RIG_VFO_SUB_B: return RIG_VFO_SUB_A; } } if (vfo == RIG_VFO_RX) { vfo = rs->rx_vfo; } else if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { vfo = RIG_VFO_A; // default to mapping VFO_MAIN to VFO_A if (VFO_HAS_MAIN_SUB_ONLY) { vfo = RIG_VFO_MAIN; } } else if (vfo == RIG_VFO_TX) { int satmode = CACHE(rig)->satmode; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): split=%d, vfo==%s tx_vfo=%s\n", __func__, __LINE__, split, rig_strvfo(vfo), rig_strvfo(rs->tx_vfo)); if (VFO_HAS_MAIN_SUB_ONLY && !split && !satmode && vfo != RIG_VFO_B) { vfo = RIG_VFO_MAIN; } else if (VFO_HAS_MAIN_SUB_ONLY && (split || satmode || vfo == RIG_VFO_B)) { vfo = RIG_VFO_SUB; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && split) { vfo = RIG_VFO_B; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && satmode) { vfo = RIG_VFO_SUB; } else if (VFO_HAS_A_B_ONLY) { vfo = split ? RIG_VFO_B : RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX changed to %s, split=%d, satmode=%d\n", __func__, rig_strvfo(vfo), split, satmode); } else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { vfo = RIG_VFO_B; // default to VFO_B if (VFO_HAS_MAIN_SUB_ONLY) { vfo = RIG_VFO_SUB; } } rig_debug(RIG_DEBUG_TRACE, "%s: final vfo=%s\n", __func__, rig_strvfo(vfo)); return vfo; } int HAMLIB_API parse_hoststr(char *hoststr, int hoststr_len, char host[256], char port[6]) { unsigned int net1, net2, net3, net4, net5, net6, net7, net8; char dummy[6], link[32], *p; host[0] = 0; port[0] = 0; dummy[0] = 0; // Exclude any names that aren't a host:port format // Handle device names 1st if (strstr(hoststr, "/dev")) { return -1; } if (strstr(hoststr, "/")) { return -1; } // probably a path so not a hoststr if (strncasecmp(hoststr, "com", 3) == 0) { return -1; } // escaped COM port like \\.\COM3 or \.\COM3 if (strstr(hoststr, "\\.\\")) { return -1; } // Now let's try and parse a host:port thing // bracketed IPV6 with optional port int n = sscanf(hoststr, "[%255[^]]]:%5s", host, port); if (n >= 1) { return RIG_OK; } // non-bracketed full IPV6 with optional link addr n = sscanf(hoststr, "%x:%x:%x:%x:%x:%x:%x:%x%%%31[^:]:%5s", &net1, &net2, &net3, &net4, &net5, &net6, &net7, &net8, link, port); if (n == 8 || n == 9) { strcpy(host, hoststr); return RIG_OK; } else if (n == 10) { strcpy(host, hoststr); p = strrchr(host, ':'); // remove port from host *p = 0; return RIG_OK; } // non-bracketed IPV6 with optional link addr and optional port n = sscanf(hoststr, "%x::%x:%x:%x:%x%%%31[^:]:%5s", &net1, &net2, &net3, &net4, &net5, link, port); if (strchr(hoststr, '%') && (n == 5 || n == 6)) { strcpy(host, hoststr); return RIG_OK; } else if (n == 7) { strcpy(host, hoststr); p = strrchr(host, ':'); // remove port from host *p = 0; return RIG_OK; } // non-bracketed IPV6 short form with optional port n = sscanf(hoststr, "%x::%x:%x:%x:%x:%5[0-9]%1s", &net1, &net2, &net3, &net4, &net5, port, dummy); if (n == 5) { strcpy(host, hoststr); return RIG_OK; } else if (n == 6) { strcpy(host, hoststr); p = strrchr(host, ':'); *p = 0; return RIG_OK; } else if (n == 7) { return -RIG_EINVAL; } // bracketed localhost if (strstr(hoststr, "::1")) { n = sscanf(hoststr, "::1%5s", dummy); strcpy(host, hoststr); if (n == 1) { p = strrchr(host, ':'); *p = 0; strcpy(port, p + 1); } return RIG_OK; } if (sscanf(hoststr, ":%5[0-9]%1s", port, dummy) == 1) // just a port if you please { SNPRINTF(hoststr, hoststr_len, "%s:%s\n", "localhost", port); rig_debug(RIG_DEBUG_VERBOSE, "%s: hoststr=%s\n", __func__, hoststr); return RIG_OK; } // if we're here then we must have a hostname n = sscanf(hoststr, "%255[^:]:%5[0-9]%1s", host, port, dummy); if (n >= 1 && strlen(dummy) == 0) { return RIG_OK; } printf("Unhandled host=%s\n", hoststr); return -1; } /** * \brief Force flush of rig communication data buffers. * \param port communication port * \param flush_async_data Flushes also asynchronous I/O pipes if non-zero. * \return status code * * This function should be used only in special cases like after handling raw command data from Hamlib clients. * When asynchronous I/O is enabled, responses to raw commands may disrupt processing of all commands, * because the responses and up in the async I/O pipes. */ int HAMLIB_API rig_flush_force(hamlib_port_t *port, int flush_async_data) { if (port->type.rig == RIG_PORT_NONE) { return RIG_OK; } // Flush also the async I/O pipes if (port->asyncio && flush_async_data) { port_flush_sync_pipes(port); } #ifndef RIG_FLUSH_REMOVE // rig_debug(RIG_DEBUG_TRACE, "%s: called for %s device\n", __func__, // port->type.rig == RIG_PORT_SERIAL ? "serial" : "network"); if (port->type.rig == RIG_PORT_NETWORK || port->type.rig == RIG_PORT_UDP_NETWORK) { network_flush(port); return RIG_OK; } if (port->type.rig != RIG_PORT_SERIAL) { rig_debug(RIG_DEBUG_WARN, "%s: Expected serial port type!!\nWhat is this rig?\n", __func__); } return serial_flush(port); // we must be on serial port #else return RIG_OK; #endif } int HAMLIB_API rig_flush(hamlib_port_t *port) { // Data should never be flushed when using async I/O if (port->asyncio) { return RIG_OK; } return rig_flush_force(port, 0); } static const struct { rot_status_t status; const char *str; } rot_status_str[] = { { ROT_STATUS_BUSY, "BUSY" }, { ROT_STATUS_MOVING, "MOVING" }, { ROT_STATUS_MOVING_AZ, "MOVING_AZ" }, { ROT_STATUS_MOVING_LEFT, "MOVING_LEFT" }, { ROT_STATUS_MOVING_RIGHT, "MOVING_RIGHT" }, { ROT_STATUS_MOVING_EL, "MOVING_EL" }, { ROT_STATUS_MOVING_UP, "MOVING_UP" }, { ROT_STATUS_MOVING_DOWN, "MOVING_DOWN" }, { ROT_STATUS_LIMIT_UP, "LIMIT_UP" }, { ROT_STATUS_LIMIT_DOWN, "LIMIT_DOWN" }, { ROT_STATUS_LIMIT_LEFT, "LIMIT_LEFT" }, { ROT_STATUS_LIMIT_RIGHT, "LIMIT_RIGHT" }, { ROT_STATUS_OVERLAP_UP, "OVERLAP_UP" }, { ROT_STATUS_OVERLAP_DOWN, "OVERLAP_DOWN" }, { ROT_STATUS_OVERLAP_LEFT, "OVERLAP_LEFT" }, { ROT_STATUS_OVERLAP_RIGHT, "OVERLAP_RIGHT" }, { 0xffffff, "" }, }; /** * \brief Convert enum ROT_STATUS_... to a string * \param status ROT_STATUS_... * \return the corresponding string value */ const char *HAMLIB_API rot_strstatus(rot_status_t status) { int i; for (i = 0 ; rot_status_str[i].str[0] != '\0'; i++) { if (status == rot_status_str[i].status) { return rot_status_str[i].str; } } return ""; } /** * \brief Get pointer to rig function instead of using rig->caps * \param rig_model * \param rig_function * \return the corresponding function pointer */ void *HAMLIB_API rig_get_function_ptr(rig_model_t rig_model, enum rig_function_e rig_function) { const struct rig_caps *caps = rig_get_caps(rig_model); if (caps == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: caps == null for model %d??\n", __func__, rig_model); return NULL; } switch (rig_function) { case RIG_FUNCTION_INIT: return caps->rig_init; case RIG_FUNCTION_CLEANUP: return caps->rig_cleanup; case RIG_FUNCTION_OPEN: return caps->rig_open; case RIG_FUNCTION_CLOSE: return caps->rig_close; case RIG_FUNCTION_SET_FREQ: return caps->set_freq; case RIG_FUNCTION_GET_FREQ: return caps->get_freq; case RIG_FUNCTION_SET_MODE: return caps->set_mode; case RIG_FUNCTION_GET_MODE: return caps->get_mode; case RIG_FUNCTION_SET_VFO: return caps->set_vfo; case RIG_FUNCTION_GET_VFO: return caps->get_vfo; case RIG_FUNCTION_SET_PTT: return caps->set_ptt; case RIG_FUNCTION_GET_PTT: return caps->get_ptt; case RIG_FUNCTION_GET_DCD: return caps->get_dcd; case RIG_FUNCTION_SET_RPTR_SHIFT: return caps->set_rptr_shift; case RIG_FUNCTION_GET_RPTR_SHIFT: return caps->get_rptr_shift; case RIG_FUNCTION_SET_RPTR_OFFS: return caps->set_rptr_offs; case RIG_FUNCTION_GET_RPTR_OFFS: return caps->get_rptr_offs; case RIG_FUNCTION_SET_SPLIT_FREQ: return caps->set_split_freq; case RIG_FUNCTION_GET_SPLIT_FREQ: return caps->get_split_freq; case RIG_FUNCTION_SET_SPLIT_MODE: return caps->set_split_mode; case RIG_FUNCTION_SET_SPLIT_FREQ_MODE: return caps->set_split_freq_mode; case RIG_FUNCTION_GET_SPLIT_FREQ_MODE: return caps->get_split_freq_mode; case RIG_FUNCTION_SET_SPLIT_VFO: return caps->set_split_vfo; case RIG_FUNCTION_GET_SPLIT_VFO: return caps->get_split_vfo; case RIG_FUNCTION_SET_RIT: return caps->set_rit; case RIG_FUNCTION_GET_RIT: return caps->get_rit; case RIG_FUNCTION_SET_XIT: return caps->set_xit; case RIG_FUNCTION_GET_XIT: return caps->get_xit; case RIG_FUNCTION_SET_TS: return caps->set_ts; case RIG_FUNCTION_GET_TS: return caps->get_ts; case RIG_FUNCTION_SET_DCS_CODE: return caps->set_dcs_code; case RIG_FUNCTION_GET_DCS_CODE: return caps->get_dcs_code; case RIG_FUNCTION_SET_TONE: return caps->set_tone; case RIG_FUNCTION_GET_TONE: return caps->get_tone; case RIG_FUNCTION_SET_CTCSS_TONE: return caps->set_ctcss_tone; case RIG_FUNCTION_GET_CTCSS_TONE: return caps->get_ctcss_tone; case RIG_FUNCTION_SET_DCS_SQL: return caps->set_dcs_sql; case RIG_FUNCTION_GET_DCS_SQL: return caps->get_dcs_sql; case RIG_FUNCTION_SET_TONE_SQL: return caps->set_tone_sql; case RIG_FUNCTION_GET_TONE_SQL: return caps->get_tone_sql; case RIG_FUNCTION_SET_CTCSS_SQL: return caps->set_ctcss_sql; case RIG_FUNCTION_GET_CTCSS_SQL: return caps->get_ctcss_sql; case RIG_FUNCTION_POWER2MW: return caps->power2mW; case RIG_FUNCTION_MW2POWER: return caps->mW2power; case RIG_FUNCTION_SET_POWERSTAT: return caps->set_powerstat; case RIG_FUNCTION_GET_POWERSTAT: return caps->get_powerstat; case RIG_FUNCTION_RESET: return caps->reset; case RIG_FUNCTION_SET_ANT: return caps->set_ant; case RIG_FUNCTION_GET_ANT: return caps->get_ant; case RIG_FUNCTION_SET_LEVEL: return caps->set_level; case RIG_FUNCTION_GET_LEVEL: return caps->get_level; case RIG_FUNCTION_SET_FUNC: return caps->set_func; case RIG_FUNCTION_GET_FUNC: return caps->get_func; case RIG_FUNCTION_SET_PARM: return caps->set_parm; case RIG_FUNCTION_GET_PARM: return caps->get_parm; case RIG_FUNCTION_SET_EXT_LEVEL: return caps->set_ext_level; case RIG_FUNCTION_GET_EXT_LEVEL: return caps->get_ext_level; case RIG_FUNCTION_SET_EXT_FUNC: return caps->set_ext_func; case RIG_FUNCTION_GET_EXT_FUNC: return caps->get_ext_func; case RIG_FUNCTION_SET_EXT_PARM: return caps->set_ext_parm; case RIG_FUNCTION_GET_EXT_PARM: return caps->get_ext_parm; case RIG_FUNCTION_SET_CONF: return caps->set_conf; case RIG_FUNCTION_GET_CONF: return caps->get_conf; case RIG_FUNCTION_GET_CONF2: return caps->get_conf2; case RIG_FUNCTION_SEND_DTMF: return caps->send_dtmf; case RIG_FUNCTION_SEND_MORSE: return caps->send_morse; case RIG_FUNCTION_STOP_MORSE: return caps->stop_morse; case RIG_FUNCTION_WAIT_MORSE: return caps->wait_morse; case RIG_FUNCTION_SEND_VOICE_MEM: return caps->send_voice_mem; case RIG_FUNCTION_SET_BANK: return caps->set_bank; case RIG_FUNCTION_SET_MEM: return caps->set_mem; case RIG_FUNCTION_GET_MEM: return caps->get_mem; case RIG_FUNCTION_VFO_OP: return caps->vfo_op; case RIG_FUNCTION_SCAN: return caps->scan; case RIG_FUNCTION_SET_TRN: return caps->set_trn; case RIG_FUNCTION_GET_TRN: return caps->get_trn; case RIG_FUNCTION_DECODE_EVENT: return caps->decode_event; case RIG_FUNCTION_SET_CHANNEL: return caps->set_channel; case RIG_FUNCTION_GET_CHANNEL: return caps->get_channel; case RIG_FUNCTION_GET_INFO: return caps->get_info; case RIG_FUNCTION_SET_CHAN_ALL_CB: return caps->set_chan_all_cb; case RIG_FUNCTION_GET_CHAN_ALL_CB: return caps->get_chan_all_cb; case RIG_FUNCTION_SET_MEM_ALL_CB: return caps->set_mem_all_cb; case RIG_FUNCTION_GET_MEM_ALL_CB: return caps->get_mem_all_cb; case RIG_FUNCTION_SET_VFO_OPT: return caps->set_vfo_opt; case RIG_FUNCTION_READ_FRAME_DIRECT: return caps->read_frame_direct; case RIG_FUNCTION_IS_ASYNC_FRAME: return caps->is_async_frame; case RIG_FUNCTION_PROCESS_ASYNC_FRAME: return caps->process_async_frame; default: rig_debug(RIG_DEBUG_ERR, "Unknown function?? function=%d\n", rig_function); } return NULL; } // negative return indicates error /** * \brief Get integer/long instead of using rig->caps * watch out for integer values that may be negative -- if needed must change hamlib * \param rig_model * \param rig_caps * \return the corresponding long value -- -RIG_EINVAL is the only error possible */ uint64_t HAMLIB_API rig_get_caps_int(rig_model_t rig_model, enum rig_caps_int_e rig_caps) { const struct rig_caps *caps = rig_get_caps(rig_model); #if 0 rig_debug(RIG_DEBUG_TRACE, "%s: getting rig_caps for model=%d, rig_caps=%d\n", __func__, rig_model, rig_caps); #endif if (caps == NULL) { #if 0 rig_debug(RIG_DEBUG_ERR, "%s: called with NULL caps...returning -1\n", __func__); #endif return -1; } switch (rig_caps) { case RIG_CAPS_TARGETABLE_VFO: return caps->targetable_vfo; case RIG_CAPS_RIG_MODEL: return caps->rig_model; case RIG_CAPS_PTT_TYPE: #if 0 rig_debug(RIG_DEBUG_TRACE, "%s: return %u\n", __func__, caps->ptt_type); #endif return caps->ptt_type; case RIG_CAPS_PORT_TYPE: return caps->port_type; case RIG_CAPS_HAS_GET_LEVEL: return caps->has_get_level; default: #if 0 rig_debug(RIG_DEBUG_ERR, "%s: Unknown rig_caps value=%d\n", __func__, rig_caps); #endif return (-RIG_EINVAL); } } const char *HAMLIB_API rig_get_caps_cptr(rig_model_t rig_model, enum rig_caps_cptr_e rig_caps) { const struct rig_caps *caps = rig_get_caps(rig_model); if (caps == NULL) { // rig_debug(RIG_DEBUG_ERR, "%s: called with NULL caps...returning NULL\n", // __func__); return NULL; } switch (rig_caps) { case RIG_CAPS_VERSION_CPTR: return caps->version; case RIG_CAPS_MFG_NAME_CPTR: return caps->mfg_name; case RIG_CAPS_MODEL_NAME_CPTR: return caps->model_name; case RIG_CAPS_STATUS_CPTR: return rig_strstatus(caps->status); default: #if 0 rig_debug(RIG_DEBUG_ERR, "%s: Unknown requested rig_caps value=%d\n", __func__, rig_caps); #endif return "Unknown caps value"; } } static const struct { rig_comm_status_t status; const char *str; } comm_status_str[] = { { RIG_COMM_STATUS_OK, "OK" }, { RIG_COMM_STATUS_CONNECTING, "CONNECTING" }, { RIG_COMM_STATUS_DISCONNECTED, "DISCONNECTED" }, { RIG_COMM_STATUS_TERMINATED, "TERMINATIED" }, { RIG_COMM_STATUS_WARNING, "WARNING" }, { RIG_COMM_STATUS_ERROR, "ERROR" }, { 0xffffffff, "" }, }; /** * \brief Convert enum RIG_COMM_STATUS... to alpha string * \param status RIG_COMM_STATUS_... * \return alpha string */ const char *HAMLIB_API rig_strcommstatus(rig_comm_status_t status) { int i; for (i = 0; comm_status_str[i].str[0] != '\0'; i++) { if (status == comm_status_str[i].status) { return comm_status_str[i].str; } } return ""; } void errmsg(int err, char *s, const char *func, const char *file, int line) { rig_debug(RIG_DEBUG_ERR, "%s(%s:%d): %s: %s\b", __func__, file, line, s, rigerror(err)); } uint32_t CRC32_function(uint8_t *buf, uint32_t len) { uint32_t crc; uint8_t i; crc = 0xFFFFFFFF; while (len--) { uint32_t val; val = (crc^*buf++) & 0xFF; for (i = 0; i < 8; i++) { val = val & 1 ? (val >> 1) ^ 0xEDB88320 : val >> 1; } crc = val ^ crc >> 8; } return crc ^ 0xFFFFFFFF; } #if defined(_WIN32) // gmtime_r can be defined by mingw #ifndef gmtime_r static struct tm *gmtime_r(const time_t *t, struct tm *r) { // gmtime is threadsafe in windows because it uses TLS const struct tm *theTm = gmtime(t); if (theTm) { *r = *theTm; return r; } else { return 0; } } #endif // gmtime_r #endif // _WIN32 //! @cond Doxygen_Suppress char *date_strget(char *buf, int buflen, int localtime) { char tmpbuf[64]; struct tm *mytm; time_t t; struct timeval tv; struct tm result = { 0, 0, 0, 0, 0, 0, 0, 0, 0}; int mytimezone; // 2038 failure here for 32-bit time_t t = time(NULL); if (localtime) { mytm = localtime_r(&t, &result); #if defined(_WIN32) mytimezone = timezone; #else mytimezone = - (int)result.tm_gmtoff; // does not compile on mingw #endif } else { mytm = gmtime_r(&t, &result); mytimezone = 0; } strftime(buf, buflen, "%Y-%m-%dT%H:%M:%S.", mytm); gettimeofday(&tv, NULL); SNPRINTF(tmpbuf, sizeof(tmpbuf), "%06ld", (long)tv.tv_usec); strcat(buf, tmpbuf); SNPRINTF(tmpbuf, sizeof(tmpbuf), "%s%04d", mytimezone >= 0 ? "-" : "+", ((int)abs(mytimezone) / 3600) * 100); strcat(buf, tmpbuf); return buf; } char *rig_date_strget(char *buf, int buflen, int localtime) { return date_strget(buf, buflen, localtime); } #define MAX_SPACES 256 const char *spaces(int len) { static const char s[MAX_SPACES + 1] = "****************************************************************" "****************************************************************" "****************************************************************" "****************************************************************"; if (len < 0 || len > MAX_SPACES) { len = 0; } return &s[MAX_SPACES - len]; } // if which==0 rig_band_select str will be returned // if which!=0 the rig_parm_gran band str will be returned const char *rig_get_band_str(RIG *rig, hamlib_band_t band, int which) { int i; if (which == 0) { for (i = 0; rig_bandselect_str[i].str != NULL; i++) { if (rig_bandselect_str[i].bandselect == band) { return rig_bandselect_str[i].str; } } } else { char bandlist[512]; rig_sprintf_parm_gran(bandlist, sizeof(bandlist) - 1, RIG_PARM_BANDSELECT, rig->caps->parm_gran); rig_debug(RIG_DEBUG_VERBOSE, "%s: bandlist=%s\n", __func__, bandlist); int n = 0; char *p = strchr(bandlist, '(') + 1; char *token; if (p == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unable to find open paren in '%s'\n", __func__, bandlist); return 0; } while ((token = strtok_r(p, ",", &p))) { if (n == band) { for (i = 0; rig_bandselect_str[i].str != NULL; i++) { if (strcmp(rig_bandselect_str[i].str, token) == 0) { return rig_bandselect_str[i].str; } } } n++; } } return "BANDGEN"; } // If freq==0 looks up using the band index (which is the rig's band reference index) // So you call for the rigs' band select value, pass it in and get back the hamlib_band_t // Then use rig_get_band_str to get the abstract band name // returns the rig's backend hamlib_band_t that can used to lookup the band str hamlib_band_t rig_get_band(RIG *rig, freq_t freq, int band) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (freq == 0) { char bandlist[512]; rig_sprintf_parm_gran(bandlist, sizeof(bandlist) - 1, RIG_PARM_BANDSELECT, rig->caps->parm_gran); rig_debug(RIG_DEBUG_VERBOSE, "%s: bandlist=%s\n", __func__, bandlist); // e.g. BANDSELECT(BAND160M,BAND80M,BANDUNUSED,BAND40M) char *p = strchr(bandlist, '(') + 1; char *token; if (p == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unable to find open paren in '%s'\n", __func__, bandlist); return 0; } int n = 0; while ((token = strtok_r(p, ",", &p))) { if (n == band) { return rig_bandselect_str[n].bandselect; } n++; } return RIG_BAND_UNUSED; } for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (freq >= rig_bandselect_str[i].start && freq <= rig_bandselect_str[i].stop) { return rig_bandselect_str[i].bandselect; } } return RIG_BAND_UNUSED; } // Gets the rig's band index from the hamlib_band_t int rig_get_band_rig(RIG *rig, freq_t freq, const char *band) { char bandlist[512]; int i; if (freq == 0 && band == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: bad combo of freq==0 && band==NULL\n", __func__); return RIG_BAND_GEN; } if (freq == 0) { bandlist[0] = 0; rig_sprintf_parm_gran(bandlist, sizeof(bandlist) - 1, RIG_PARM_BANDSELECT, rig->caps->parm_gran); rig_debug(RIG_DEBUG_VERBOSE, "%s: bandlist=%s\n", __func__, bandlist); // e.g. BANDSELECT(BAND160M,BAND80M,BANDUNUSED,BAND40M) if (strlen(bandlist) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: rig does not have bandlist\n", __func__); return RIG_BAND_GEN; } char *p = strchr(bandlist, '(') + 1; char *token; if (p == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unable to find open paren in '%s'\n", __func__, bandlist); return 0; } int n = 0; while ((token = strtok_r(p, ",", &p))) { if (strcmp(token, band) == 0) { return n; } n++; } rig_debug(RIG_DEBUG_ERR, "%s: unknown band %s\n", __func__, band); return 0; } for (i = 0 ; rig_bandselect_str[i].str != NULL; i++) { if (freq >= rig_bandselect_str[i].start && freq <= rig_bandselect_str[i].stop) { // now we know the hamlib_band_t so we can look it up now // this is 1-time recursive return rig_get_band_rig(rig, 0.0, rig_bandselect_str[i].str); } } rig_debug(RIG_DEBUG_ERR, "%s: unable to find band=%s, freq=%f\n", __func__, band, freq); return 0; // just give a value for now of the 1st band -- this should be an error } // Returns RIG_OK if 2038 time routines pass tests int rig_test_2038(RIG *rig) { #if defined(_TIME_BITS) #if defined(__GLIBC_MINOR__) && defined(__TIMESIZE) rig_debug(RIG_DEBUG_TRACE, "%s: enter _TIME_BITS=%d, __TIMESIZE=%d testing enabled for GLIBC %d.%d\n", __func__, _TIME_BITS, __TIMESIZE, __GLIBC__, __GLIBC_MINOR__); #else rig_debug(RIG_DEBUG_TRACE, "%s: enter _TIME_BITS=64 testing enabled for unknown libc\n", __func__); #endif #else rig_debug(RIG_DEBUG_TRACE, "%s: enter _TIME_BITS=64 testing not enabled\n", __func__); #endif #if defined(__MSVCRT_VERSION__) rig_debug(RIG_DEBUG_TRACE, "%s: __MSVCRT_VERSION__=0x%04x\n", __func__, __MSVCRT_VERSION__); #endif int failed = 0; char *stime = NULL; #if defined(__MSVCRT_VERSION__) __time64_t const x = (__time64_t)0xF0000000; char s[64]; struct tm mytm; int timeerr = _localtime64_s(&mytm, &x); if (timeerr) { rig_debug(RIG_DEBUG_ERR, "%s: _localtime64_s: %s\n", __func__, strerror(errno)); } strftime(s, sizeof(s), "%a %b %d %H:%M:%S %Y\n", &mytm); rig_debug(RIG_DEBUG_VERBOSE, "%s: MSVCRT 2038 test = 0x%08llx:%s", __func__, x, s); if (strlen(s) == 0) { failed = 1; } else if (strstr(s, "2097")) { return RIG_OK; } #else if (sizeof(time_t) == 4) { rig_debug(RIG_DEBUG_TRACE, "%s: time_t is 4 bytes, 2038 test failed\n", __func__); return 1; } time_t x = (time_t)0xF0000000; stime = ctime(&x); if (stime == NULL) { failed = 1; } #if 0 // this fails on 32-bit RigPi -- time_t 32-bit maybe? else rig_debug(RIG_DEBUG_VERBOSE, "%s: time_t 2038 test = 0x%08lx:%s", __func__, x, s == NULL ? "NULL" : s); #endif #endif if (failed) { rig_debug(RIG_DEBUG_TRACE, "%s: ctime is null, 2038 test failed\n", __func__); return 1; } if (stime != NULL && strstr(stime, "2097")) { return RIG_OK; } #if defined(__MSVCRT_VERSION__) _ctime64_s(s, sizeof(s), &x); if (strstr(s, "2097")) { return RIG_OK; } #else char *s = ctime(&x); if (s != NULL && strstr(s, "2097")) { return RIG_OK; } #endif return 1; } //! @endcond /** * Add item to be sent to device after it is opened * (currently only used by rotators) **/ int queue_deferred_config(deferred_config_header_t *head, hamlib_token_t token, const char *val) { deferred_config_item_t *item; if (!(item = malloc(sizeof(deferred_config_item_t)))) { return -RIG_ENOMEM; } if (!(item->value = strdup(val))) { free(item); return -RIG_ENOMEM; } item->token = token; item->next = NULL; if (!head->first) { head->first = item; } else { head->last->next = item; } head->last = item; return RIG_OK; } /** @} */ hamlib-4.6.5/src/extamp.c0000664000175000017500000001651315056640443010713 /* * Hamlib Interface - extra parameter interface for amplifiers * Copyright (c) 2000-2008 by Stephane Fillod * Derived from ext.c * Copyright (c) 2019 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup amplifier * @{ */ /** * \file extamp.c * \brief Amplifier extension parameters and levels interface. * * \author Michael Black * \date 2019 * * An open-ended set of extension parameters and levels are available for each * amplifier, as provided in the amp_caps::extparms and amp_caps::extlevels * lists. These provide a way to work with amplifier-specific functions that * don't fit into the basic "virtual amplifier" of Hamlib. See * `amplifiers/elecraft/kpa.c` for an example. */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include "token.h" /** * \brief Executes \a cfunc on all the elements stored in the amp_caps::extlevels * extension levels table. * * \param amp The #AMP handle. * \param cfunc Callback function of each amp_caps::extlevels. * \param data Cookie to be passed to the callback function \a cfunc. * * The callback function \a cfunc is called until it returns a value which is * not strictly positive. * * \returns A zero value which means a normal end of iteration, or a * **negative value** which means an abnormal end, * * \retval RIG_OK All extension levels elements successfully processed. * \retval RIG_EINVAL \a amp or \a cfunc is NULL or inconsistent. */ int HAMLIB_API amp_ext_level_foreach(AMP *amp, int (*cfunc)(AMP *, const struct confparams *, amp_ptr_t), amp_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = amp->caps->extlevels; cfp && cfp->name; cfp++) { int ret = (*cfunc)(amp, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \brief Executes \a cfunc on all the elements stored in the * amp_caps::extparms extension parameters table. * * \param amp The #AMP handle. * \param cfunc Callback function of each amp_caps::extparms. * \param data Cookie to be passed to the callback function \a cfunc. * * The callback function \a cfunc is called until it returns a value which is not * strictly positive. * * \returns A zero value which means a normal end of iteration, or a * **negative value** which means an abnormal end. * * \retval RIG_OK All extension parameters elements successfully processed. * \retval RIG_EINVAL \a amp or \a cfunc is NULL or inconsistent. */ int HAMLIB_API amp_ext_parm_foreach(AMP *amp, int (*cfunc)(AMP *, const struct confparams *, amp_ptr_t), amp_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = amp->caps->extparms; cfp && cfp->name; cfp++) { int ret = (*cfunc)(amp, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \brief Lookup an extension levels or parameters token by its name and return * a pointer to the containing #confparams structure member. * * \param amp The #AMP handle. * \param name The extension levels or parameters token name. * * Searches the amp_caps::extlevels table and then the amp_caps::extparms * table for the token by its name. * * \note As this function is called by amp_ext_token_lookup(), it can be * considered a lower level API. * * \return A pointer to the containing #confparams structure member or NULL if * nothing found or if \a amp is NULL or inconsistent. * * \sa amp_ext_token_lookup() * * \todo Should use Lex to speed it up, strcmp() hurts! */ const struct confparams *HAMLIB_API amp_ext_lookup(AMP *amp, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return NULL; } for (cfp = amp->caps->extlevels; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } for (cfp = amp->caps->extparms; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } return NULL; } /** * \brief Search for an extension levels or parameters token by its constant * value and return a pointer to the #confparams structure member. * * \param amp The #AMP handle. * \param token The token value (constant). * * Searches the amp_caps::extlevels table first and then the * amp_caps::extparms for the token by its constant value. * * \return A pointer to the containing #confparams structure member or NULL if * nothing found or if \a amp is NULL or inconsistent. */ const struct confparams *HAMLIB_API amp_ext_lookup_tok(AMP *amp, hamlib_token_t token) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return NULL; } for (cfp = amp->caps->extlevels; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } for (cfp = amp->caps->extparms; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } return NULL; } /** * \brief Simple search returning the extension token ID associated with * \a name. * * \param amp The #AMP handle. * \param name The token name string to search. * * \note As this function calls amp_ext_lookup(), it can be considered a * higher level API. * * \return The token ID or #RIG_CONF_END if there is a lookup failure. * * \sa amp_ext_lookup() */ hamlib_token_t HAMLIB_API amp_ext_token_lookup(AMP *amp, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); cfp = amp_ext_lookup(amp, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** @} */ hamlib-4.6.5/src/parallel.c0000664000175000017500000004411115056640443011204 /* * Hamlib Interface - parallel communication low-level support * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \brief Parallel Port IO * \file parallel.c */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_WINDOWS_H # include # include "par_nt.h" #endif #ifdef HAVE_WINIOCTL_H # include #endif #ifdef HAVE_WINBASE_H # include #endif #include "parallel.h" #ifdef HAVE_LINUX_PPDEV_H # include # include #endif #ifdef HAVE_DEV_PPBUS_PPI_H # include # include #endif //! @cond Doxygen_Suppress /* * These control port bits are active low. * We toggle them so that this weirdness doesn't get propagated * through our interface. */ #define CP_ACTIVE_LOW_BITS 0x0B /* * These status port bits are active low. * We toggle them so that this weirdness doesn't get propagated * through our interface. */ #define SP_ACTIVE_LOW_BITS 0x80 //! @endcond /* Pinout table of parallel port from http://en.wikipedia.org/wiki/Parallel_port#Pinouts Pin No (DB25) Signal name Direction Register-bit Inverted 1 *Strobe In/Out Control-0 Yes 2 Data0 Out Data-0 No 3 Data1 Out Data-1 No 4 Data2 Out Data-2 No 5 Data3 Out Data-3 No 6 Data4 Out Data-4 No 7 Data5 Out Data-5 No 8 Data6 Out Data-6 No 9 Data7 Out Data-7 No 10 *Ack In Status-6 No 11 Busy In Status-7 Yes 12 Paper-Out In Status-5 No 13 Select In Status-4 No 14 Linefeed In/Out Control-1 Yes 15 *Error In Status-3 No 16 *Reset In/Out Control-2 No 17 *Select-Printer In/Out Control-3 Yes * means low true, e.g., *Strobe. */ /** * \brief Open Parallel Port * \param port * \return file descriptor * * TODO: to be called before exiting: atexit(parport_cleanup) * void parport_cleanup() { ioctl(fd, PPRELEASE); } */ int par_open(hamlib_port_t *port) { int fd; #ifdef HAVE_LINUX_PPDEV_H int mode; #endif #if defined (__WIN64__) || defined(__WIN32__) // cppcheck-suppress * HANDLE handle; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port->pathname[0]) { return -RIG_EINVAL; } #ifdef HAVE_LINUX_PPDEV_H /* TODO: open with O_NONBLOCK ? */ fd = open(port->pathname, O_RDWR); if (fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: opening device \"%s\": %s\n", __func__, port->pathname, strerror(errno)); return -RIG_EIO; } mode = IEEE1284_MODE_COMPAT; if (ioctl(fd, PPSETMODE, &mode) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: PPSETMODE \"%s\": %s\n", __func__, port->pathname, strerror(errno)); close(fd); return -RIG_EIO; } #elif defined(HAVE_DEV_PPBUS_PPI_H) fd = open(port->pathname, O_RDWR); if (fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: opening device \"%s\": %s\n", __func__, port->pathname, strerror(errno)); return -RIG_EIO; } #elif defined(__WIN64__) || defined(__WIN32__) handle = CreateFile(port->pathname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (handle == INVALID_HANDLE_VALUE) { rig_debug(RIG_DEBUG_ERR, "%s: opening device \"%s\"\n", __func__, port->pathname); CloseHandle(handle); return -RIG_EIO; } else { fd = _open_osfhandle((intptr_t)handle, _O_APPEND | _O_RDONLY); if (fd == -1) { return -RIG_EIO; } } #else port->fd = fd = 0; return -RIG_ENIMPL; #endif port->fd = fd; return fd; } /** * \brief Close Parallel Port * \param port */ int par_close(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #ifdef HAVE_LINUX_PPDEV_H #elif defined(HAVE_DEV_PPBUS_PPI_H) #elif defined(__WIN64__) || defined(__WIN32__) _close(port->fd); return RIG_OK; #endif return close(port->fd); } /** * \brief Send data on Parallel port * \param port * \param data */ int HAMLIB_API par_write_data(hamlib_port_t *port, unsigned char data) { #ifdef HAVE_LINUX_PPDEV_H int status; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPWDATA, &data); return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(HAVE_DEV_PPBUS_PPI_H) int status; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPISDATA, &data); return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(__WIN64__) || defined(__WIN32__) unsigned int dummy = 0; intptr_t handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); handle = _get_osfhandle(port->fd); if (handle != (intptr_t)INVALID_HANDLE_VALUE) { if (!(DeviceIoControl((HANDLE)handle, NT_IOCTL_DATA, &data, sizeof(data), NULL, 0, (LPDWORD)&dummy, NULL))) { rig_debug(RIG_DEBUG_ERR, "%s: DeviceIoControl failed!\n", __func__); return -RIG_EIO; } } return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Receive data on Parallel port * \param port * \param data */ int HAMLIB_API par_read_data(hamlib_port_t *port, unsigned char *data) { #ifdef HAVE_LINUX_PPDEV_H int status; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPRDATA, data); return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(HAVE_DEV_PPBUS_PPI_H) int status; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPIGDATA, &data); return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(__WIN64__) || defined(__WIN32__) unsigned char ret = 0; unsigned int dummy = 0; intptr_t handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); handle = _get_osfhandle(port->fd); if (handle != (intptr_t)INVALID_HANDLE_VALUE) { if (!(DeviceIoControl((HANDLE)handle, NT_IOCTL_STATUS, NULL, 0, &ret, sizeof(ret), (LPDWORD)&dummy, NULL))) { rig_debug(RIG_DEBUG_ERR, "%s: DeviceIoControl failed!\n", __func__); return -RIG_EIO; } } *data = ret ^ S1284_INVERTED; return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Set control data for Parallel Port * \param port * \param control */ int HAMLIB_API par_write_control(hamlib_port_t *port, unsigned char control) { #ifdef HAVE_LINUX_PPDEV_H int status; unsigned char ctrl = control ^ CP_ACTIVE_LOW_BITS; status = ioctl(port->fd, PPWCONTROL, &ctrl); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (status < 0) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(PPWCONTROL) failed: %s\n", __func__, strerror(errno)); } return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(HAVE_DEV_PPBUS_PPI_H) int status; unsigned char ctrl = control ^ CP_ACTIVE_LOW_BITS; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPISCTRL, &ctrl); return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(__WIN64__) || defined(__WIN32__) unsigned char ctr = control; unsigned char dummyc; unsigned int dummy = 0; const unsigned char wm = (C1284_NSTROBE | C1284_NAUTOFD | C1284_NINIT | C1284_NSELECTIN); intptr_t handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ctr & 0x20) { rig_debug(RIG_DEBUG_WARN, "%s: use ieee1284_data_dir to change data line direction!\n", __func__); } /* Deal with inversion issues. */ ctr ^= wm & C1284_INVERTED; ctr = (ctr & ~wm) ^ (ctr & wm); handle = _get_osfhandle(port->fd); if (handle != (intptr_t)INVALID_HANDLE_VALUE) { if (!(DeviceIoControl((HANDLE)handle, NT_IOCTL_CONTROL, &ctr, sizeof(ctr), &dummyc, sizeof(dummyc), (LPDWORD)&dummy, NULL))) { rig_debug(RIG_DEBUG_ERR, "%s: frob_control: DeviceIoControl failed!\n", __func__); return -RIG_EIO; } } return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Read control data for Parallel Port * \param port * \param control */ int HAMLIB_API par_read_control(hamlib_port_t *port, unsigned char *control) { #ifdef HAVE_LINUX_PPDEV_H int status; unsigned char ctrl; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPRCONTROL, &ctrl); if (status < 0) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(PPRCONTROL) failed: %s\n", __func__, strerror(errno)); } *control = ctrl ^ CP_ACTIVE_LOW_BITS; return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(HAVE_DEV_PPBUS_PPI_H) int status; unsigned char ctrl; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); status = ioctl(port->fd, PPIGCTRL, &ctrl); *control = ctrl ^ CP_ACTIVE_LOW_BITS; return status == 0 ? RIG_OK : -RIG_EIO; #elif defined(__WIN64__) || defined(__WIN32__) unsigned char ret = 0; unsigned int dummy = 0; intptr_t handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); handle = _get_osfhandle(port->fd); if (handle != (intptr_t)INVALID_HANDLE_VALUE) { if (!(DeviceIoControl((HANDLE)handle, NT_IOCTL_CONTROL, NULL, 0, &ret, sizeof(ret), (LPDWORD)&dummy, NULL))) { rig_debug(RIG_DEBUG_ERR, "%s: DeviceIoControl failed!\n", __func__); return -RIG_EIO; } } *control = ret ^ S1284_INVERTED; return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Get parallel port status * \param port * \param status * \return RIG_OK or < 0 for error */ int HAMLIB_API par_read_status(hamlib_port_t *port, unsigned char *status) { #ifdef HAVE_LINUX_PPDEV_H int ret; unsigned char sta; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = ioctl(port->fd, PPRSTATUS, &sta); *status = sta ^ SP_ACTIVE_LOW_BITS; return ret == 0 ? RIG_OK : -RIG_EIO; #elif defined(HAVE_DEV_PPBUS_PPI_H) int ret; unsigned char sta; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = ioctl(port->fd, PPIGSTATUS, &sta); *status = sta ^ SP_ACTIVE_LOW_BITS; return ret == 0 ? RIG_OK : -RIG_EIO; #elif defined(__WIN64__) || defined(__WIN32__) unsigned char ret = 0; unsigned int dummy = 0; intptr_t handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); handle = _get_osfhandle(port->fd); if (handle != (intptr_t)INVALID_HANDLE_VALUE) { if (!(DeviceIoControl((HANDLE)handle, NT_IOCTL_STATUS, NULL, 0, &ret, sizeof(ret), (LPDWORD)&dummy, NULL))) { rig_debug(RIG_DEBUG_ERR, "%s: DeviceIoControl failed!\n", __func__); return -RIG_EIO; } } *status = ret ^ S1284_INVERTED; return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Get a lock on the Parallel Port * \param port * \return RIG_OK or < 0 */ int HAMLIB_API par_lock(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #ifdef HAVE_LINUX_PPDEV_H if (ioctl(port->fd, PPCLAIM) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: claiming device \"%s\": %s\n", __func__, port->pathname, strerror(errno)); return -RIG_EIO; } return RIG_OK; #elif defined(HAVE_DEV_PPBUS_PPI_H) return RIG_OK; #elif defined(__WIN64__) || defined(__WIN32__) return RIG_OK; #else return -RIG_ENIMPL; #endif } /** * \brief Release lock on Parallel Port * \param port * \return RIG_OK or < 0 */ int HAMLIB_API par_unlock(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #ifdef HAVE_LINUX_PPDEV_H if (ioctl(port->fd, PPRELEASE) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: releasing device \"%s\": %s\n", __func__, port->pathname, strerror(errno)); return -RIG_EIO; } return RIG_OK; #elif defined(HAVE_DEV_PPBUS_PPI_H) return RIG_OK; #elif defined(__WIN64__) || defined(__WIN32__) return RIG_OK; #else return -RIG_ENIMPL; #endif } #ifndef PARPORT_CONTROL_STROBE # define PARPORT_CONTROL_STROBE 0x1 #endif #ifndef PARPORT_CONTROL_INIT # define PARPORT_CONTROL_INIT 0x4 #endif /** * \brief Set or unset Push to talk bit on Parallel Port * \param p * \param pttx RIG_PTT_ON --> Set PTT * \return RIG_OK or < 0 error */ int par_ptt_set(hamlib_port_t *p, ptt_t pttx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (p->type.ptt) { case RIG_PTT_PARALLEL: { unsigned char ctl; int status; par_lock(p); status = par_read_control(p, &ctl); if (status != RIG_OK) { return status; } /* Enable CW & PTT - /STROBE bit (pin 1) */ ctl &= ~PARPORT_CONTROL_STROBE; /* TODO: kill parm.parallel.pin? */ /* PTT keying - /INIT bit (pin 16) (inverted) */ if (pttx == RIG_PTT_ON) { ctl |= PARPORT_CONTROL_INIT; } else { ctl &= ~PARPORT_CONTROL_INIT; } status = par_write_control(p, ctl); par_unlock(p); return status; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, p->type.ptt); return -RIG_EINVAL; } return RIG_OK; } /** * \brief Get state of Push to Talk from Parallel Port * \param p * \param pttx return value (must be non NULL) * \return RIG_OK or < 0 error */ int par_ptt_get(hamlib_port_t *p, ptt_t *pttx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (p->type.ptt) { case RIG_PTT_PARALLEL: { unsigned char ctl; int status; par_lock(p); status = par_read_control(p, &ctl); par_unlock(p); if (status == RIG_OK) { *pttx = (ctl & PARPORT_CONTROL_INIT) && !(ctl & PARPORT_CONTROL_STROBE) ? RIG_PTT_ON : RIG_PTT_OFF; } return status; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, p->type.ptt); return -RIG_ENAVAIL; } return RIG_OK; } /** * \brief get Data Carrier Detect (squelch) from Parallel Port * \param p * \param dcdx return value (Must be non NULL) * \return RIG_OK or < 0 error */ int par_dcd_get(hamlib_port_t *p, dcd_t *dcdx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (p->type.dcd) { case RIG_DCD_PARALLEL: { unsigned char reg; int status; status = par_read_data(p, ®); if (status == RIG_OK) { *dcdx = (reg & (1 << p->parm.parallel.pin)) ? RIG_DCD_ON : RIG_DCD_OFF; } return status; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported DCD type %d\n", __func__, p->type.dcd); return -RIG_ENAVAIL; } return RIG_OK; } /** @} */ hamlib-4.6.5/src/version_dll.rc0000775000175000017500000000113015056640474012113 #include #include #include //#define HAMLIB_RC_FILEVERSION 4,6,0,0 VS_VERSION_INFO VERSIONINFO FILEVERSION ABI_VERSION,ABI_REVISION,ABI_AGE,0 FILETYPE VFT_DLL FILESUBTYPE VFT2_UNKNOWN { BLOCK "StringFileInfo" { BLOCK "040904E4" { VALUE "FileDescription", "Hamlib DLL" VALUE "ProductName", PACKAGE_STRING VALUE "ProductVersion", HAMLIBDATETIME VALUE "LegalCopyright", "Copyright Hamlib Team 1991-2023" VALUE "OriginalFilename", "libhamlib-4.dll" } } BLOCK "VarFileInfo" { VALUE "Translation", 0x409, 20127 } } hamlib-4.6.5/src/usb_port.h0000664000175000017500000000214415056640443011252 /* * Hamlib Interface - USB communication header * Copyright (c) 2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _USB_PORT_H #define _USB_PORT_H 1 #include #include "iofunc.h" __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int usb_port_open(hamlib_port_t *p); int usb_port_close(hamlib_port_t *p); __END_DECLS #endif /* _USB_PORT_H */ hamlib-4.6.5/src/cm108.h0000664000175000017500000000407115056640443010246 /* * Hamlib Interface - CM108 GPIO communication header * Copyright (c) 2000-2003 by Frank Singleton * Copyright (c) 2000-2010 by Stephane Fillod * Copyright (c) 2011 by Andrew Errington * * 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. * */ #ifndef _CM108_H #define _CM108_H 1 #include #include "iofunc.h" __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int cm108_open(hamlib_port_t *p); int cm108_close(hamlib_port_t *p); int cm108_ptt_set(hamlib_port_t *p, ptt_t pttx); int cm108_ptt_get(hamlib_port_t *p, ptt_t *pttx); int cm108_dcd_get(hamlib_port_t *p, dcd_t *dcdx); extern HAMLIB_EXPORT(int) cm108_write_data(hamlib_port_t *p, unsigned char data); extern HAMLIB_EXPORT(int) cm108_write_control(hamlib_port_t *p, unsigned char control); extern HAMLIB_EXPORT(int) cm108_read_data(hamlib_port_t *p, unsigned char *data); extern HAMLIB_EXPORT(int) cm108_read_control(hamlib_port_t *p, unsigned char *control); extern HAMLIB_EXPORT(int) cm108_read_status(hamlib_port_t *p, unsigned char *status); extern HAMLIB_EXPORT(int) cm108_lock(hamlib_port_t *p); extern HAMLIB_EXPORT(int) cm108_unlock(hamlib_port_t *p); __END_DECLS #endif /* _CM108_H */ hamlib-4.6.5/src/rot_ext.c0000664000175000017500000002327615056640443011105 /* * Hamlib Interface - rotator ext parameter interface * Copyright (c) 2020 by Mikael Nousiainen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rotator * @{ */ /** * \file rot_ext.c * \brief Rotator extension parameters and levels interface. * * \author Mikael Nousiainen * \date 2020 * * An open-ended set of extension parameters, functions and levels are * available for each rotator, as provided in the rot_caps::extparms, * rot_caps::extfuncs and rot_caps::extlevels lists. These provide a way to * work with rotator-specific functions that don't fit into the basic "virtual * rotator" of Hamlib. */ #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include #include "token.h" static int rot_has_ext_token(ROT *rot, hamlib_token_t token) { const int *ext_tokens = rot->caps->ext_tokens; int i; if (ext_tokens == NULL) { // Assume that all listed extfuncs/extlevels/extparms are supported if // the ext_tokens list is not defined to preserve backwards-compatibility return 1; } for (i = 0; ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (ext_tokens[i] == token) { return 1; } } return 0; } /** * \brief Executes \a cfunc on all the elements stored in the * rot_caps::extfuncs table. * * \param rot The #ROT handle. * \param cfunc Callback function of each rot_caps::extfunc. * \param data Cookie to be passed to the callback function \a cfunc. * * The callback \a cfunc is called until it returns a value which is not * strictly positive. * * \returns A zero value means a normal end of iteration, or a **negative * value** which means an abnormal end. * * \retval RIG_OK All extension functions elements successfully processed. * \retval RIG_EINVAL \a rot or \a cfunc is NULL or inconsistent. */ int HAMLIB_API rot_ext_func_foreach(ROT *rot, int (*cfunc)(ROT *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rot->caps->extfuncs; cfp && cfp->name; cfp++) { if (!rot_has_ext_token(rot, cfp->token)) { continue; } int ret = (*cfunc)(rot, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \brief Executes \a cfunc on all the elements stored in the * rot_caps::extlevels extension levels table. * * \param rot The #ROT handle. * \param cfunc Callback function of each rot_caps::extlevels. * \param data Cookie to be passed to the callback function \a cfunc. * * The callback \a cfunc is called until it returns a value which is not * strictly positive. * * \returns A zero value which means a normal end of iteration, or a * **negative value** which means an abnormal end. * * \retval RIG_OK All extension levels elements successfully processed. * \retval RIG_EINVAL \a rot or \a cfunc is NULL or inconsistent. */ int HAMLIB_API rot_ext_level_foreach(ROT *rot, int (*cfunc)(ROT *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rot->caps->extlevels; cfp && cfp->name; cfp++) { if (!rot_has_ext_token(rot, cfp->token)) { continue; } int ret = (*cfunc)(rot, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \brief Executes \a cfunc on all the elements stored in the * rot_caps::extparms extension parameters table. * * \param rot The #ROT handle. * \param cfunc callback function of each rot_caps::extparms. * \param data Cookie to be passed to the callback function \a cfunc. * * The callback function \a cfunc is called until it returns a value which is not * strictly positive. * * \returns A zero value which means a normal end of iteration, or a * **negative value** which means an abnormal end. * * \retval RIG_OK All extension parameters elements successfully processed. * \retval RIG_EINVAL \a rot or \a cfunc is NULL or inconsistent. */ int HAMLIB_API rot_ext_parm_foreach(ROT *rot, int (*cfunc)(ROT *, const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = rot->caps->extparms; cfp && cfp->name; cfp++) { if (!rot_has_ext_token(rot, cfp->token)) { continue; } int ret = (*cfunc)(rot, cfp, data); if (ret == 0) { return RIG_OK; } if (ret < 0) { return ret; } } return RIG_OK; } /** * \brief Lookup an extension functions, levels, or parameters token by its * name and return a pointer to the containing #confparams structure member. * * \param rot The #ROT handle. * \param name The extension functions, levels, or parameters token name. * * Searches the rot_caps::extlevels, rot_caps::extfuncs and the * rot_caps::extparms tables in order for the token by its name. * * \note As this function is called by rot_ext_token_lookup(), it can be * considered a lower level API. * * \return A pointer to the containing #confparams structure member or NULL if * nothing found or if \a rot is NULL or inconsistent. * * \sa rot_ext_token_lookup() * * \todo Should use Lex to speed it up, strcmp() hurts! */ const struct confparams *HAMLIB_API rot_ext_lookup(ROT *rot, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return NULL; } for (cfp = rot->caps->extlevels; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } for (cfp = rot->caps->extfuncs; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } for (cfp = rot->caps->extparms; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name)) { return cfp; } } return NULL; } /** * \brief Searches for an extension levels, functions, or parameters token by * its constant value and return a pointer to the #confparams structure * member. * * \param rot The #ROT handle. * \param token The token value (constant). * * Searches the rot_caps::extlevels, rot_caps::extfuncs, and the * rot_caps::extparms tables in order for the token by its constant value. * * \return A pointer to the containing #confparams structure member or NULL if * nothing found or if \a rot is NULL or inconsistent. */ const struct confparams *HAMLIB_API rot_ext_lookup_tok(ROT *rot, hamlib_token_t token) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return NULL; } for (cfp = rot->caps->extlevels; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } for (cfp = rot->caps->extfuncs; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } for (cfp = rot->caps->extparms; cfp && cfp->token; cfp++) { if (cfp->token == token) { return cfp; } } return NULL; } /** * \brief Simple search returning the extension token ID associated with * \a name. * * \param rot The #ROT handle. * \param name The token name string to search. * * \note As this function calls rot_ext_lookup(), it can be considered a * higher level API. * * \return The token ID or #RIG_CONF_END if there is a lookup failure. * * \sa rot_ext_lookup() */ hamlib_token_t HAMLIB_API rot_ext_token_lookup(ROT *rot, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); cfp = rot_ext_lookup(rot, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** @} */ hamlib-4.6.5/src/sprintflst.c0000664000175000017500000006211215056640443011621 /* * Hamlib Interface - sprintf toolbox * Copyright (c) 2000-2009 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include #include #include "../rigs/icom/icom.h" #include "sprintflst.h" #include "misc.h" /* #define DUMMY_ALL 0x7ffffffffffffffLL */ #define DUMMY_ALL ((setting_t)-1) // just doing a warning message for now // eventually should make this -RIG_EINTERNAL int check_buffer_overflow(char *str, int len, int nlen) { if (len + 32 >= nlen) // make sure at least 32 bytes are available { rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow, len=%d, nlen=%d, str='%s', len+32 must be >= nlen\n", __func__, len, nlen, str); } return RIG_OK; } int rig_sprintf_vfo(char *str, int nlen, vfo_t vfo) { unsigned int i; int len = 0; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *str = '\0'; if (vfo == RIG_VFO_NONE) { return 0; } for (i = 0; i < HAMLIB_MAX_VFOS; i++) { const char *sv = rig_strvfo(vfo & RIG_VFO_N(i)); if (sv && sv[0] && (strstr(sv, "None") == 0)) { int written = snprintf(str + len, nlen - len, "%s ", sv); if (written < 0 || written >= nlen - len) { // Truncate and break if there's no space left rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; } if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rig_sprintf_mode(char *str, int nlen, rmode_t mode) { unsigned int i, len = 0; *str = '\0'; if (mode == RIG_MODE_NONE) { return 0; } for (i = 0; i < HAMLIB_MAX_MODES; i++) { const char *ms = rig_strrmode(mode & (1ULL << i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } if (i > 0) { strcat(str, " "); } strcat(str, ms); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_ant(char *str, int str_len, ant_t ant) { int i, len = 0; const char *ant_name; *str = '\0'; if (ant == RIG_ANT_NONE) { snprintf(str, str_len, "ANT_NONE"); return (int)strlen(str); // Return length of "ANT_NONE" } for (i = 0; i < RIG_ANT_MAX; i++) { if (ant & (1UL << i)) { switch (i) { case 0: ant_name = "ANT1"; break; case 1: ant_name = "ANT2"; break; case 2: ant_name = "ANT3"; break; case 3: ant_name = "ANT4"; break; case 4: ant_name = "ANT5"; break; case 30: ant_name = "ANT_UNKNOWN"; break; case 31: ant_name = "ANT_CURR"; break; default: ant_name = "ANT_UNK"; rig_debug(RIG_DEBUG_ERR, "%s: unknown ant=%d\n", __func__, i); break; } int written = snprintf(str + len, str_len - len, "%s ", ant_name); if (written < 0 || written >= str_len - len) { // Truncate if buffer is full rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = str_len - 1; str[len] = '\0'; break; } len += written; } if (len >= str_len) { // Ensure null-termination rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[str_len - 1] = '\0'; break; } } return len; } int rig_sprintf_func(char *str, int nlen, setting_t func) { unsigned int i, len = 0; *str = '\0'; if (func == RIG_FUNC_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rig_strfunc(func & rig_idx2setting(i)); if (!ms || !ms[0]) { rig_debug(RIG_DEBUG_ERR, "%s: unknown RIG_FUNC=%x\n", __func__, i); continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rot_sprintf_func(char *str, int nlen, setting_t func) { unsigned int i, len = 0; *str = '\0'; if (func == ROT_FUNC_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rot_strfunc(func & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_level(char *str, int nlen, setting_t level) { int i, len = 0; *str = '\0'; if (level == RIG_LEVEL_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rig_strlevel(level & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rot_sprintf_level(char *str, int nlen, setting_t level) { int i, len = 0; *str = '\0'; if (level == ROT_LEVEL_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rot_strlevel(level & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int amp_sprintf_level(char *str, int nlen, setting_t level) { int i, len = 0; *str = '\0'; if (level == AMP_LEVEL_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = amp_strlevel(level & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int sprintf_level_ext(char *str, int nlen, const struct confparams *extlevels) { int len = 0; *str = '\0'; if (!extlevels) { return 0; } for (; extlevels->token != RIG_CONF_END; extlevels++) { if (!extlevels->name) { continue; /* no name */ } switch (extlevels->type) { case RIG_CONF_INT: case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: case RIG_CONF_NUMERIC: case RIG_CONF_STRING: case RIG_CONF_BINARY: strcat(str, extlevels->name); strcat(str, " "); len += strlen(extlevels->name) + 1; break; case RIG_CONF_BUTTON: /* ignore case RIG_CONF_BUTTON */ break; } check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_level_gran(char *str, int nlen, setting_t level, const gran_t *gran) { int i, len = 0; *str = '\0'; if (level == RIG_LEVEL_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms; if (!(level & rig_idx2setting(i))) { continue; } ms = rig_strlevel(level & rig_idx2setting(i)); if (!ms || !ms[0]) { if (level != DUMMY_ALL && level != RIG_LEVEL_SET(DUMMY_ALL)) { rig_debug(RIG_DEBUG_BUG, "unknown level idx %d\n", i); } continue; } int written; if (RIG_LEVEL_IS_FLOAT(rig_idx2setting(i))) { written = snprintf(str + len, nlen - len, "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, gran[i].step.f); } else { written = snprintf(str + len, nlen - len, "%s(%d..%d/%d) ", ms, gran[i].min.i, gran[i].max.i, gran[i].step.i); } if (written < 0 || written >= nlen - len) { // Truncate and stop further processing if the buffer is full rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rot_sprintf_level_gran(char *str, int nlen, setting_t level, const gran_t *gran) { int i, len = 0; *str = '\0'; if (level == ROT_LEVEL_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms; if (!(level & rig_idx2setting(i))) { continue; } ms = rot_strlevel(level & rig_idx2setting(i)); if (!ms || !ms[0]) { if (level != DUMMY_ALL && level != ROT_LEVEL_SET(DUMMY_ALL)) { rig_debug(RIG_DEBUG_BUG, "unknown level idx %d\n", i); } continue; } int written; if (ROT_LEVEL_IS_FLOAT(rig_idx2setting(i))) { written = snprintf(str + len, nlen - len, "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, gran[i].step.f); } else { written = snprintf(str + len, nlen - len, "%s(%d..%d/%d) ", ms, gran[i].min.i, gran[i].max.i, gran[i].step.i); } if (written < 0 || written >= nlen - len) { // Truncate and stop further processing if the buffer is full len = nlen - 1; rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[len] = '\0'; break; } len += written; if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rig_sprintf_parm(char *str, int nlen, setting_t parm) { int i, len = 0; *str = '\0'; if (parm == RIG_PARM_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rig_strparm(parm & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rot_sprintf_parm(char *str, int nlen, setting_t parm) { int i, len = 0; *str = '\0'; if (parm == ROT_PARM_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rot_strparm(parm & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } int written = snprintf(str + len, nlen - len, "%s ", ms); if (written < 0 || written >= nlen - len) { // Truncate and stop further processing if the buffer is full rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rig_sprintf_parm_gran(char *str, int nlen, setting_t parm, const gran_t *gran) { int i, len = 0; *str = '\0'; if (parm == RIG_PARM_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms; if (!(parm & rig_idx2setting(i))) { continue; } ms = rig_strparm(parm & rig_idx2setting(i)); if (!ms || !ms[0]) { if (parm != DUMMY_ALL && parm != RIG_PARM_SET(DUMMY_ALL)) { rig_debug(RIG_DEBUG_BUG, "unknown parm idx %d\n", i); } continue; } int written; if (RIG_PARM_IS_FLOAT(rig_idx2setting(i))) { written = snprintf(str + len, nlen - len, "%s(%.g..%.g/%.g) ", ms, gran[i].min.f, gran[i].max.f, gran[i].step.f); } else if (RIG_PARM_IS_STRING(rig_idx2setting(i))) { if (gran[i].step.s) { written = snprintf(str + len, nlen - len, "%s(%s) ", ms, gran[i].step.s); } else { continue; } } else { written = snprintf(str + len, nlen - len, "%s(%d..%d/%d) ", ms, gran[i].min.i, gran[i].max.i, gran[i].step.i); } if (written < 0 || written >= nlen - len) { // Truncate and stop further processing if the buffer is full rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rot_sprintf_parm_gran(char *str, int nlen, setting_t parm, const gran_t *gran) { int i, len = 0; *str = '\0'; if (parm == ROT_PARM_NONE) { return 0; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms; if (!(parm & rig_idx2setting(i))) { continue; } ms = rot_strparm(parm & rig_idx2setting(i)); if (!ms || !ms[0]) { if (parm != DUMMY_ALL && parm != ROT_PARM_SET(DUMMY_ALL)) { rig_debug(RIG_DEBUG_BUG, "unknown parm idx %d\n", i); } continue; } int written; if (ROT_PARM_IS_FLOAT(rig_idx2setting(i))) { written = snprintf(str + len, nlen - len, "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, gran[i].step.f); } else { written = snprintf(str + len, nlen - len, "%s(%d..%d/%d) ", ms, gran[i].min.i, gran[i].max.i, gran[i].step.i); } if (written < 0 || written >= nlen - len) { // Truncate and stop further processing if the buffer is full rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rig_sprintf_vfop(char *str, int nlen, vfo_op_t op) { int i, len = 0; *str = '\0'; if (op == RIG_OP_NONE) { return 0; } for (i = 0; i < HAMLIB_MAX_VFO_OPS; i++) { const char *ms = rig_strvfop(op & (1UL << i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_scan(char *str, int nlen, scan_t rscan) { int i, len = 0; *str = '\0'; if (rscan == RIG_SCAN_NONE) { return 0; } for (i = 0; i < HAMLIB_MAX_RSCANS; i++) { const char *ms = rig_strscan(rscan & (1UL << i)); if (!ms || !ms[0]) { continue; /* unknown, FIXME! */ } strcat(str, ms); strcat(str, " "); len += strlen(ms) + 1; check_buffer_overflow(str, len, nlen); } return len; } int rot_sprintf_status(char *str, int nlen, rot_status_t status) { int len = 0; unsigned long i; rig_debug(RIG_DEBUG_TRACE, "%s: status=%08x\n", __func__, status); *str = '\0'; if (status == ROT_STATUS_NONE) { return 0; } for (i = 0; i <= HAMLIB_MAX_ROTOR_STATUS; i++) { const char *sv = rot_strstatus(status & ROT_STATUS_N(i)); if (sv && sv[0] && (strstr(sv, "None") == 0)) { int written = snprintf(str + len, nlen - len, "%s ", sv); if (written < 0 || written >= nlen - len) { // Truncate and break if there's no space left rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); len = nlen - 1; str[len] = '\0'; break; } len += written; } if (len >= nlen) { // Ensure null-termination and avoid overflow rig_debug(RIG_DEBUG_ERR, "%s: buffer overflow\n", __func__); str[nlen - 1] = '\0'; break; } } return len; } int rig_sprintf_spectrum_modes(char *str, int nlen, const enum rig_spectrum_mode_e *modes) { int i, len = 0; *str = '\0'; for (i = 0; i < HAMLIB_MAX_SPECTRUM_MODES; i++) { const char *sm; int lentmp; if (modes[i] == RIG_SPECTRUM_MODE_NONE) { break; } sm = rig_strspectrummode(modes[i]); if (!sm || !sm[0]) { break; } lentmp = snprintf(str + len, nlen - len, "%d=%s ", modes[i], sm); if (len < 0 || lentmp >= nlen - len) { rig_debug(RIG_DEBUG_ERR, "%s(%d): overflowed str buffer\n", __FILE__, __LINE__); break; } len += lentmp; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_spectrum_spans(char *str, int nlen, const freq_t *spans) { int i, len = 0; *str = '\0'; for (i = 0; i < HAMLIB_MAX_SPECTRUM_SPANS; i++) { int lentmp; if (spans[i] == 0) { break; } lentmp = snprintf(str + len, nlen - len, "%.0f ", spans[i]); if (len < 0 || lentmp >= nlen - len) { rig_debug(RIG_DEBUG_ERR, "%s(%d): overflowed str buffer\n", __FILE__, __LINE__); break; } len += lentmp; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_spectrum_avg_modes(char *str, int nlen, const struct rig_spectrum_avg_mode *avg_modes) { int i, len = 0; *str = '\0'; for (i = 0; i < HAMLIB_MAX_SPECTRUM_MODES; i++) { int lentmp; if (avg_modes[i].name == NULL || avg_modes[i].id < 0) { break; } lentmp = snprintf(str + len, nlen - len, "%d=\"%s\" ", avg_modes[i].id, avg_modes[i].name); if (len < 0 || lentmp >= nlen - len) { rig_debug(RIG_DEBUG_ERR, "%s(%d): overflowed str buffer\n", __FILE__, __LINE__); break; } len += lentmp; check_buffer_overflow(str, len, nlen); } return len; } int rig_sprintf_tuning_steps(char *str, int nlen, const struct tuning_step_list *tuning_step_list) { int i, len = 0; *str = '\0'; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { int lentmp; if (tuning_step_list[i].modes == RIG_MODE_NONE) { break; } lentmp = snprintf(str + len, nlen - len, "%s%d", i > 0 ? ", " : "", (int)tuning_step_list[i].ts); if (len < 0 || lentmp >= nlen - len) { rig_debug(RIG_DEBUG_ERR, "%s(%d): overflowed str buffer\n", __FILE__, __LINE__); break; } len += lentmp; check_buffer_overflow(str, len, nlen); } return len; } char *get_rig_conf_type(enum rig_conf_e type) { switch (type) { case RIG_CONF_STRING: return "STRING"; case RIG_CONF_COMBO: return "COMBO"; case RIG_CONF_NUMERIC: return "NUMERIC"; case RIG_CONF_CHECKBUTTON: return "CHECKBUTTON"; case RIG_CONF_BUTTON: return "BUTTON"; case RIG_CONF_BINARY: return "BINARY"; case RIG_CONF_INT: return "INT"; } return "UNKNOWN"; } int print_ext_param(const struct confparams *cfp, rig_ptr_t ptr) { int i; fprintf((FILE *)ptr, "\t%s\n", cfp->name); fprintf((FILE *)ptr, "\t\tType: %s\n", get_rig_conf_type(cfp->type)); fprintf((FILE *)ptr, "\t\tDefault: %s\n", cfp->dflt != NULL ? cfp->dflt : ""); fprintf((FILE *)ptr, "\t\tLabel: %s\n", cfp->label != NULL ? cfp->label : ""); fprintf((FILE *)ptr, "\t\tTooltip: %s\n", cfp->tooltip != NULL ? cfp->tooltip : ""); switch (cfp->type) { case RIG_CONF_NUMERIC: fprintf((FILE *)ptr, "\t\tRange: %f..%f/%f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; case RIG_CONF_INT: fprintf((FILE *)ptr, "\t\tRange: %d..%d/%d\n", (int) cfp->u.n.min, (int) cfp->u.n.max, (int) cfp->u.n.step); break; case RIG_CONF_COMBO: fprintf((FILE *)ptr, "\t\tValues:"); for (i = 0; i < RIG_COMBO_MAX && cfp->u.c.combostr[i] != NULL; i++) { fprintf((FILE *)ptr, " %d=\"%s\"", i, cfp->u.c.combostr[i]); } fprintf((FILE *)ptr, "\n"); break; default: break; } return 1; /* process them all */ } int rig_sprintf_agc_levels(RIG *rig, char *str, int lenstr) { const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; int len = 0; int i; char tmpbuf[256]; str[len] = 0; if (priv_caps && RIG_BACKEND_NUM(rig->caps->rig_model) == RIG_ICOM && priv_caps->agc_levels_present) { for (i = 0; i <= HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST ; i++) { if (strlen(str) > 0) { strcat(str, " "); } snprintf(tmpbuf, sizeof(tmpbuf), "%d=%s", priv_caps->agc_levels[i].icom_level, rig_stragclevel(priv_caps->agc_levels[i].level)); if (strlen(str) + strlen(tmpbuf) < lenstr - 1) { strncat(str, tmpbuf, lenstr - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: buffer overrun!! len=%d > maxlen=%d\n", __func__, (int)(strlen(str) + strlen(tmpbuf)), lenstr - 1); } } } else { for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && i < rig->caps->agc_level_count; i++) { if (strlen(str) > 0) { strcat(str, " "); } snprintf(tmpbuf, sizeof(tmpbuf), "%d=%s", rig->caps->agc_levels[i], rig_stragclevel(rig->caps->agc_levels[i])); if (strlen(str) + strlen(tmpbuf) < lenstr - 1) { strncat(str, tmpbuf, lenstr - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: buffer overrun!! len=%d > maxlen=%d\n", __func__, (int)(strlen(str) + strlen(tmpbuf)), lenstr - 1); } } } return strlen(str); } hamlib-4.6.5/src/rot_settings.c0000664000175000017500000005152315056640443012141 /* * Hamlib Interface - rotator func/level/parm * Copyright (c) 2020 by Mikael Nousiainen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rotator * @{ */ /** * \file rot_settings.c * \brief Rotator functions/levels/parameters interface. * * \author Mikael Nousiainen * \date 2020 * * This Hamlib interface is a frontend implementing wrapper functions. */ #include #include #include #include #include #include #ifndef DOC_HIDDEN # define CHECK_ROT_ARG(r) (!(r) || !(r)->caps || !(ROTSTATE(r)->comm_state)) #endif /* !DOC_HIDDEN */ /** * \brief Set a rotator level to a given value. * * \param rot The #ROT handle. * \param level The level to set. * \param val The value of the level. * * Set \a level to \a val. * * \note \a val can be any type defined by #value_t. * \note As this function calls rot_has_set_level(), this may be considered a * higher level API. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK Setting the level was successful. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#set_level() capability is not available. * * \sa rot_has_set_level(), rot_get_level() */ int HAMLIB_API rot_set_level(ROT *rot, setting_t level, value_t val) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->set_level == NULL || !rot_has_set_level(rot, level)) { return -RIG_ENAVAIL; } return caps->set_level(rot, level, val); } /** * \brief Query the value of a requested rotator level. * * \param rot The #ROT handle. * \param level The requested level. * \param val The variable to store the \a level value. * * Query the \a val corresponding to the \a level. * * \note \a val can be any type defined by #value_t. * \note As this function calls rot_has_get_level(), this may be considered a * higher level API. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The query was successful. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_level() capability is not available. * * \sa rot_has_get_level(), rot_set_level() */ int HAMLIB_API rot_get_level(ROT *rot, setting_t level, value_t *val) { const struct rot_caps *caps; // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !val) { return -RIG_EINVAL; } caps = rot->caps; if (caps->get_level == NULL || !rot_has_get_level(rot, level)) { return -RIG_ENAVAIL; } return caps->get_level(rot, level, val); } /** * \brief Set a rotator parameter to a given value. * * \param rot The #ROT handle. * \param parm The parameter to set. * \param val The value of the parameter. * * Sets \a parm to \a val. * * \note \a val can be any type defined by #value_t. * \note As this function calls rot_has_set_parm(), this may be considered a * higher level API. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The parameter was set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#set_parm() capability is not available. * * \sa rot_has_set_parm(), rot_get_parm() */ int HAMLIB_API rot_set_parm(ROT *rot, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } if (rot->caps->set_parm == NULL || !rot_has_set_parm(rot, parm)) { return -RIG_ENAVAIL; } return rot->caps->set_parm(rot, parm, val); } /** * \brief Query the value of a requested rotator parameter. * * \param rot The #ROT handle. * \param parm The requested parameter. * \param val The variable to store the \a parm value. * * Query the \a val corresponding to the \a parm. * * \note \a val can be any type defined by #value_t. * \note As this function calls rot_has_get_parm(), this may be considered a * higher level API. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The parameter was queried successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_parm() capability is not available. * * \sa rot_has_get_parm(), rot_set_parm() */ int HAMLIB_API rot_get_parm(ROT *rot, setting_t parm, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !val) { return -RIG_EINVAL; } if (rot->caps->get_parm == NULL || !rot_has_get_parm(rot, parm)) { return -RIG_ENAVAIL; } return rot->caps->get_parm(rot, parm, val); } /** * \brief Check which rotator level settings can be queried. * * \param rot The #ROT handle. * \param level The level settings bitmap. * * Checks if a rotator is capable of *getting* a level setting. Since * \a level is an OR'ed bitwise argument, more than one level can be checked * at the same time. * * EXAMPLE: * \code * if (rot_has_get_level(my_rot, ROT_LEVEL_SPEED)) * my_get_speed(&my_speed); * \endcode * * \note As this function is called by rot_get_level(), this may be considered * a lower level API. * * \return A bit map of supported level settings that can be retrieved, * otherwise 0 if none supported or \a rot is NULL or inconsistent. * * \sa rot_get_level(), rot_has_set_level() */ setting_t HAMLIB_API rot_has_get_level(ROT *rot, setting_t level) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_get_level & level); } /** * \brief Query the rotator levels that may be set. * * \param rot The #ROT handle. * \param level The level settings bitmap. * * Checks if a rotator can *set* a level setting. Since \a level is an OR'ed * bitwise argument, more than one level can be checked at the same time. * * EXAMPLE: * \code * if (rot_has_set_level(my_rot, ROT_LEVEL_SPEED)) * my_set_speed(MEDIUM); * \endcode * * \note As this function is called by rot_set_level(), this may be considered * a lower level API. * * \return A bit map of supported level settings that can be set, otherwise 0 * if none supported or \a rot is NULL or inconsistent. * * \sa rot_set_level(), rot_has_get_level() */ setting_t HAMLIB_API rot_has_set_level(ROT *rot, setting_t level) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_set_level & level); } /** * \brief Check which rotator parameter settings can be queried. * * \param rot The #ROT handle. * \param parm The parameter settings bitmap. * * Checks if a rotator is capable of *getting* a parameter setting. Since * \a parm is an OR'ed bitwise argument, more than one parameter can be * checked at the same time. * * EXAMPLE: * \code * if (rot_has_get_parm(my_rot, ROT_PARM_NONE)) * my_get_parms(&parms); * \endcode * * \note As this function is called by rot_get_parm(), this may be considered * a lower level API. * * \return A bit map of supported parameter settings that can be retrieved, * otherwise 0 if none supported or \a rot is NULL or inconsistent. * * \sa rot_get_parm(), rot_has_set_parm() */ setting_t HAMLIB_API rot_has_get_parm(ROT *rot, setting_t parm) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_get_parm & parm); } /** * \brief Query the rotator parameters that may be set. * * \param rot The #ROT handle. * \param parm The parameter settings bitmap. * * Checks if a rotator can *set* a parameter setting. Since \a parm is an * OR'ed bitwise argument, more than one parameter can be checked at the same * time. * * EXAMPLE: * \code * if (rot_has_set_parm(my_rig, ROT_PARM_NONE)) * my_set_parm(parameter); * \endcode * * \note As this function is called by rot_set_parm(), this may be considered * a lower level API. * * \return A bit map of supported parameter settings that can be set, * otherwise 0 if none supported or \a rot is NULL or inconsistent. * * \sa rot_set_parm(), rot_has_get_parm() */ setting_t HAMLIB_API rot_has_set_parm(ROT *rot, setting_t parm) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_set_parm & parm); } /** * \brief Check which rotator functions can be queried. * * \param rot The #ROT handle. * \param func The functions bitmap. * * Checks if a rotator supports a set of functions. Since \a func is an OR'ed * bitwise argument, more than one function can be checked at the same time. * * EXAMPLE: * \code * if (rot_has_get_func(my_rig, RIG_FUNC_NONE)) * do_something(); * \endcode * * \note As this function is called by rot_get_func(), this may be considered * a lower level API. * * \return A bit map of supported functions that can be retrieved, otherwise 0 * if none supported or \a rot is NULL or inconsistent. * * \sa rot_get_func(), rot_has_set_func() */ setting_t HAMLIB_API rot_has_get_func(ROT *rot, setting_t func) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_get_func & func); } /** * \brief Query support of rotator functions. * * \param rot The #ROT handle. * \param func The functions bitmap. * * Checks if a rotator supports a set of functions. Since \a func is an OR'ed * bitwise argument, more than one function can be checked at the same time. * * EXAMPLE: * \code * if (rot_has_set_func(my_rig, RIG_FUNC_NONE)) * do_this_func(my_func); * \endcode * * \note As this function is called by rot_set_func(), this may be considered * a lower level API. * * \return A bit map of supported functions that can be set, otherwise 0 if * none supported or \a rot is NULL or inconsistent. * * \sa rot_set_func(), rot_has_get_func() */ setting_t HAMLIB_API rot_has_set_func(ROT *rot, setting_t func) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rot || !rot->caps) { return 0; } return (ROTSTATE(rot)->has_set_func & func); } /** * \brief Activate or deactivate functions of a rotator. * * \param rot The #ROT handle. * \param func The function to activate or deactivate. * \param status The status (On or Off) to set. * * Activate or deactivate a function of the rotator. * * The \a status argument is a value that is not NULL for "activate", * "deactivate" otherwise, much as TRUE or FALSE boolean definitions in the C * language. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The function was activated or deactivated successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#set_func() capability is not available or * \a func is not supported. * * \sa rot_get_func() */ int HAMLIB_API rot_set_func(ROT *rot, setting_t func, int status) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->set_func == NULL || !rot_has_set_func(rot, func)) { return -RIG_ENAVAIL; } return caps->set_func(rot, func, status); } /** * \brief Query the status of functions of the rotator. * * \param rot The #ROT handle. * \param func The function to query the status. * \param status The variable to store the function status. * * Retrieves the status (On or Off) of a function of the rotator. Upon * return, \a status will hold the status of the function. The value pointed * to by the \a status argument is not NULL for "On", or "Off" otherwise, much * as TRUE or FALSE boolean definitions in the C language. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The function status was queried successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_func() capability is not available or * \a func is not supported. * * \sa rot_set_func() */ int HAMLIB_API rot_get_func(ROT *rot, setting_t func, int *status) { const struct rot_caps *caps; // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !func) { return -RIG_EINVAL; } caps = rot->caps; if (caps->get_func == NULL || !rot_has_get_func(rot, func)) { return -RIG_ENAVAIL; } return caps->get_func(rot, func, status); } /** * \brief Set a rotator extension level to a given value. * * \param rot The #ROT handle. * \param token The extension level token. * \param val The value of the extension level. * * Set extension level \a token to \a val. * * \note \a val can be any type defined by #value_t. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension level was set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#set_ext_level() capability is not available. * * \sa rot_get_ext_level() */ int HAMLIB_API rot_set_ext_level(ROT *rot, hamlib_token_t token, value_t val) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->set_ext_level == NULL) { return -RIG_ENAVAIL; } return caps->set_ext_level(rot, token, val); } /** * \brief Query the value of a requested rotator extension level. * * \param rot The #ROT handle. * \param token The extension level token. * \param val The location where to store the value of \a token. * * Query the \a val corresponding to the extension level \a token. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension level was queried successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_ext_level() capability is not available. * * \sa rot_set_ext_level() */ int HAMLIB_API rot_get_ext_level(ROT *rot, hamlib_token_t token, value_t *val) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !val) { return -RIG_EINVAL; } caps = rot->caps; if (caps->get_ext_level == NULL) { return -RIG_ENAVAIL; } return caps->get_ext_level(rot, token, val); } /** * \brief Activate or deactivate extension functions of a rotator. * * \param rot The #ROT handle. * \param token The extension function to activate or deactivate. * \param status The status (On or Off) to set. * * Activate or deactivate an extension function of the rotator. * * The \a status argument is a value that is not NULL for "activate", * "deactivate" otherwise, much as TRUE or FALSE boolean definitions in the C * language. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension function status was set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_ext_func() capability is not available. * * \sa rot_get_ext_func() */ int HAMLIB_API rot_set_ext_func(ROT *rot, hamlib_token_t token, int status) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } caps = rot->caps; if (caps->set_ext_func == NULL) { return -RIG_ENAVAIL; } return caps->set_ext_func(rot, token, status); } /** * \brief Query the status of extension functions of a rotator. * * \param rot The #ROT handle. * \param token The extension function to query the status. * \param status The variable to store the extension function status. * * Retrieves the status (On or Off) of an extension function of the rotator. * Upon return, \a status will hold the status of the extension function. The * value pointed to by the \a status argument is not NULL for "On", or "Off" * otherwise, much as TRUE or FALSE boolean definitions in the C language. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension function status was queried successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_ext_func() capability is not available or * \a token is not supported. * * \sa rot_set_ext_func() */ int HAMLIB_API rot_get_ext_func(ROT *rot, hamlib_token_t token, int *status) { const struct rot_caps *caps; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !status) { return -RIG_EINVAL; } caps = rot->caps; if (caps->get_ext_func == NULL) { return -RIG_ENAVAIL; } return caps->get_ext_func(rot, token, status); } /** * \brief Set a rotator extension parameter to a given value. * * \param rot The #ROT handle. * \param token The extension parameter token. * \param val The value of the extension parameter. * * Set an extension parameter \a token to \a val. * * \note \a val can be any type defined by #value_t. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension parameter was set successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#set_ext_parm() capability is not available. * * \sa rot_get_ext_parm() */ int HAMLIB_API rot_set_ext_parm(ROT *rot, hamlib_token_t token, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot)) { return -RIG_EINVAL; } if (rot->caps->set_ext_parm == NULL) { return -RIG_ENAVAIL; } return rot->caps->set_ext_parm(rot, token, val); } /** * \brief Query the value of a requested rotator extension parameter. * * \param rot The #ROT handle. * \param token The extension parameter to query the status. * \param val The variable to store the extension parameter status. * * Query the \a val corresponding to the extension parameter \a token. * * \note \a val can be any type defined by #value_t. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The extension parameter was queried successfully. * \retval RIG_EINVAL \a rot is NULL or inconsistent. * \retval RIG_ENAVAIL rot_caps#get_ext_parm() capability is not available. * * \sa rot_set_ext_parm() */ int HAMLIB_API rot_get_ext_parm(ROT *rot, hamlib_token_t token, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_ROT_ARG(rot) || !val) { return -RIG_EINVAL; } if (rot->caps->get_ext_parm == NULL) { return -RIG_ENAVAIL; } return rot->caps->get_ext_parm(rot, token, val); } /*! @} */ hamlib-4.6.5/src/par_nt.h0000664000175000017500000000262315056640443010702 /* NT Parport Access stuff - Matthew Duggan (2002) */ /* * ParallelVdm Device (0x2C) is mostly undocumented, used by VDM for parallel * port compatibility. */ /* * Different from CTL_CODE in DDK, limited to ParallelVdm but makes this * code cleaner. */ #ifndef _PAR_NT_H #define _PAR_NT_H #define NT_CTL_CODE( Function ) ( (0x2C<<16) | ((Function) << 2) ) /* IOCTL codes */ #define NT_IOCTL_DATA NT_CTL_CODE(1) /* Write Only */ #define NT_IOCTL_CONTROL NT_CTL_CODE(2) /* Read/Write */ #define NT_IOCTL_STATUS NT_CTL_CODE(3) /* Read Only */ /* * Raw port access (PC-style port registers but within inversions) * Functions returning int may fail. */ /* The status pin functions operate in terms of these bits: */ enum ieee1284_status_bits { S1284_NFAULT = 0x08, S1284_SELECT = 0x10, S1284_PERROR = 0x20, S1284_NACK = 0x40, S1284_BUSY = 0x80, /* To convert those values into PC-style register values, use this: */ S1284_INVERTED = S1284_BUSY }; /* The control pin functions operate in terms of these bits: */ enum ieee1284_control_bits { C1284_NSTROBE = 0x01, C1284_NAUTOFD = 0x02, C1284_NINIT = 0x04, C1284_NSELECTIN = 0x08, /* To convert those values into PC-style register values, use this: */ C1284_INVERTED = (C1284_NSTROBE | C1284_NAUTOFD | C1284_NSELECTIN) }; #endif /* _PAR_NT_H */ hamlib-4.6.5/src/fifo.c0000664000175000017500000000616015056640443010335 #include #include #include #include "fifo.h" #include "config.h" void initFIFO(FIFO_RIG *fifo) { fifo->head = 0; fifo->tail = 0; #ifdef _PTHREAD_H static pthread_mutex_t t = PTHREAD_MUTEX_INITIALIZER; fifo->mutex = t; #endif } void resetFIFO(FIFO_RIG *fifo) { rig_debug(RIG_DEBUG_TRACE, "%s: fifo flushed\n", __func__); fifo->head = fifo->tail; fifo->flush = 1; } // returns RIG_OK if added // return -RIG error if overflow int push(FIFO_RIG *fifo, const char *msg) { #ifdef _PTHREAD_H pthread_mutex_lock(&fifo->mutex); #endif int len = strlen(msg); for (int i = 0; i < len; ++i) { // FIFO is meant for CW use only // So we skip some chars that don't work with CW if (msg[i] & 0x80) { continue; } // drop any chars that have high bit set switch (msg[i]) { case 0x0d: case 0x0a: continue; } fifo->data[fifo->tail] = msg[i]; if (isalnum(msg[i])) rig_debug(RIG_DEBUG_VERBOSE, "%s: push %c (%d,%d)\n", __func__, msg[i], fifo->head, fifo->tail); else rig_debug(RIG_DEBUG_VERBOSE, "%s: push 0x%02x (%d,%d)\n", __func__, msg[i], fifo->head, fifo->tail); if (fifo->tail + 1 == fifo->head) { return -RIG_EDOM; } fifo->tail = (fifo->tail + 1) % HAMLIB_FIFO_SIZE; } #ifdef _PTHREAD_H pthread_mutex_unlock(&fifo->mutex); #endif return RIG_OK; } int peek(FIFO_RIG *fifo) { if (fifo == NULL) { return -1; } if (fifo->tail < 0 || fifo->head < 0) { return -1; } if (fifo->tail > 1023 || fifo->head > 1023) { return -1; } if (fifo->tail == fifo->head) { return -1; } #ifdef _PTHREAD_H pthread_mutex_lock(&fifo->mutex); #endif char c = fifo->data[fifo->head]; #if 0 if (isalnum(c)) rig_debug(RIG_DEBUG_VERBOSE, "%s: peek %c (%d,%d)\n", __func__, c, fifo->head, fifo->tail); else rig_debug(RIG_DEBUG_VERBOSE, "%s: peek 0x%02x (%d,%d)\n", __func__, c, fifo->head, fifo->tail); #endif #ifdef _PTHREAD_H pthread_mutex_unlock(&fifo->mutex); #endif return c; } int pop(FIFO_RIG *fifo) { if (fifo->tail == fifo->head) { return -1; } #ifdef _PTHREAD_H pthread_mutex_lock(&fifo->mutex); #endif char c = fifo->data[fifo->head]; #if 0 if (isalnum(c)) rig_debug(RIG_DEBUG_VERBOSE, "%s: pop %c (%d,%d)\n", __func__, c, fifo->head, fifo->tail); else rig_debug(RIG_DEBUG_VERBOSE, "%s: pop 0x%02x (%d,%d)\n", __func__, c, fifo->head, fifo->tail); #endif fifo->head = (fifo->head + 1) % HAMLIB_FIFO_SIZE; #ifdef _PTHREAD_H pthread_mutex_unlock(&fifo->mutex); #endif return c; } #ifdef TEST int main() { FIFO_RIG fifo; initFIFO(&fifo); const char *str = "Hello, World!\n"; // Pushing the string onto the FIFO push(&fifo, str); // Popping and printing one character at a time int c; while ((c = pop(&fifo)) != -1) { printf("%c", c); } return 0; } #endif hamlib-4.6.5/src/usb_port.c0000664000175000017500000002602415056640443011250 /* * Hamlib Interface - USB communication low-level support * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \brief USB IO * \file usb_port.c * * doc todo: deal with defined(HAVE_LIBUSB)... quashing the doc process. */ #include #include #include /* String function definitions */ #include #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "usb_port.h" /* * Compile only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) /** * \brief Find and open USB device * \param port * \return usb_handle */ static libusb_device_handle *find_and_open_device(const hamlib_port_t *port) { libusb_device_handle *udh = NULL; libusb_device *dev, **devs; struct libusb_device_descriptor desc; char string[256]; int i, r; rig_debug(RIG_DEBUG_VERBOSE, "%s called LIBUSB_API_VERSION=%x\n", __func__, LIBUSB_API_VERSION); rig_debug(RIG_DEBUG_VERBOSE, "%s: looking for device %04x:%04x...\n", __func__, port->parm.usb.vid, port->parm.usb.pid); r = libusb_get_device_list(NULL, &devs); if (r < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed getting usb device list: %s", __func__, libusb_error_name(r)); return NULL; } for (i = 0; (dev = devs[i]) != NULL; i++) { libusb_get_device_descriptor(dev, &desc); rig_debug(RIG_DEBUG_VERBOSE, " %04x:%04x\n", desc.idVendor, desc.idProduct); if (desc.idVendor == port->parm.usb.vid && desc.idProduct == port->parm.usb.pid) { /* we need to open the device in order to query strings */ r = libusb_open(dev, &udh); if (r < 0) { rig_debug(RIG_DEBUG_WARN, "%s: Warning: Cannot open USB device: %s\n", __func__, libusb_error_name(r)); continue; } /* now check whether the names match: */ if (port->parm.usb.vendor_name) { string[0] = '\0'; r = libusb_get_string_descriptor_ascii(udh, desc.iManufacturer, (unsigned char *)string, sizeof(string)); if (r < 0) { rig_debug(RIG_DEBUG_WARN, "Warning: cannot query manufacturer for USB device: %s\n", libusb_error_name(r)); libusb_close(udh); continue; } rig_debug(RIG_DEBUG_VERBOSE, " vendor >%s<", string); if (strcmp(string, port->parm.usb.vendor_name) != 0) { rig_debug(RIG_DEBUG_WARN, "%s: Warning: Vendor name string mismatch!\n", __func__); libusb_close(udh); continue; } } if (port->parm.usb.product) { string[0] = '\0'; r = libusb_get_string_descriptor_ascii(udh, desc.iProduct, (unsigned char *)string, sizeof(string)); if (r < 0) { rig_debug(RIG_DEBUG_WARN, "Warning: cannot query product for USB device: %s\n", libusb_error_name(r)); libusb_close(udh); continue; } rig_debug(RIG_DEBUG_VERBOSE, " product >%s<", string); if (strcmp(string, port->parm.usb.product) != 0) { /* Now testing with strncasecmp() for case insensitive * match. Updating firmware on FUNcube Dongle to v18f resulted * in product string changing from "FunCube Dongle" to * "FUNcube Dongle". As new dongles are shipped with * older firmware, both product strings are valid. Sigh... */ if (strncasecmp(string, port->parm.usb.product, sizeof(port->parm.usb.product) - 1) != 0) { rig_debug(RIG_DEBUG_WARN, "%s: Warning: Product string mismatch!\n", __func__); libusb_close(udh); continue; } } } libusb_free_device_list(devs, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s", " -> found\n"); return udh; } } libusb_free_device_list(devs, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s", " -> not found\n"); return NULL; /* not found */ } /** * \brief Open hamlib_port of USB device * \param port * \return status */ int usb_port_open(hamlib_port_t *port) { static char pathname[HAMLIB_FILPATHLEN]; libusb_device_handle *udh; char *p, *q; int r; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* init default libusb-1.0 library contexte, if needed */ r = libusb_init(NULL); if (r < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_init failed: %s\n", __func__, libusb_error_name(r)); return -RIG_EIO; } //libusb_set_debug(NULL, 1); /* Extract VID/PID/Vendor/Product name from pathname. */ /* Duplicate the string since we may modify it. */ strncpy(pathname, port->pathname, sizeof pathname); pathname[HAMLIB_FILPATHLEN - 1] = '\0'; p = pathname; if (strlen(pathname) == 9) { // then is new new libusb format with just vid:pid int n = sscanf(pathname, "%x:%x", &port->parm.usb.vid, &port->parm.usb.pid); if (n != 2) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse vid:pid from '%s'\n", __func__, pathname); return -RIG_EINVAL; } } else { q = strchr(p, ':'); if (q) { ++q; port->parm.usb.vid = strtol(q, NULL, 16); p = q; q = strchr(p, ':'); if (q) { ++q; port->parm.usb.pid = strtol(q, NULL, 16); p = q; q = strchr(p, ':'); if (q) { ++q; port->parm.usb.vendor_name = q; p = q; q = strchr(p, ':'); if (q) { *q++ = '\0'; port->parm.usb.product = q; } } } } } udh = find_and_open_device(port); if (udh == 0) { libusb_exit(NULL); return -RIG_EIO; } /* Try to detach ftdi_sio kernel module. * This should be performed only for devices using * USB-serial converters (like FTDI chips), for other * devices this may cause problems, so do not do it. */ (void)libusb_set_auto_detach_kernel_driver(udh, port->parm.usb.iface); if (port->parm.usb.iface >= 0) { #ifdef _WIN32 /* Is it still needed with libusb-1.0 ? */ if (port->parm.usb.conf >= 0 && (r = libusb_set_configuration(udh, port->parm.usb.conf)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_set_configuration: failed conf %d: %s\n", __func__, port->parm.usb.conf, libusb_error_name(r)); libusb_close(udh); libusb_exit(NULL); return -RIG_EIO; } #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: claiming %d\n", __func__, port->parm.usb.iface); r = libusb_claim_interface(udh, port->parm.usb.iface); if (r < 0) { rig_debug(RIG_DEBUG_ERR, "%s:libusb_claim_interface: failed interface %d: %s\n", __func__, port->parm.usb.iface, libusb_error_name(r)); libusb_close(udh); libusb_exit(NULL); return -RIG_EIO; } #if 0 r = libusb_set_interface_alt_setting(udh, port->parm.usb.iface, port->parm.usb.alt); if (r < 0) { fprintf(stderr, "%s:usb_set_alt_interface: failed: %s\n", __func__, libusb_error_name(r)); libusb_release_interface(udh, port->parm.usb.iface); libusb_close(udh); libusb_exit(NULL); return -RIG_EIO; } #endif } port->handle = (void *) udh; return RIG_OK; } /** * \brief Close hamlib_port of USB device * \param port * \return status */ int usb_port_close(hamlib_port_t *port) { libusb_device_handle *udh = port->handle; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); libusb_release_interface(udh, port->parm.usb.iface); libusb_close(udh); libusb_exit(NULL); return RIG_OK; } #else //! @cond Doxygen_Suppress int usb_port_open(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENAVAIL; } //! @endcond //! @cond Doxygen_Suppress int usb_port_close(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENAVAIL; } //! @endcond #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ /** @} */ hamlib-4.6.5/src/gpio.c0000664000175000017500000001032015056640443010341 /* * Hamlib Interface - gpio support * Copyright (c) 2016 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "gpio.h" int gpio_open(hamlib_port_t *port, int output, int on_value) { char pathname[HAMLIB_FILPATHLEN * 2]; FILE *fexp, *fdir; int fd; char *dir; port->parm.gpio.on_value = on_value; SNPRINTF(pathname, HAMLIB_FILPATHLEN, "/sys/class/gpio/export"); fexp = fopen(pathname, "w"); if (!fexp) { rig_debug(RIG_DEBUG_ERR, "Export GPIO%s (using %s): %s\n", port->pathname, pathname, strerror(errno)); return -RIG_EIO; } fprintf(fexp, "%s\n", port->pathname); fclose(fexp); SNPRINTF(pathname, sizeof(pathname), "/sys/class/gpio/gpio%s/direction", port->pathname); fdir = fopen(pathname, "w"); if (!fdir) { rig_debug(RIG_DEBUG_ERR, "GPIO%s direction (using %s): %s\n", port->pathname, pathname, strerror(errno)); return -RIG_EIO; } dir = output ? "out" : "in"; rig_debug(RIG_DEBUG_VERBOSE, "Setting direction of GPIO%s to %s\n", port->pathname, dir); fprintf(fdir, "%s\n", dir); fclose(fdir); SNPRINTF(pathname, sizeof(pathname), "/sys/class/gpio/gpio%s/value", port->pathname); fd = open(pathname, O_RDWR); if (fd < 0) { rig_debug(RIG_DEBUG_ERR, "GPIO%s opening value file %s: %s\n", port->pathname, pathname, strerror(errno)); return -RIG_EIO; } port->fd = fd; return fd; } int gpio_close(hamlib_port_t *port) { int retval; char pathname[HAMLIB_FILPATHLEN * 2]; FILE *fexp; retval = close(port->fd); SNPRINTF(pathname, HAMLIB_FILPATHLEN, "/sys/class/gpio/unexport"); fexp = fopen(pathname, "w"); if (!fexp) { rig_debug(RIG_DEBUG_ERR, "Export GPIO%s (using %s): %s\n", port->pathname, pathname, strerror(errno)); return -RIG_EIO; } fprintf(fexp, "%s\n", port->pathname); fclose(fexp); return retval; } int gpio_ptt_set(hamlib_port_t *port, ptt_t pttx) { char *val; port->parm.gpio.value = pttx != RIG_PTT_OFF; if ((port->parm.gpio.value && port->parm.gpio.on_value) || (!port->parm.gpio.value && !port->parm.gpio.on_value)) { val = "1\n"; } else { val = "0\n"; } if (write(port->fd, val, strlen(val)) <= 0) { return -RIG_EIO; } return RIG_OK; } int gpio_ptt_get(hamlib_port_t *port, ptt_t *pttx) { if (port->parm.gpio.value) { *pttx = RIG_PTT_ON; } else { *pttx = RIG_PTT_OFF; } return RIG_OK; } int gpio_dcd_get(hamlib_port_t *port, dcd_t *dcdx) { char val; int port_value; lseek(port->fd, 0, SEEK_SET); if (read(port->fd, &val, sizeof(val)) <= 0) { return -RIG_EIO; } rig_debug(RIG_DEBUG_VERBOSE, "DCD GPIO pin value: %c\n", val); port_value = val - '0'; if (port_value == port->parm.gpio.on_value) { *dcdx = RIG_DCD_ON; } else { *dcdx = RIG_DCD_OFF; } return RIG_OK; } hamlib-4.6.5/src/idx_builtin.h0000664000175000017500000002204715056640443011733 /* * Hamlib Interface - setting2idx for builtin constants * Copyright (c) 2002-2005 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _IDX_BUILTIN_H #define _IDX_BUILTIN_H 1 #include #include /* * only for Hamlib internal use (backend caps) * This is a rig_setting2idx version that works for builtin_constant, * hence allowing its use in array initializers. The compiler simplifies * everything at compile time. * * struct rig_caps foo = { * .level_gran = { [LVL_PREAMP] = { .min = 0, .max = 20, .step = 10 } }, * } * * Of course, it can't work with setting2idx_builtin(RIG_LEVEL_XX|RIG_LEVEL_YY) */ // This is future-proofed for 64 levels #define setting2idx_builtin(s) (( \ (s)==(1ull<<0)?0: \ (s)==(1ull<<1)?1: \ (s)==(1ull<<2)?2: \ (s)==(1ull<<3)?3: \ (s)==(1ull<<4)?4: \ (s)==(1ull<<5)?5: \ (s)==(1ull<<6)?6: \ (s)==(1ull<<7)?7: \ (s)==(1ull<<8)?8: \ (s)==(1ull<<9)?9: \ (s)==(1ull<<10)?10: \ (s)==(1ull<<11)?11: \ (s)==(1ull<<12)?12: \ (s)==(1ull<<13)?13: \ (s)==(1ull<<14)?14: \ (s)==(1ull<<15)?15: \ (s)==(1ull<<16)?16: \ (s)==(1ull<<17)?17: \ (s)==(1ull<<18)?18: \ (s)==(1ull<<19)?19: \ (s)==(1ull<<20)?20: \ (s)==(1ull<<21)?21: \ (s)==(1ull<<22)?22: \ (s)==(1ull<<23)?23: \ (s)==(1ull<<24)?24: \ (s)==(1ull<<25)?25: \ (s)==(1ull<<26)?26: \ (s)==(1ull<<27)?27: \ (s)==(1ull<<28)?28: \ (s)==(1ull<<29)?29: \ (s)==(1ull<<30)?30: \ (s)==(1ull<<31)?31: \ (s)==(1ull<<32)?32: \ (s)==(1ull<<33)?33: \ (s)==(1ull<<34)?34: \ (s)==(1ull<<35)?35: \ (s)==(1ull<<36)?36: \ (s)==(1ull<<37)?37: \ (s)==(1ull<<38)?38: \ (s)==(1ull<<39)?39: \ (s)==(1ull<<40)?40: \ (s)==(1ull<<41)?41: \ (s)==(1ull<<42)?42: \ (s)==(1ull<<43)?43: \ (s)==(1ull<<44)?44: \ (s)==(1ull<<45)?45: \ (s)==(1ull<<46)?46: \ (s)==(1ull<<47)?47: \ (s)==(1ull<<48)?48: \ (s)==(1ull<<49)?49: \ (s)==(1ull<<50)?50: \ (s)==(1ull<<51)?51: \ (s)==(1ull<<52)?52: \ (s)==(1ull<<53)?53: \ (s)==(1ull<<54)?54: \ (s)==(1ull<<55)?55: \ (s)==(1ull<<56)?56: \ (s)==(1ull<<57)?57: \ (s)==(1ull<<58)?58: \ (s)==(1ull<<59)?59: \ (s)==(1ull<<60)?60: \ (s)==(1ull<<61)?61: \ (s)==(1ull<<62)?62: \ (s)==(1ull<<63)?63: \ -1) \ ) #define LVL_PREAMP setting2idx_builtin(RIG_LEVEL_PREAMP) #define LVL_ATT setting2idx_builtin(RIG_LEVEL_ATT) #define LVL_VOXDELAY setting2idx_builtin(RIG_LEVEL_VOXDELAY) #define LVL_AF setting2idx_builtin(RIG_LEVEL_AF) #define LVL_RF setting2idx_builtin(RIG_LEVEL_RF) #define LVL_SQL setting2idx_builtin(RIG_LEVEL_SQL) #define LVL_IF setting2idx_builtin(RIG_LEVEL_IF) #define LVL_APF setting2idx_builtin(RIG_LEVEL_APF) #define LVL_NR setting2idx_builtin(RIG_LEVEL_NR) #define LVL_PBT_IN setting2idx_builtin(RIG_LEVEL_PBT_IN) #define LVL_PBT_OUT setting2idx_builtin(RIG_LEVEL_PBT_OUT) #define LVL_CWPITCH setting2idx_builtin(RIG_LEVEL_CWPITCH) #define LVL_RFPOWER setting2idx_builtin(RIG_LEVEL_RFPOWER) #define LVL_MICGAIN setting2idx_builtin(RIG_LEVEL_MICGAIN) #define LVL_KEYSPD setting2idx_builtin(RIG_LEVEL_KEYSPD) #define LVL_NOTCHF setting2idx_builtin(RIG_LEVEL_NOTCHF) #define LVL_COMP setting2idx_builtin(RIG_LEVEL_COMP) #define LVL_AGC setting2idx_builtin(RIG_LEVEL_AGC) #define LVL_BKINDL setting2idx_builtin(RIG_LEVEL_BKINDL) #define LVL_BALANCE setting2idx_builtin(RIG_LEVEL_BALANCE) #define LVL_METER setting2idx_builtin(RIG_LEVEL_METER) #define LVL_VOXGAIN setting2idx_builtin(RIG_LEVEL_VOXGAIN) #define LVL_ANTIVOX setting2idx_builtin(RIG_LEVEL_ANTIVOX) #define LVL_SLOPE_LOW setting2idx_builtin(RIG_LEVEL_SLOPE_LOW) #define LVL_SLOPE_HIGH setting2idx_builtin(RIG_LEVEL_SLOPE_HIGH) #define LVL_BKIN_DLYMS setting2idx_builtin(RIG_LEVEL_BKIN_DLYMS) #define LVL_RAWSTR setting2idx_builtin(RIG_LEVEL_RAWSTR) #define LVL_SQLSTAT setting2idx_builtin(RIG_LEVEL_SQLSTAT) #define LVL_SWR setting2idx_builtin(RIG_LEVEL_SWR) #define LVL_ALC setting2idx_builtin(RIG_LEVEL_ALC) #define LVL_STRENGTH setting2idx_builtin(RIG_LEVEL_STRENGTH) #define LVL_USB_AF setting2idx_builtin(RIG_LEVEL_USB_AF) #define LVL_USB_AF_INPUT setting2idx_builtin(RIG_LEVEL_USB_AF_INPUT) /*#define LVL_BWC setting2idx_builtin(RIG_LEVEL_BWC)*/ #define LVL_RFPOWER_METER setting2idx_builtin(RIG_LEVEL_RFPOWER_METER) #define LVL_RFPOWER_METER_WATTS setting2idx_builtin(RIG_LEVEL_RFPOWER_METER_WATTS) #define LVL_COMP_METER setting2idx_builtin(RIG_LEVEL_COMP_METER) #define LVL_VD_METER setting2idx_builtin(RIG_LEVEL_VD_METER) #define LVL_ID_METER setting2idx_builtin(RIG_LEVEL_ID_METER) #define LVL_NOTCHF_RAW setting2idx_builtin(RIG_LEVEL_NOTCHF_RAW) #define LVL_MONITOR_GAIN setting2idx_builtin(RIG_LEVEL_MONITOR_GAIN) #define LVL_NB setting2idx_builtin(RIG_LEVEL_NB) #define LVL_BRIGHT setting2idx_builtin(RIG_LEVEL_BRIGHT) #define LVL_SPECTRUM_MODE setting2idx_builtin(RIG_LEVEL_SPECTRUM_MODE) #define LVL_SPECTRUM_SPAN setting2idx_builtin(RIG_LEVEL_SPECTRUM_SPAN) #define LVL_SPECTRUM_EDGE_LOW setting2idx_builtin(RIG_LEVEL_SPECTRUM_EDGE_LOW) #define LVL_SPECTRUM_EDGE_HIGH setting2idx_builtin(RIG_LEVEL_SPECTRUM_EDGE_HIGH) #define LVL_SPECTRUM_SPEED setting2idx_builtin(RIG_LEVEL_SPECTRUM_SPEED) #define LVL_SPECTRUM_REF setting2idx_builtin(RIG_LEVEL_SPECTRUM_REF) #define LVL_SPECTRUM_AVG setting2idx_builtin(RIG_LEVEL_SPECTRUM_AVG) #define LVL_SPECTRUM_ATT setting2idx_builtin(RIG_LEVEL_SPECTRUM_ATT) #define LVL_USB_AF setting2idx_builtin(RIG_LEVEL_USB_AF) #define LVL_AGC_TIME setting2idx_builtin(RIG_LEVEL_AGC_TIME) #define LVL_BAND_SELECT setting2idx_builtin(RIG_LEVEL_BAND_SELECT) #define LVL_51 setting2idx_builtin(RIG_LEVEL_51) #define LVL_52 setting2idx_builtin(RIG_LEVEL_52) #define LVL_53 setting2idx_builtin(RIG_LEVEL_53) #define LVL_54 setting2idx_builtin(RIG_LEVEL_54) #define LVL_55 setting2idx_builtin(RIG_LEVEL_55) #define LVL_56 setting2idx_builtin(RIG_LEVEL_56) #define LVL_57 setting2idx_builtin(RIG_LEVEL_57) #define LVL_58 setting2idx_builtin(RIG_LEVEL_58) #define LVL_59 setting2idx_builtin(RIG_LEVEL_59) #define LVL_60 setting2idx_builtin(RIG_LEVEL_60) #define LVL_61 setting2idx_builtin(RIG_LEVEL_61) #define LVL_62 setting2idx_builtin(RIG_LEVEL_62) #define LVL_63 setting2idx_builtin(RIG_LEVEL_63) #define PARM_ANN setting2idx_builtin(RIG_PARM_ANN) #define PARM_APO setting2idx_builtin(RIG_PARM_APO) #define PARM_BACKLIGHT setting2idx_builtin(RIG_PARM_BACKLIGHT) #define PARM_BEEP setting2idx_builtin(RIG_PARM_BEEP) #define PARM_TIME setting2idx_builtin(RIG_PARM_TIME) #define PARM_BAT setting2idx_builtin(RIG_PARM_BAT) #define PARM_KEYLIGHT setting2idx_builtin(RIG_PARM_KEYLIGHT) #define PARM_BANDSELECT setting2idx_builtin(RIG_PARM_BANDSELECT) #define PARM_SCREENSAVER setting2idx_builtin(RIG_PARM_SCREENSAVER) #define PARM_KEYERTYPE setting2idx_builtin(RIG_PARM_KEYERTYPE) /* Rotator levels */ #define ROT_LVL_SPEED setting2idx_builtin(ROT_LEVEL_SPEED) #endif /* _IDX_BUILTIN_H */ hamlib-4.6.5/src/debug.c0000664000175000017500000002047115056640443010501 /* * Hamlib Interface - debug * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig * @{ */ /** * \file debug.c * * \brief Control Hamlib debugging functions. */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include #ifdef ANDROID # include #endif #include #include #include "misc.h" /*! @} */ /** * \addtogroup rig_internal * @{ */ /** \brief Sets the number of hexadecimal pairs to print per line. */ #define DUMP_HEX_WIDTH 16 static int rig_debug_level = RIG_DEBUG_TRACE; static int rig_debug_time_stamp = 0; FILE *rig_debug_stream; static vprintf_cb_t rig_vprintf_cb; static rig_ptr_t rig_vprintf_arg; extern HAMLIB_EXPORT(void) dump_hex(const unsigned char ptr[], size_t size); /** * \brief Do a hex dump of the unsigned char array. * * \param ptr Pointer to a character array. * \param size Number of chars to words to dump. * * Prints the hex dump to `stderr` via rig_debug(): * * ``` * 0000 4b 30 30 31 34 35 30 30 30 30 30 30 30 35 30 32 K001450000000502 * 0010 30 30 0d 0a 00.. * ``` */ void dump_hex(const unsigned char ptr[], size_t size) { /* example * 0000 4b 30 30 31 34 35 30 30 30 30 30 30 30 35 30 32 K001450000000502 * 0010 30 30 0d 0a 00.. */ char line[4 + 4 + 3 * DUMP_HEX_WIDTH + 4 + DUMP_HEX_WIDTH + 1]; int i; if (!rig_need_debug(RIG_DEBUG_TRACE)) { return; } line[sizeof(line) - 1] = '\0'; for (i = 0; i < size; ++i) { unsigned char c; if (i % DUMP_HEX_WIDTH == 0) { /* new line */ SNPRINTF(line + 0, sizeof(line), "%04x", i); memset(line + 4, ' ', sizeof(line) - 4 - 1); } c = ptr[i]; /* hex print */ sprintf(line + 8 + 3 * (i % DUMP_HEX_WIDTH), "%02x", c); line[8 + 3 * (i % DUMP_HEX_WIDTH) + 2] = ' '; /* no \0 */ /* ascii print */ line[8 + 3 * DUMP_HEX_WIDTH + 4 + (i % DUMP_HEX_WIDTH)] = (c >= ' ' && c < 0x7f) ? c : '.'; /* actually print the line */ if (i + 1 == size || (i && i % DUMP_HEX_WIDTH == DUMP_HEX_WIDTH - 1)) { rig_debug(RIG_DEBUG_TRACE, "%s\n", line); } } } /*! @} */ /** * \addtogroup rig * @{ */ /** * \brief Change the current debug level. * * \param debug_level Equivalent to the `-v` option of the utilities. * * Allows for dynamically changing the debugging output without reinitializing * the library. * * Useful for programs that want to enable and disable debugging * output without restarting. */ void HAMLIB_API rig_set_debug(enum rig_debug_level_e debug_level) { rig_debug_level = debug_level; } /** * \brief Get the current debug level. * * \param debug_level Equivalent to the `-v` option of the utilities. * * Allows for obtaining the current debug level * */ void HAMLIB_API rig_get_debug(enum rig_debug_level_e *debug_level) { *debug_level = rig_debug_level; } /** * \brief Test if a given debug level is active. * * \param debug_level The level to test. * * May be used to determine if an action such as opening a dialog should * happen only if a desired debug level is active. * * Also useful for dump_hex(), etc. */ int HAMLIB_API rig_need_debug(enum rig_debug_level_e debug_level) { return (debug_level <= rig_debug_level); } /** * \brief Enable or disable the time stamp on debugging output. * * \param flag `TRUE` or `FALSE`. * * Sets or unsets the flag which controls whether debugging output includes a * time stamp. */ void HAMLIB_API rig_set_debug_time_stamp(int flag) { rig_debug_time_stamp = flag; } /** * \brief Print debugging messages through `stderr` by default. * * \param debug_level Debug level from none to most output. * \param fmt Formatted character string to print. * * The formatted character string is passed to the `vfprintf`(3) C library * call and follows its format specification. */ #undef rig_debug void HAMLIB_API rig_debug(enum rig_debug_level_e debug_level, const char *fmt, ...) { static pthread_mutex_t client_debug_lock = PTHREAD_MUTEX_INITIALIZER; va_list ap; if (!rig_need_debug(debug_level)) { return; } pthread_mutex_lock(&client_debug_lock); va_start(ap, fmt); if (rig_vprintf_cb) { rig_vprintf_cb(debug_level, rig_vprintf_arg, fmt, ap); } else { if (!rig_debug_stream) { rig_debug_stream = stderr; } if (rig_debug_time_stamp) { char buf[256]; fprintf(rig_debug_stream, "%s: ", date_strget(buf, sizeof(buf), 1)); } vfprintf(rig_debug_stream, fmt, ap); fflush(rig_debug_stream); } va_end(ap); #ifdef ANDROID int a; va_start(ap, fmt); switch (debug_level) { // case RIG_DEBUG_NONE: case RIG_DEBUG_BUG: a = ANDROID_LOG_FATAL; break; case RIG_DEBUG_ERR: a = ANDROID_LOG_ERROR; break; case RIG_DEBUG_WARN: a = ANDROID_LOG_WARN; break; case RIG_DEBUG_VERBOSE: a = ANDROID_LOG_VERBOSE; break; case RIG_DEBUG_TRACE: a = ANDROID_LOG_VERBOSE; break; default: a = ANDROID_LOG_DEBUG; break; } __android_log_vprint(a, PACKAGE_NAME, fmt, ap); va_end(ap); #endif pthread_mutex_unlock(&client_debug_lock); } /** * \brief Set callback to handle debugging messages. * * \param cb The callback function to install. * \param arg A Pointer to some private data to pass later on to the callback. * * Install a callback for rig_debug() messages. * \code * int * rig_message_cb(enum rig_debug_level_e debug_level, * rig_ptr_t user_data, * const char *fmt, * va_list ap) * { * char buf[1024]; * * sprintf (buf, "Message(%s) ", (char*)user_data); * syslog (LOG_USER, buf); * vsprintf (buf, fmt, ap); * syslog (LOG_USER, buf); * * return RIG_OK; * } * * . . . * * char *cookie = "Foo"; * rig_set_debug_callback (rig_message_cb, (rig_ptr_t)cookie); * \endcode * * \return A pointer to the previous callback that was set, if any. * * \sa rig_debug() */ vprintf_cb_t HAMLIB_API rig_set_debug_callback(vprintf_cb_t cb, rig_ptr_t arg) { vprintf_cb_t prev_cb = rig_vprintf_cb; rig_vprintf_cb = cb; rig_vprintf_arg = arg; return prev_cb; } /** * \brief Change the output stream from `stderr` to a different stream. * * \param stream The stream to direct debugging output. * * \sa `FILE`(3) */ FILE *HAMLIB_API rig_set_debug_file(FILE *stream) { FILE *prev_stream = rig_debug_stream; rig_debug_stream = stream; return prev_stream; } /** * \brief Change the output stream to a filename * * \param filename The filename to direct debugging output. * * \sa `FILE`(3) */ // cppcheck-suppress unusedFunction FILE *HAMLIB_API rig_set_debug_filename(char *filename) { FILE *prev_stream = rig_debug_stream; rig_debug(RIG_DEBUG_WARN, "%s: debug will stream to '%s'\n", __func__, filename); FILE *stream = fopen(filename, "w"); if (stream == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error opening stream: %s\n", __func__, strerror(errno)); return NULL; } rig_debug_stream = stream; return prev_stream; } /** @} */ hamlib-4.6.5/src/parallel.h0000664000175000017500000000532215056640443011212 /* * Hamlib Interface - parallel communication header * Copyright (c) 2000-2003 by Frank Singleton * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _PARALLEL_H #define _PARALLEL_H 1 #include #include "iofunc.h" #ifdef HAVE_PARALLEL #ifdef HAVE_LINUX_PARPORT_H # include #endif #endif #ifndef PARPORT_CONTROL_STROBE # define PARPORT_CONTROL_STROBE 0x1 #endif #ifndef PARPORT_CONTROL_AUTOFD # define PARPORT_CONTROL_AUTOFD 0x2 #endif #ifndef PARPORT_CONTROL_INIT # define PARPORT_CONTROL_INIT 0x4 #endif #ifndef PARPORT_CONTROL_SELECT # define PARPORT_CONTROL_SELECT 0x8 #endif #ifndef PARPORT_STATUS_ERROR # define PARPORT_STATUS_ERROR 0x8 #endif #ifndef PARPORT_STATUS_SELECT # define PARPORT_STATUS_SELECT 0x10 #endif #ifndef PARPORT_STATUS_PAPEROUT # define PARPORT_STATUS_PAPEROUT 0x20 #endif #ifndef PARPORT_STATUS_ACK # define PARPORT_STATUS_ACK 0x40 #endif #ifndef PARPORT_STATUS_BUSY # define PARPORT_STATUS_BUSY 0x80 #endif __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int par_open(hamlib_port_t *p); int par_close(hamlib_port_t *p); int par_ptt_set(hamlib_port_t *p, ptt_t pttx); int par_ptt_get(hamlib_port_t *p, ptt_t *pttx); int par_dcd_get(hamlib_port_t *p, dcd_t *dcdx); extern HAMLIB_EXPORT(int) par_write_data(hamlib_port_t *p, unsigned char data); extern HAMLIB_EXPORT(int) par_write_control(hamlib_port_t *p, unsigned char control); extern HAMLIB_EXPORT(int) par_read_data(hamlib_port_t *p, unsigned char *data); extern HAMLIB_EXPORT(int) par_read_control(hamlib_port_t *p, unsigned char *control); extern HAMLIB_EXPORT(int) par_read_status(hamlib_port_t *p, unsigned char *status); extern HAMLIB_EXPORT(int) par_lock(hamlib_port_t *p); extern HAMLIB_EXPORT(int) par_unlock(hamlib_port_t *p); __END_DECLS #endif /* _PARALLEL_H */ hamlib-4.6.5/src/event.h0000664000175000017500000000275115056640443010542 /* * Hamlib Interface - event handling header * Copyright (c) 2000-2003 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _EVENT_H #define _EVENT_H 1 #include int rig_poll_routine_start(RIG *rig); int rig_poll_routine_stop(RIG *rig); int rig_fire_freq_event(RIG *rig, vfo_t vfo, freq_t freq); int rig_fire_mode_event(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int rig_fire_vfo_event(RIG *rig, vfo_t vfo); int rig_fire_ptt_event(RIG *rig, vfo_t vfo, ptt_t ptt); int rig_fire_dcd_event(RIG *rig, vfo_t vfo, dcd_t dcd); int rig_fire_pltune_event(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); int rig_fire_spectrum_event(RIG *rig, struct rig_spectrum_line *line); #endif /* _EVENT_H */ hamlib-4.6.5/src/tones.h0000664000175000017500000001040615056640443010545 /* * Hamlib Interface - CTCSS and DCS tables header * Copyright (c) 2000-2009 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TONES_H #define _TONES_H 1 #include /* and implicitly rig_dll.h */ /* * 52 CTCSS sub-audible tones */ #define FULL_CTCSS_LIST \ 600, 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, \ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1200, 1230, 1273, \ 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, \ 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, \ 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, \ 0, static const tone_t static_full_ctcss_list[] = { FULL_CTCSS_LIST }; #define FULL_CTCSS_LIST_COUNT 52 /* * 50 CTCSS sub-audible tones, from 67.0Hz to 254.1Hz * * \note Don't even think about changing a bit of this array, several * backends depend on it. If you need to, create a copy for your * own caps. --SF */ #define COMMON_CTCSS_LIST \ 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, \ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, \ 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, \ 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, \ 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, \ 0, static const tone_t static_common_ctcss_list[] = { COMMON_CTCSS_LIST }; #define COMMON_CTCSS_LIST_COUNT 50 /* * 104 DCS codes */ #define COMMON_DCS_LIST \ 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, \ 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, \ 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, \ 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, \ 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, \ 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, \ 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, \ 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, \ 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, \ 0, static const tone_t static_common_dcs_list[] = { COMMON_DCS_LIST }; #define COMMON_DCS_LIST_COUNT 104 /* * 106 DCS codes */ #define FULL_DCS_LIST \ 17, 23, 25, 26, 31, 32, 36, 43, 47, 50, 51, 53, \ 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, \ 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, \ 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, \ 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, \ 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, \ 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, \ 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, \ 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, \ 0, static const tone_t static_full_dcs_list[] = { FULL_DCS_LIST }; #define FULL_DCS_LIST_COUNT 106 /* * These arrays cannot be shared on Win32 systems, * because DLL's vars don't have constant address. */ #if (defined(_WIN32) || defined(__CYGWIN__)) // && !defined(IN_HAMLIB) #define common_ctcss_list (tone_t*)static_common_ctcss_list #define full_ctcss_list (tone_t*)static_full_ctcss_list #define full_dcs_list (tone_t*)static_full_dcs_list #define common_dcs_list (tone_t*)static_common_dcs_list #else extern HAMLIB_EXPORT_VAR(tone_t) full_ctcss_list[]; extern HAMLIB_EXPORT_VAR(tone_t) common_ctcss_list[]; extern HAMLIB_EXPORT_VAR(tone_t) full_dcs_list[]; extern HAMLIB_EXPORT_VAR(tone_t) common_dcs_list[]; #endif #endif /* _TONES_H */ hamlib-4.6.5/src/cache.h0000664000175000017500000000223715056640443010463 /* * Hamlib Interface - rig state cache routines * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _CACHE_H #define _CACHE_H #include int rig_set_cache_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int rig_set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq); void rig_cache_show(RIG *rig, const char *func, int line); #endif hamlib-4.6.5/src/snapshot_data.c0000664000175000017500000002513515056640443012245 #include #define _XOPEN_SOURCE 700 #include #include #include #include "misc.h" #include "snapshot_data.h" #include "hamlibdatetime.h" #include "sprintflst.h" #include "cJSON.h" #define SPECTRUM_MODE_FIXED "FIXED" #define SPECTRUM_MODE_CENTER "CENTER" char snapshot_data_pid[20]; static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig) { cJSON *node; char buf[1024]; struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); cJSON *id_node = cJSON_CreateObject(); cJSON_AddStringToObject(id_node, "model", rig->caps->model_name); cJSON_AddStringToObject(id_node, "endpoint", RIGPORT(rig)->pathname); cJSON_AddStringToObject(id_node, "process", snapshot_data_pid); cJSON_AddStringToObject(id_node, "deviceId", rs->device_id); cJSON_AddItemToObject(rig_node, "id", id_node); node = cJSON_AddStringToObject(rig_node, "status", rig_strcommstatus(rs->comm_status)); if (node == NULL) { goto error; } // TODO: need to store last error code node = cJSON_AddStringToObject(rig_node, "errorMsg", ""); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(rig_node, "name", rig->caps->model_name); if (node == NULL) { goto error; } node = cJSON_AddBoolToObject(rig_node, "split", cachep->split == RIG_SPLIT_ON ? 1 : 0); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(rig_node, "splitVfo", rig_strvfo(cachep->split_vfo)); if (node == NULL) { goto error; } node = cJSON_AddBoolToObject(rig_node, "satMode", cachep->satmode ? 1 : 0); if (node == NULL) { goto error; } rig_sprintf_mode(buf, sizeof(buf), rs->mode_list); char *p; cJSON *modes_array = cJSON_CreateArray(); for (p = strtok(buf, " "); p; p = strtok(NULL, " ")) { if (strlen(buf) > 0) { cJSON *tmp = cJSON_CreateString(p); cJSON_AddItemToArray(modes_array, tmp); } } cJSON_AddItemToObject(rig_node, "modes", modes_array); return RIG_OK; error: RETURNFUNC2(-RIG_EINTERNAL); } // 128 max modes should last a while #define MAX_MODES 128 static int snapshot_serialize_vfo(cJSON *vfo_node, RIG *rig, vfo_t vfo) { freq_t freq; int freq_ms, mode_ms, width_ms; rmode_t mode; //rmode_t modes[MAX_MODES]; pbwidth_t width; ptt_t ptt; split_t split; vfo_t split_vfo; int result; int is_rx, is_tx; cJSON *node; struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); // TODO: This data should match rig_get_info command response node = cJSON_AddStringToObject(vfo_node, "name", rig_strvfo(vfo)); if (node == NULL) { goto error; } result = rig_get_cache(rig, vfo, &freq, &freq_ms, &mode, &mode_ms, &width, &width_ms); if (result == RIG_OK) { node = cJSON_AddNumberToObject(vfo_node, "freq", freq); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(vfo_node, "mode", rig_strrmode(mode)); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(vfo_node, "width", (double) width); if (node == NULL) { goto error; } } split = cachep->split; split_vfo = cachep->split_vfo; is_rx = (split == RIG_SPLIT_OFF && vfo == rs->current_vfo) || (split == RIG_SPLIT_ON && vfo != split_vfo); is_tx = (split == RIG_SPLIT_OFF && vfo == rs->current_vfo) || (split == RIG_SPLIT_ON && vfo == split_vfo); ptt = cachep->ptt && is_tx; if (is_tx) { node = cJSON_AddBoolToObject(vfo_node, "ptt", ptt == RIG_PTT_OFF ? 0 : 1); } else { node = cJSON_AddBoolToObject(vfo_node, "ptt", 0); } if (node == NULL) { goto error; } node = cJSON_AddBoolToObject(vfo_node, "rx", is_rx); if (node == NULL) { goto error; } node = cJSON_AddBoolToObject(vfo_node, "tx", is_tx); if (node == NULL) { goto error; } return RIG_OK; error: RETURNFUNC2(-RIG_EINTERNAL); } static int snapshot_serialize_spectrum(cJSON *spectrum_node, RIG *rig, struct rig_spectrum_line *spectrum_line) { // Spectrum data is represented as a hexadecimal ASCII string where each data byte is represented as 2 ASCII letters char spectrum_data_string[HAMLIB_MAX_SPECTRUM_DATA * 2]; cJSON *node; int i; struct rig_spectrum_scope *scopes = rig->caps->spectrum_scopes; char *name = "?"; for (i = 0; scopes[i].name != NULL; i++) { if (scopes[i].id == spectrum_line->id) { name = scopes[i].name; } } node = cJSON_AddNumberToObject(spectrum_node, "id", spectrum_line->id); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(spectrum_node, "name", name); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(spectrum_node, "type", spectrum_line->spectrum_mode == RIG_SPECTRUM_MODE_CENTER ? SPECTRUM_MODE_CENTER : SPECTRUM_MODE_FIXED); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "minLevel", spectrum_line->data_level_min); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "maxLevel", spectrum_line->data_level_max); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "minStrength", spectrum_line->signal_strength_min); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "maxStrength", spectrum_line->signal_strength_max); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "centerFreq", spectrum_line->center_freq); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "span", spectrum_line->span_freq); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "lowFreq", spectrum_line->low_edge_freq); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "highFreq", spectrum_line->high_edge_freq); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(spectrum_node, "length", (double) spectrum_line->spectrum_data_length); if (node == NULL) { goto error; } to_hex(spectrum_line->spectrum_data_length, spectrum_line->spectrum_data, sizeof(spectrum_data_string), spectrum_data_string); node = cJSON_AddStringToObject(spectrum_node, "data", spectrum_data_string); if (node == NULL) { goto error; } return RIG_OK; error: RETURNFUNC2(-RIG_EINTERNAL); } void snapshot_init() { snprintf(snapshot_data_pid, sizeof(snapshot_data_pid), "%d", getpid()); } int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line) { cJSON *root_node; cJSON *rig_node, *vfos_array, *vfo_node, *spectra_array, *spectrum_node; cJSON *node; cJSON_bool bool_result; char buf[256]; int result; int i; struct rig_state *rs = STATE(rig); root_node = cJSON_CreateObject(); if (root_node == NULL) { RETURNFUNC2(-RIG_EINTERNAL); } node = cJSON_AddStringToObject(root_node, "app", PACKAGE_NAME); if (node == NULL) { goto error; } node = cJSON_AddStringToObject(root_node, "version", PACKAGE_VERSION " " HAMLIBDATETIME); if (node == NULL) { goto error; } node = cJSON_AddNumberToObject(root_node, "seq", rs->snapshot_packet_sequence_number); if (node == NULL) { goto error; } date_strget(buf, sizeof(buf), 0); node = cJSON_AddStringToObject(root_node, "time", buf); if (node == NULL) { goto error; } // TODO: Calculate 32-bit CRC of the entire JSON record replacing the CRC value with 0 node = cJSON_AddNumberToObject(root_node, "crc", 0); if (node == NULL) { goto error; } rig_node = cJSON_CreateObject(); if (rig_node == NULL) { goto error; } result = snapshot_serialize_rig(rig_node, rig); if (result != RIG_OK) { cJSON_Delete(rig_node); goto error; } cJSON_AddItemToObject(root_node, "rig", rig_node); vfos_array = cJSON_CreateArray(); if (vfos_array == NULL) { goto error; } for (i = 0; i < HAMLIB_MAX_VFOS; i++) { vfo_t vfo = rs->vfo_list & RIG_VFO_N(i); if (!vfo) { continue; } vfo_node = cJSON_CreateObject(); result = snapshot_serialize_vfo(vfo_node, rig, vfo); if (result != RIG_OK) { cJSON_Delete(vfo_node); goto error; } cJSON_AddItemToArray(vfos_array, vfo_node); } cJSON_AddItemToObject(root_node, "vfos", vfos_array); if (spectrum_line != NULL) { spectra_array = cJSON_CreateArray(); if (spectra_array == NULL) { goto error; } spectrum_node = cJSON_CreateObject(); result = snapshot_serialize_spectrum(spectrum_node, rig, spectrum_line); if (result != RIG_OK) { cJSON_Delete(spectrum_node); goto error; } cJSON_AddItemToArray(spectra_array, spectrum_node); cJSON_AddItemToObject(root_node, "spectra", spectra_array); } bool_result = cJSON_PrintPreallocated(root_node, buffer, (int) buffer_length, 0); cJSON_Delete(root_node); if (!bool_result) { RETURNFUNC2(-RIG_EINVAL); } rs->snapshot_packet_sequence_number++; return RIG_OK; error: cJSON_Delete(root_node); RETURNFUNC2(-RIG_EINTERNAL); } hamlib-4.6.5/src/Android.mk0000664000175000017500000000212215056640443011151 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ ../android/ltdl.c \ rig.c \ serial.c \ misc.c \ register.c \ event.c \ cal.c \ conf.c \ tones.c \ rotator.c \ locator.c \ rot_reg.c \ rot_conf.c \ iofunc.c \ ext.c \ mem.c \ settings.c \ parallel.c \ debug.c \ network.c \ sleep.c \ gpio.c \ microham.c \ rot_ext.c \ cm108.c \ sprintflst.c LOCAL_MODULE := libhamlib LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include LOCAL_STATIC_LIBRARIES := adat alinco amsat aor ars barrett celestron cnctrk \ dorji drake dummy easycomm elad ether6 flexradio fodtrack \ gs232a heathkit icmarine icom ioptron jrc kachina kenwood kit \ lowe m2 meade pcr prm80 prosistel racal rft \ rotorez rs sartek satel skanti spid tapr tentec ts7400 tuner \ uniden wj yaesu radant androidsensor LOCAL_LDLIBS := -llog -landroid include $(BUILD_SHARED_LIBRARY) hamlib-4.6.5/src/register.h0000664000175000017500000000707015056640443011244 /* * Hamlib Interface - plugin registration * Copyright (c) 2003-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _REGISTER_H #define _REGISTER_H 1 #include #include #include #include #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C extern #endif #define CONCAT4(w__, x__, y__, z__) w__ ## x__ ## y__ ## z__ #define MAKE_VERSIONED_FN(prefix__, version__, name_args__) CONCAT4(prefix__, version__, _, name_args__) /* void MAKE_VERSIONED_FN(foo, 42, bar(int i)) -> void foo42_bar(int i) */ #ifndef ABI_VERSION #error ABI_VERSION undefined! Did you include config.h? #endif #define PREFIX_INITRIG initrigs #define PREFIX_PROBERIG probeallrigs #define DECLARE_INITRIG_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(int) \ MAKE_VERSIONED_FN(PREFIX_INITRIG, ABI_VERSION, backend(void *be_handle)) #define DECLARE_PROBERIG_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(rig_model_t) \ MAKE_VERSIONED_FN(PREFIX_PROBERIG, \ ABI_VERSION, \ backend(hamlib_port_t *port, \ rig_probe_func_t cfunc, \ rig_ptr_t data)) #define PREFIX_INITROTS initrots #define PREFIX_PROBEROTS probeallrots #define DECLARE_INITROT_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(int) \ MAKE_VERSIONED_FN(PREFIX_INITROTS, ABI_VERSION, backend(void *be_handle)) #define DECLARE_PROBEROT_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(rot_model_t) \ MAKE_VERSIONED_FN(PREFIX_PROBEROTS, \ ABI_VERSION, \ backend(hamlib_port_t *port, \ rig_probe_func_t cfunc, \ rig_ptr_t data)) #define PREFIX_INITAMPS initamps #define PREFIX_PROBEAMPS probeallamps #define DECLARE_INITAMP_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(int) \ MAKE_VERSIONED_FN(PREFIX_INITAMPS, ABI_VERSION, backend(void *be_handle)) #define DECLARE_PROBEAMP_BACKEND(backend) \ EXTERN_C BACKEND_EXPORT(amp_model_t) \ MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, \ ABI_VERSION, \ backend(hamlib_port_t *port, \ rig_probe_func_t cfunc, \ rig_ptr_t data)) #endif /* _REGISTER_H */ hamlib-4.6.5/src/serial_cfg_params.h0000664000175000017500000000241615056640443013060 { TOK_SERIAL_SPEED, "serial_speed", "Serial speed", "Serial port baud rate", "0", RIG_CONF_NUMERIC, { .n = { 300, 115200, 1 } } }, { TOK_DATA_BITS, "data_bits", "Serial data bits", "Serial port data bits", "8", RIG_CONF_NUMERIC, { .n = { 5, 8, 1 } } }, { TOK_STOP_BITS, "stop_bits", "Serial stop bits", "Serial port stop bits", "1", RIG_CONF_NUMERIC, { .n = { 0, 3, 1 } } }, { TOK_PARITY, "serial_parity", "Serial parity", "Serial port parity", "None", RIG_CONF_COMBO, { .c = {{ "None", "Odd", "Even", "Mark", "Space", NULL }} } }, { TOK_HANDSHAKE, "serial_handshake", "Serial handshake", "Serial port handshake", "None", RIG_CONF_COMBO, { .c = {{ "None", "XONXOFF", "Hardware", NULL }} } }, { TOK_RTS_STATE, "rts_state", "RTS state", "Serial port set state of RTS signal for external powering", "Unset", RIG_CONF_COMBO, { .c = {{ "Unset", "ON", "OFF", NULL }} } }, { TOK_DTR_STATE, "dtr_state", "DTR state", "Serial port set state of DTR signal for external powering", "Unset", RIG_CONF_COMBO, { .c = {{ "Unset", "ON", "OFF", NULL }} } }, { RIG_CONF_END, NULL, } hamlib-4.6.5/src/token.h0000664000175000017500000001460415056640443010541 /* * Hamlib Interface - token header * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \brief Token definitions * \file token.h * */ #ifndef _TOKEN_H #define _TOKEN_H 1 #include /** \brief Create a backend token, \a t */ #define TOKEN_BACKEND(t) (t) /** \brief Create a frontend token, \a t */ #define TOKEN_FRONTEND(t) ((t)|(1<<30)) /** \brief Test for token - frontend? */ #define IS_TOKEN_FRONTEND(t) ((t)&(1<<30)) /** \brief Null frontend token */ #define TOK_FRONTEND_NONE TOKEN_FRONTEND(0) /** \brief Null backend token */ #define TOK_BACKEND_NONE TOKEN_BACKEND(0) /* * tokens shared among rig and rotator, * Numbers go from TOKEN_FRONTEND(1) to TOKEN_FRONTEND(99) */ /** \brief Pathname is device for rig control, e.g. /dev/ttyS0 */ #define TOK_PATHNAME TOKEN_FRONTEND(10) /** \brief Delay before serial output (units?) */ #define TOK_WRITE_DELAY TOKEN_FRONTEND(12) /** \brief Delay after serial output (units?) */ #define TOK_POST_WRITE_DELAY TOKEN_FRONTEND(13) /** \brief Timeout delay (units?) */ #define TOK_TIMEOUT TOKEN_FRONTEND(14) /** \brief Number of retries permitted */ #define TOK_RETRY TOKEN_FRONTEND(15) /** \brief Serial speed - "baud rate" */ #define TOK_SERIAL_SPEED TOKEN_FRONTEND(20) /** \brief No. data bits per serial character */ #define TOK_DATA_BITS TOKEN_FRONTEND(21) /** \brief No. stop bits per serial character */ #define TOK_STOP_BITS TOKEN_FRONTEND(22) /** \brief Serial parity (format?) */ #define TOK_PARITY TOKEN_FRONTEND(23) /** \brief Serial Handshake (format?) */ #define TOK_HANDSHAKE TOKEN_FRONTEND(24) /** \brief Serial Req. To Send status */ #define TOK_RTS_STATE TOKEN_FRONTEND(25) /** \brief Serial Data Terminal Ready status */ #define TOK_DTR_STATE TOKEN_FRONTEND(26) /** \brief PTT type override */ #define TOK_PTT_TYPE TOKEN_FRONTEND(30) /** \brief PTT pathname override */ #define TOK_PTT_PATHNAME TOKEN_FRONTEND(31) /** \brief DCD type override */ #define TOK_DCD_TYPE TOKEN_FRONTEND(32) /** \brief DCD pathname override */ #define TOK_DCD_PATHNAME TOKEN_FRONTEND(33) /** \brief CM108 GPIO bit number for PTT */ #define TOK_PTT_BITNUM TOKEN_FRONTEND(34) /** \brief PTT share with other applications */ #define TOK_PTT_SHARE TOKEN_FRONTEND(35) /** \brief Flush with read instead of TCFLUSH */ #define TOK_FLUSHX TOKEN_FRONTEND(36) /** \brief Asynchronous data transfer support */ #define TOK_ASYNC TOKEN_FRONTEND(37) /** \brief Tuner external control pathname */ #define TOK_TUNER_CONTROL_PATHNAME TOKEN_FRONTEND(38) /** \brief Number of retries permitted in case of read timeouts */ #define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39) #define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40) #define TOK_DEVICE_ID TOKEN_FRONTEND(41) /* * rig specific tokens */ /* rx_range_list/tx_range_list, filters, announces, has(func,lvl,..) */ /** \brief rig: VFO compensation in ppm */ #define TOK_VFO_COMP TOKEN_FRONTEND(110) /** \brief rig: Rig state poll interval in milliseconds */ #define TOK_POLL_INTERVAL TOKEN_FRONTEND(111) /** \brief rig: lo frequency of any transverters */ #define TOK_LO_FREQ TOKEN_FRONTEND(112) /** \brief rig: Range index 1-5 */ #define TOK_RANGE_SELECTED TOKEN_FRONTEND(121) /** \brief rig: Range Name */ #define TOK_RANGE_NAME TOKEN_FRONTEND(122) /** \brief rig: Cache timeout in milliseconds */ #define TOK_CACHE_TIMEOUT TOKEN_FRONTEND(123) /** \brief rig: Auto power on rig_open when supported */ #define TOK_AUTO_POWER_ON TOKEN_FRONTEND(124) /** \brief rig: Auto power off rig_close when supported */ #define TOK_AUTO_POWER_OFF TOKEN_FRONTEND(125) /** \brief rig: Auto disable screensaver */ #define TOK_AUTO_DISABLE_SCREENSAVER TOKEN_FRONTEND(126) /** \brief rig: Disable Yaesu band select logic */ #define TOK_DISABLE_YAESU_BANDSELECT TOKEN_FRONTEND(127) /** \brief rig: Suppress get_freq on VFOB for satellite RIT tuning */ #define TOK_TWIDDLE_TIMEOUT TOKEN_FRONTEND(128) /** \brief rig: Suppress get_freq on VFOB for satellite RIT tuning */ #define TOK_TWIDDLE_RIT TOKEN_FRONTEND(129) /** \brief rig: Add Hz to VFOA/Main frequency set */ #define TOK_OFFSET_VFOA TOKEN_FRONTEND(130) /** \brief rig: Add Hz to VFOB/Sub frequency set */ #define TOK_OFFSET_VFOB TOKEN_FRONTEND(131) /** \brief rig: Multicast data UDP address for publishing rig data and state, default 224.0.0.1, value of 0.0.0.0 disables multicast data publishing */ #define TOK_MULTICAST_DATA_ADDR TOKEN_FRONTEND(132) /** \brief rig: Multicast data UDP port, default 4532 */ #define TOK_MULTICAST_DATA_PORT TOKEN_FRONTEND(133) /** \brief rig: Multicast command server UDP address for sending commands to rig, default 224.0.0.2, value of 0.0.0.0 disables multicast command server */ #define TOK_MULTICAST_CMD_ADDR TOKEN_FRONTEND(134) /** \brief rig: Multicast command server UDP port, default 4532 */ #define TOK_MULTICAST_CMD_PORT TOKEN_FRONTEND(135) /** \brief rig: Skip setting freq on opposite VFO when in split mode */ #define TOK_FREQ_SKIP TOKEN_FRONTEND(136) /** \brief rig: Client ID of WSJTX or GPREDICT */ #define TOK_CLIENT TOKEN_FRONTEND(137) /* * rotator specific tokens * (strictly, should be documented as rotator_internal) */ /** \brief rot: Minimum Azimuth */ #define TOK_MIN_AZ TOKEN_FRONTEND(110) /** \brief rot: Maximum Azimuth */ #define TOK_MAX_AZ TOKEN_FRONTEND(111) /** \brief rot: Minimum Elevation */ #define TOK_MIN_EL TOKEN_FRONTEND(112) /** \brief rot: Maximum Elevation */ #define TOK_MAX_EL TOKEN_FRONTEND(113) /** \brief rot: South is zero degrees */ #define TOK_SOUTH_ZERO TOKEN_FRONTEND(114) #endif /* _TOKEN_H */ /** @} */ /* rig_internal definitions */ hamlib-4.6.5/src/gpio.h0000664000175000017500000000234115056640443010352 /* * Hamlib Interface - gpio support header * Copyright (c) 2016 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _GPIO_H #define _GPIO_H #include __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int gpio_open(hamlib_port_t *p, int output, int on_value); int gpio_close(hamlib_port_t *p); int gpio_ptt_set(hamlib_port_t *p, ptt_t pttx); int gpio_ptt_get(hamlib_port_t *p, ptt_t *pttx); int gpio_dcd_get(hamlib_port_t *p, dcd_t *dcdx); __END_DECLS #endif /* _GPIO_H */ hamlib-4.6.5/src/settings.c0000664000175000017500000007474715056640443011272 /** * \addtogroup rig * @{ */ /** * \file settings.c * \brief func/level/parm interface * \author Stephane Fillod * \date 2000-2010 * * Hamlib interface is a frontend implementing wrapper functions. */ /* * Hamlib Interface - func/level/parm * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include /* Error number definitions */ #include #include #include "cal.h" #include "misc.h" #ifndef DOC_HIDDEN # define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state) #endif /* !DOC_HIDDEN */ /** * \brief set a radio level setting * \param rig The rig handle * \param vfo The target VFO * \param level The level setting * \param val The value to set the level setting to * * Sets the level of a setting. * The level value \a val can be a float or an integer. See #value_t * for more information. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_set_level(), rig_get_level() */ int HAMLIB_API rig_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_level == NULL || !rig_has_set_level(rig, level)) { return -RIG_ENAVAIL; } rig_lock(rig, 1); if ((caps->targetable_vfo & RIG_TARGETABLE_LEVEL) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { #if defined(HAVE_PTHREAD) if (level == RIG_LEVEL_KEYSPD) { extern int morse_data_handler_set_keyspd(RIG * rig, int keyspd); morse_data_handler_set_keyspd(rig, val.i); } #endif retcode = caps->set_level(rig, vfo, level, val); rig_lock(rig, 0); return retcode; } if (!caps->set_vfo) { rig_lock(rig, 0); return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { rig_lock(rig, 0); return retcode; } retcode = caps->set_level(rig, vfo, level, val); caps->set_vfo(rig, curr_vfo); rig_lock(rig, 0); return retcode; } /** * \brief get the value of a level * \param rig The rig handle * \param vfo The target VFO * \param level The level setting * \param val The location where to store the value of \a level * * Retrieves the value of a \a level. * The level value \a val can be a float or an integer. See #value_t * for more information. * * RIG_LEVEL_STRENGTH: \a val is an integer, representing the S Meter * level in dB relative to S9, according to the ideal S Meter scale. * The ideal S Meter scale is as follow: S0=-54, S1=-48, S2=-42, S3=-36, * S4=-30, S5=-24, S6=-18, S7=-12, S8=-6, S9=0, +10=10, +20=20, * +30=30, +40=40, +50=50 and +60=60. This is the responsibility * of the backend to return values calibrated for this scale. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_get_level(), rig_set_level() */ int HAMLIB_API rig_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !val) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_level == NULL || !rig_has_get_level(rig, level)) { return -RIG_ENAVAIL; } rig_lock(rig, 1); // Keep Out! /* * Special case(frontend emulation): calibrated S-meter reading */ if (level == RIG_LEVEL_STRENGTH && (caps->has_get_level & RIG_LEVEL_STRENGTH) == 0 && rig_has_get_level(rig, RIG_LEVEL_RAWSTR) && rs->str_cal.size) { value_t rawstr; retcode = rig_get_level(rig, vfo, RIG_LEVEL_RAWSTR, &rawstr); if (retcode != RIG_OK) { rig_lock(rig, 0); return retcode; } val->i = (int)rig_raw2val(rawstr.i, &rs->str_cal); rig_lock(rig, 0); return RIG_OK; } if ((caps->targetable_vfo & RIG_TARGETABLE_LEVEL) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { retcode = caps->get_level(rig, vfo, level, val); rig_lock(rig, 0); return retcode; } if (!caps->set_vfo) { rig_lock(rig, 0); return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { rig_lock(rig, 0); return retcode; } retcode = caps->get_level(rig, vfo, level, val); caps->set_vfo(rig, curr_vfo); rig_lock(rig, 0); return retcode; } /** * \brief set a radio parameter * \param rig The rig handle * \param parm The parameter * \param val The value to set the parameter * * Sets a parameter. * The parameter value \a val can be a float or an integer. See #value_t * for more information. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_set_parm(), rig_get_parm() */ int HAMLIB_API rig_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } if (rig->caps->set_parm == NULL || !rig_has_set_parm(rig, parm)) { return -RIG_ENAVAIL; } return rig->caps->set_parm(rig, parm, val); } /** * \brief get the value of a parameter * \param rig The rig handle * \param parm The parameter * \param val The location where to store the value of \a parm * * Retrieves the value of a \a parm. * The parameter value \a val can be a float or an integer. See #value_t * for more information. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_get_parm(), rig_set_parm() */ int HAMLIB_API rig_get_parm(RIG *rig, setting_t parm, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !val) { return -RIG_EINVAL; } if (rig->caps->get_parm == NULL || !rig_has_get_parm(rig, parm)) { return -RIG_ENAVAIL; } return rig->caps->get_parm(rig, parm, val); } /** * \brief check retrieval ability of level settings * \param rig The rig handle * \param level The level settings * * Checks if a rig is capable of *getting* a level setting. * Since the \a level is an OR'ed bitwise argument, more than * one level can be checked at the same time. * * EXAMPLE: if (rig_has_get_level(my_rig, RIG_LVL_STRENGTH)) disp_Smeter(); * * \return a bit map of supported level settings that can be retrieved, * otherwise 0 if none supported. * * \sa rig_has_set_level(), rig_get_level() */ setting_t HAMLIB_API rig_has_get_level(RIG *rig, setting_t level) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_get_level & level); } /** * \brief check settable ability of level settings * \param rig The rig handle * \param level The level settings * * Checks if a rig can *set* a level setting. * Since the \a level is an OR'ed bitwise argument, more than * one level can be check at the same time. * * EXAMPLE: if (rig_has_set_level(my_rig, RIG_LVL_RFPOWER)) crank_tx(); * * \return a bit map of supported level settings that can be set, * otherwise 0 if none supported. * * \sa rig_has_get_level(), rig_set_level() */ setting_t HAMLIB_API rig_has_set_level(RIG *rig, setting_t level) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_set_level & level); } /** * \brief check retrieval ability of parameter settings * \param rig The rig handle * \param parm The parameter settings * * Checks if a rig is capable of *getting* a parm setting. * Since the \a parm is an OR'ed bitwise argument, more than * one parameter can be checked at the same time. * * EXAMPLE: if (rig_has_get_parm(my_rig, RIG_PARM_ANN)) good4you(); * * \return a bit map of supported parameter settings that can be retrieved, * otherwise 0 if none supported. * * \sa rig_has_set_parm(), rig_get_parm() */ setting_t HAMLIB_API rig_has_get_parm(RIG *rig, setting_t parm) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_get_parm & parm); } /** * \brief check settable ability of parameter settings * \param rig The rig handle * \param parm The parameter settings * * Checks if a rig can *set* a parameter setting. * Since the \a parm is an OR'ed bitwise argument, more than * one parameter can be check at the same time. * * EXAMPLE: if (rig_has_set_parm(my_rig, RIG_PARM_ANN)) announce_all(); * * \return a bit map of supported parameter settings that can be set, * otherwise 0 if none supported. * * \sa rig_has_get_parm(), rig_set_parm() */ setting_t HAMLIB_API rig_has_set_parm(RIG *rig, setting_t parm) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_set_parm & parm); } /** * \brief check ability of radio functions * \param rig The rig handle * \param func The functions * * Checks if a rig supports a set of functions. * Since the \a func is an OR'ed bitwise argument, more than * one function can be checked at the same time. * * EXAMPLE: if (rig_has_get_func(my_rig,RIG_FUNC_FAGC)) disp_fagc_button(); * * \return a bit map of supported functions, * otherwise 0 if none supported. * * \sa rig_has_set_func(), rig_get_func() */ setting_t HAMLIB_API rig_has_get_func(RIG *rig, setting_t func) { // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_get_func & func); } /** * \brief check ability of radio functions * \param rig The rig handle * \param func The functions * * Checks if a rig supports a set of functions. * Since the \a func is an OR'ed bitwise argument, more than * one function can be checked at the same time. * * EXAMPLE: if (rig_has_set_func(my_rig,RIG_FUNC_FAGC)) disp_fagc_button(); * * \return a bit map of supported functions, * otherwise 0 if none supported. * * \sa rig_set_func(), rig_has_get_func() */ setting_t HAMLIB_API rig_has_set_func(RIG *rig, setting_t func) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return 0; } return (STATE(rig)->has_set_func & func); } /** * \brief activate/de-activate functions of radio * \param rig The rig handle * \param vfo The target VFO * \param func The functions to activate * \param status The status (on or off) to set to * * Activate/de-activate a function of the radio. * * The \a status argument is a non null value for "activate", * "de-activate" otherwise, much as TRUE/FALSE definitions in C language. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_func() */ int HAMLIB_API rig_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if ((caps->set_func == NULL || !rig_has_set_func(rig, func)) && access(rs->tuner_control_pathname, X_OK) == -1) { return -RIG_ENAVAIL; } if (access(rs->tuner_control_pathname, X_OK) != -1) { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s %d", rs->tuner_control_pathname, status); rig_debug(RIG_DEBUG_TRACE, "%s: Calling external script '%s'\n", __func__, rs->tuner_control_pathname); retcode = system(cmd); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "%s: executing %s failed\n", __func__, rs->tuner_control_pathname); } return (retcode == 0 ? RIG_OK : -RIG_ERJCTED); } else { if (strcmp(rs->tuner_control_pathname, "hamlib_tuner_control")) { rig_debug(RIG_DEBUG_ERR, "%s: unable to find '%s'\n", __func__, rs->tuner_control_pathname); return -RIG_EINVAL; } } if ((caps->targetable_vfo & RIG_TARGETABLE_FUNC) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->set_func(rig, vfo, func, status); } else { int targetable = caps->targetable_vfo & RIG_TARGETABLE_FUNC; rig_debug(RIG_DEBUG_TRACE, "%s: targetable=%d, vfo=%s, currvfo=%s\n", __func__, targetable, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_func(rig, vfo, func, status); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the status of functions of the radio * \param rig The rig handle * \param vfo The target VFO * \param func The functions to get the status * \param status The location where to store the function status * * Retrieves the status (on/off) of a function of the radio. * Upon return, \a status will hold the status of the function, * The value pointer to by the \a status argument is a non null * value for "on", "off" otherwise, much as TRUE/FALSE * definitions in C language. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_func() */ int HAMLIB_API rig_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int retcode; vfo_t curr_vfo; // too verbose //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !func) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_func == NULL || !rig_has_get_func(rig, func)) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_FUNC) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { return caps->get_func(rig, vfo, func, status); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_func(rig, vfo, func, status); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set a radio level extra parameter * \param rig The rig handle * \param vfo The target VFO * \param token The parameter * \param val The value to set the parameter to * * Sets an level extra parameter. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ext_level() */ int HAMLIB_API rig_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_ext_level == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_LEVEL) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->set_ext_level(rig, vfo, token, val); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_ext_level(rig, vfo, token, val); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the value of a level extra parameter * \param rig The rig handle * \param vfo The target VFO * \param token The parameter * \param val The location where to store the value of \a token * * Retrieves the value of a level extra parameter associated with \a token. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ext_level() */ int HAMLIB_API rig_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !val) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_ext_level == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_LEVEL) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->get_ext_level(rig, vfo, token, val); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_ext_level(rig, vfo, token, val); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set a radio function extra parameter * \param rig The rig handle * \param vfo The target VFO * \param token The parameter * \param status The value to set the parameter to * * Sets a function extra parameter. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ext_func() */ int HAMLIB_API rig_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } caps = rig->caps; if (caps->set_ext_func == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_FUNC) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->set_ext_func(rig, vfo, token, status); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->set_ext_func(rig, vfo, token, status); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief get the value of a function extra parameter * \param rig The rig handle * \param vfo The target VFO * \param token The parameter * \param status The location where to store the value of \a token * * Retrieves the value of a function extra parameter associated with \a token. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ext_func() */ int HAMLIB_API rig_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { const struct rig_caps *caps; int retcode; vfo_t curr_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !status) { return -RIG_EINVAL; } caps = rig->caps; if (caps->get_ext_func == NULL) { return -RIG_ENAVAIL; } if ((caps->targetable_vfo & RIG_TARGETABLE_FUNC) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { return caps->get_ext_func(rig, vfo, token, status); } if (!caps->set_vfo) { return -RIG_ENTARGET; } curr_vfo = STATE(rig)->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { return retcode; } retcode = caps->get_ext_func(rig, vfo, token, status); caps->set_vfo(rig, curr_vfo); return retcode; } /** * \brief set a radio parm extra parameter * \param rig The rig handle * \param token The parameter * \param val The value to set the parameter to * * Sets an parm extra parameter. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ext_parm() */ int HAMLIB_API rig_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig)) { return -RIG_EINVAL; } if (rig->caps->set_ext_parm == NULL) { return -RIG_ENAVAIL; } return rig->caps->set_ext_parm(rig, token, val); } /** * \brief get the value of a parm extra parameter * \param rig The rig handle * \param token The parameter * \param val The location where to store the value of \a token * * Retrieves the value of a parm extra parameter associated with \a token. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ext_parm() */ int HAMLIB_API rig_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (CHECK_RIG_ARG(rig) || !val) { return -RIG_EINVAL; } if (rig->caps->get_ext_parm == NULL) { return -RIG_ENAVAIL; } return rig->caps->get_ext_parm(rig, token, val); } /** * \brief basically convert setting_t expressed 2^n to n * \param s The setting to convert to * * Converts a setting_t value expressed by 2^n to the value of n. * * \return the index such that 2^n is the setting, otherwise 0 * if the setting was not found. */ int HAMLIB_API rig_setting2idx(setting_t s) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; i < RIG_SETTING_MAX; i++) { if (s & rig_idx2setting(i)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: idx=%d\n", __func__, i); return i; } } return 0; } #include /* UNIX standard function definitions */ #if 0 #include #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #include #include #endif #define SETTINGS_FILE "hamlib_settings" char settings_file[4096]; HAMLIB_EXPORT(int) rig_settings_get_path(char *path, int pathlen) { char cwd[4096]; if (getcwd(cwd, 4096) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: getcwd: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } #ifdef APPLE //#include "TargetConditionals.h" #ifdef TARGET_OS_IPHONE // iOS #elif TARGET_IPHONE_SIMULATOR // iOS Simulator #elif TARGET_OS_MAC // Other kinds of Mac OS #else // Unsupported platform #endif #endif const char *xdgpath = getenv("XDG_CONFIG_HOME"); char *home = getenv("HOME"); if (home == NULL) { home = getenv("HOMEPATH"); } if (home == NULL) { home = "?HOME"; } snprintf(path, pathlen, "%s/.config", home); if (xdgpath) { snprintf(path, pathlen - 1, "%s/%s", xdgpath, HAMLIB_SETTINGS_FILE); } else if (home && access(path, F_OK) != -1) { snprintf(path, pathlen - 1, "%s/.config/%s", home, HAMLIB_SETTINGS_FILE); } else if (home) { // we add a leading period to hide the file snprintf(path, pathlen - 1, "%s/.%s", home, HAMLIB_SETTINGS_FILE); } else { snprintf(path, pathlen - 1, ".%s", HAMLIB_SETTINGS_FILE); } rig_debug(RIG_DEBUG_TRACE, "%s: path=%s\n", __func__, path); return RIG_OK; } /** * \brief Save setting parameter * \param setting * \param value * \return RIG_OK or error * * \sa rig_setting_load() */ HAMLIB_EXPORT(int) rig_settings_save(const char *setting, void *value, settings_value_t valuetype) { FILE *fp; FILE *fptmp; char path[4096]; char buf[4096]; char *cvalue = (char *)value; int *ivalue = (int *)value; int n = 0; long *lvalue = (long *) value; float *fvalue = (float *) value; double *dvalue = (double *) value; char *vformat = "Unknown format??"; char template[64]; rig_settings_get_path(path, sizeof(path)); fp = fopen(path, "r"); if (fp == NULL) { rig_debug(RIG_DEBUG_WARN, "%s: %s not found\n", __func__, path); return -RIG_EIO; } strcpy(template, "hamlib_settings_XXXXXX"); switch (valuetype) { case e_CHAR: cvalue = (char *)value; vformat = "%s=%s\n"; break; case e_INT: ivalue = (int *)value; vformat = "%s=%d\n"; break; case e_LONG: lvalue = (long *)value; vformat = "%s=%l\n"; break; case e_FLOAT: fvalue = (float *)value; vformat = "%s=%f\n"; break; case e_DOUBLE: dvalue = (double *)value; vformat = "%s=%f\n"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown valuetype=%d\n", __func__, valuetype); } if (fp == NULL) { // first time for this file fp = fopen(settings_file, "w"); switch (valuetype) { case e_CHAR: fprintf(fp, vformat, setting, cvalue); break; case e_INT: fprintf(fp, vformat, setting, *ivalue); break; case e_LONG: fprintf(fp, vformat, setting, *lvalue); break; case e_FLOAT: fprintf(fp, vformat, setting, *fvalue); break; case e_DOUBLE: fprintf(fp, vformat, setting, *dvalue); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown valuetype=%d\n", __func__, valuetype); } fclose(fp); return RIG_OK; } int fd = mkstemp(template); close(fd); fptmp = fopen(template, "w"); if (fptmp == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error opening for write %s: %s\n", __func__, template, strerror(errno)); fclose(fp); return -RIG_EIO; } while (fgets(buf, sizeof(buf), fp)) { char *tmp = strdup(buf); char *s = strtok(tmp, "="); if (buf[0] == '#') { fprintf(fptmp, "%s\n", buf); continue; } if (s == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse setting from '%s'\n", __func__, strtok(buf, "\r\n")); fclose(fp); fclose(fptmp); return -RIG_EINTERNAL; } ++n; char *v = strtok(NULL, "\r\n"); if (v == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse value from '%s'\n", __func__, strtok(buf, "\r\n")); fclose(fp); fclose(fptmp); return -RIG_EINTERNAL; } rig_debug(RIG_DEBUG_TRACE, "%s: parsing setting %s=%s\n", __func__, s, v); fprintf(fptmp, vformat, s, value); } fclose(fp); fclose(fptmp); remove(settings_file); rename(template, settings_file); rig_debug(RIG_DEBUG_TRACE, "%s: %d settings read\n", __func__, n); return -RIG_ENIMPL; } HAMLIB_EXPORT(int) rig_settings_load(char *setting, void *value, settings_value_t valuetype) { return -RIG_ENIMPL; } HAMLIB_EXPORT(int) rig_settings_load_all(char *settings_file) { FILE *fp; char buf[4096]; char settingstmp[4096]; if (settings_file == NULL) { rig_settings_get_path(settingstmp, sizeof(settingstmp)); settings_file = settingstmp; } fp = fopen(settings_file, "r"); if (fp == NULL) { #if 0 // until we actually implement this rig_debug(RIG_DEBUG_VERBOSE, "%s: settings_file (%s): %s\n", __func__, settings_file, strerror(errno)); return -RIG_EINVAL; #else return RIG_OK; #endif } rig_debug(RIG_DEBUG_TRACE, "%s: opened %s\n", __func__, settings_file); while (fgets(buf, sizeof(buf), fp)) { const char *s = strtok(buf, "="); const char *v = strtok(NULL, "\r\n"); if (strcmp(s, "sharedkey") == 0) { char *sharedkey = strdup(v); rig_debug(RIG_DEBUG_TRACE, "%s: settings_file=%s, shared_key=%s\n", __func__, settings_file, sharedkey); free(sharedkey); } } return RIG_OK; } /*! @} */ hamlib-4.6.5/src/Makefile.in0000664000175000017500000010450515056640454011317 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @VERSIONDLL_TRUE@am__append_1 = \ @VERSIONDLL_TRUE@ version_dll.rc subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = am__libhamlib_la_SOURCES_DIST = hamlibdatetime.h rig.c serial.c \ serial.h misc.c misc.h register.c register.h event.c event.h \ cal.c cal.h conf.c tones.c tones.h rotator.c locator.c \ rot_reg.c rot_conf.c rot_conf.h rot_settings.c rot_ext.c \ iofunc.c iofunc.h ext.c mem.c settings.c parallel.c parallel.h \ usb_port.c usb_port.h debug.c network.c network.h cm108.c \ cm108.h gpio.c gpio.h idx_builtin.h token.h par_nt.h \ microham.c microham.h amplifier.c amp_reg.c amp_conf.c \ amp_conf.h amp_settings.c extamp.c sleep.c sleep.h \ sprintflst.c sprintflst.h cache.c cache.h snapshot_data.c \ snapshot_data.h fifo.c fifo.h serial_cfg_params.h mutex.h \ version_dll.rc @VERSIONDLL_TRUE@am__objects_1 = version_dll.lo am__objects_2 = rig.lo serial.lo misc.lo register.lo event.lo cal.lo \ conf.lo tones.lo rotator.lo locator.lo rot_reg.lo rot_conf.lo \ rot_settings.lo rot_ext.lo iofunc.lo ext.lo mem.lo settings.lo \ parallel.lo usb_port.lo debug.lo network.lo cm108.lo gpio.lo \ microham.lo amplifier.lo amp_reg.lo amp_conf.lo \ amp_settings.lo extamp.lo sleep.lo sprintflst.lo cache.lo \ snapshot_data.lo fifo.lo $(am__objects_1) am_libhamlib_la_OBJECTS = $(am__objects_2) libhamlib_la_OBJECTS = $(am_libhamlib_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libhamlib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libhamlib_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/amp_conf.Plo ./$(DEPDIR)/amp_reg.Plo \ ./$(DEPDIR)/amp_settings.Plo ./$(DEPDIR)/amplifier.Plo \ ./$(DEPDIR)/cache.Plo ./$(DEPDIR)/cal.Plo \ ./$(DEPDIR)/cm108.Plo ./$(DEPDIR)/conf.Plo \ ./$(DEPDIR)/debug.Plo ./$(DEPDIR)/event.Plo \ ./$(DEPDIR)/ext.Plo ./$(DEPDIR)/extamp.Plo \ ./$(DEPDIR)/fifo.Plo ./$(DEPDIR)/gpio.Plo \ ./$(DEPDIR)/iofunc.Plo ./$(DEPDIR)/locator.Plo \ ./$(DEPDIR)/mem.Plo ./$(DEPDIR)/microham.Plo \ ./$(DEPDIR)/misc.Plo ./$(DEPDIR)/network.Plo \ ./$(DEPDIR)/parallel.Plo ./$(DEPDIR)/register.Plo \ ./$(DEPDIR)/rig.Plo ./$(DEPDIR)/rot_conf.Plo \ ./$(DEPDIR)/rot_ext.Plo ./$(DEPDIR)/rot_reg.Plo \ ./$(DEPDIR)/rot_settings.Plo ./$(DEPDIR)/rotator.Plo \ ./$(DEPDIR)/serial.Plo ./$(DEPDIR)/settings.Plo \ ./$(DEPDIR)/sleep.Plo ./$(DEPDIR)/snapshot_data.Plo \ ./$(DEPDIR)/sprintflst.Plo ./$(DEPDIR)/tones.Plo \ ./$(DEPDIR)/usb_port.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_la_SOURCES) DIST_SOURCES = $(am__libhamlib_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BUILT_SOURCES = $(builddir)/hamlibdatetime.h DISTCLEANFILES = hamlibdatetime.h RIGSRC = hamlibdatetime.h rig.c serial.c serial.h misc.c misc.h \ register.c register.h event.c event.h cal.c cal.h conf.c \ tones.c tones.h rotator.c locator.c rot_reg.c rot_conf.c \ rot_conf.h rot_settings.c rot_ext.c iofunc.c iofunc.h ext.c \ mem.c settings.c parallel.c parallel.h usb_port.c usb_port.h \ debug.c network.c network.h cm108.c cm108.h gpio.c gpio.h \ idx_builtin.h token.h par_nt.h microham.c microham.h \ amplifier.c amp_reg.c amp_conf.c amp_conf.h amp_settings.c \ extamp.c sleep.c sleep.h sprintflst.c sprintflst.h cache.c \ cache.h snapshot_data.c snapshot_data.h fifo.c fifo.h \ serial_cfg_params.h mutex.h $(am__append_1) lib_LTLIBRARIES = libhamlib.la libhamlib_la_SOURCES = $(RIGSRC) $(VERSIONDLL) libhamlib_la_LDFLAGS = $(WINLDFLAGS) $(OSXLDFLAGS) -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) libhamlib_la_LIBADD = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/libsecurity.la \ $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS) $(INDI_LIBS) libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/libsecurity.la $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) EXTRA_DIST = Android.mk hamlibdatetime.h.in band_changed.c RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .mc .o .obj .rc $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib.la: $(libhamlib_la_OBJECTS) $(libhamlib_la_DEPENDENCIES) $(EXTRA_libhamlib_la_DEPENDENCIES) $(AM_V_CCLD)$(libhamlib_la_LINK) -rpath $(libdir) $(libhamlib_la_OBJECTS) $(libhamlib_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amp_conf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amp_reg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amp_settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amplifier.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cal.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cm108.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extamp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iofunc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/microham.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/register.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rig.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_conf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_ext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_reg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serial.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sleep.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snapshot_data.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprintflst.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tones.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usb_port.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/amp_conf.Plo -rm -f ./$(DEPDIR)/amp_reg.Plo -rm -f ./$(DEPDIR)/amp_settings.Plo -rm -f ./$(DEPDIR)/amplifier.Plo -rm -f ./$(DEPDIR)/cache.Plo -rm -f ./$(DEPDIR)/cal.Plo -rm -f ./$(DEPDIR)/cm108.Plo -rm -f ./$(DEPDIR)/conf.Plo -rm -f ./$(DEPDIR)/debug.Plo -rm -f ./$(DEPDIR)/event.Plo -rm -f ./$(DEPDIR)/ext.Plo -rm -f ./$(DEPDIR)/extamp.Plo -rm -f ./$(DEPDIR)/fifo.Plo -rm -f ./$(DEPDIR)/gpio.Plo -rm -f ./$(DEPDIR)/iofunc.Plo -rm -f ./$(DEPDIR)/locator.Plo -rm -f ./$(DEPDIR)/mem.Plo -rm -f ./$(DEPDIR)/microham.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/network.Plo -rm -f ./$(DEPDIR)/parallel.Plo -rm -f ./$(DEPDIR)/register.Plo -rm -f ./$(DEPDIR)/rig.Plo -rm -f ./$(DEPDIR)/rot_conf.Plo -rm -f ./$(DEPDIR)/rot_ext.Plo -rm -f ./$(DEPDIR)/rot_reg.Plo -rm -f ./$(DEPDIR)/rot_settings.Plo -rm -f ./$(DEPDIR)/rotator.Plo -rm -f ./$(DEPDIR)/serial.Plo -rm -f ./$(DEPDIR)/settings.Plo -rm -f ./$(DEPDIR)/sleep.Plo -rm -f ./$(DEPDIR)/snapshot_data.Plo -rm -f ./$(DEPDIR)/sprintflst.Plo -rm -f ./$(DEPDIR)/tones.Plo -rm -f ./$(DEPDIR)/usb_port.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/amp_conf.Plo -rm -f ./$(DEPDIR)/amp_reg.Plo -rm -f ./$(DEPDIR)/amp_settings.Plo -rm -f ./$(DEPDIR)/amplifier.Plo -rm -f ./$(DEPDIR)/cache.Plo -rm -f ./$(DEPDIR)/cal.Plo -rm -f ./$(DEPDIR)/cm108.Plo -rm -f ./$(DEPDIR)/conf.Plo -rm -f ./$(DEPDIR)/debug.Plo -rm -f ./$(DEPDIR)/event.Plo -rm -f ./$(DEPDIR)/ext.Plo -rm -f ./$(DEPDIR)/extamp.Plo -rm -f ./$(DEPDIR)/fifo.Plo -rm -f ./$(DEPDIR)/gpio.Plo -rm -f ./$(DEPDIR)/iofunc.Plo -rm -f ./$(DEPDIR)/locator.Plo -rm -f ./$(DEPDIR)/mem.Plo -rm -f ./$(DEPDIR)/microham.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/network.Plo -rm -f ./$(DEPDIR)/parallel.Plo -rm -f ./$(DEPDIR)/register.Plo -rm -f ./$(DEPDIR)/rig.Plo -rm -f ./$(DEPDIR)/rot_conf.Plo -rm -f ./$(DEPDIR)/rot_ext.Plo -rm -f ./$(DEPDIR)/rot_reg.Plo -rm -f ./$(DEPDIR)/rot_settings.Plo -rm -f ./$(DEPDIR)/rotator.Plo -rm -f ./$(DEPDIR)/serial.Plo -rm -f ./$(DEPDIR)/settings.Plo -rm -f ./$(DEPDIR)/sleep.Plo -rm -f ./$(DEPDIR)/snapshot_data.Plo -rm -f ./$(DEPDIR)/sprintflst.Plo -rm -f ./$(DEPDIR)/tones.Plo -rm -f ./$(DEPDIR)/usb_port.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: all check install install-am install-exec install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ ctags ctags-am dist-hook distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile # Rule to build the dependencies of libhamlib.la that are in other directories $(libhamlib_la_DEPENDENCIES): $(MAKE) -C $(@D) $(@F) # If we have a .git directory then we will generate the hamlibdate.h # file and replace it if it is different. Fall back to a copy of a # generic hamlibdatetime.h.in in the source tree. Build looks in build # directory before the source directory for the hamlibdatetime.h # header. hamlibdatetime.h: FORCE @if test -x $(top_srcdir)/.git ; then \ echo "/* This date time is from the last non-merge commit to Hamlib. */" > $(builddir)/$(@F).tmp ;\ echo "#define HAMLIBDATETIME "\"$$(TZ=UTC git --git-dir=$(top_srcdir)/.git log --no-merges --date='format-local:%Y-%m-%dT%H:%M:%SZ SHA=' --format='%cd' -n 1)$$(git --git-dir=$(top_srcdir)/.git log --no-merges -n 1 | head -n 1 | cut -c8-13)\" >> $(builddir)/$(@F).tmp ;\ diff -qN $(builddir)/$(@F).tmp $(builddir)/$(@F) ; test $$? -eq 0 || { echo "Generating SCS header \"$(builddir)/$(@F)\"" ; mv -f $(builddir)/$(@F).tmp $(builddir)/$(@F) ; } ;\ rm -f $(builddir)/$(@F).tmp ;\ touch -c $(top_srcdir)/src/version_dll.rc ;\ else \ test -f $(srcdir)/$(@F) || cp $(srcdir)/$(@F).in $(srcdir)/$(@F) ;\ fi .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" .rc.o: $(RCCOMPILE) -O coff -i "$<" -o "$@" .mc.rc: $(WINDMC) "$<" #version.la: version.rc # windres $(srcdir)/version.rc -o $(builddir)/version.o FORCE: # If we are making a distribution out-of-source and we have generated # a hamlibdatetime.h; then copy it to the tests directory of the # source tarball so that downstream builds pick up the version # information we know about. dist-hook: test ./ -ef $(srcdir)/ || test ! -f hamlibdatetime.h || cp -f hamlibdatetime.h $(srcdir)/ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/src/amp_reg.c0000664000175000017500000002176415056640443011033 /* * Hamlib Interface - provides registering for dynamically loadable backends. * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \brief Dynamic registration of amplifier backends * \file amp_reg.c * * Similar to register.c * doc todo: Let's explain what's going on here! */ #include #include #include #include #include #include #include #include "register.h" //! @cond Doxygen_Suppress #ifndef PATH_MAX # define PATH_MAX 1024 #endif #define AMP_BACKEND_MAX 32 #define DEFINE_INITAMP_BACKEND(backend) \ int MAKE_VERSIONED_FN(PREFIX_INITAMPS, \ ABI_VERSION, \ backend(void *be_handle)); \ rig_model_t MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, \ ABI_VERSION, \ backend(hamlib_port_t *port, \ rig_probe_func_t cfunc, \ rig_ptr_t data)) #define AMP_FUNCNAMA(backend) MAKE_VERSIONED_FN(PREFIX_INITAMPS, ABI_VERSION, backend) #define AMP_FUNCNAMB(backend) MAKE_VERSIONED_FN(PREFIX_PROBEAMPS, ABI_VERSION, backend) #define AMP_FUNCNAM(backend) AMP_FUNCNAMA(backend),AMP_FUNCNAMB(backend) DEFINE_INITAMP_BACKEND(dummy); DEFINE_INITAMP_BACKEND(kpa1500); DEFINE_INITAMP_BACKEND(gemini); DEFINE_INITAMP_BACKEND(expert); //! @endcond /** * \def amp_backend_list * \brief Static list of amplifier models. * * This is a NULL terminated list of available amplifier backends. Each entry * in the list consists of two fields: The branch number, which is an integer, * and the branch name, which is a character string. * An external library, loaded dynamically, could add its own functions * pointers in this array. */ static struct { int be_num; const char *be_name; int (*be_init)(void *); amp_model_t (*be_probe)(hamlib_port_t *); } amp_backend_list[AMP_BACKEND_MAX] = { { AMP_DUMMY, AMP_BACKEND_DUMMY, AMP_FUNCNAMA(dummy) }, { AMP_ELECRAFT, AMP_BACKEND_ELECRAFT, AMP_FUNCNAMA(kpa1500) }, { AMP_GEMINI, AMP_BACKEND_GEMINI, AMP_FUNCNAMA(gemini) }, { AMP_EXPERT, AMP_BACKEND_EXPERT, AMP_FUNCNAMA(expert) }, { 0, NULL }, /* end */ }; // Apparently, no amplifier can be probed. /* * AMP_BACKEND_LIST is here, please keep it up to date, * i.e. each time you implement a new backend. */ /* * This struct to keep track of known amp models. * It is chained, and used in a hash table, see below. */ //! @cond Doxygen_Suppress struct amp_list { const struct amp_caps *caps; struct amp_list *next; }; #define AMPLSTHASHSZ 16 #define HASH_FUNC(a) ((a)%AMPLSTHASHSZ) //! @endcond /* * The amp_hash_table is a hash table pointing to a list of next==NULL * terminated caps. */ static struct amp_list *amp_hash_table[AMPLSTHASHSZ] = { NULL, }; static int amp_lookup_backend(amp_model_t amp_model); /* * Basically, this is a hash insert function that doesn't check for dup! */ //! @cond Doxygen_Suppress int HAMLIB_API amp_register(const struct amp_caps *caps) { int hval; struct amp_list *p; if (!caps) { return -RIG_EINVAL; } amp_debug(RIG_DEBUG_VERBOSE, "amp_register (%d)\n", caps->amp_model); #ifndef DONT_WANT_DUP_CHECK if (amp_get_caps(caps->amp_model) != NULL) { return -RIG_EINVAL; } #endif p = (struct amp_list *)calloc(1, sizeof(struct amp_list)); if (!p) { return -RIG_ENOMEM; } hval = HASH_FUNC(caps->amp_model); p->caps = caps; // p->handle = NULL; p->next = amp_hash_table[hval]; amp_hash_table[hval] = p; return RIG_OK; } //! @endcond /* * Get amp capabilities. * i.e. amp_hash_table lookup */ //! @cond Doxygen_Suppress const struct amp_caps *HAMLIB_API amp_get_caps(amp_model_t amp_model) { struct amp_list *p; for (p = amp_hash_table[HASH_FUNC(amp_model)]; p; p = p->next) { if (p->caps->amp_model == amp_model) { return p->caps; } } return NULL; /* sorry, caps not registered! */ } //! @endcond /* * lookup for backend index in amp_backend_list table, * according to BACKEND_NUM * return -1 if not found. */ //! @cond Doxygen_Suppress static int amp_lookup_backend(amp_model_t amp_model) { int i; for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++) { if (AMP_BACKEND_NUM(amp_model) == amp_backend_list[i].be_num) { return i; } } return -1; } //! @endcond /* * amp_check_backend * check the backend declaring this model has been loaded * and if not loaded already, load it! * This permits seamless operation in amp_init. */ //! @cond Doxygen_Suppress int HAMLIB_API amp_check_backend(amp_model_t amp_model) { const struct amp_caps *caps; int be_idx; int retval; /* already loaded ? */ caps = amp_get_caps(amp_model); if (caps) { return RIG_OK; } be_idx = amp_lookup_backend(amp_model); /* * Never heard about this backend family! */ if (be_idx == -1) { amp_debug(RIG_DEBUG_VERBOSE, "%s: unsupported backend %d for model %d\n", __func__, AMP_BACKEND_NUM(amp_model), amp_model); return -RIG_ENAVAIL; } retval = amp_load_backend(amp_backend_list[be_idx].be_name); return retval; } //! @endcond //! @cond Doxygen_Suppress int HAMLIB_API amp_unregister(amp_model_t amp_model) { int hval; struct amp_list *p, *q; hval = HASH_FUNC(amp_model); q = NULL; for (p = amp_hash_table[hval]; p; p = p->next) { if (p->caps->amp_model == amp_model) { if (q == NULL) { amp_hash_table[hval] = p->next; } else { q->next = p->next; } free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* sorry, caps not registered! */ } //! @endcond /* * amp_list_foreach * executes cfunc on all the elements stored in the amp hash list */ //! @cond Doxygen_Suppress int HAMLIB_API amp_list_foreach(int (*cfunc)(const struct amp_caps *, rig_ptr_t), rig_ptr_t data) { struct amp_list *p; int i; if (!cfunc) { return -RIG_EINVAL; } for (i = 0; i < AMPLSTHASHSZ; i++) { for (p = amp_hash_table[i]; p; p = p->next) if ((*cfunc)(p->caps, data) == 0) { return RIG_OK; } } return RIG_OK; } //! @endcond /* * amp_probe_all * called straight by amp_probe */ //! @cond Doxygen_Suppress amp_model_t HAMLIB_API amp_probe_all(hamlib_port_t *p) { int i; amp_model_t amp_model; for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++) { if (amp_backend_list[i].be_probe) { amp_model = (*amp_backend_list[i].be_probe)(p); if (amp_model != AMP_MODEL_NONE) { return amp_model; } } } return AMP_MODEL_NONE; } //! @endcond //! @cond Doxygen_Suppress int amp_load_all_backends() { int i; for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++) { amp_load_backend(amp_backend_list[i].be_name); } return RIG_OK; } //! @endcond /* * amp_load_backend * Dynamically load a amp backend through dlopen mechanism */ //! @cond Doxygen_Suppress int HAMLIB_API amp_load_backend(const char *be_name) { int status; int (*be_init)(rig_ptr_t); int i; for (i = 0; i < AMP_BACKEND_MAX && amp_backend_list[i].be_name; i++) { if (!strcmp(be_name, amp_backend_list[i].be_name)) { be_init = amp_backend_list[i].be_init; if (be_init == NULL) { printf("Null\n"); return -EINVAL; } status = (*be_init)(NULL); return status; } } return -EINVAL; } //! @endcond hamlib-4.6.5/src/locator.c0000664000175000017500000005335015056640443011060 /* * Hamlib Interface - locator and bearing conversion calls * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2003 by Nate Bargmann * Copyright (c) 2003 by Dave Hines * * * Code to determine bearing and range was taken from the Great Circle, * by S. R. Sampson, N5OWK. * Ref: "Air Navigation", Air Force Manual 51-40, 1 February 1987 * Ref: "ARRL Satellite Experimenters Handbook", August 1990 * * Code to calculate distance and azimuth between two Maidenhead locators, * taken from wwl, by IK0ZSN Mirko Caserta. * * New bearing code added by N0NB was found at: * http://williams.best.vwh.net/avform.htm#Crs * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup utilities * @{ */ /** * \file src/locator.c * * \brief QRA locator (Maidenhead grid square) and latitude/longitude bearing * conversion interface. * * \author Stephane Fillod * \author Nate Bargmann * \author Dave Hines * \author The Hamlib Group * \date 2000-2020 */ /** * \page hamlib Hamlib general purpose API * * Hamlib function call interface for determining QRA locator (Maidenhead grid * square), bearing, and conversion between QRA locator and latitude/longitude * formats. * * \par Sources used in writing these routines * * \parblock * Code to determine bearing and range was taken from the Great Circle, * by Steven R. Sampson, N5OWK.
* Ref: "Air Navigation", Air Force Manual 51-40, 1 February 1987
* Ref: "ARRL Satellite Experimenters Handbook", August 1990 * * Code to calculate distance and azimuth between two QRA locators, taken from * wwl, by IK0ZSN, Mirko Caserta. * * New bearing code added by N0NB was found at: * http://williams.best.vwh.net/avform.htm#Crs * \endparblock */ #include #include #include #include #include #include /** \brief Standard definition of a radian. */ #define RADIAN (180.0 / M_PI) /** \brief arc length for 1 degree in kilometers, i.e. 60 Nautical Miles */ #define ARC_IN_KM 111.2 /* The following is contributed by Dave Hines M1CXW * * begin dph */ /* At this time documenting a single static variable as in loc_char_range[] * below is not supported by Doxygen. Hide this section until support exists * or a work-around becomes available. */ #ifndef DOC_HIDDEN /** * \brief Constants used when converting between Maidenhead grid * locators and longitude/latitude values. * * \ref MAX_LOCATOR_PAIRS is the maximum number of locator character pairs to * convert. This number MUST NOT exceed the number of pairs of values in * loc_char_range[]. Setting \ref MAX_LOCATOR_PAIRS to 3 will convert the * currently defined 6 character locators. A value of 4 will convert the * extended 8 character locators described in section 3L of "The IARU region 1 * VHF managers handbook". Values of 5 and 6 will extent the format even * more, to the longest definition I have seen for locators, see * http://www.btinternet.com/~g8yoa/geog/non-ra.html (currently a dead * link. -N0NB). Be aware that there seems to be no universally accepted * standard for 10 & 12 character locators. * * The ranges of characters which will be accepted by locator2longlat(), and * generated by longlat2locator(), are specified by the \ref loc_char_range[] * array. This array may be changed without requiring any other code changes. * * For the fifth pair to range from aa to xx use: * \code const static int loc_char_range[] = { 18, 10, 24, 10, 24, 10 };\endcode * * For the fifth pair to range from aa to yy use: * \code const static int loc_char_range[] = { 18, 10, 24, 10, 25, 10 };\endcode */ const static int loc_char_range[] = { 18, 10, 24, 10, 24, 10 }; #endif /* !DOC_HIDDEN */ /** \def MAX_LOCATOR_PAIRS * * \brief Longest locator to process, e.g. AA00AA00AA00. * * Sets the limit locator2longlat() will convert and sets the maximum length * longlat2locator() will generate. Each function properly handles any value * from `1` to `6` so \ref MAX_LOCATOR_PAIRS should be left at `6`. * * \def MIN_LOCATOR_PAIRS * * \brief Shortest locator to process, e.g. AA. * * Sets a floor on the shortest locator that should be handled. */ #define MAX_LOCATOR_PAIRS 6 #define MIN_LOCATOR_PAIRS 1 /* end dph */ /** * \brief Convert Degrees Minutes Seconds (DMS) notation to decimal degrees * (D.DDD) angle. * * \param degrees Degrees, whole degrees. * \param minutes Minutes, whole minutes. * \param seconds Seconds, decimal seconds. * \param sw South or West. * * Convert a Degrees Minutes Seconds (DMS) notation value to a decimal degrees * (D.DDD) angle value. * * \note For the parameters \a degrees >360, \a minutes > 60, and \a seconds > * 60.0 are allowed, but the resulting angle will not be normalized. * * When the variable \a sw is passed a value of 1, the returned decimal * degrees value will be negative (*South* or *West*). When passed a value of 0 * the returned decimal degrees value will be positive (*North* or *East*). * * \return The signed angle in decimal degrees (D.DDD). * * \sa dec2dms() */ double HAMLIB_API dms2dec(int degrees, int minutes, double seconds, int sw) { double st; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (degrees < 0) { degrees = abs(degrees); } if (minutes < 0) { minutes = abs(minutes); } if (seconds < 0) { seconds = fabs(seconds); } st = (double)degrees + (double)minutes / 60. + seconds / 3600.; if (sw == 1) { return -st; } else { return st; } } /** * \brief Convert degrees decimal minutes (D M.MMM) notation to decimal * degrees (D.DDD) angle. * * \param degrees Degrees, whole degrees. * \param minutes Minutes, decimal minutes. * \param seconds Seconds, decimal seconds. * \param sw South or West. * * Convert a degrees decimal minutes (D M.MMM) notation common on many GPS * units to a decimal degrees (D.DDD) angle value. * * \note For the parameters \a degrees > 360, \a minutes > 60.0, \a seconds > * 60.0 are allowed, but the resulting angle will not be normalized. * * When the variable \a sw is passed a value of 1, the returned decimal * degrees value will be negative (*South* or *West*). When passed a value of * 0 the returned decimal degrees value will be positive (*North* or *East*). * * \return The signed angle in decimal degrees (D.DDD). * * \sa dec2dmmm() */ double HAMLIB_API dmmm2dec(int degrees, double minutes, double seconds, int sw) { double st; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (degrees < 0) { degrees = abs(degrees); } if (minutes < 0) { minutes = fabs(minutes); } st = (double)degrees + (minutes / 60) + (seconds / 3600); if (sw == 1) { return -st; } else { return st; } } /** * \brief Convert a decimal degrees (D.DDD) angle into Degrees Minutes * Seconds (DMS) notation. * * \param dec Decimal degrees (D.DDD). * \param degrees Pointer for the calculated whole Degrees. * \param minutes Pointer for the calculated whole Minutes. * \param seconds Pointer for the calculated decimal Seconds. * \param sw Pointer for the calculated SW (South/West) flag. * * Convert decimal degrees angle (D.DDD) into its Degree Minute Second (DMS) * notation. * * When \a dec < -180 or \a dec > 180, the angle will be normalized within * these limits and the sign set appropriately. * * Upon return, guarantees 0 >= \a degrees <= 180, 0 >= \a minutes < 60, and * 0.0 >= \a seconds < 60.0. * * When \a dec is < 0.0 \a sw will be set to 1. When \a dec is >= 0.0 \a sw * will be set to 0. This flag allows the application to determine whether * the DMS angle should be treated as negative (*South* or *West*). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The conversion was successful. * \retval RIG_EINVAL Either of the pointers are NULL. * * \sa dms2dec() */ int HAMLIB_API dec2dms(double dec, int *degrees, int *minutes, double *seconds, int *sw) { int deg, min; double st; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* bail if NULL pointers passed */ if (!degrees || !minutes || !seconds || !sw) { return -RIG_EINVAL; } /* reverse the sign if dec has a magnitude greater * than 180 and factor out multiples of 360. * e.g. when passed 270 st will be set to -90 * and when passed -270 st will be set to 90. If * passed 361 st will be set to 1, etc. If passed * a value > -180 || < 180, value will be unchanged. */ if (dec >= 0.0) { st = fmod(dec + 180, 360) - 180; } else { st = fmod(dec - 180, 360) + 180; } /* if after all of that st is negative, we want deg * to be negative as well except for 180 which we want * to be positive. */ if (st < 0.0 && st != -180) { *sw = 1; } else { *sw = 0; } /* work on st as a positive value to remove a * bug introduced by the effect of floor() when * passed a negative value. e.g. when passed * -96.8333 floor() returns -95! Also avoids * a rounding error introduced on negative values. */ st = fabs(st); deg = (int)floor(st); st = 60. * (st - (double)deg); min = (int)floor(st); st = 60. * (st - (double)min); *degrees = deg; *minutes = min; *seconds = st; return RIG_OK; } /** * \brief Convert a decimal degrees (D.DDD) angle into degrees decimal minutes * (D M.MMM) notation. * * \param dec Decimal degrees angle. * \param degrees Pointer for the calculated whole Degrees. * \param minutes Pointer for the calculated decimal Minutes. * \param sw Pointer for the calculated SW flag. * * Convert a decimal angle into its degree, decimal minute * notation common on many GPS units. * * When passed a value < -180 or > 180, the value will be normalized * within these limits and the sign set appropriately. * * Upon return dec2dmmm guarantees 0 >= \a degrees <= 180, * 0.0 >= \a minutes < 60.0. * * When \a dec is < 0.0 \a sw will be set to 1. When \a dec is * >= 0.0 \a sw will be set to 0. This flag allows the application * to determine whether the D M.MMM angle should be treated as negative * (south or west). * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The conversion was successful. * \retval RIG_EINVAL Either of the pointers are NULL. * * \sa dmmm2dec() */ int HAMLIB_API dec2dmmm(double dec, int *degrees, double *minutes, int *sw) { int r, min; double sec; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* bail if NULL pointers passed */ if (!degrees || !minutes || !sw) { return -RIG_EINVAL; } r = dec2dms(dec, degrees, &min, &sec, sw); if (r != RIG_OK) { return r; } *minutes = (double)min + sec / 60; return RIG_OK; } /** * \brief Convert QRA locator (Maidenhead grid square) to Longitude/Latitude. * * \param longitude Pointer for the calculated Longitude. * \param latitude Pointer for the calculated Latitude. * \param locator The QRA locator--2 through 12 characters + nul string. * * Convert a QRA locator string to Longitude/Latitude in decimal degrees * (D.DDD). The locator should be 2 through 12 chars long format. * \a locator2longlat is case insensitive, however it checks for locator * validity. * * Decimal long/lat is computed to center of grid square, i.e. given * `EM19` will return coordinates equivalent to the southwest corner * of `EM19mm`. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The conversion was successful. * \retval RIG_EINVAL The QRA locator exceeds RR99xx99xx99 or exceeds length * limit--currently 1 to 6 lon/lat pairs--or is otherwise malformed. * * \bug The fifth pair ranges from aa to xx, there is another convention * that ranges from aa to yy. At some point both conventions should be * supported. * * \sa longlat2locator() */ /* begin dph */ int HAMLIB_API locator2longlat(double *longitude, double *latitude, const char *locator) { int x_or_y, paircount; int locvalue, pair; double xy[2]; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* bail if NULL pointers passed */ if (!longitude || !latitude) { return -RIG_EINVAL; } paircount = strlen(locator) / 2; /* verify paircount is within limits */ if (paircount > MAX_LOCATOR_PAIRS) { paircount = MAX_LOCATOR_PAIRS; } else if (paircount < MIN_LOCATOR_PAIRS) { return -RIG_EINVAL; } /* For x(=longitude) and y(=latitude) */ for (x_or_y = 0; x_or_y < 2; ++x_or_y) { double ordinate = -90.0; int divisions = 1; for (pair = 0; pair < paircount; ++pair) { locvalue = locator[pair * 2 + x_or_y]; /* Value of digit or letter */ locvalue -= (loc_char_range[pair] == 10) ? '0' : (isupper(locvalue)) ? 'A' : 'a'; /* Check range for non-letter/digit or out of range */ if ((locvalue < 0) || (locvalue >= loc_char_range[pair])) { return -RIG_EINVAL; } divisions *= loc_char_range[pair]; ordinate += locvalue * 180.0 / divisions; } /* Center ordinate in the Maidenhead "square" or "subsquare" */ ordinate += 90.0 / divisions; xy[x_or_y] = ordinate; } *longitude = xy[0] * 2.0; *latitude = xy[1]; return RIG_OK; } /* end dph */ /** * \brief Convert longitude/latitude to QRA locator (Maidenhead grid square). * * \param longitude Longitude, decimal degrees. * \param latitude Latitude, decimal degrees. * \param locator Pointer for the QRA Locator. * \param pair_count Requested precision expressed as lon/lat pairs in the * returned QRA locator string. * * Convert longitude/latitude given in decimal degrees (D.DDD) to a QRA * locator (Maidenhead grid square). \a locator must point to an array length * that is at least \a pair_count * 2 char + '\\0'. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The conversion was successful. * \retval RIG_EINVAL if \a locator is NULL or \a pair_count exceeds length * limit. Currently 1 to 6 lon/lat pairs. * * \bug \a locator is not tested for overflow. * \bug The fifth pair ranges from aa to yy, there is another convention * that ranges from aa to xx. At some point both conventions should be * supported. * * \sa locator2longlat() */ /* begin dph */ int HAMLIB_API longlat2locator(double longitude, double latitude, char *locator, int pair_count) { int x_or_y, pair, locvalue; double square_size; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!locator) { return -RIG_EINVAL; } if (pair_count < MIN_LOCATOR_PAIRS || pair_count > MAX_LOCATOR_PAIRS) { return -RIG_EINVAL; } for (x_or_y = 0; x_or_y < 2; ++x_or_y) { double ordinate = (x_or_y == 0) ? longitude / 2.0 : latitude; int divisions = 1; /* The 1e-6 here guards against floating point rounding errors */ ordinate = fmod(ordinate + 270.000001, 180.0); for (pair = 0; pair < pair_count; ++pair) { divisions *= loc_char_range[pair]; square_size = 180.0 / divisions; locvalue = (int)(ordinate / square_size); ordinate -= square_size * locvalue; locvalue += (loc_char_range[pair] == 10) ? '0' : 'A'; locator[pair * 2 + x_or_y] = locvalue; } } locator[pair_count * 2] = '\0'; return RIG_OK; } /* end dph */ /** * \brief Calculate the distance and bearing between two points. * * \param lon1 The local Longitude, decimal degrees. * \param lat1 The local Latitude, decimal degrees, * \param lon2 The remote Longitude, decimal degrees. * \param lat2 The remote Latitude, decimal degrees. * \param distance Pointer for the distance, km. * \param azimuth Pointer for the bearing, decimal degrees. * * Calculate the distance and bearing (QRB) between \a lon1, \a lat1 and * \a lon2, \a lat2. * * This version will calculate the QRB to a precision sufficient for 12 * character locators. Antipodal points, which are easily calculated, are * considered equidistant and the bearing is simply resolved to be true north, * e.g. \a azimuth = 0.0. * * \return RIG_OK if the operation has been successful, otherwise a **negative * value** if an error occurred (in which case, cause is set appropriately). * * \retval RIG_OK The calculations were successful. * \retval RIG_EINVAL If a NULL pointer passed or \a lat and \a lon values * exceed -90 to 90 or -180 to 180. * * \sa distance_long_path(), azimuth_long_path() */ int HAMLIB_API qrb(double lon1, double lat1, double lon2, double lat2, double *distance, double *azimuth) { double delta_long, tmp, arc, az; rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* bail if NULL pointers passed */ if (!distance || !azimuth) { return -RIG_EINVAL; } if ((lat1 > 90.0 || lat1 < -90.0) || (lat2 > 90.0 || lat2 < -90.0)) { return -RIG_EINVAL; } if ((lon1 > 180.0 || lon1 < -180.0) || (lon2 > 180.0 || lon2 < -180.0)) { return -RIG_EINVAL; } /* Prevent ACOS() Domain Error */ if (lat1 == 90.0) { lat1 = 89.999999999; } else if (lat1 == -90.0) { lat1 = -89.999999999; } if (lat2 == 90.0) { lat2 = 89.999999999; } else if (lat2 == -90.0) { lat2 = -89.999999999; } /* Convert variables to Radians */ lat1 /= RADIAN; lon1 /= RADIAN; lat2 /= RADIAN; lon2 /= RADIAN; delta_long = lon2 - lon1; tmp = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(delta_long); if (tmp > .999999999999999) { /* Station points coincide, use an Omni! */ *distance = 0.0; *azimuth = 0.0; return RIG_OK; } if (tmp < -.999999) { /* * points are antipodal, it's straight down. * Station is equal distance in all Azimuths. * So take 180 Degrees of arc times 60 nm, * and you get 10800 nm, or whatever units... */ *distance = 180.0 * ARC_IN_KM; *azimuth = 0.0; return RIG_OK; } arc = acos(tmp); /* * One degree of arc is 60 Nautical miles * at the surface of the earth, 111.2 km, or 69.1 sm * This method is easier than the one in the handbook */ *distance = ARC_IN_KM * RADIAN * arc; /* Short Path */ /* Change to azimuth computation by Dave Freese, W1HKJ */ az = RADIAN * atan2(sin(lon2 - lon1) * cos(lat2), (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1))); az = fmod(360.0 + az, 360.0); if (az < 0.0) { az += 360.0; } else if (az >= 360.0) { az -= 360.0; } *azimuth = floor(az + 0.5); return RIG_OK; } /** * \brief Calculate the long path distance between two points. * * \param distance The shortpath distance in kilometers. * * Calculate the long path (opposite bearing of the short path) of a given * distance. * * \return The distance in kilometers for the opposite path. * * \sa qrb() */ double HAMLIB_API distance_long_path(double distance) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return (ARC_IN_KM * 360.0) - distance; } /** * \brief Calculate the long path bearing between two points. * * \param azimuth The shortpath bearing--0.0 to 360.0 degrees. * * Calculate the long path (opposite of the short path) of a given bearing. * * \return the azimuth in decimal degrees for the opposite path or RIG_EINVAL * (negated value) upon input error (outside the range of 0.0 to 360.0). * * \sa qrb() */ double HAMLIB_API azimuth_long_path(double azimuth) { rot_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (azimuth == 0.0 || azimuth == 360.0) { return 180.0; } else if (azimuth > 0.0 && azimuth < 180.0) { return 180.0 + azimuth; } else if (azimuth == 180.0) { return 0.0; } else if (azimuth > 180.0 && azimuth < 360.0) { return (180.0 - azimuth) * -1.0; } else { return -RIG_EINVAL; } } /*! @} */ hamlib-4.6.5/src/event.c0000664000175000017500000005244615056640443010543 /* * Hamlib Interface - event handling * Copyright (c) 2021 by Mikael Nousiainen * Copyright (c) 2000-2010 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Doc todo: Verify assignment to rig group. Consider doc of internal rtns. */ /** * \addtogroup rig * @{ */ /** * \file event.c * \brief Event handling */ #include #include #include #include #include #include #ifdef HAVE_PTHREAD # include #endif #include #include "event.h" #include "misc.h" #include "cache.h" #include "network.h" #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state) #ifdef HAVE_PTHREAD typedef struct rig_poll_routine_args_s { RIG *rig; } rig_poll_routine_args; typedef struct rig_poll_routine_priv_data_s { pthread_t thread_id; rig_poll_routine_args args; } rig_poll_routine_priv_data; void *rig_poll_routine(void *arg) { rig_poll_routine_args *args = (rig_poll_routine_args *)arg; RIG *rig = args->rig; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); int update_occurred; vfo_t vfo = RIG_VFO_NONE, tx_vfo = RIG_VFO_NONE; freq_t freq_main_a = 0, freq_main_b = 0, freq_main_c = 0, freq_sub_a = 0, freq_sub_b = 0, freq_sub_c = 0; rmode_t mode_main_a = 0, mode_main_b = 0, mode_main_c = 0, mode_sub_a = 0, mode_sub_b = 0, mode_sub_c = 0; pbwidth_t width_main_a = 0, width_main_b = 0, width_main_c = 0, width_sub_a = 0, width_sub_b = 0, width_sub_c = 0; ptt_t ptt = RIG_PTT_OFF; split_t split = RIG_SPLIT_OFF; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting rig poll routine thread\n", __FILE__, __LINE__); // Rig cache time should be equal to rig poll interval (should be set automatically by rigctld at least) rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, rs->poll_interval); // Attempt to detect changes with the interval below (in milliseconds) int change_detection_interval = 50; int interval_count = 0; update_occurred = 0; network_publish_rig_poll_data(rig); while (rs->poll_routine_thread_run) { if (rs->current_vfo != vfo) { vfo = rs->current_vfo; update_occurred = 1; } if (rs->tx_vfo != tx_vfo) { tx_vfo = rs->tx_vfo; update_occurred = 1; } if (cachep->freqMainA != freq_main_a) { freq_main_a = cachep->freqMainA; update_occurred = 1; } if (cachep->freqMainB != freq_main_b) { freq_main_b = cachep->freqMainB; update_occurred = 1; } if (cachep->freqMainC != freq_main_c) { freq_main_b = cachep->freqMainC; update_occurred = 1; } if (cachep->freqSubA != freq_sub_a) { freq_sub_a = cachep->freqSubA; update_occurred = 1; } if (cachep->freqSubB != freq_sub_b) { freq_sub_b = cachep->freqSubB; update_occurred = 1; } if (cachep->freqSubC != freq_sub_c) { freq_sub_c = cachep->freqSubC; update_occurred = 1; } if (cachep->ptt != ptt) { ptt = cachep->ptt; update_occurred = 1; } if (cachep->split != split) { split = cachep->split; update_occurred = 1; } if (cachep->modeMainA != mode_main_a) { mode_main_a = cachep->modeMainA; update_occurred = 1; } if (cachep->modeMainB != mode_main_b) { mode_main_b = cachep->modeMainB; update_occurred = 1; } if (cachep->modeMainC != mode_main_c) { mode_main_c = cachep->modeMainC; update_occurred = 1; } if (cachep->modeSubA != mode_sub_a) { mode_sub_a = cachep->modeSubA; update_occurred = 1; } if (cachep->modeSubB != mode_sub_b) { mode_sub_b = cachep->modeSubB; update_occurred = 1; } if (cachep->modeSubC != mode_sub_c) { mode_sub_c = cachep->modeSubC; update_occurred = 1; } if (cachep->widthMainA != width_main_a) { width_main_a = cachep->widthMainA; update_occurred = 1; } if (cachep->widthMainB != width_main_b) { width_main_b = cachep->widthMainB; update_occurred = 1; } if (cachep->widthMainC != width_main_c) { width_main_c = cachep->widthMainC; update_occurred = 1; } if (cachep->widthSubA != width_sub_a) { width_sub_a = cachep->widthSubA; update_occurred = 1; } if (cachep->widthSubB != width_sub_b) { width_sub_b = cachep->widthSubB; update_occurred = 1; } if (cachep->widthSubC != width_sub_c) { width_sub_c = cachep->widthSubC; update_occurred = 1; } if (update_occurred) { network_publish_rig_poll_data(rig); update_occurred = 0; interval_count = 0; } hl_usleep(change_detection_interval * 1000); interval_count++; // Publish updates every poll_interval if no changes have been detected if (interval_count >= (rs->poll_interval / change_detection_interval)) { interval_count = 0; network_publish_rig_poll_data(rig); } } network_publish_rig_poll_data(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n", __FILE__, __LINE__); return NULL; } /** * \brief Start rig poll routine * * Start rig poll routine * * \return RIG_OK or < 0 if error */ int rig_poll_routine_start(RIG *rig) { struct rig_state *rs = STATE(rig); rig_poll_routine_priv_data *poll_routine_priv; ENTERFUNC; if (rs->poll_interval < 1) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig poll routine disabled, poll interval set to zero\n", __FILE__, __LINE__); RETURNFUNC(RIG_OK); } if (rs->poll_routine_priv_data != NULL) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig poll routine already running\n", __FILE__, __LINE__); RETURNFUNC(-RIG_EINVAL); } rs->poll_routine_thread_run = 1; rs->poll_routine_priv_data = calloc(1, sizeof(rig_poll_routine_priv_data)); if (rs->poll_routine_priv_data == NULL) { RETURNFUNC(-RIG_ENOMEM); } poll_routine_priv = (rig_poll_routine_priv_data *) rs->poll_routine_priv_data; poll_routine_priv->args.rig = rig; int err = pthread_create(&poll_routine_priv->thread_id, NULL, rig_poll_routine, &poll_routine_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error: %s\n", __FILE__, __LINE__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } network_publish_rig_poll_data(rig); RETURNFUNC(RIG_OK); } /** * \brief Stop rig poll routine * * Stop rig poll routine * * \return RIG_OK or < 0 if error */ int rig_poll_routine_stop(RIG *rig) { struct rig_state *rs = STATE(rig); rig_poll_routine_priv_data *poll_routine_priv; ENTERFUNC; if (rs->poll_interval < 1) { RETURNFUNC(RIG_OK); } if (rs->poll_routine_priv_data == NULL) { RETURNFUNC(-RIG_EINVAL); } rs->poll_routine_thread_run = 0; poll_routine_priv = (rig_poll_routine_priv_data *) rs->poll_routine_priv_data; if (poll_routine_priv->thread_id != 0) { int err = pthread_join(poll_routine_priv->thread_id, NULL); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d): pthread_join error %s\n", __FILE__, __LINE__, strerror(errno)); // just ignore it } poll_routine_priv->thread_id = 0; } network_publish_rig_poll_data(rig); free(rs->poll_routine_priv_data); rs->poll_routine_priv_data = NULL; RETURNFUNC(RIG_OK); } #endif /** * \brief set the callback for freq events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for freq events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_freq_callback(RIG *rig, freq_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.freq_event = cb; rig->callbacks.freq_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for mode events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for mode events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_mode_callback(RIG *rig, mode_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.mode_event = cb; rig->callbacks.mode_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for vfo events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for vfo events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_vfo_callback(RIG *rig, vfo_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.vfo_event = cb; rig->callbacks.vfo_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for ptt events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for ptt events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_ptt_callback(RIG *rig, ptt_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.ptt_event = cb; rig->callbacks.ptt_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for dcd events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for dcd events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_dcd_callback(RIG *rig, dcd_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.dcd_event = cb; rig->callbacks.dcd_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for pipelined tuning module * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * used to maintain state during pipelined tuning. * * Install a callback for pipelined tuning module, to be called when the * rig_scan( SCAN_PLT ) loop needs a new frequency, mode and width. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_pltune_callback(RIG *rig, pltune_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.pltune = cb; rig->callbacks.pltune_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief set the callback for spectrum line reception events * \param rig The rig handle * \param cb The callback to install * \param arg A Pointer to some private data to pass later on to the callback * * Install a callback for spectrum line reception events, to be called when in async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_spectrum_callback(RIG *rig, spectrum_cb_t cb, rig_ptr_t arg) { ENTERFUNC; if (CHECK_RIG_ARG(rig)) { RETURNFUNC(-RIG_EINVAL); } rig->callbacks.spectrum_event = cb; rig->callbacks.spectrum_arg = arg; RETURNFUNC(RIG_OK); } /** * \brief control the transceive mode * \param rig The rig handle * \param trn The transceive status to set to * * Enable/disable the transceive handling of a rig and kick off async mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_trn() * * \deprecated This functionality has never worked correctly and it is now disabled in favor of new async data handling capabilities. * The command will always return RIG_EDEPRECATED until the command will be removed eventually. */ int HAMLIB_API rig_set_trn(RIG *rig, int trn) { ENTERFUNC; RETURNFUNC(-RIG_EDEPRECATED); } /** * \brief get the current transceive mode * \param rig The rig handle * \param trn The location where to store the current transceive mode * * Retrieves the current status of the transceive mode, i.e. if radio * sends new status automatically when some changes happened on the radio. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_trn() * * \deprecated This functionality has never worked correctly and it is now disabled in favor of new async data handling capabilities. * The command will always return RIG_EDEPRECATED until the command will be removed eventually. */ int HAMLIB_API rig_get_trn(RIG *rig, int *trn) { ENTERFUNC; RETURNFUNC(-RIG_EDEPRECATED); } #if defined(HAVE_PTHREAD) int rig_fire_freq_event(RIG *rig, vfo_t vfo, freq_t freq) { ENTERFUNC; struct rig_state *rs = STATE(rig); double dfreq = freq; rig_debug(RIG_DEBUG_TRACE, "Event: freq changed to %.0f Hz on %s\n", dfreq, rig_strvfo(vfo)); rig_set_cache_freq(rig, vfo, freq); // This doesn't work well for Icom rigs -- no way to tell which VFO we're on // Should work for most other rigs using AI1; mode if (RIG_BACKEND_NUM(rig->caps->rig_model) != RIG_ICOM) { rs->use_cached_freq = 1; } if (rs->freq_event_elapsed.tv_sec == 0) { elapsed_ms(&rs->freq_event_elapsed, HAMLIB_ELAPSED_SET); } double e = elapsed_ms(&rs->freq_event_elapsed, HAMLIB_ELAPSED_GET); if (e >= 250) // throttle events to 4 per sec { elapsed_ms(&rs->freq_event_elapsed, HAMLIB_ELAPSED_SET); network_publish_rig_transceive_data(rig); if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg); } } RETURNFUNC(0); } #endif #if defined(HAVE_PTHREAD) int rig_fire_mode_event(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "Event: mode changed to %s, width %liHz on %s\n", rig_strrmode(mode), width, rig_strvfo(vfo)); rig_set_cache_mode(rig, vfo, mode, width); // This doesn't work well for Icom rigs -- no way to tell which VFO we're on // Should work for most other rigs using AI1; mode if (RIG_BACKEND_NUM(rig->caps->rig_model) != RIG_ICOM) { STATE(rig)->use_cached_mode = 1; } network_publish_rig_transceive_data(rig); if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, vfo, mode, width, rig->callbacks.mode_arg); } RETURNFUNC(0); } #endif #if defined(HAVE_PTHREAD) int rig_fire_vfo_event(RIG *rig, vfo_t vfo) { struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "Event: vfo changed to %s\n", rig_strvfo(vfo)); cachep->vfo = vfo; elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_SET); network_publish_rig_transceive_data(rig); if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } RETURNFUNC(0); } #endif #if defined(HAVE_PTHREAD) int rig_fire_ptt_event(RIG *rig, vfo_t vfo, ptt_t ptt) { struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "Event: PTT changed to %i on %s\n", ptt, rig_strvfo(vfo)); cachep->ptt = ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); network_publish_rig_transceive_data(rig); if (rig->callbacks.ptt_event) { rig->callbacks.ptt_event(rig, vfo, ptt, rig->callbacks.ptt_arg); } RETURNFUNC(0); } #endif #if defined(HAVE_PTHREAD) int rig_fire_dcd_event(RIG *rig, vfo_t vfo, dcd_t dcd) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "Event: DCD changed to %i on %s\n", dcd, rig_strvfo(vfo)); network_publish_rig_transceive_data(rig); if (rig->callbacks.dcd_event) { rig->callbacks.dcd_event(rig, vfo, dcd, rig->callbacks.dcd_arg); } RETURNFUNC(0); } #endif #if defined(HAVE_PTHREAD) int rig_fire_pltune_event(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "Event: Pipelined tuning event, vfo=%s\n", rig_strvfo(vfo)); network_publish_rig_transceive_data(rig); if (rig->callbacks.pltune) { rig->callbacks.pltune(rig, vfo, freq, mode, width, rig->callbacks.pltune_arg); } RETURNFUNC(RIG_OK); } #endif #if defined(HAVE_PTHREAD) static int print_spectrum_line(char *str, size_t length, struct rig_spectrum_line *line) { int data_level_max = line->data_level_max / 2; int aggregate_count = line->spectrum_data_length / 120; int aggregate_value = 0; int i, c; int charlen = strlen("█"); str[0] = '\0'; for (i = 0, c = 0; i < line->spectrum_data_length; i++) { int current = line->spectrum_data[i]; aggregate_value = current > aggregate_value ? current : aggregate_value; if (i > 0 && i % aggregate_count == 0) { if (c + charlen >= length) { break; } int level = aggregate_value * 10 / data_level_max; if (level >= 8) { strcpy(str + c, "█"); c += charlen; } else if (level >= 6) { strcpy(str + c, "▓"); c += charlen; } else if (level >= 4) { strcpy(str + c, "▒"); c += charlen; } else if (level >= 2) { strcpy(str + c, "░"); c += charlen; } else if (level >= 0) { strcpy(str + c, " "); c += 1; } aggregate_value = 0; } } return c; } #endif #if defined(HAVE_PTHREAD) int rig_fire_spectrum_event(RIG *rig, struct rig_spectrum_line *line) { ENTERFUNC; if (rig_need_debug(RIG_DEBUG_TRACE)) { char spectrum_debug[line->spectrum_data_length * 4]; print_spectrum_line(spectrum_debug, sizeof(spectrum_debug), line); rig_debug(RIG_DEBUG_TRACE, "%s: ASCII Spectrum Scope: %s\n", __func__, spectrum_debug); } network_publish_rig_spectrum_data(rig, line); if (rig->callbacks.spectrum_event) { rig->callbacks.spectrum_event(rig, line, rig->callbacks.spectrum_arg); } RETURNFUNC(RIG_OK); } #endif /** @} */ hamlib-4.6.5/src/sleep.c0000664000175000017500000001245215056640443010523 /** * \addtogroup rig * @{ */ /** * \file src/sleep.c * \brief Replacements for sleep and usleep * \author Michael Black W9MDB * \date 2020 */ /* * Hamlib Interface - Replacements for sleep and usleep * Copyright (c) 2020 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \brief provide sleep and usleep replacements * \note parameters are same as man page for each * */ #include #include #include #include "hamlib/config.h" #include "sleep.h" #ifdef __cplusplus extern "C" { #endif extern double monotonic_seconds(); int hl_usleep(rig_useconds_t usec) { double sleep_time = usec / 1e6; struct timespec tv1; double delay = sleep_time; if (sleep_time > .001) { delay -= .0001; } else if (sleep_time > .0001) { delay -= .00005; } tv1.tv_sec = (time_t) delay; tv1.tv_nsec = (long)((delay - tv1.tv_sec) * 1e+9); // rig_debug(RIG_DEBUG_CACHE,"usec=%ld, sleep_time=%f, tv1=%ld,%ld\n", usec, sleep_time, (long)tv1.tv_sec, // (long)tv1.tv_nsec); #ifdef __WIN32__ if (sleep_time < 0.003) { // Busy-wait for small durations < 2 milliseconds LARGE_INTEGER frequency, start, end; double elapsed; QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&start); do { struct timespec startc; clock_gettime(CLOCK_REALTIME, &startc); QueryPerformanceCounter(&end); elapsed = (double)(end.QuadPart - start.QuadPart) / frequency.QuadPart; } while (elapsed < sleep_time); } else { // Use Sleep for larger durations >= 3 milliseconds //Sleep((DWORD)(seconds * 1000 - 1)); // Convert seconds to milliseconds usleep(sleep_time * 1e6 - 400); } #else { struct timespec tv2; double lasterr = 0; double start_at = monotonic_seconds(); double end_at = start_at + sleep_time; tv2.tv_sec = 0; tv2.tv_nsec = 1000000; nanosleep(&tv1, NULL); while (((lasterr = end_at - monotonic_seconds()) > 0)) { nanosleep(&tv2, NULL); } } #endif return 0; } #if 0 // In order to stop the usleep warnings in cppcheck we provide our own interface // So this will use system usleep or our usleep depending on availability of nanosleep // This version of usleep can handle > 1000000 usec values int hl_usleep(rig_useconds_t usec) { int retval = 0; rig_debug(RIG_DEBUG_ERR, "%s: usec=%ld\n", __func__, usec); if (usec <= 1000) { return 0; } // don't sleep if only 1ms is requested -- speeds things up on Windows while (usec > 1000000) { if (retval != 0) { return retval; } retval = usleep(1000000); usec -= 1000000; } #ifdef HAVE_NANOSLEEP struct timespec t, tleft; t.tv_sec = usec / 1e6; t.tv_nsec = (usec - (t.tv_sec * 1e6)) * 1e3; return nanosleep(&t, &tleft); #else return usleep(usec); #endif } #endif #ifdef HAVE_NANOSLEEP #ifndef HAVE_SLEEP /** * \brief sleep * \param secs is seconds to sleep */ unsigned int sleep(unsigned int secs) { int retval; struct timespec t; struct timespec tleft; t.tv_sec = secs; t.tv_nsec = 0; retval = nanosleep(&t, &tleft); if (retval == -1) { return tleft.tv_sec; } return 0; } #endif #if 0 /** * \brief microsecond sleep * \param usec is microseconds to sleep * This does not have the same 1000000 limit as POSIX usleep */ int usleep(rig_useconds_t usec) { int retval; unsigned long sec = usec / 1000000ul; unsigned long nsec = usec * 1000ul - (sec * 1000000000ul); struct timespec t; t.tv_sec = sec; t.tv_nsec = nsec; retval = nanosleep(&t, NULL); // EINTR is the only error return usleep should need // since EINVAL should not be a problem if (retval == -1) { return EINTR; } return 0; } #endif #endif // HAVE_NANOSLEEP #ifdef __cplusplus } #endif /** @} */ #ifdef TEST #include "misc.h" // cppcheck-suppress unusedFunction double get_elapsed_time(struct tm start, struct tm end) { // Convert struct tm to time_t time_t start_seconds = mktime(&start); time_t end_seconds = mktime(&end); double elapsed_time = difftime(end_seconds, start_seconds); return elapsed_time; } int main() { //struct tm start_time, end_time; time_t rawtime; for (int i = 0; i < 11; ++i) { char buf[256]; time(&rawtime); hl_usleep(1000000); // test 1s sleep date_strget(buf, sizeof(buf), 0); printf("%s\n", buf); time(&rawtime); } return 0; } #endif hamlib-4.6.5/src/iofunc.c0000664000175000017500000012241215056640443010674 /* * Hamlib Interface - generic file based io functions * Copyright (c) 2021-2022 by Mikael Nousiainen * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \file iofunc.c * \brief Generic file-based IO functions */ /** * \addtogroup rig_internal * @{ */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #include #include #include "iofunc.h" #include "misc.h" #include "serial.h" #include "parallel.h" #include "usb_port.h" #include "network.h" #include "cm108.h" #include "asyncpipe.h" #define HAMLIB_TRACE2 rig_debug(RIG_DEBUG_TRACE,"%s trace(%d)\n", __FILE__, __LINE__) #if defined(WIN32) && defined(HAVE_WINDOWS_H) #include static void init_sync_data_pipe(hamlib_port_t *p) { p->sync_data_pipe = NULL; p->sync_data_error_pipe = NULL; } static void close_sync_data_pipe(hamlib_port_t *p) { if (p->sync_data_pipe != NULL) { async_pipe_close(p->sync_data_pipe); p->sync_data_pipe = NULL; } if (p->sync_data_error_pipe != NULL) { async_pipe_close(p->sync_data_error_pipe); p->sync_data_error_pipe = NULL; } } static int create_sync_data_pipe(hamlib_port_t *p) { int status; status = async_pipe_create(&p->sync_data_pipe, PIPE_BUFFER_SIZE_DEFAULT, p->timeout); if (status < 0) { close_sync_data_pipe(p); return (-RIG_EINTERNAL); } status = async_pipe_create(&p->sync_data_error_pipe, PIPE_BUFFER_SIZE_DEFAULT, p->timeout); if (status < 0) { close_sync_data_pipe(p); return (-RIG_EINTERNAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s: created data pipe for synchronous transactions\n", __func__); return (RIG_OK); } #else static void init_sync_data_pipe(hamlib_port_t *p) { p->fd_sync_write = -1; p->fd_sync_read = -1; p->fd_sync_error_write = -1; p->fd_sync_error_read = -1; } static void close_sync_data_pipe(hamlib_port_t *p) { if (p->fd_sync_read != -1) { close(p->fd_sync_read); p->fd_sync_read = -1; } if (p->fd_sync_write != -1) { close(p->fd_sync_write); p->fd_sync_write = -1; } if (p->fd_sync_error_read != -1) { close(p->fd_sync_error_read); p->fd_sync_error_read = -1; } if (p->fd_sync_error_write != -1) { close(p->fd_sync_error_write); p->fd_sync_error_write = -1; } } static int create_sync_data_pipe(hamlib_port_t *p) { int status; int sync_pipe_fds[2]; int flags; status = pipe(sync_pipe_fds); flags = fcntl(sync_pipe_fds[0], F_GETFL); flags |= O_NONBLOCK; if (fcntl(sync_pipe_fds[0], F_SETFL, flags)) { rig_debug(RIG_DEBUG_ERR, "%s: error setting O_NONBLOCK on sync_read=%s\n", __func__, strerror(errno)); } flags = fcntl(sync_pipe_fds[1], F_GETFL); flags |= O_NONBLOCK; if (fcntl(sync_pipe_fds[1], F_SETFL, flags)) { rig_debug(RIG_DEBUG_ERR, "%s: error setting O_NONBLOCK on sync_write=%s\n", __func__, strerror(errno)); } if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: synchronous data pipe open status=%d, err=%s\n", __func__, status, strerror(errno)); close_sync_data_pipe(p); return (-RIG_EINTERNAL); } p->fd_sync_read = sync_pipe_fds[0]; p->fd_sync_write = sync_pipe_fds[1]; status = pipe(sync_pipe_fds); flags = fcntl(sync_pipe_fds[0], F_GETFL); flags |= O_NONBLOCK; if (fcntl(sync_pipe_fds[0], F_SETFL, flags)) { rig_debug(RIG_DEBUG_ERR, "%s: error setting O_NONBLOCK on error_read=%s\n", __func__, strerror(errno)); } flags = fcntl(sync_pipe_fds[1], F_GETFL); flags |= O_NONBLOCK; if (fcntl(sync_pipe_fds[1], F_SETFL, flags)) { rig_debug(RIG_DEBUG_ERR, "%s: error setting O_NONBLOCK on error_write=%s\n", __func__, strerror(errno)); } if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: synchronous data error code pipe open status=%d, err=%s\n", __func__, status, strerror(errno)); close_sync_data_pipe(p); return (-RIG_EINTERNAL); } p->fd_sync_error_read = sync_pipe_fds[0]; p->fd_sync_error_write = sync_pipe_fds[1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: created data pipe for synchronous transactions\n", __func__); return (RIG_OK); } #endif /** * \brief Open a hamlib_port based on its rig port type * \param p rig port descriptor * \return status */ int HAMLIB_API port_open(hamlib_port_t *p) { int status; int want_state_delay = 0; p->fd = -1; init_sync_data_pipe(p); if (p->asyncio) { status = create_sync_data_pipe(p); if (status < 0) { return (status); } } switch (p->type.rig) { case RIG_PORT_SERIAL: status = serial_open(p); if (status < 0) { #if defined(WIN32) // rig_debug(RIG_DEBUG_ERR, "%s: serial_open(%s) status=%d, err=%s\n", __func__, // p->pathname, status, rigerror(status)); #else rig_debug(RIG_DEBUG_ERR, "%s: serial_open(%s) status=%d, err=%s\n", __func__, p->pathname, status, strerror(errno)); #endif close_sync_data_pipe(p); return (status); } if (p->parm.serial.rts_state != RIG_SIGNAL_UNSET && p->parm.serial.handshake != RIG_HANDSHAKE_HARDWARE) { status = ser_set_rts(p, p->parm.serial.rts_state == RIG_SIGNAL_ON); want_state_delay = 1; } if (status != 0) { close_sync_data_pipe(p); return (status); } if (p->parm.serial.dtr_state != RIG_SIGNAL_UNSET) { status = ser_set_dtr(p, p->parm.serial.dtr_state == RIG_SIGNAL_ON); want_state_delay = 1; } if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: set_dtr status=%d\n", __func__, status); close_sync_data_pipe(p); return (status); } /* * Wait whatever electrolytics in the circuit come up to voltage. * Is 100ms enough? Too much? */ if (want_state_delay) { hl_usleep(100 * 1000); } break; case RIG_PORT_PARALLEL: status = par_open(p); if (status < 0) { close_sync_data_pipe(p); return (status); } break; case RIG_PORT_CM108: status = cm108_open(p); if (status < 0) { close_sync_data_pipe(p); return (status); } break; case RIG_PORT_DEVICE: status = open(p->pathname, O_RDWR, 0); if (status < 0) { close_sync_data_pipe(p); return (-RIG_EIO); } p->fd = status; break; #if defined(HAVE_LIBUSB_H) || defined (HAVE_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: status = usb_port_open(p); if (status < 0) { close_sync_data_pipe(p); return (status); } break; #endif case RIG_PORT_NONE: case RIG_PORT_RPC: break; /* ez :) */ case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: /* FIXME: hardcoded network port */ status = network_open(p, 4532); if (status < 0) { close_sync_data_pipe(p); return (status); } break; default: close_sync_data_pipe(p); return (-RIG_EINVAL); } return (RIG_OK); } /** * \brief Close a hamlib_port * \param p rig port descriptor * \param port_type equivalent rig port type * \return status */ int HAMLIB_API port_close(hamlib_port_t *p, rig_port_t port_type) { int ret = RIG_OK; if (p->fd != -1) { switch (port_type) { case RIG_PORT_SERIAL: ret = ser_close(p); break; #if defined(HAVE_LIBUSB_H) || defined (HAVE_LIBUSB_1_0_LIBUSB_H) case RIG_PORT_USB: ret = usb_port_close(p); break; #endif case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: ret = network_close(p); break; default: rig_debug(RIG_DEBUG_ERR, "%s(): Unknown port type %d\n", __func__, port_type); /* fall through */ case RIG_PORT_DEVICE: ret = close(p->fd); } p->fd = -1; } close_sync_data_pipe(p); return (ret); } #if defined(WIN32) && !defined(HAVE_TERMIOS_H) # include "win32termios.h" extern int is_uh_radio_fd(int fd); static int port_read_sync_data_error_code(hamlib_port_t *p) { ssize_t total_bytes_read = 0; signed char data; int result; do { // Wait for data using a zero-length read result = async_pipe_read(p->sync_data_error_pipe, &data, 0, p->timeout); if (result < 0) { if (result == -RIG_ETIMEOUT) { if (total_bytes_read > 0) { return data; } } return result; } result = async_pipe_read(p->sync_data_error_pipe, &data, 1, p->timeout); if (result < 0) { if (result == -RIG_ETIMEOUT) { if (total_bytes_read > 0) { return data; } } return result; } total_bytes_read += result; } while (result > 0); return data; } static int port_read_sync_data(hamlib_port_t *p, void *buf, size_t count) { // Wait for data in both the response data pipe and the error code pipe to detect errors occurred during read LARGE_INTEGER timeout; HANDLE hLocal = CreateWaitableTimer(NULL, FALSE, NULL); HANDLE event_handles[3] = { p->sync_data_pipe->read_overlapped.hEvent, p->sync_data_error_pipe->read_overlapped.hEvent, hLocal }; HANDLE read_handle = p->sync_data_pipe->read; LPOVERLAPPED overlapped = &p->sync_data_pipe->read_overlapped; DWORD wait_result; int result; ssize_t bytes_read; result = ReadFile(p->sync_data_pipe->read, buf, count, NULL, overlapped); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? break; case ERROR_IO_PENDING: timeout.QuadPart = (p->timeout * -1000000LL); if ((result = SetWaitableTimer(hLocal, &timeout, 0, NULL, NULL, 0)) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: SetWaitableTimer error: %d\n", __func__, result); wait_result = WaitForMultipleObjects(3, event_handles, FALSE, INFINITE); } else { wait_result = WaitForMultipleObjects(3, event_handles, FALSE, p->timeout); } switch (wait_result) { case WAIT_OBJECT_0 + 0: break; case WAIT_OBJECT_0 + 1: return port_read_sync_data_error_code(p); case WAIT_OBJECT_0 + 2: if (count == 0) { CancelIo(read_handle); return -RIG_ETIMEOUT; } else { // Should not happen return -RIG_EINTERNAL; } default: result = GetLastError(); rig_debug(RIG_DEBUG_ERR, "%s(): WaitForMultipleObjects() error: %d\n", __func__, result); return -RIG_EINTERNAL; } break; default: rig_debug(RIG_DEBUG_ERR, "%s(): ReadFile() error: %d\n", __func__, result); return -RIG_EIO; } } result = GetOverlappedResult(read_handle, overlapped, (LPDWORD) &bytes_read, FALSE); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? bytes_read = 0; break; case ERROR_IO_PENDING: // Shouldn't happen? bytes_read = 0; return -RIG_ETIMEOUT; default: rig_debug(RIG_DEBUG_ERR, "%s(): GetOverlappedResult() error: %d\n", __func__, result); return -RIG_EIO; } } return bytes_read; } static int port_wait_for_data_sync_pipe(hamlib_port_t *p) { unsigned char data; int result; // Use a zero-length read to wait for data in pipe result = port_read_sync_data(p, &data, 0); if (result > 0) { return RIG_OK; } return result; } static ssize_t port_read_sync_data_pipe(hamlib_port_t *p, void *buf, size_t count) { return port_read_sync_data(p, buf, count); } /* On MinGW32/MSVC/.. the appropriate accessor must be used * depending on the port type, sigh. */ static ssize_t port_read_generic(hamlib_port_t *p, void *buf, size_t count, int direct) { int fd = p->fd; int i; ssize_t bytes_read; if (!direct) { return port_read_sync_data_pipe(p, buf, count); } /* * Since WIN32 does its special serial read, we have * to catch the microHam case to do just "read". * Note that we always have RIG_PORT_SERIAL in the * microHam case. */ if (is_uh_radio_fd(fd)) { return read(fd, buf, count); } if (p->type.rig == RIG_PORT_SERIAL) { bytes_read = win32_serial_read(fd, buf, (int) count); if (p->parm.serial.data_bits == 7) { unsigned char *pbuf = buf; /* clear MSB */ for (i = 0; i < bytes_read; i++) { pbuf[i] &= ~0x80; } } return bytes_read; } else if (p->type.rig == RIG_PORT_NETWORK || p->type.rig == RIG_PORT_UDP_NETWORK) { return recv(fd, buf, count, 0); } else { return read(fd, buf, count); } } static ssize_t port_write(hamlib_port_t *p, const void *buf, size_t count) { /* * Since WIN32 does its special serial write, we have * to catch the microHam case to do just "write". * Note that we always have RIG_PORT_SERIAL in the * microHam case. */ if (is_uh_radio_fd(p->fd)) { return write(p->fd, buf, count); } if (p->type.rig == RIG_PORT_SERIAL) { return win32_serial_write(p->fd, buf, (int) count); } else if (p->type.rig == RIG_PORT_NETWORK || p->type.rig == RIG_PORT_UDP_NETWORK) { return send(p->fd, buf, count, 0); } else { return write(p->fd, buf, count); } } static int port_select(hamlib_port_t *p, int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, int direct) { #if 1 /* select does not work very well with writefds/exceptfds * So let's pretend there's none of them */ if (exceptfds) { FD_ZERO(exceptfds); } if (writefds) { FD_ZERO(writefds); } writefds = NULL; exceptfds = NULL; #endif /* * Since WIN32 does its special serial select, we have * to catch the microHam case to do just "select". * Note that we always have RIG_PORT_SERIAL in the * microHam case. */ if (direct && is_uh_radio_fd(p->fd)) { return select(n, readfds, writefds, exceptfds, timeout); } if (direct && p->type.rig == RIG_PORT_SERIAL) { return win32_serial_select(n, readfds, writefds, exceptfds, timeout); } else { return select(n, readfds, writefds, exceptfds, timeout); } } static int port_wait_for_data_direct(hamlib_port_t *p) { fd_set rfds, efds; int fd = p->fd; struct timeval tv, tv_timeout; int result; tv_timeout.tv_sec = p->timeout / 1000; tv_timeout.tv_usec = (p->timeout % 1000) * 1000; //rig_debug(RIG_DEBUG_CACHE, "%s(%d): timeout=%ld,%ld\n", __func__, __LINE__, tv_timeout.tv_sec, tv_timeout.tv_usec); tv = tv_timeout; /* select may have updated it */ FD_ZERO(&rfds); FD_SET(fd, &rfds); efds = rfds; result = port_select(p, fd + 1, &rfds, NULL, &efds, &tv, 1); //rig_debug(RIG_DEBUG_CACHE, "%s(%d): timeout=%ld,%ld\n", __func__, __LINE__, tv_timeout.tv_sec, tv_timeout.tv_usec); if (result == 0) { return -RIG_ETIMEOUT; } else if (result < 0) { rig_debug(RIG_DEBUG_ERR, "%s(): select() error: %s\n", __func__, strerror(errno)); return -RIG_EIO; } if (FD_ISSET(fd, &efds)) { rig_debug(RIG_DEBUG_ERR, "%s(): fd error\n", __func__); return -RIG_EIO; } return RIG_OK; } static int port_wait_for_data(hamlib_port_t *p, int direct) { if (direct) { return port_wait_for_data_direct(p); } return port_wait_for_data_sync_pipe(p); } int HAMLIB_API write_block_sync(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { return async_pipe_write(p->sync_data_pipe, txbuffer, count, p->timeout); } int HAMLIB_API write_block_sync_error(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { return async_pipe_write(p->sync_data_error_pipe, txbuffer, count, p->timeout); } int HAMLIB_API port_flush_sync_pipes(hamlib_port_t *p) { // TODO: To be implemented for Windows return RIG_OK; } #else /* POSIX */ static ssize_t port_read_generic(hamlib_port_t *p, void *buf, size_t count, int direct) { int fd = direct ? p->fd : p->fd_sync_read; if (p->type.rig == RIG_PORT_SERIAL && p->parm.serial.data_bits == 7) { unsigned char *pbuf = buf; ssize_t ret = read(fd, buf, count); /* clear MSB */ ssize_t i; for (i = 0; i < ret; i++) { pbuf[i] &= ~0x80; } return ret; } else { return read(fd, buf, count); } } //! @cond Doxygen_Suppress #define port_write(p,b,c) write((p)->fd,(b),(c)) #define port_select(p,n,r,w,e,t,d) select((n),(r),(w),(e),(t)) //! @endcond static int port_read_sync_data_error_code(hamlib_port_t *p, int fd, int direct) { fd_set rfds, efds; ssize_t total_bytes_read = 0; ssize_t bytes_read; struct timeval tv_timeout; signed char data; do { int result; tv_timeout.tv_sec = 0; tv_timeout.tv_usec = 0; FD_ZERO(&rfds); FD_SET(fd, &rfds); efds = rfds; result = port_select(p, fd + 1, &rfds, NULL, &efds, &tv_timeout, direct); if (result < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s(): select() timeout, direct=%d\n", __func__, direct); return -RIG_ETIMEOUT; } if (result == 0) { if (total_bytes_read > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s(): returning error code %d, direct=%d\n", __func__, (int) data, direct); return data; } rig_debug(RIG_DEBUG_ERR, "%s(): no error code available\n", __func__); return -RIG_EIO; } if (FD_ISSET(fd, &efds)) { rig_debug(RIG_DEBUG_ERR, "%s(): select() indicated error\n", __func__); return -RIG_EIO; } bytes_read = read(fd, &data, 1); total_bytes_read += bytes_read; } while (bytes_read > 0); rig_debug(RIG_DEBUG_VERBOSE, "%s(): returning error code %d\n", __func__, data); return data; } static int port_wait_for_data(hamlib_port_t *p, int direct) { fd_set rfds, efds; int fd, errorfd, maxfd; struct timeval tv, tv_timeout; int result; fd = direct ? p->fd : p->fd_sync_read; errorfd = direct ? -1 : p->fd_sync_error_read; maxfd = (fd > errorfd) ? fd : errorfd; tv_timeout.tv_sec = p->timeout / 1000; tv_timeout.tv_usec = (p->timeout % 1000) * 1000; tv = tv_timeout; /* select may have updated it */ FD_ZERO(&rfds); FD_SET(fd, &rfds); if (!direct) { FD_SET(errorfd, &rfds); } efds = rfds; result = port_select(p, maxfd + 1, &rfds, NULL, &efds, &tv, direct); if (result == 0) { return -RIG_ETIMEOUT; } else if (result < 0) { rig_debug(RIG_DEBUG_ERR, "%s(): select() error, direct=%d: %s\n", __func__, direct, strerror(errno)); return -RIG_EIO; } if (FD_ISSET(fd, &efds)) { rig_debug(RIG_DEBUG_ERR, "%s(): fd error, direct=%d\n", __func__, direct); return -RIG_EIO; } if (!direct) { if (FD_ISSET(errorfd, &efds)) { rig_debug(RIG_DEBUG_ERR, "%s(): fd error from sync error pipe, direct=%d\n", __func__, direct); return -RIG_EIO; } if (FD_ISSET(errorfd, &rfds)) { rig_debug(RIG_DEBUG_VERBOSE, "%s(): attempting to read error code, direct=%d\n", __func__, direct); return port_read_sync_data_error_code(p, errorfd, 0); } } return RIG_OK; } int HAMLIB_API write_block_sync(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { int retval = RIG_OK; if (p->asyncio) { retval = write(p->fd_sync_write, txbuffer, count); } else { retval = write(p->fd, txbuffer, count); } if (retval != count) { rig_debug(RIG_DEBUG_ERR, "%s: write failed: %s\n", __func__, strerror(errno)); retval = -RIG_EIO; } return retval; } int HAMLIB_API write_block_sync_error(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { if (!p->asyncio) { return -RIG_EINTERNAL; } return (int) write(p->fd_sync_error_write, txbuffer, count); } int HAMLIB_API port_flush_sync_pipes(hamlib_port_t *p) { unsigned char buf[1024]; int n; int nbytes; if (!p->asyncio) { return RIG_OK; } rig_debug(RIG_DEBUG_TRACE, "%s: flushing sync pipes\n", __func__); nbytes = 0; while ((n = read(p->fd_sync_read, buf, sizeof(buf))) > 0) { nbytes += n; } rig_debug(RIG_DEBUG_TRACE, "read flushed %d bytes from sync read pipe\n", nbytes); nbytes = 0; while ((n = read(p->fd_sync_error_read, buf, sizeof(buf))) > 0) { nbytes += n; } rig_debug(RIG_DEBUG_TRACE, "read flushed %d bytes from sync error read pipe\n", nbytes); return RIG_OK; } #endif /** * \brief Write a block of characters to an fd. * \param p rig port descriptor * \param txbuffer command sequence to be sent * \param count number of bytes to send * \return 0 = OK, <0 = NOK * * Write a block of count characters to port file descriptor, * with a pause between each character if write_delay is > 0 * * The write_delay is for Yaesu type rigs..require 5 character * sequence to be sent with 50-200msec between each char. * * Also, post_write_delay is for some Yaesu rigs (eg: FT747) that * get confused with sequential fast writes between cmd sequences. * * input: * * fd - file descriptor to write to * txbuffer - pointer to a command sequence array * count - count of byte to send from the txbuffer * write_delay - write delay in ms between 2 chars * post_write_delay - minimum delay between two writes * post_write_date - timeval of last write * * Actually, this function has nothing specific to serial comm, * it could work very well also with any file handle, like a socket. */ int HAMLIB_API write_block(hamlib_port_t *p, const unsigned char *txbuffer, size_t count) { int ret; if (p->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: port not open\n", __func__); return (-RIG_EIO); } #ifdef WANT_NON_ACTIVE_POST_WRITE_DELAY if (p->post_write_date.tv_sec != 0) { signed int date_delay; /* in us */ struct timeval tv; /* FIXME in Y2038 ... */ gettimeofday(&tv, NULL); date_delay = p->post_write_delay * 1000 - ((tv.tv_sec - p->post_write_date.tv_sec) * 1000000 + (tv.tv_usec - p->post_write_date.tv_usec)); if (date_delay > 0) { /* * optional delay after last write */ hl_sleep(date_delay); } p->post_write_date.tv_sec = 0; } #endif if (p->write_delay > 0) { int i; for (i = 0; i < count; i++) { ret = port_write(p, txbuffer + i, 1); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s():%d failed %d - %s\n", __func__, __LINE__, ret, strerror(errno)); return -RIG_EIO; } if (p->write_delay > 0) { hl_usleep(p->write_delay * 1000); } } } else { ret = port_write(p, txbuffer, count); if (ret != count) { rig_debug(RIG_DEBUG_ERR, "%s():%d failed %d - %s\n", __func__, __LINE__, ret, strerror(errno)); return -RIG_EIO; } } rig_debug(RIG_DEBUG_TRACE, "%s(): TX %d bytes\n", __func__, (int)count); dump_hex((unsigned char *) txbuffer, count); if (p->post_write_delay > 0) { #if 0 #ifdef WANT_NON_ACTIVE_POST_WRITE_DELAY #define POST_WRITE_DELAY_TRSHLD 10 if (p->post_write_delay > POST_WRITE_DELAY_TRSHLD) { struct timeval tv; gettimeofday(&tv, NULL); p->post_write_date.tv_sec = tv.tv_sec; p->post_write_date.tv_usec = tv.tv_usec; } else #endif #endif hl_usleep(p->post_write_delay * 1000); /* optional delay after last write */ /* otherwise some yaesu rigs get confused */ /* with sequential fast writes*/ } return RIG_OK; } static int read_block_generic(hamlib_port_t *p, unsigned char *rxbuffer, size_t count, int direct) { struct timeval start_time, end_time, elapsed_time; int total_count = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, direct=%d\n", __func__, direct); if (!p->asyncio && !direct) { return -RIG_EINTERNAL; } /* Store the time of the read loop start */ gettimeofday(&start_time, NULL); short timeout_retries = p->timeout_retry; while (count > 0) { int result; int rd_count; result = port_wait_for_data(p, direct); if (result == -RIG_ETIMEOUT) { if (timeout_retries > 0) { timeout_retries--; rig_debug(RIG_DEBUG_CACHE, "%s(%d): retrying read timeout %d/%d timeout=%dms\n", __func__, __LINE__, p->timeout_retry - timeout_retries, p->timeout_retry, p->timeout); hl_usleep(10 * 1000); continue; } /* Record timeout time and calculate elapsed time */ gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); if (direct) { dump_hex((unsigned char *) rxbuffer, total_count); } rig_debug(RIG_DEBUG_WARN, "%s(): Timed out %d.%d seconds after %d chars, direct=%d\n", __func__, (int)elapsed_time.tv_sec, (int)elapsed_time.tv_usec, total_count, direct); return -RIG_ETIMEOUT; } if (result < 0) { if (direct) { dump_hex((unsigned char *) rxbuffer, total_count); } rig_debug(RIG_DEBUG_ERR, "%s(%d): I/O error after %d chars, direct=%d: %d\n", __func__, __LINE__, total_count, direct, result); return result; } /* * grab bytes from the rig * The file descriptor must have been set up non blocking. */ rd_count = (int) port_read_generic(p, rxbuffer + total_count, count, direct); if (rd_count < 0) { rig_debug(RIG_DEBUG_ERR, "%s(): read failed, direct=%d - %s\n", __func__, direct, strerror(errno)); return -RIG_EIO; } total_count += rd_count; count -= rd_count; } if (direct) { rig_debug(RIG_DEBUG_TRACE, "%s(): RX %d bytes, direct=%d\n", __func__, total_count, direct); dump_hex((unsigned char *) rxbuffer, total_count); } return total_count; /* return bytes count read */ } /** * \brief Read bytes from the device directly or from the synchronous data pipe, depending on the device caps * \param p rig port descriptor * \param rxbuffer buffer to receive text * \param count number of bytes * \return count of bytes received * * Read "num" bytes from "fd" and put results into * an array of unsigned char pointed to by "rxbuffer" * * Blocks on read until timeout hits. * * It then reads "num" bytes into rxbuffer. * * Actually, this function has nothing specific to serial comm, * it could work very well also with any file handle, like a socket. */ int HAMLIB_API read_block(hamlib_port_t *p, unsigned char *rxbuffer, size_t count) { return read_block_generic(p, rxbuffer, count, !p->asyncio); } /** * \brief Read bytes directly from the device file descriptor * \param p rig port descriptor * \param rxbuffer buffer to receive text * \param count number of bytes * \return count of bytes received * * Read "num" bytes from "fd" and put results into * an array of unsigned char pointed to by "rxbuffer" * * Blocks on read until timeout hits. * * It then reads "num" bytes into rxbuffer. * * Actually, this function has nothing specific to serial comm, * it could work very well also with any file handle, like a socket. */ int HAMLIB_API read_block_direct(hamlib_port_t *p, unsigned char *rxbuffer, size_t count) { return read_block_generic(p, rxbuffer, count, 1); } static int read_string_generic(hamlib_port_t *p, unsigned char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len, int flush_flag, int expected_len, int direct) { struct timeval start_time, end_time, elapsed_time; int total_count = 0; int i = 0; static int minlen = 1; // dynamic minimum length of rig response data if (p != NULL && !p->asyncio && !direct) { return -RIG_EINTERNAL; } rig_debug(RIG_DEBUG_CACHE, "%s called, rxmax=%d direct=%d, expected_len=%d\n", __func__, (int)rxmax, direct, expected_len); if (!p || !rxbuffer) { rig_debug(RIG_DEBUG_ERR, "%s: error p=%p, rxbuffer=%p\n", __func__, p, rxbuffer); return -RIG_EINVAL; } if (rxmax < 1) { rig_debug(RIG_DEBUG_ERR, "%s: error rxmax=%ld\n", __func__, (long)rxmax); return 0; } /* Store the time of the read loop start */ gettimeofday(&start_time, NULL); memset(rxbuffer, 0, rxmax); short timeout_retries = p->timeout_retry; while (total_count < rxmax - 1) // allow 1 byte for end-of-string { ssize_t rd_count = 0; int result; result = port_wait_for_data(p, direct); if (result == -RIG_ETIMEOUT) { if (timeout_retries > 0) { timeout_retries--; rig_debug(RIG_DEBUG_CACHE, "%s(%d): retrying read timeout %d/%d timeout=%d\n", __func__, __LINE__, p->timeout_retry - timeout_retries, p->timeout_retry, p->timeout); hl_usleep(10 * 1000); continue; } // a timeout is a timeout no matter how many bytes //if (0 == total_count) { /* Record timeout time and calculate elapsed time */ gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); if (direct) { dump_hex((unsigned char *) rxbuffer, total_count); } if (!flush_flag) { rig_debug(RIG_DEBUG_CACHE, "%s(): Timed out %d.%03d seconds after %d chars, direct=%d\n", __func__, (int)elapsed_time.tv_sec, (int)elapsed_time.tv_usec / 1000, total_count, direct); } return -RIG_ETIMEOUT; } break; /* return what we have read */ } if (result < 0) { if (direct) { dump_hex(rxbuffer, total_count); } rig_debug(RIG_DEBUG_ERR, "%s(%d): I/O error after %d chars, direct=%d: %d\n", __func__, __LINE__, total_count, direct, result); return result; } /* * read 1 character from the rig, (check if in stop set) * The file descriptor must have been set up non blocking. */ do { #if 0 #ifndef __MINGW32__ // The ioctl works on Linux but not mingw int avail = 0; ioctl(p->fd, FIONREAD, &avail); //rig_debug(RIG_DEBUG_ERR, "xs: avail=%d expected_len=%d, minlen=%d, direct=%d\n", __func__, avail, expected_len, minlen, direct); #endif #endif shortcut: rd_count = port_read_generic(p, &rxbuffer[total_count], expected_len == 1 ? 1 : minlen, direct); // rig_debug(RIG_DEBUG_VERBOSE, "%s: read %d bytes tot=%d\n", __func__, (int)rd_count, total_count); minlen -= rd_count; if (errno == EAGAIN) { hl_usleep(5 * 1000); // rig_debug(RIG_DEBUG_WARN, "%s: port_read is busy? direct=%d\n", __func__, // direct); } // special read for FLRig if (stopset != NULL && strcmp(stopset, "") == 0) { if (strstr((char *)rxbuffer, stopset)) { HAMLIB_TRACE2; } else { HAMLIB_TRACE2; goto shortcut; } } } while (++i < 10 && errno == EBUSY); // 50ms should be enough /* if we get 0 bytes or an error something is wrong */ if (rd_count <= 0) { if (direct) { dump_hex((unsigned char *) rxbuffer, total_count); } rig_debug(RIG_DEBUG_ERR, "%s(): read failed, direct=%d - %s\n", __func__, direct, strerror(errno)); return -RIG_EIO; } // check to see if our string startis with \...if so we need more chars if (total_count == 0 && rxbuffer[total_count] == '\\') { rxmax = (rxmax - 1) * 5; } total_count += (int) rd_count; if (total_count == rxmax) { break; } if (stopset && memchr(stopset, rxbuffer[total_count - 1], stopset_len)) { if (minlen == 1) { minlen = total_count; } if (minlen < total_count) { minlen = total_count; //rig_debug(RIG_DEBUG_VERBOSE, "%s: minlen now %d\n", __func__, minlen); } break; } } if (total_count > 1 && rxbuffer[0] == ';') { while (rxbuffer[0] == ';' && total_count > 1) { memmove(rxbuffer, &rxbuffer[1], strlen((char *)rxbuffer) - 1); --total_count; } rig_debug(RIG_DEBUG_VERBOSE, "%s: skipping single ';' chars at beginning of reply\n", __func__); } /* * Doesn't hurt anyway. But be aware, some binary protocols may have * null chars within the received buffer. */ rxbuffer[total_count] = '\000'; if (direct) { rig_debug(RIG_DEBUG_TRACE, "%s(): RX %d characters, direct=%d\n", __func__, total_count, direct); dump_hex((unsigned char *) rxbuffer, total_count); } return total_count; /* return bytes count read */ } /** * \brief Read a string from the device directly or from the synchronous data pipe, depending on the device caps * \param p Hamlib port descriptor * \param rxbuffer buffer to receive string * \param rxmax maximum string size + 1 * \param stopset string of recognized end of string characters * \param stopset_len length of stopset * \return number of characters read if the operation has been successful, * otherwise a negative value if an error occurred (in which case, cause is * set appropriately). * * Read a string from "fd" and put result into * an array of unsigned char pointed to by "rxbuffer" * * Blocks on read until timeout hits. * * It then reads characters until one of the characters in * "stopset" is found, or until "rxmax-1" characters was copied * into rxbuffer. String termination character is added at the end. * * Actually, this function has nothing specific to serial comm, * it could work very well also with any file handle, like a socket. * * Assumes rxbuffer!=NULL */ int HAMLIB_API read_string(hamlib_port_t *p, unsigned char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len, int flush_flag, int expected_len) { return read_string_generic(p, rxbuffer, rxmax, stopset, stopset_len, flush_flag, expected_len, !p->asyncio); } /** * \brief Read a string directly from the device file descriptor * \param p Hamlib port descriptor * \param rxbuffer buffer to receive string * \param rxmax maximum string size + 1 * \param stopset string of recognized end of string characters * \param stopset_len length of stopset * \return number of characters read if the operation has been successful, * otherwise a negative value if an error occurred (in which case, cause is * set appropriately). * * Read a string from "fd" and put result into * an array of unsigned char pointed to by "rxbuffer" * * Blocks on read until timeout hits. * * It then reads characters until one of the characters in * "stopset" is found, or until "rxmax-1" characters was copied * into rxbuffer. String termination character is added at the end. * * Actually, this function has nothing specific to serial comm, * it could work very well also with any file handle, like a socket. * * Assumes rxbuffer!=NULL */ int HAMLIB_API read_string_direct(hamlib_port_t *p, unsigned char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len, int flush_flag, int expected_len) { return read_string_generic(p, rxbuffer, rxmax, stopset, stopset_len, flush_flag, expected_len, 1); } /** @} */ hamlib-4.6.5/src/mutex.h0000664000175000017500000000065415056640443010563 #include "hamlib/config.h" #if defined(HAVE_PTHREAD) #include #endif #ifdef HAVE_PTHREAD #define MUTEX(var) static pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #define MUTEX_LOCK(var) pthread_mutex_lock(&var) #define MUTEX_UNLOCK(var) pthread_mutex_unlock(&var) #else #warning NOT PTHREAD #define MUTEX(var) #define MUTEX_LOCK(var) #define MUTEX_UNLOCK(var) #endif extern int MUTEX_CHECK(pthread_mutex_t *m); hamlib-4.6.5/src/amp_settings.c0000664000175000017500000000571315056640443012112 /* * Hamlib Interface - amplifier func/level/parm * Copyright (c) 2000-2010 by Stephane Fillod * Copyright (c) 2020 by Mikael Nousiainen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup amplifier * @{ */ /** * \brief Amplifier function/level/parameter interface. * * \file amp_settings.c * * \author Stephane Fillod * \date 2000-2010 * \author Mikael Nousiainen * \date 2020 * * This Hamlib interface is a frontend implementing wrapper functions. */ #include #include #include /** * \brief Check which level settings can be set. * * \param amp The #AMP handle. * \param level The level settings bitmap. * * Checks if an amplifier is capable of *setting* a level setting. Since the * \a level is an OR'ed bitwise argument, more than one level can be checked * at the same time. * * EXAMPLE: * \code * if (amp_has_set_level(my_amp, AMP_LVL_PWR)) * my_disp_PWR(); * \endcode * * \return A bit map of supported level settings that can be retrieved, * otherwise 0 if none supported or \a amp is NULL or inconsistent. * * \sa amp_has_set_level(), amp_set_level() */ setting_t HAMLIB_API amp_has_set_level(AMP *amp, setting_t level) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return 0; } return (AMPSTATE(amp)->has_set_level & level); } /** * \brief Check which level settings can be queried. * * \param amp The #AMP handle. * \param level The level settings bitmap. * * Checks if an amplifier is capable of *getting* a level setting. Since the * \a level is an OR'ed bitwise argument, more than one level can be checked * at the same time. * * EXAMPLE: * \code * if (amp_has_get_level(my_amp, AMP_LVL_SWR)) * my_disp_SWR(); * \endcode * * \return A bit map of supported level settings that can be retrieved, * otherwise 0 if none supported or \a amp is NULL or inconsistent. * * \sa amp_has_set_level(), amp_get_level() */ setting_t HAMLIB_API amp_has_get_level(AMP *amp, setting_t level) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp || !amp->caps) { return 0; } return (AMPSTATE(amp)->has_get_level & level); } /*! @} */ hamlib-4.6.5/src/register.c0000664000175000017500000003373715056640443011250 /* * Hamlib Interface - provides registering for dynamically loadable backends. * Copyright (c) 2000-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \brief Dynamic registration of backends * \file register.c * * doc todo: Let's explain what's going on here! */ #include #include #include #include #include #include #include #include "misc.h" //! @cond Doxygen_Suppress #ifndef PATH_MAX # define PATH_MAX 1024 #endif #define RIG_BACKEND_MAX 50 #define DEFINE_INITRIG_BACKEND(backend) \ int MAKE_VERSIONED_FN(PREFIX_INITRIG, ABI_VERSION, backend(void *be_handle)); \ rig_model_t MAKE_VERSIONED_FN(PREFIX_PROBERIG, ABI_VERSION, backend(hamlib_port_t *port, rig_probe_func_t cfunc, rig_ptr_t data)) #define RIG_FUNCNAMA(backend) MAKE_VERSIONED_FN(PREFIX_INITRIG, ABI_VERSION, backend) #define RIG_FUNCNAMB(backend) MAKE_VERSIONED_FN(PREFIX_PROBERIG, ABI_VERSION, backend) #define RIG_FUNCNAM(backend) RIG_FUNCNAMA(backend),RIG_FUNCNAMB(backend) /* * RIG_BACKEND_LIST is defined here, please keep it up to date, * i.e. each time you implement a new backend. */ DEFINE_INITRIG_BACKEND(dummy); DEFINE_INITRIG_BACKEND(yaesu); DEFINE_INITRIG_BACKEND(kenwood); DEFINE_INITRIG_BACKEND(icom); DEFINE_INITRIG_BACKEND(icmarine); DEFINE_INITRIG_BACKEND(pcr); DEFINE_INITRIG_BACKEND(aor); DEFINE_INITRIG_BACKEND(jrc); DEFINE_INITRIG_BACKEND(uniden); DEFINE_INITRIG_BACKEND(drake); DEFINE_INITRIG_BACKEND(lowe); DEFINE_INITRIG_BACKEND(racal); DEFINE_INITRIG_BACKEND(wj); DEFINE_INITRIG_BACKEND(skanti); DEFINE_INITRIG_BACKEND(tentec); DEFINE_INITRIG_BACKEND(alinco); DEFINE_INITRIG_BACKEND(kachina); DEFINE_INITRIG_BACKEND(tapr); DEFINE_INITRIG_BACKEND(flexradio); DEFINE_INITRIG_BACKEND(rft); DEFINE_INITRIG_BACKEND(kit); DEFINE_INITRIG_BACKEND(tuner); DEFINE_INITRIG_BACKEND(rs); DEFINE_INITRIG_BACKEND(prm80); DEFINE_INITRIG_BACKEND(adat); DEFINE_INITRIG_BACKEND(dorji); DEFINE_INITRIG_BACKEND(barrett); DEFINE_INITRIG_BACKEND(elad); DEFINE_INITRIG_BACKEND(codan); DEFINE_INITRIG_BACKEND(gomspace); DEFINE_INITRIG_BACKEND(mds); DEFINE_INITRIG_BACKEND(anytone); DEFINE_INITRIG_BACKEND(motorola); DEFINE_INITRIG_BACKEND(commradio); //! @endcond #ifdef HAVE_WINRADIO //! @cond Doxygen_Suppress DEFINE_INITRIG_BACKEND(winradio); //! @endcond #endif /** * \def rig_backend_list * \brief Static list of rig models. * * This is a NULL terminated list of available rig backends. Each entry in * the list consists of two fields: The branch number, which is an integer, * and the branch name, which is a character string. */ static struct { int be_num; const char *be_name; int (* be_init_all)(void *handle); rig_model_t (* be_probe_all)(hamlib_port_t *, rig_probe_func_t, rig_ptr_t); } rig_backend_list[RIG_BACKEND_MAX] = { { RIG_DUMMY, RIG_BACKEND_DUMMY, RIG_FUNCNAMA(dummy) }, { RIG_YAESU, RIG_BACKEND_YAESU, RIG_FUNCNAM(yaesu) }, { RIG_KENWOOD, RIG_BACKEND_KENWOOD, RIG_FUNCNAM(kenwood) }, { RIG_ICOM, RIG_BACKEND_ICOM, RIG_FUNCNAM(icom) }, { RIG_ICMARINE, RIG_BACKEND_ICMARINE, RIG_FUNCNAMA(icmarine) }, { RIG_PCR, RIG_BACKEND_PCR, RIG_FUNCNAMA(pcr) }, { RIG_AOR, RIG_BACKEND_AOR, RIG_FUNCNAMA(aor) }, { RIG_JRC, RIG_BACKEND_JRC, RIG_FUNCNAMA(jrc) }, { RIG_UNIDEN, RIG_BACKEND_UNIDEN, RIG_FUNCNAM(uniden) }, { RIG_DRAKE, RIG_BACKEND_DRAKE, RIG_FUNCNAM(drake) }, { RIG_LOWE, RIG_BACKEND_LOWE, RIG_FUNCNAM(lowe) }, { RIG_RACAL, RIG_BACKEND_RACAL, RIG_FUNCNAMA(racal) }, { RIG_WJ, RIG_BACKEND_WJ, RIG_FUNCNAMA(wj) }, { RIG_SKANTI, RIG_BACKEND_SKANTI, RIG_FUNCNAMA(skanti) }, #ifdef HAVE_WINRADIO { RIG_WINRADIO, RIG_BACKEND_WINRADIO, RIG_FUNCNAMA(winradio) }, #endif /* HAVE_WINRADIO */ { RIG_TENTEC, RIG_BACKEND_TENTEC, RIG_FUNCNAMA(tentec) }, { RIG_ALINCO, RIG_BACKEND_ALINCO, RIG_FUNCNAMA(alinco) }, { RIG_KACHINA, RIG_BACKEND_KACHINA, RIG_FUNCNAMA(kachina) }, { RIG_TAPR, RIG_BACKEND_TAPR, RIG_FUNCNAMA(tapr) }, { RIG_FLEXRADIO, RIG_BACKEND_FLEXRADIO, RIG_FUNCNAMA(flexradio) }, { RIG_RFT, RIG_BACKEND_RFT, RIG_FUNCNAMA(rft) }, { RIG_KIT, RIG_BACKEND_KIT, RIG_FUNCNAMA(kit) }, { RIG_TUNER, RIG_BACKEND_TUNER, RIG_FUNCNAMA(tuner) }, { RIG_RS, RIG_BACKEND_RS, RIG_FUNCNAMA(rs) }, { RIG_PRM80, RIG_BACKEND_PRM80, RIG_FUNCNAMA(prm80) }, { RIG_ADAT, RIG_BACKEND_ADAT, RIG_FUNCNAM(adat) }, { RIG_DORJI, RIG_BACKEND_DORJI, RIG_FUNCNAMA(dorji) }, { RIG_BARRETT, RIG_BACKEND_BARRETT, RIG_FUNCNAMA(barrett) }, { RIG_ELAD, RIG_BACKEND_ELAD, RIG_FUNCNAMA(elad) }, { RIG_CODAN, RIG_BACKEND_CODAN, RIG_FUNCNAMA(codan) }, { RIG_GOMSPACE, RIG_BACKEND_GOMSPACE, RIG_FUNCNAM(gomspace) }, { RIG_MDS, RIG_BACKEND_MDS, RIG_FUNCNAMA(mds) }, { RIG_ANYTONE, RIG_BACKEND_ANYTONE, RIG_FUNCNAMA(anytone) }, { RIG_MOTOROLA, RIG_BACKEND_MOTOROLA, RIG_FUNCNAMA(motorola) }, { RIG_COMMRADIO, RIG_BACKEND_COMMRADIO, RIG_FUNCNAM(commradio) }, { 0, NULL }, /* end */ }; /* * This struct to keep track of known rig models. * It is chained, and used in a hash table, see below. */ //! @cond Doxygen_Suppress struct rig_list { struct rig_caps *caps; struct rig_list *next; }; //! @endcond // This size has to be > than the max# of rigs for any manufacturer // A fatal error will occur when running rigctl if this value is too small //! @cond Doxygen_Suppress #define RIGLSTHASHSZ 65535 #define HASH_FUNC(a) ((a)%RIGLSTHASHSZ) //! @endcond /* * The rig_hash_table is a hash table pointing to a list of next==NULL * terminated caps. */ static struct rig_list *rig_hash_table[RIGLSTHASHSZ] = { NULL, }; static int rig_lookup_backend(rig_model_t rig_model); /* * Basically, this is a hash insert function that doesn't check for dup! */ //! @cond Doxygen_Suppress int HAMLIB_API rig_register(struct rig_caps *caps) { int hval; struct rig_list *p; //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!caps) { return -RIG_EINVAL; } #if 0 rig_debug(RIG_DEBUG_ERR, "%s: rig_register (%u)\n", __func__, caps->rig_model); #endif p = (struct rig_list *)calloc(1, sizeof(struct rig_list)); if (!p) { return -RIG_ENOMEM; } hval = HASH_FUNC(caps->rig_model); if (rig_hash_table[hval]) { printf("Hash collision!!! Fatal error!!\n"); exit(1); } p->caps = caps; // p->handle = NULL; p->next = rig_hash_table[hval]; rig_hash_table[hval] = p; return RIG_OK; } //! @endcond /* * Get rig capabilities. * ie. rig_hash_table lookup */ //! @cond Doxygen_Suppress struct rig_caps *HAMLIB_API rig_get_caps(rig_model_t rig_model) { struct rig_list *p; for (p = rig_hash_table[HASH_FUNC(rig_model)]; p; p = p->next) { if (p->caps->rig_model == rig_model) { return p->caps; } } return NULL; /* sorry, caps not registered! */ } //! @endcond /* * lookup for backend index in rig_backend_list table, * according to BACKEND_NUM * return -1 if not found. */ //! @cond Doxygen_Suppress static int rig_lookup_backend(rig_model_t rig_model) { int i; for (i = 0; i < RIG_BACKEND_MAX && rig_backend_list[i].be_name; i++) { if (RIG_BACKEND_NUM(rig_model) == rig_backend_list[i].be_num) { return i; } } return -1; } //! @endcond /* * rig_check_backend * check the backend declaring this model has been loaded * and if not loaded already, load it! * This permits seamless operation in rig_init. */ //! @cond Doxygen_Suppress int HAMLIB_API rig_check_backend(rig_model_t rig_model) { const struct rig_caps *caps; int be_idx; int retval; // int i; /* already loaded ? */ caps = rig_get_caps(rig_model); if (caps) { return RIG_OK; } #if 0 // this stopped a 2nd rig_init call with a valid model to fail -- reversing // hmmm...no caps so did we already load the rigs? for (n = 0, i = 0; i < RIGLSTHASHSZ; i++) { if (rig_hash_table[i]) { ++n; } } if (n > 1) { rig_debug(RIG_DEBUG_ERR, "%s: rig model %u not found and rig count=%d\n", __func__, rig_model, n); return -RIG_ENAVAIL; } #endif be_idx = rig_lookup_backend(rig_model); /* * Never heard about this backend family! */ if (be_idx == -1) { rig_debug(RIG_DEBUG_VERBOSE, "rig_check_backend: unsupported backend %u for model %u\n", RIG_BACKEND_NUM(rig_model), rig_model); return -RIG_ENAVAIL; } // do we need to load the backend? // if (rig_backend_list[be_idx].be_init_all == 0) { retval = rig_load_backend(rig_backend_list[be_idx].be_name); } #if 0 else { retval = RIG_OK; } #endif return retval; } //! @endcond //! @cond Doxygen_Suppress int HAMLIB_API rig_unregister(rig_model_t rig_model) { int hval; struct rig_list *p, *q; hval = HASH_FUNC(rig_model); q = NULL; for (p = rig_hash_table[hval]; p; p = p->next) { if (p->caps->rig_model == rig_model) { if (q == NULL) { rig_hash_table[hval] = p->next; } else { q->next = p->next; } free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* sorry, caps not registered! */ } //! @endcond /* * rig_list_foreach * executes cfunc on all the elements stored in the rig hash list */ //! @cond Doxygen_Suppress int HAMLIB_API rig_list_foreach(int (*cfunc)(const struct rig_caps *, rig_ptr_t), rig_ptr_t data) { struct rig_list *p; int i; if (!cfunc) { return -RIG_EINVAL; } for (i = 0; i < RIGLSTHASHSZ; i++) { struct rig_list *next = NULL; for (p = rig_hash_table[i]; p; p = next) { next = p->next; /* read before call in case it is unregistered */ if ((*cfunc)(p->caps, data) == 0) { return RIG_OK; } } } return RIG_OK; } //! @endcond /* * rig_list_foreach_model * executes cfunc on all the elements stored in the rig hash list */ //! @cond Doxygen_Suppress int HAMLIB_API rig_list_foreach_model(int (*cfunc)(const rig_model_t rig_model, rig_ptr_t), rig_ptr_t data) { struct rig_list *p; int i; if (!cfunc) { return -RIG_EINVAL; } for (i = 0; i < RIGLSTHASHSZ; i++) { struct rig_list *next = NULL; for (p = rig_hash_table[i]; p; p = next) { next = p->next; /* read before call in case it is unregistered */ if ((*cfunc)(p->caps->rig_model, data) == 0) { return RIG_OK; } } } return RIG_OK; } //! @endcond //! @cond Doxygen_Suppress static int dummy_rig_probe(const hamlib_port_t *p, rig_model_t model, rig_ptr_t data) { rig_debug(RIG_DEBUG_TRACE, "Found rig, model %u\n", model); return RIG_OK; } //! @endcond /* * rig_probe_first * called straight by rig_probe */ //! @cond Doxygen_Suppress rig_model_t rig_probe_first(hamlib_port_t *p) { int i; rig_model_t model; for (i = 0; i < RIG_BACKEND_MAX && rig_backend_list[i].be_name; i++) { if (rig_backend_list[i].be_probe_all) { model = (*rig_backend_list[i].be_probe_all)(p, dummy_rig_probe, (rig_ptr_t)NULL); /* stop at first one found */ if (model != RIG_MODEL_NONE) { return model; } } } return RIG_MODEL_NONE; } //! @endcond /* * rig_probe_all_backends * called straight by rig_probe_all */ //! @cond Doxygen_Suppress int rig_probe_all_backends(hamlib_port_t *p, rig_probe_func_t cfunc, rig_ptr_t data) { int i; for (i = 0; i < RIG_BACKEND_MAX && rig_backend_list[i].be_name; i++) { if (rig_backend_list[i].be_probe_all) { (*rig_backend_list[i].be_probe_all)(p, cfunc, data); } } return RIG_OK; } //! @endcond //! @cond Doxygen_Suppress int rig_load_all_backends() { int i; memset(rig_hash_table, 0, sizeof(rig_hash_table)); for (i = 0; i < RIG_BACKEND_MAX && rig_backend_list[i].be_name; i++) { rig_load_backend(rig_backend_list[i].be_name); } return RIG_OK; } //! @endcond //! @cond Doxygen_Suppress typedef int (*backend_init_t)(rig_ptr_t); //! @endcond /* * rig_load_backend */ //! @cond Doxygen_Suppress int HAMLIB_API rig_load_backend(const char *be_name) { int i; backend_init_t be_init; for (i = 0; i < RIG_BACKEND_MAX && rig_backend_list[i].be_name; i++) { if (!strcmp(be_name, rig_backend_list[i].be_name)) { be_init = rig_backend_list[i].be_init_all ; if (be_init) { return (*be_init)(NULL); } else { return -RIG_EINVAL; } } } return -RIG_EINVAL; } //! @endcond hamlib-4.6.5/src/microham.c0000664000175000017500000007331615056640443011220 /* * Hamlib Interface - Microham device support for POSIX systems * Copyright (c) 2017 by Christoph van Wüllen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // // This file contains the support for microHam devices // // On WIN32, this behaves as if no microHam device is connected // to the computer since (at least my version of MinGW) does not // support socketpair(). // #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif //#define FRAME(s, ...) printf(s, ##__VA_ARGS__) //#define DEBUG(s, ...) printf(s, ##__VA_ARGS__) //#define TRACE(s, ...) printf(s, ##__VA_ARGS__) //#define MYERROR(s, ...) printf(s, ##__VA_ARGS__) #ifndef FRAME # define FRAME(s, ...) #endif #ifndef DEBUG # define DEBUG(s, ...) #endif #ifndef TRACE # define TRACE(s, ...) #endif #ifndef MYERROR # define MYERROR(s, ...) #endif #ifndef PATH_MAX // should not happen, should be defined in limits.h // but better paranoia than a code that does not work #define PATH_MAX 256 #endif #if !(defined(WIN32) || !defined(HAVE_GLOB_H)) static char uh_device_path[PATH_MAX]; // use PATH_MAX since udev names can be VERY long! #endif static int uh_device_fd = -1; static int uh_is_initialized = 0; static int uh_radio_pair[2] = { -1, -1}; static int uh_ptt_pair[2] = { -1, -1}; static int uh_wkey_pair[2] = { -1, -1}; static int uh_radio_in_use; static int uh_ptt_in_use; static int uh_wkey_in_use; static int statusbyte = 0; #ifdef HAVE_PTHREAD #include static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_t readthread; #define getlock() if (pthread_mutex_lock(&mutex)) perror("GETLOCK:") #define freelock() if (pthread_mutex_unlock(&mutex)) perror("FREELOCK:") #else #define getlock() #define freelock() #endif #if defined(HAVE_SELECT) // // time of last heartbeat. Updated by heartbeat() // static time_t lastbeat = 0; #endif #if defined(HAVE_PTHREAD) && defined(HAVE_SOCKETPAIR) && defined(HAVE_SELECT) static time_t starttime; #define TIME ((int) (time(NULL) - starttime)) #endif // // close all sockets and mark them free // static void close_all_files() { if (uh_radio_pair[0] >= 0) { close(uh_radio_pair[0]); } if (uh_radio_pair[1] >= 0) { close(uh_radio_pair[1]); } if (uh_ptt_pair[0] >= 0) { close(uh_ptt_pair[0]); } if (uh_ptt_pair[1] >= 0) { close(uh_ptt_pair[1]); } if (uh_wkey_pair[0] >= 0) { close(uh_wkey_pair[0]); } if (uh_wkey_pair[1] >= 0) { close(uh_wkey_pair[1]); } uh_radio_pair[0] = -1; uh_radio_pair[1] = -1; uh_ptt_pair[0] = -1; uh_ptt_pair[1] = -1; uh_wkey_pair[0] = -1; uh_wkey_pair[1] = -1; uh_radio_in_use = 0; uh_ptt_in_use = 0; uh_wkey_in_use = 0; // finally, close connection to microHam device if (uh_device_fd >= 0) { close(uh_device_fd); } } static void close_microham() { if (!uh_is_initialized) { return; } TRACE("%10d:Closing MicroHam device\n", TIME); uh_is_initialized = 0; #ifdef HAVE_PTHREAD // wait for read_device thread to finish pthread_join(readthread, NULL); #endif close_all_files(); } #if defined(WIN32) || !defined(HAVE_GLOB_H) /* * On Windows, this is not really needed since we have uhrouter.exe * creating virtual COM ports * * I do now know how to "find" a microham device under Windows. * * Therefore, a dummy version of finddevices() is included such that it compiles * well on WIN32. Since the dummy version does not find anything, no reading thread * and no sockets are created. * * * For those who want to implement the WIN32 case here properly: * * What finddevices() must do: * Scan all USB-serial ports with an FTDI chip, and look * for its serial number, take the first port you can find where the serial * number begins with MK, M2, CK, DK, D2, 2R, 2P or UR. Then, open the serial * line with correct serial speed etc. and put a valid fd into uh_device_fd. */ /* Commenting out the following dummy function to quell the warning from * MinGW's GCC of a defined but not used function. */ /* static void finddevices() */ /* { */ /* } */ #else /* * POSIX (including APPLE) * * Finding microHam devices can be a mess. * On Apple, the FTDI chips inside the microHam device show up as * /dev/tty.usbserial- where is the serial number * of the chip. So we can easily look for MK, MK-II, DK etc. * devices. * * On LINUX, these show up as /dev/ttyUSBx where x=0,1,2... * depending on when the device has been recognized. Fortunately * today all LINUX boxes have udev, and there is a symlink * in /dev/serial/by-id containing the serial number pointing * to the relevant special file in /dev. * * This technique is used such that we do not need to open * ALL serial ports in the system looking which one corresponds * to microHam. Note we could use libusb directly, but this * probably requires root privileges. * * Note: StationMaster uses a different protocol, and * the protocol of StationMaster DeLuxe is not * even disclosed. * * We are using the glob() function to obtain a list * of candidates. */ #define NUMUHTYPES 9 static struct uhtypes { const char *name; const char *device; } uhtypes[NUMUHTYPES] = { #ifdef __APPLE__ { "microKeyer", "/dev/tty.usbserial-MK*"}, { "microKeyer-II", "/dev/tty.usbserial-M2*"}, { "microKeyer-III", "/dev/tty.usbserial-M3*"}, { "CW Keyer", "/dev/tty.usbserial-CK*"}, { "digiKeyer", "/dev/tty.usbserial-DK*"}, { "digiKeyer-II", "/dev/tty.usbserial-D2*"}, { "micorKeyer-IIR", "/dev/tty.usbserial-2R*"}, { "microKeyer-IIR+", "/dev/tty.usbserial-2P*"}, { "microKeyer-U2R", "/dev/tty.usbserial-UR*"}, #else { "microKeyer", "/dev/serial/by-id/*microHAM*_MK*"}, { "microKeyer-II", "/dev/serial/by-id/*microHAM*_M2*"}, { "microKeyer-III", "/dev/serial/by-id/*microHAM*_M3*"}, { "CW Keyer", "/dev/serial/by-id/*microHAM*_CK*"}, { "digiKeyer", "/dev/serial/by-id/*microHAM*_DK*"}, { "digiKeyer-II", "/dev/serial/by-id/*microHAM*_D2*"}, { "micorKeyer-IIR", "/dev/serial/by-id/*microHAM*_2R*"}, { "microKeyer-IIR+", "/dev/serial/by-id/*microHAM*_2P*"}, { "microKeyer-U2R", "/dev/serial/by-id/*microHAM*_UR*"}, #endif }; // // Find a microHamDevice. Here we assume that the device special // file has a name from which we can tell this is a microHam device // This is the case for MacOS and LINUX (for LINUX: use udev) // #include #include #include static void finddevices() { struct stat st; glob_t gbuf; int i, j; struct termios TTY; int fd; uh_device_fd = -1; // indicates "no device is found" // // Check ALL device special files that might be relevant, // for (i = 0; i < NUMUHTYPES; i++) { DEBUG("Checking for %s device\n", uhtypes[i].device); glob(uhtypes[i].device, 0, NULL, &gbuf); for (j = 0; j < gbuf.gl_pathc; j++) { DEBUG("Found file: %s\n", gbuf.gl_pathv[j]); if (!stat(gbuf.gl_pathv[j], &st)) { if (S_ISCHR(st.st_mode)) { // found a character special device with correct name if (strlen(gbuf.gl_pathv[j]) >= PATH_MAX) { // I do not know if this can happen, but if it happens, we just skip the device. MYERROR("Name too long: %s\n", gbuf.gl_pathv[j]); continue; } DEBUG("%s is a character special file\n", gbuf.gl_pathv[j]); strcpy(uh_device_path, gbuf.gl_pathv[j]); TRACE("Found a %s, Device=%s\n", uhtypes[i].name, uh_device_path); fd = open(uh_device_path, O_RDWR | O_NONBLOCK | O_NOCTTY); if (fd < 0) { MYERROR("Cannot open serial port %s\n", uh_device_path); perror("Open:"); continue; } tcflush(fd, TCIFLUSH); if (tcgetattr(fd, &TTY)) { MYERROR("Cannot get comm params\n"); close(fd); continue; } // microHam devices always use 230400 baud, 8N1, only TxD/RxD is used (no h/w handshake) // 8 data bits TTY.c_cflag &= ~CSIZE; TTY.c_cflag |= CS8; // enable receiver, set local mode TTY.c_cflag |= (CLOCAL | CREAD); // no parity TTY.c_cflag &= ~PARENB; // 1 stop bit TTY.c_cflag &= ~CSTOPB; cfsetispeed(&TTY, B230400); cfsetospeed(&TTY, B230400); // NO h/w handshake // TTY.c_cflag &= ~CRTSCTS; // raw input TTY.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // raw output TTY.c_oflag &= ~OPOST; // software flow control disabled // TTY.c_iflag &= ~IXON; // do not translate CR to NL // TTY.c_iflag &= ~ICRNL; // timeouts TTY.c_cc[VMIN] = 0; TTY.c_cc[VTIME] = 255; if (tcsetattr(fd, TCSANOW, &TTY)) { MYERROR("Can't set device communication parameters"); close(fd); continue; } TRACE("SerialPort opened: %s fd=%d\n", uh_device_path, fd); uh_device_fd = fd; // The first time we were successful, we skip all what might come return; } } } } } #endif #if defined(HAVE_SELECT) // // parse a frame received from the keyer // This is called from the "device reading" thread // once a complete frame has been received // Send Radio and Winkey bytes received to the client sockets. // static int frameseq = 0; static int incontrol = 0; static unsigned char controlstring[256]; static int numcontrolbytes = 0; static void parseFrame(const unsigned char *frame) { unsigned char byte; FRAME("RCV frame %02x %02x %02x %02x\n", frame[0], frame[1], frame[2], frame[3]); // frames come in sequences. The first frame of a sequence has bit6 cleared in the headerbyte. if ((frame[0] & 0x40) == 0) { frameseq = 0; } else { frameseq++; } // A frame is of the form header-byte1-byte2-byte3 // byte 1 is always RADIO, byte 2 is always RADIO2/AUX (if validity bit set) // byte 3 has different meaning, depending on the sequence number of the frame: // seq=0 -> Flags // seq=1 -> control // seq=2 -> WinKey // seq=3 -> PS2 // if RADIO byte is valid, send it to client if ((frame[0] & 0x20) != 0) { byte = frame[1] & 0x7F; if ((frame[0] & 0x04) != 0) { byte |= 0x80; } DEBUG("%10d:FromRadio: %02x\n", TIME, byte); if (write(uh_radio_pair[0], &byte, 1) != 1) { MYERROR("Write Radio Socket\n"); } } // ignore AUX/RADIO2 for the time being // check the shared channel for validity, if it is the CONTROL channel it is always valid if ((frame[0] & 0x08) || (frameseq == 1)) { byte = frame[3] & 0x7F; if (frame[0] & 0x01) { byte |= 0x80; } switch (frameseq) { case 0: // Flag byte DEBUG("%10d:RCV: Flags=%02x\n", TIME, byte); // No reason to pass the flags to clients break; case 1: // part of control string if ((frame[0] & 0x08) == 0 && !incontrol) { // start or end of a control sequence numcontrolbytes = 1; controlstring[0] = byte; incontrol = 1; break; } if ((frame[0] & 0x08) == 0 && incontrol) { int i; // end of a control sequence controlstring[numcontrolbytes++] = byte; DEBUG("%10d:FromControl:", TIME); for (i = 0; i < numcontrolbytes; i++) { DEBUG(" %02x", controlstring[i]); } DEBUG(".\n"); incontrol = 0; // printing control messages is only used for debugging. // Note that we can get a lot of unsolicited control messages // here (squelch, voltage change, etc.) break; } // in the middle of a control string controlstring[numcontrolbytes++] = byte; break; case 2: // message from WinKey chip DEBUG("%10d:RCV: WinKey=%02x\n", TIME, byte); if (write(uh_wkey_pair[0], &byte, 1) != 1) { MYERROR("Write Winkey socket\n"); } break; case 3: // Key pressed on PS2 keyboard connected to microHam device DEBUG("%10d:RCV: PS2=%02x\n", TIME, byte); break; } } } #endif /* HAVE_SELECT */ #if defined(HAVE_SELECT) // // Send radio bytes to microHam device // static void writeRadio(const unsigned char *bytes, int len) { unsigned char seq[4]; int i; DEBUG("%10d:Send radio data: ", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", (int) bytes[i]); } DEBUG(".\n"); getlock(); for (i = 0; i < len; i++) { int ret; seq[0] = 0x28; seq[1] = 0x80 | bytes[i]; seq[2] = 0x80; seq[3] = 0X80 | statusbyte; if (statusbyte & 0x80) { seq[0] |= 0x01; } if (bytes[i] & 0x80) { seq[0] |= 0x04; } if ((ret = write(uh_device_fd, seq, 4)) < 4) { MYERROR("WriteRadio failed with %d\n", ret); if (ret < 0) { perror("WriteRadioError:"); } } } freelock(); } #endif /* HAVE_SELECT */ // // send statusbyte to microHam device // static void writeFlags() { unsigned char seq[4]; int ret; DEBUG("%10d:Sending FlagByte: %02x\n", TIME, statusbyte); getlock(); seq[0] = 0x08; if (statusbyte & 0x80) { seq[0] = 0x09; } seq[1] = 0x80; seq[2] = 0x80; seq[3] = 0x80 | statusbyte; if ((ret = write(uh_device_fd, seq, 4)) < 4) { MYERROR("WriteFlags failed with %d\n", ret); if (ret < 0) { perror("WriteFlagsError:"); } } freelock(); } #if defined(HAVE_SELECT) // // Send bytes to the WinKeyer within microHam device // static void writeWkey(const unsigned char *bytes, int len) { unsigned char seq[12]; int i; DEBUG("%10d:Send WinKey data: ", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", (int) bytes[i]); } DEBUG(".\n"); // Winkey data is in the third frame of a sequence, // So send two no-ops first. Include statusbyte in first frame getlock(); for (i = 0; i < len; i++) { int ret; seq[ 0] = 0x08; seq[ 1] = 0x80; seq[ 2] = 0x80; seq[ 3] = 0X80 | statusbyte; seq[ 4] = 0x40; seq[ 5] = 0x80; seq[ 6] = 0x80; seq[ 7] = 0x80; seq[ 8] = 0x48; seq[ 9] = 0x80; seq[10] = 0x80; seq[11] = 0x80 | bytes[i]; if (statusbyte & 0x80) { seq[ 0] |= 0x01; } if (bytes[i] & 0x80) { seq[ 8] |= 0x01; } if ((ret = write(uh_device_fd, seq, 12)) < 12) { MYERROR("WriteWINKEY failed with %d\n", ret); if (ret < 0) { perror("WriteWinkeyError:"); } } } freelock(); } #endif /* HAVE_SELECT */ // // Write a control string to the microHam device // static void writeControl(const unsigned char *data, int len) { int i; unsigned char seq[8]; DEBUG("%10d:WriteControl:", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", data[i]); } DEBUG(".\n"); // Control data is in the second frame of a sequence, // So send a no-op first. Include statusbyte in first frame. // First and last byte of the control message is NOT marked "valid" getlock(); for (i = 0; i < len; i++) { int ret; // encode statusbyte in first frame seq[0] = 0x08; seq[1] = 0x80; seq[2] = 0x80; seq[3] = 0x80 | statusbyte; seq[4] = 0x48; // marked valid seq[5] = 0x80; seq[6] = 0x80; seq[7] = 0x80 | data[i]; if (statusbyte & 0x80) { seq[0] |= 1; } if (i == 0 || i == len - 1) { seq[4] = 0x40; // un-mark valid } if (data[i] & 0x80) { seq[4] |= 0x01; } if ((ret = write(uh_device_fd, seq, 8)) < 8) { MYERROR("WriteControl failed, ret=%d\n", ret); if (ret < 0) { perror("WriteControlError:"); } } } freelock(); } #if defined(HAVE_PTHREAD) && defined(HAVE_SOCKETPAIR) && defined(HAVE_SELECT) // // send a heartbeat and record time // The "last heartbeat" time is recorded in a global variable // such that the service thread can decide whether a new // heartbeat is due. // static void heartbeat() { unsigned char seq[2]; seq[0] = 0x7e; seq[1] = 0xfe; writeControl(seq, 2); lastbeat = time(NULL); } #endif /* defined(HAVE_PTHREAD) && defined(HAVE_SOCKETPAIR) && defined(HAVE_SELECT) */ #if defined(HAVE_SELECT) // // This thread reads from the microHam device and puts data on the sockets // it also issues periodic heartbeat messages // it also reads the sockets if data is available // static void *read_device(void *p) { unsigned char frame[4]; int framepos = 0; unsigned char buf[2]; fd_set fds; struct timeval tv; // the bytes from the microHam decive come in "frames" // a frame is a four-byte sequence. The first byte has the MSB unset, // then come three bytes with the MSB set // What comes here is an "infinite" loop. However this thread // terminates if the device is closed. for (;;) { int ret; int maxdev; // // setting uh_is_initialized to zero in the main thread // tells this one that it is all over now // if (!uh_is_initialized) { return NULL; } #if defined(HAVE_PTHREAD) && defined(HAVE_SOCKETPAIR) && defined(HAVE_SELECT) // // This is the right place to ensure that a heartbeat is sent // to the microham device regularly (15 sec delay is the maximum // allowed, let us use 5 secs to be on the safe side). // if ((time(NULL) - lastbeat) > 5) { heartbeat(); } #endif // // Wait for something to arrive, either from the microham device // or from the sockets used for I/O from hamlib. // If nothing arrives within 100 msec, restart the "infinite loop". // FD_ZERO(&fds); FD_SET(uh_device_fd, &fds); FD_SET(uh_radio_pair[0], &fds); FD_SET(uh_ptt_pair[0], &fds); FD_SET(uh_wkey_pair[0], &fds); // determine max of these fd's for use in select() maxdev = uh_device_fd; if (uh_radio_pair[0] > maxdev) { maxdev = uh_radio_pair[0]; } if (uh_ptt_pair[0] > maxdev) { maxdev = uh_ptt_pair[0]; } if (uh_wkey_pair[0] > maxdev) { maxdev = uh_wkey_pair[0]; } tv.tv_usec = 100000; tv.tv_sec = 0; ret = select(maxdev + 1, &fds, NULL, NULL, &tv); // // select returned error, or nothing has arrived: // continue "infinite" loop. // if (ret <= 0) { continue; } // // Take care of the incoming data (microham device, sockets) // if (FD_ISSET(uh_device_fd, &fds)) { // compose frame, if it is complete, all parseFrame while (read(uh_device_fd, buf, 1) > 0) { if (!(buf[0] & 0x80) && framepos != 0) { MYERROR("FrameSyncStartError\n"); framepos = 0; } if ((buf[0] & 0x80) && framepos == 0) { MYERROR("FrameSyncStartError\n"); framepos = 0; continue; } frame[framepos++] = buf[0]; if (framepos >= 4) { framepos = 0; parseFrame(frame); } } } if (FD_ISSET(uh_ptt_pair[0], &fds)) { // we do not expect any data here, but drain the socket while (read(uh_ptt_pair[0], buf, 1) > 0) { // do nothing } } if (FD_ISSET(uh_radio_pair[0], &fds)) { // read everything that is there, and send it to the radio while (read(uh_radio_pair[0], buf, 1) > 0) { writeRadio(buf, 1); } } if (FD_ISSET(uh_wkey_pair[0], &fds)) { // read everything that is there, and send it to the WinKey chip while (read(uh_wkey_pair[0], buf, 1) > 0) { writeWkey(buf, 1); } } } // return NULL; } #endif /* * If we do not have pthreads, we cannot use the microham device. * This is so because we have to digest unsolicited messages * (e.g. voltage change) and since we have to send periodic * heartbeats. * Nevertheless, the program should compile well even we we do not * have pthreads, in this case start_thread is a dummy since uh_is_initialized * is never set. * * If we do not have socketpair(), the same thing applies. * * If we do not have select(), then the read thread cannot work so we * do not spawn it. */ static void start_thread() { #if defined(HAVE_PTHREAD) && defined(HAVE_SOCKETPAIR) && defined(HAVE_SELECT) /* * Find a microHam device and open serial port to it. * If successful, create sockets for doing I/O from within hamlib * and start a thread to listen to the "other ends" of the sockets */ int ret, fail; unsigned char buf[4]; pthread_attr_t attr; if (uh_is_initialized) { return; // PARANOIA: this should not happen } finddevices(); if (uh_device_fd < 0) { MYERROR("Could not open any microHam device.\n"); return; } // Create socket pairs if (socketpair(AF_UNIX, SOCK_STREAM, 0, uh_radio_pair) < 0) { perror("RadioPair:"); return; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, uh_ptt_pair) < 0) { perror("PTTPair:"); return; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, uh_wkey_pair) < 0) { perror("WkeyPair:"); return; } DEBUG("RADIO sockets: server=%d client=%d\n", uh_radio_pair[0], uh_radio_pair[1]); DEBUG("PTT sockets: server=%d client=%d\n", uh_ptt_pair[0], uh_ptt_pair[1]); DEBUG("WinKey sockets: server=%d client=%d\n", uh_wkey_pair[0], uh_wkey_pair[1]); // // Make the sockets nonblocking // First try if we can set flags, then do set the flags // fail = 0; ret = fcntl(uh_radio_pair[0], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_radio_pair[0], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } ret = fcntl(uh_ptt_pair[0], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_ptt_pair[0], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } ret = fcntl(uh_wkey_pair[0], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_wkey_pair[0], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } ret = fcntl(uh_radio_pair[1], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_radio_pair[1], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } ret = fcntl(uh_ptt_pair[1], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_ptt_pair[1], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } ret = fcntl(uh_wkey_pair[1], F_GETFL, 0); if (ret != -1) { ret = fcntl(uh_wkey_pair[1], F_SETFL, ret | O_NONBLOCK); } if (ret == -1) { fail = 1; } // // If something went wrong, close everything and return // if (fail) { close_all_files(); return; } // drain input from microHam device while (read(uh_device_fd, buf, 1) > 0) { // do_nothing } uh_is_initialized = 1; starttime = time(NULL); // Do some heartbeats to sync-in heartbeat(); heartbeat(); heartbeat(); // Set keyer mode to DIGITAL buf[0] = 0x0A; buf[1] = 0x03; buf[2] = 0x8a; writeControl(buf, 3); // Start background thread reading the microham device and the sockets pthread_attr_init(&attr); ret = pthread_create(&readthread, &attr, read_device, NULL); if (ret != 0) { MYERROR("Could not start read_device thread\n"); close_all_files(); uh_is_initialized = 0; return; } //TRACE("Started daemonized thread reading microHam\n"); #endif // if we do not have pthreads, this function does nothing. } /* * What comes now are "public" functions that can be called from outside * void uh_close_XXX() XXX= ptt, radio, wkey void uh_open_XXX() XXX= ptt, wkey void uh_open_radio(int baud, int databits, int stopbits, int rtscts) void uh_set_ptt(int ptt) int uh_get_ptt() * Note that it is not intended that any I/O is done via the PTT sockets * but hamlib needs a valid file descriptor! * */ /* * Close routines: * Mark the channel as closed, but close the connection * to the microHam device only if ALL channels are closed * * NOTE: hamlib repeatedly opens/closes the PTT port while keeping the * the radio port open. */ void uh_close_ptt() { uh_ptt_in_use = 0; if (!uh_radio_in_use && ! uh_wkey_in_use) { close_microham(); } } void uh_close_radio() { uh_radio_in_use = 0; if (!uh_ptt_in_use && ! uh_wkey_in_use) { close_microham(); } } void uh_close_wkey() { uh_wkey_in_use = 0; if (!uh_ptt_in_use && ! uh_radio_in_use) { close_microham(); } } int uh_open_ptt() { if (!uh_is_initialized) { start_thread(); if (!uh_is_initialized) { return -1; } } uh_ptt_in_use = 1; return uh_ptt_pair[1]; } int uh_open_wkey() { if (!uh_is_initialized) { start_thread(); if (!uh_is_initialized) { return -1; } } uh_wkey_in_use = 1; return uh_wkey_pair[1]; } // // Number of stop bits must be 1 or 2. // Number of data bits can be 5,6,7,8 // Hardware handshake (rtscts) can be on of off. // microHam devices ALWAYS use "no parity". // int uh_open_radio(int baud, int databits, int stopbits, int rtscts) { unsigned char string[5]; int baudrateConst; if (!uh_is_initialized) { start_thread(); if (!uh_is_initialized) { return -1; } } baudrateConst = 11059200 / baud ; string[0] = 0x01; string[1] = baudrateConst & 0xff ; string[2] = baudrateConst / 256 ; switch (stopbits) { case 1: string[3] = 0x00; break; case 2: string[3] = 0x40; break; default: return -1; } if (rtscts) { string[3] |= 0x10; } switch (databits) { case 5: break; case 6: string[3] |= 0x20; break; case 7: string[3] |= 0x40; break; case 8: string[3] |= 0x60; break; default: return -1; } string[4] = 0x81; writeControl(string, 5); uh_radio_in_use = 1; return uh_radio_pair[1]; } void uh_set_ptt(int ptt) { if (!uh_ptt_in_use) { MYERROR("%10d:SetPTT but not open\n", TIME); return; } DEBUG("%10d:SET PTT = %d\n", TIME, ptt); if (ptt) { statusbyte |= 0x04; } else { statusbyte &= ~0x04; } writeFlags(); } int uh_get_ptt() { // Possibly we can do better, but we just reflect // what we have done via uh_set_ptt. if (statusbyte & 0x04) { return 1; } else { return 0; } } hamlib-4.6.5/src/cache.c0000664000175000017500000004642315056640443010463 /* * Hamlib Interface - rig state cache routines * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "cache.h" #include "misc.h" #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE(r)->comm_state) /** * \file cache.c * \addtogroup rig * @{ */ int rig_set_cache_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); ENTERFUNC; rig_cache_show(rig, __func__, __LINE__); if (vfo == RIG_VFO_CURR) { // if CURR then update this before we figure out the real VFO vfo = rs->current_vfo; } else if (vfo == RIG_VFO_TX) { vfo = rs->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: TX VFO = %s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_RX) { vfo = rs->rx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: RX VFO = %s\n", __func__, rig_strvfo(vfo)); } // pick a sane default if (vfo == RIG_VFO_NONE || vfo == RIG_VFO_CURR) { vfo = RIG_VFO_A; } if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; }; if (vfo == RIG_VFO_OTHER) { vfo = vfo_fixup(rig, vfo, cachep->split); } if (vfo == rs->current_vfo) { cachep->modeCurr = mode; if (width > 0) { cachep->widthCurr = width; } elapsed_ms(&cachep->time_modeCurr, HAMLIB_ELAPSED_SET); } switch (vfo) { case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubC, HAMLIB_ELAPSED_INVALIDATE); break; case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_MAIN_A: cachep->modeMainA = mode; if (width > 0) { cachep->widthMainA = width; } elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_SET); elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_SET); break; case RIG_VFO_B: case RIG_VFO_SUB: case RIG_VFO_MAIN_B: cachep->modeMainB = mode; if (width > 0) { cachep->widthMainB = width; } elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_SET); elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_SET); break; case RIG_VFO_C: case RIG_VFO_MAIN_C: cachep->modeMainC = mode; if (width > 0) { cachep->widthMainC = width; } elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_SET); elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_SET); break; case RIG_VFO_SUB_A: cachep->modeSubA = mode; elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_SET); break; case RIG_VFO_SUB_B: cachep->modeSubB = mode; elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_SET); break; case RIG_VFO_SUB_C: cachep->modeSubC = mode; elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_SET); break; case RIG_VFO_MEM: cachep->modeMem = mode; elapsed_ms(&cachep->time_modeMem, HAMLIB_ELAPSED_SET); break; default: rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINTERNAL); } rig_cache_show(rig, __func__, __LINE__); RETURNFUNC(RIG_OK); } int rig_set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq) { int flag = HAMLIB_ELAPSED_SET; struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); if (rig_need_debug(RIG_DEBUG_CACHE)) { rig_cache_show(rig, __func__, __LINE__); } rig_debug(RIG_DEBUG_CACHE, "%s(%d): vfo=%s, current_vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); if (vfo == RIG_VFO_CURR) { // if CURR then update this before we figure out the real VFO vfo = rs->current_vfo; } // if freq == 0 then we are asking to invalidate the cache if (freq == 0) { flag = HAMLIB_ELAPSED_INVALIDATE; } // pick a sane default if (vfo == RIG_VFO_NONE || vfo == RIG_VFO_CURR) { vfo = RIG_VFO_A; } if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; }; if (rig_need_debug(RIG_DEBUG_CACHE)) { rig_debug(RIG_DEBUG_CACHE, "%s(%d): set vfo=%s to freq=%.0f\n", __func__, __LINE__, rig_strvfo(vfo), freq); } if (vfo == rs->current_vfo) { cachep->freqCurr = freq; elapsed_ms(&cachep->time_freqCurr, flag); } switch (vfo) { case RIG_VFO_ALL: // we'll use NONE to reset all VFO caches elapsed_ms(&cachep->time_freqMainA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqMainB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqMainC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqSubA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqSubB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqSubC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_freqMem, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubA, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubB, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_widthSubC, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_INVALIDATE); elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_INVALIDATE); break; case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_MAIN_A: cachep->freqMainA = freq; elapsed_ms(&cachep->time_freqMainA, flag); break; case RIG_VFO_B: case RIG_VFO_MAIN_B: case RIG_VFO_SUB: cachep->freqMainB = freq; elapsed_ms(&cachep->time_freqMainB, flag); break; case RIG_VFO_C: case RIG_VFO_MAIN_C: cachep->freqMainC = freq; elapsed_ms(&cachep->time_freqMainC, flag); break; case RIG_VFO_SUB_A: cachep->freqSubA = freq; elapsed_ms(&cachep->time_freqSubA, flag); break; case RIG_VFO_SUB_B: cachep->freqSubB = freq; elapsed_ms(&cachep->time_freqSubB, flag); break; case RIG_VFO_SUB_C: cachep->freqSubC = freq; elapsed_ms(&cachep->time_freqSubC, flag); break; case RIG_VFO_MEM: cachep->freqMem = freq; elapsed_ms(&cachep->time_freqMem, flag); break; case RIG_VFO_OTHER: rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): ignoring VFO_OTHER\n", __func__, __LINE__); break; default: rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); return (-RIG_EINVAL); } if (rig_need_debug(RIG_DEBUG_CACHE)) { rig_cache_show(rig, __func__, __LINE__); return (RIG_OK); } return (RIG_OK); } /** * \brief get cached values for a VFO * \param rig The rig handle * \param vfo The VFO to get information from * \param freq The frequency is stored here * \param cache_ms_freq The age of the last frequency update in ms * \param mode The mode is stored here * \param cache_ms_mode The age of the last mode update in ms * \param width The width is stored here * \param cache_ms_width The age of the last width update in ms * * Use this to query the cache and then determine to actually fetch data from * the rig. * * \note All pointers must be given. No pointer can be left at NULL * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq, rmode_t *mode, int *cache_ms_mode, pbwidth_t *width, int *cache_ms_width) { struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); if (CHECK_RIG_ARG(rig) || !freq || !cache_ms_freq || !mode || !cache_ms_mode || !width || !cache_ms_width) { return -RIG_EINVAL; } if (rig_need_debug(RIG_DEBUG_CACHE)) { ENTERFUNC2; } rig_debug(RIG_DEBUG_CACHE, "%s(%d): vfo=%s, current_vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } else if (vfo == RIG_VFO_TX) { vfo = rs->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: TX VFO = %s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_RX) { vfo = rs->rx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: RX VFO = %s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_OTHER) { switch (rs->current_vfo) { case RIG_VFO_CURR: break; // no change case RIG_VFO_OTHER: vfo = RIG_VFO_OTHER; break; case RIG_VFO_A: vfo = RIG_VFO_B; break; case RIG_VFO_MAIN_A: vfo = RIG_VFO_MAIN_B; break; case RIG_VFO_MAIN: vfo = RIG_VFO_SUB; break; case RIG_VFO_B: vfo = RIG_VFO_A; break; case RIG_VFO_MAIN_B: vfo = RIG_VFO_MAIN_A; break; case RIG_VFO_SUB_A: vfo = RIG_VFO_SUB_B; break; case RIG_VFO_SUB_B: vfo = RIG_VFO_SUB_A; break; case RIG_VFO_NONE: rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): ignoring VFO_NONE\n", __func__, __LINE__); break; default: rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo=%s, curr_vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); } } // pick a sane default if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } // If we're in satmode we map SUB to SUB_A if (vfo == RIG_VFO_SUB && cachep->satmode) { vfo = RIG_VFO_SUB_A; }; switch (vfo) { case RIG_VFO_CURR: *freq = cachep->freqCurr; *mode = cachep->modeCurr; *width = cachep->widthCurr; *cache_ms_freq = elapsed_ms(&cachep->time_freqCurr, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeCurr, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthCurr, HAMLIB_ELAPSED_GET); break; case RIG_VFO_OTHER: *freq = cachep->freqOther; *mode = cachep->modeOther; *width = cachep->widthOther; *cache_ms_freq = elapsed_ms(&cachep->time_freqOther, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeOther, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthOther, HAMLIB_ELAPSED_GET); break; case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_MAIN_A: *freq = cachep->freqMainA; *mode = cachep->modeMainA; *width = cachep->widthMainA; *cache_ms_freq = elapsed_ms(&cachep->time_freqMainA, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeMainA, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthMainA, HAMLIB_ELAPSED_GET); break; case RIG_VFO_B: case RIG_VFO_SUB: case RIG_VFO_MAIN_B: *freq = cachep->freqMainB; *mode = cachep->modeMainB; *width = cachep->widthMainB; *cache_ms_freq = elapsed_ms(&cachep->time_freqMainB, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeMainB, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthMainB, HAMLIB_ELAPSED_GET); break; case RIG_VFO_SUB_A: *freq = cachep->freqSubA; *mode = cachep->modeSubA; *width = cachep->widthSubA; *cache_ms_freq = elapsed_ms(&cachep->time_freqSubA, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeSubA, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthSubA, HAMLIB_ELAPSED_GET); break; case RIG_VFO_SUB_B: *freq = cachep->freqSubB; *mode = cachep->modeSubB; *width = cachep->widthSubB; *cache_ms_freq = elapsed_ms(&cachep->time_freqSubB, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeSubB, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthSubB, HAMLIB_ELAPSED_GET); break; case RIG_VFO_C: //case RIG_VFO_MAINC: // not used by any rig yet *freq = cachep->freqMainC; *mode = cachep->modeMainC; *width = cachep->widthMainC; *cache_ms_freq = elapsed_ms(&cachep->time_freqMainC, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeMainC, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthMainC, HAMLIB_ELAPSED_GET); break; case RIG_VFO_SUB_C: *freq = cachep->freqSubC; *mode = cachep->modeSubC; *width = cachep->widthSubC; *cache_ms_freq = elapsed_ms(&cachep->time_freqSubC, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeSubC, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthSubC, HAMLIB_ELAPSED_GET); break; case RIG_VFO_MEM: *freq = cachep->freqMem; *mode = cachep->modeMem; *width = cachep->widthMem; *cache_ms_freq = elapsed_ms(&cachep->time_freqMem, HAMLIB_ELAPSED_GET); *cache_ms_mode = elapsed_ms(&cachep->time_modeMem, HAMLIB_ELAPSED_GET); *cache_ms_width = elapsed_ms(&cachep->time_widthMem, HAMLIB_ELAPSED_GET); break; default: rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown vfo?, vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_CACHE, "%s(%d): vfo=%s, freq=%.0f, mode=%s, width=%d\n", __func__, __LINE__, rig_strvfo(vfo), (double)*freq, rig_strrmode(*mode), (int)*width); if (rig_need_debug(RIG_DEBUG_CACHE)) { RETURNFUNC2(RIG_OK); } return RIG_OK; } /** * \brief get cached values for a VFO * \param rig The rig handle * \param vfo The VFO to get information from * \param freq The frequency is stored here * \param cache_ms_freq The age of the last frequency update in ms -- NULL if you don't want it * Use this to query the frequency cache and then determine to actually fetch data from * the rig. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int rig_get_cache_freq(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq_p) { rmode_t mode; int cache_ms_freq; int cache_ms_mode; pbwidth_t width; int cache_ms_width; int retval; retval = rig_get_cache(rig, vfo, freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval == RIG_OK) { if (cache_ms_freq_p) { *cache_ms_freq_p = cache_ms_freq; } } return retval; } void rig_cache_show(RIG *rig, const char *func, int line) { struct rig_cache *cachep = CACHE(rig); rig_debug(RIG_DEBUG_CACHE, "%s(%d): freqMainA=%.0f, modeMainA=%s, widthMainA=%d\n", func, line, cachep->freqMainA, rig_strrmode(cachep->modeMainA), (int)cachep->widthMainA); rig_debug(RIG_DEBUG_CACHE, "%s(%d): freqMainB=%.0f, modeMainB=%s, widthMainB=%d\n", func, line, cachep->freqMainB, rig_strrmode(cachep->modeMainB), (int)cachep->widthMainB); if (STATE(rig)->vfo_list & RIG_VFO_SUB_A) { rig_debug(RIG_DEBUG_CACHE, "%s(%d): freqSubA=%.0f, modeSubA=%s, widthSubA=%d\n", func, line, cachep->freqSubA, rig_strrmode(cachep->modeSubA), (int)cachep->widthSubA); rig_debug(RIG_DEBUG_CACHE, "%s(%d): freqSubB=%.0f, modeSubB=%s, widthSubB=%d\n", func, line, cachep->freqSubB, rig_strrmode(cachep->modeSubB), (int)cachep->widthSubB); } } /*! @} */ hamlib-4.6.5/src/cm108.c0000664000175000017500000003066015056640443010244 /* * Hamlib Interface - CM108 HID communication low-level support * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2011 by Andrew Errington * CM108 detection code Copyright (c) Thomas Sailer used with permission * * 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. * */ /** * \addtogroup rig_internal * @{ */ /** * \file cm108.c * \brief CM108 GPIO support. * * CM108 Audio chips found on many USB audio interfaces have controllable * General Purpose Input/Output pins. */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_WINDOWS_H # include # include "par_nt.h" #endif #ifdef HAVE_WINIOCTL_H # include #endif #ifdef HAVE_WINBASE_H # include #endif #ifdef HAVE_LINUX_HIDRAW_H # include #endif #include "cm108.h" #include const char *get_usb_device_class_string(int device_class) { switch (device_class) { case 0x00: return "Device Unspecified (Defined at Interface level)"; case 0x01: return "Audio"; case 0x02: return "Communications and CDC Control"; case 0x03: return "Human Interface Device (HID)"; case 0x05: return "Physical Interface Device"; case 0x06: return "Image (Scanner, Camera)"; case 0x07: return "Printer"; case 0x08: return "Mass Storage"; case 0x09: return "Hub"; case 0x0A: return "CDC Data"; case 0x0B: return "Smart Card"; case 0x0D: return "Content Security"; case 0x0E: return "Video"; case 0x0F: return "Personal Healthcare"; case 0x10: return "Audio/Video Devices"; case 0x11: return "Billboard Device Class"; case 0x12: return "USB Type-C Bridge Class"; case 0x13: return "Bulk Display"; case 0x14: return "MCTCP over USB"; case 0x3C: return "I3C"; case 0x58: return "Xbox"; case 0xDC: return "Diagnostic Device"; case 0xE0: return "Wireless Controller"; case 0xEF: return "Miscellaneous"; case 0xFE: return "Application Specific"; case 0xFF: return "Vendor Specific"; default: return "Unknown Device Class"; } } /** * \brief Open CM108 HID port (/dev/hidrawX). * * \param port The port structure. * * \return File descriptor, otherwise a **negative value** if an error * occurred (in which case, cause is set appropriately). * * \retval RIG_EINVAL The port pathname is empty or no CM108 device detected. * \retval RIG_EIO The `open`(2) system call returned a **negative value**. */ int cm108_open(hamlib_port_t *port) { int fd; #ifdef HAVE_LINUX_HIDRAW_H struct hidraw_devinfo hiddevinfo; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port->pathname[0]) { return -RIG_EINVAL; } fd = open(port->pathname, O_RDWR); if (fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: opening device \"%s\": %s\n", __func__, port->pathname, strerror(errno)); return -RIG_EIO; } #ifdef HAVE_LINUX_HIDRAW_H // CM108 detection copied from Thomas Sailer's soundmodem code rig_debug(RIG_DEBUG_VERBOSE, "%s: checking for cm108 (or compatible) device\n", __func__); if (!ioctl(fd, HIDIOCGRAWINFO, &hiddevinfo) && ((hiddevinfo.vendor == 0x0d8c // CM108/108B/109/119/119A/119B && ((hiddevinfo.product >= 0x0008 && hiddevinfo.product <= 0x000f) || hiddevinfo.product == 0x0012 || hiddevinfo.product == 0x013a || hiddevinfo.product == 0x013c || hiddevinfo.product == 0x0013)) // SSS1621/23 || (hiddevinfo.vendor == 0x0c76 && (hiddevinfo.product == 0x1605 || hiddevinfo.product == 0x1607 || hiddevinfo.product == 0x160b)))) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cm108 compatible device detected\n", __func__); } else { close(fd); rig_debug(RIG_DEBUG_VERBOSE, "%s: no cm108 (or compatible) device detected\n", __func__); return -RIG_EINVAL; } #endif port->fd = fd; return fd; } /** * \brief Close a CM108 HID port. * * \param port The port structure * * \return Zero if the port was closed successfully, otherwise -1 if an error * occurred (in which case, the system `errno`(3) is set appropriately). * * \sa The `close`(2) system call. */ int cm108_close(hamlib_port_t *port) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return close(port->fd); } /** * \brief Set or unset the Push To Talk bit on a CM108 GPIO. * * \param p The port structure. * \param pttx RIG_PTT_ON --> Set PTT, else unset PTT. * * \return RIG_OK on success, otherwise a **negative value** if an error * occurred (in which case, cause is set appropriately). * * \retval RIG_OK Setting or unsetting the PTT was successful. * \retval RIG_EINVAL The file descriptor is invalid or the PTT type is * unsupported. * \retval RIG_EIO The `write`(2) system call returned a **negative value**. */ int cm108_ptt_set(hamlib_port_t *p, ptt_t pttx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // For a CM108 USB audio device PTT is wired up to one of the GPIO // pins. Usually this is GPIO3 (bit 2 of the GPIO register) because it // is on the corner of the chip package (pin 13) so it's easily accessible. // Some CM108 chips are epoxy-blobbed onto the PCB, so no GPIO // pins are accessible. The SSS1623 chips have a different pinout, so // we make the GPIO bit number configurable. switch (p->type.ptt) { case RIG_PTT_CM108: { ssize_t bytes; char out_rep[] = { 0x00, // report number // HID output report 0x00, (pttx == RIG_PTT_ON) ? (1 << p->parm.cm108.ptt_bitnum) : 0, // set GPIO 1 << p->parm.cm108.ptt_bitnum, // Data direction register (1=output) 0x00 }; // Build a packet for CM108 HID to turn GPIO bit on or off. // Packet is 4 bytes, preceded by a 'report number' byte // 0x00 report number // Write data packet (from CM108 documentation) // byte 0: 00xx xxxx Write GPIO // byte 1: xxxx dcba GPIO3-0 output values (1=high) // byte 2: xxxx dcba GPIO3-0 data-direction register (1=output) // byte 3: xxxx xxxx SPDIF rig_debug(RIG_DEBUG_VERBOSE, "%s: bit number %d to state %d\n", __func__, p->parm.cm108.ptt_bitnum, (pttx == RIG_PTT_ON) ? 1 : 0); if (p->fd == -1) { return -RIG_EINVAL; } // Send the HID packet bytes = write(p->fd, out_rep, sizeof(out_rep)); if (bytes < 0) { return -RIG_EIO; } return RIG_OK; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, p->type.ptt); return -RIG_EINVAL; } return RIG_OK; } /** * \brief Get the state of Push To Talk from a CM108 GPIO. * * \param p The port structure. * \param pttx Return value (must be non NULL). * * \return RIG_OK on success, otherwise a **negative value** if an error * occurred (in which case, cause is set appropriately). * * \retval RIG_OK Getting the PTT state was successful. * \retval RIG_ENIMPL Getting the state is not yet implemented. * \retval RIG_ENAVAIL Getting the state is not available for this PTT type. */ int cm108_ptt_get(hamlib_port_t *p, ptt_t *pttx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (p->type.ptt) { case RIG_PTT_CM108: { return -RIG_ENIMPL; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, p->type.ptt); return -RIG_ENAVAIL; } return RIG_OK; } #ifdef XXREMOVEXX // Not referenced anywhere /** * \brief get Data Carrier Detect (squelch) from CM108 GPIO * \param p * \param dcdx return value (Must be non NULL) * \return RIG_OK or < 0 error */ int cm108_dcd_get(hamlib_port_t *p, dcd_t *dcdx) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } #endif int cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ssize_t bytes; char out_rep[] = { 0x00, // report number // HID output report 0x00, bit ? (1 << (gpio - 1)) : 0, // set GPIO 1 << (gpio - 1), // Data direction register (1=output) 0x00 }; rig_debug(RIG_DEBUG_VERBOSE, "%s: out_rep = 0x%02x 0x%02x\n", __func__, out_rep[2], out_rep[3]); // Build a packet for CM108 HID to turn GPIO bit on or off. // Packet is 4 bytes, preceded by a 'report number' byte // 0x00 report number // Write data packet (from CM108 documentation) // byte 0: 00xx xxxx Write GPIO // byte 1: xxxx dcba GPIO3-0 output values (1=high) // byte 2: xxxx dcba GPIO3-0 data-direction register (1=output) // byte 3: xxxx xxxx SPDIF // Send the HID packet bytes = write(p->fd, out_rep, sizeof(out_rep)); if (bytes < 0) { return -RIG_EIO; } return RIG_OK; } int cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit) { ssize_t bytes; char reply[4]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); char in_rep[] = { 0x00, // report number 0x01, // HID input report 0x00, 0x00 }; // Send the HID packet bytes = write(p->fd, in_rep, sizeof(in_rep)); if (bytes < 0) { return -RIG_EIO; } bytes = read(p->fd, reply, sizeof(reply)); if (bytes <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read error: %s\n", __func__, strerror(errno)); return -RIG_EPROTO; } int mask = 1 << (gpio - 1); *bit = (reply[1] & mask) != 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: mask=0x%02x, reply=0x%02x 0x%02x 0x%02x 0x%02x, bit=%d\n", __func__, mask, reply[0], reply[1], reply[2], reply[3], *bit); return RIG_OK; } int rig_cm108_get_bit(hamlib_port_t *p, enum GPIO gpio, int *bit) { if (gpio < 1 || gpio > 4) { rig_debug(RIG_DEBUG_ERR, "%s: gpio must be 1,2,3,4 for cm108\n", __func__); return -RIG_EINVAL; } cm108_get_bit(p, gpio, bit); rig_debug(RIG_DEBUG_TRACE, "%s: gpio=%d bit=%d\n", __func__, gpio, *bit); return RIG_OK; } int rig_cm108_set_bit(hamlib_port_t *p, enum GPIO gpio, int bit) { if (gpio < 1 || gpio > 4) { rig_debug(RIG_DEBUG_ERR, "%s: gpio must be 1,2,3,4 for cm108\n", __func__); return -RIG_EINVAL; } int retval = cm108_set_bit(p, gpio, bit); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cm108_set_bit: %s\n", __func__, strerror(retval)); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: simulated gpio=%d bit=%d\n", __func__, gpio, bit); return RIG_OK; } /** @} */ hamlib-4.6.5/src/iofunc.h0000664000175000017500000000566015056640443010706 /* * Hamlib Interface - io function header * Copyright (c) 2000-2005 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _IOFUNC_H #define _IOFUNC_H 1 #include #include extern HAMLIB_EXPORT(int) port_open(hamlib_port_t *p); extern HAMLIB_EXPORT(int) port_close(hamlib_port_t *p, rig_port_t port_type); extern HAMLIB_EXPORT(int) read_block(hamlib_port_t *p, unsigned char *rxbuffer, size_t count); extern HAMLIB_EXPORT(int) read_block_direct(hamlib_port_t *p, unsigned char *rxbuffer, size_t count); extern HAMLIB_EXPORT(int) write_block(hamlib_port_t *p, const unsigned char *txbuffer, size_t count); extern HAMLIB_EXPORT(int) write_block_sync(hamlib_port_t *p, const unsigned char *txbuffer, size_t count); extern HAMLIB_EXPORT(int) write_block_sync_error(hamlib_port_t *p, const unsigned char *txbuffer, size_t count); extern HAMLIB_EXPORT(int) port_flush_sync_pipes(hamlib_port_t *p); extern HAMLIB_EXPORT(int) read_string(hamlib_port_t *p, unsigned char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len, int flush_flag, int expected_len); extern HAMLIB_EXPORT(int) read_string_direct(hamlib_port_t *p, unsigned char *rxbuffer, size_t rxmax, const char *stopset, int stopset_len, int flush_flag, int expected_len); #endif /* _IOFUNC_H */ hamlib-4.6.5/src/rig.c0000664000175000017500000073332115056640443010201 /* * Hamlib Interface - main file * Copyright (c) 2021 by Mikael Nousiainen * Copyright (c) 2000-2012 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /** * \addtogroup rig * @{ */ /** * \file src/rig.c * \brief Ham Radio Control Libraries interface * \author Stephane Fillod * \author Frank Singleton * \date 2000-2012 * * Hamlib provides a user-callable API, a set of "front-end" routines that * call rig-specific "back-end" routines which actually communicate with * the physical rig. */ /** * \page rig Rig (radio) interface * * For us, a "rig" is an item of general remote controllable radio equipment. * Generally, there are a VFO settings, gain controls, etc. */ /** * \example ../tests/testrig.c */ #include "hamlib/rig.h" #include "hamlib/config.h" #include "fifo.h" #include #include #include #include #include #include #include #include "mutex.h" #include "serial.h" #include "parallel.h" #include "network.h" #include "event.h" #include "cm108.h" #include "gpio.h" #include "misc.h" #include "sprintflst.h" #include "hamlibdatetime.h" #include "cache.h" /** * \brief Hamlib short license name * */ const char *hamlib_license = "LGPL"; /** * \brief Hamlib release number * * The version number has the format x.y.z */ /* * Careful: The hamlib 1.2 ABI implicitly specifies a size of 21 bytes for * the hamlib_version string. Changing the size provokes a warning from the * dynamic loader. */ //! @cond Doxygen_Suppress const char hamlib_version[21] = "Hamlib " PACKAGE_VERSION; #if INTPTR_MAX == INT128_MAX #define ARCHBITS "128-bit" #elif INTPTR_MAX == INT64_MAX #define ARCHBITS "64-bit" #else #define ARCHBITS "32-bit" #endif //! @endcond const char *hamlib_version2 = "Hamlib " PACKAGE_VERSION " " HAMLIBDATETIME " " ARCHBITS; HAMLIB_EXPORT_VAR(int) cookie_use; HAMLIB_EXPORT_VAR(int) skip_init; HAMLIB_EXPORT_VAR(int) lock_mode; // for use by rigctld HAMLIB_EXPORT_VAR(powerstat_t) rig_powerstat; // for use by both rigctld and rigctl struct rig_caps caps_test; /** * \brief Hamlib copyright notice */ const char *hamlib_copyright2 = "Copyright (C) 2000-2012 Stephane Fillod\n" "Copyright (C) 2000-2003 Frank Singleton\n" "Copyright (C) 2014-2020 Michael Black W9MDB\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."; //! @cond Doxygen_Suppress const char hamlib_copyright[231] = /* hamlib 1.2 ABI specifies 231 bytes */ "Copyright (C) 2000-2012 Stephane Fillod\n" "Copyright (C) 2000-2003 Frank Singleton\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."; //! @endcond #ifndef DOC_HIDDEN #if defined(WIN32) && !defined(__CYGWIN__) # define DEFAULT_SERIAL_PORT "\\\\.\\COM1" #elif BSD # define DEFAULT_SERIAL_PORT "/dev/cuaa0" #elif MACOSX # define DEFAULT_SERIAL_PORT "/dev/cu.usbserial" #else # define DEFAULT_SERIAL_PORT "/dev/ttyS0" #endif #if defined(WIN32) # define DEFAULT_PARALLEL_PORT "\\\\.\\$VDMLPT1" #elif defined(HAVE_DEV_PPBUS_PPI_H) # define DEFAULT_PARALLEL_PORT "/dev/ppi0" #else # define DEFAULT_PARALLEL_PORT "/dev/parport0" #endif #if defined(WIN32) && !defined(__CYGWIN__) # define DEFAULT_CM108_PORT "fixme" #elif BSD # define DEFAULT_CM108_PORT "fixme" #else # define DEFAULT_CM108_PORT "/dev/hidraw0" #endif #define DEFAULT_TUNER_CONTROL_PATHNAME "hamlib_tuner_control" #if defined(WIN32) && !defined(__CYGWIN__) /* FIXME: Determine correct GPIO bit number for W32 using MinGW. */ # define DEFAULT_CM108_PTT_BITNUM 2 #elif BSD /* FIXME: Determine correct GPIO bit number for *BSD. */ # define DEFAULT_CM108_PTT_BITNUM 2 #else # define DEFAULT_CM108_PTT_BITNUM 2 #endif #define DEFAULT_GPIO_PORT "0" #define CHECK_RIG_ARG(r) (!(r) || !(r)->caps || !STATE((r))->comm_state) #define CHECK_RIG_CAPS(r) (!(r) || !(r)->caps) #define ICOM_EXCEPTIONS (rig->caps->rig_model == RIG_MODEL_IC9700 || rig->caps->rig_model == RIG_MODEL_IC9100 || rig->caps->rig_model == RIG_MODEL_IC910) // If the OS/library supports it, use a recursive mutex for the main lock. // This eliminates depth races, and guards against multiple app threads, too. // Set define to 0 to use depth-based locking. It should be deduced from the // environment, but I can't find a fine-grained enough parameter. Should be // OK on any POSIX-2017 or later system. #define USE_RECURSIVE_MUTEX 1 #if USE_RECURSIVE_MUTEX #define LOCK(n) rig_lock(rig,n) #else // The LOCK macro is for the primary thread calling the rig functions // For a separate thread use rig_lock directly // The purpose here is to avoid deadlock during recursion // Any other thread should grab the mutex itself via rig_lock #define LOCK(n) if (STATE(rig)->depth == 1) { rig_debug(RIG_DEBUG_CACHE, "%s: %s\n", n?"lock":"unlock", __func__); rig_lock(rig,n); } #endif MUTEX(morse_mutex); #ifdef HAVE_PTHREAD // returns true if mutex is busy int MUTEX_CHECK(pthread_mutex_t *m) { int trylock = pthread_mutex_trylock(m); if (trylock != EBUSY) { pthread_mutex_unlock(m); } return trylock == EBUSY; } #else #define MUTEX_CHECK(var) 0 #endif /* * Data structure to track the opened rig (by rig_open) */ struct opened_rig_l { RIG *rig; struct opened_rig_l *next; }; static struct opened_rig_l *opened_rig_list = { NULL }; /* * Careful, the order must be the same as their RIG_E* counterpart! * TODO: localise the messages.. */ static const char *const rigerror_table[] = { "Command completed successfully", "Invalid parameter", "Invalid configuration", "Memory shortage", "Feature not implemented", "Communication timed out", "IO error", "Internal Hamlib error", "Protocol error", "Command rejected by the rig", "Command performed, but arg truncated, result not guaranteed", "Feature not available", "Target VFO unaccessible", "Communication bus error", "Communication bus collision", "NULL RIG handle or invalid pointer parameter", "Invalid VFO", "Argument out of domain of func", "Function deprecated", "Security error password not provided or crypto failure", "Rig is not powered on", "Limit exceeded", "Access denied" }; #define ERROR_TBL_SZ (sizeof(rigerror_table)/sizeof(char *)) #if defined(HAVE_PTHREAD) typedef struct async_data_handler_args_s { RIG *rig; } async_data_handler_args; typedef struct async_data_handler_priv_data_s { pthread_t thread_id; async_data_handler_args args; } async_data_handler_priv_data; static int async_data_handler_start(RIG *rig); static int async_data_handler_stop(RIG *rig); void *async_data_handler(void *arg); #endif #if defined(HAVE_PTHREAD) typedef struct morse_data_handler_args_s { RIG *rig; } morse_data_handler_args; typedef struct morse_data_handler_priv_data_s { pthread_t thread_id; morse_data_handler_args args; volatile FIFO_RIG fifo_morse; int keyspd; } morse_data_handler_priv_data; static int morse_data_handler_start(RIG *rig); static int morse_data_handler_stop(RIG *rig); int morse_data_handler_set_keyspd(RIG *rig, int keyspd); void *morse_data_handler(void *arg); #endif /* * track which rig is opened (with rig_open) * needed at least for transceive mode */ static int add_opened_rig(RIG *rig) { struct opened_rig_l *p; ENTERFUNC2; p = (struct opened_rig_l *)calloc(1, sizeof(struct opened_rig_l)); if (!p) { RETURNFUNC2(-RIG_ENOMEM); } p->rig = rig; p->next = opened_rig_list; opened_rig_list = p; RETURNFUNC2(RIG_OK); } static int remove_opened_rig(const RIG *rig) { struct opened_rig_l *p, *q; q = NULL; for (p = opened_rig_list; p; p = p->next) { if (p->rig == rig) { if (q == NULL) { opened_rig_list = opened_rig_list->next; } else { q->next = p->next; } free(p); return (RIG_OK); } q = p; } return (-RIG_EINVAL); /* Not found in list ! */ } /** * \brief execs cfunc() on each opened rig * \param cfunc The function to be executed on each rig * \param data Data pointer to be passed to cfunc() * * Calls cfunc() function for each opened rig. * The contents of the opened rig table * is processed in random order according to a function * pointed to by \a cfunc, which is called with two arguments, * the first pointing to the RIG handle, the second * to a data pointer \a data. * If \a data is not needed, then it can be set to NULL. * The processing of the opened rig table is stopped * when cfunc() returns 0. * \internal * * \return always RIG_OK. */ // cppcheck-suppress unusedFunction int foreach_opened_rig(int (*cfunc)(RIG *, rig_ptr_t), rig_ptr_t data) { struct opened_rig_l *p; for (p = opened_rig_list; p; p = p->next) { if ((*cfunc)(p->rig, data) == 0) { return (RIG_OK); } } return (RIG_OK); } #endif /* !DOC_HIDDEN */ char debugmsgsave[DEBUGMSGSAVE_SIZE] = ""; char debugmsgsave2[DEBUGMSGSAVE_SIZE] = ""; // deprecated char debugmsgsave3[DEBUGMSGSAVE_SIZE] = ""; // deprecated MUTEX(mutex_debugmsgsave); void add2debugmsgsave(const char *s) { char *p; char stmp[DEBUGMSGSAVE_SIZE]; int i, nlines; int maxmsg = DEBUGMSGSAVE_SIZE / 2; MUTEX_LOCK(mutex_debugmsgsave); memset(stmp, 0, sizeof(stmp)); // we'll keep 20 lines including this one // so count the lines for (i = 0, nlines = 0; debugmsgsave[i] != 0; ++i) { if (debugmsgsave[i] == '\n') { ++nlines; } } // strip the last 19 lines p = debugmsgsave; while ((nlines > 19 || strlen(debugmsgsave) > maxmsg) && p != NULL) { p = strchr(debugmsgsave, '\n'); if (p && strlen(p + 1) > 0) { strcpy(stmp, p + 1); strcpy(debugmsgsave, stmp); } else { debugmsgsave[0] = '\0'; } --nlines; if (nlines == 0 && strlen(debugmsgsave) > maxmsg) { strcpy(debugmsgsave, "!!!!debugmsgsave too long\n"); } } if (strlen(stmp) + strlen(s) + 1 < DEBUGMSGSAVE_SIZE) { strcat(debugmsgsave, s); } else { rig_debug(RIG_DEBUG_BUG, "%s: debugmsgsave overflow!! len of debugmsgsave=%d, len of add=%d\n", __func__, (int)strlen(debugmsgsave), (int)strlen(s)); } MUTEX_UNLOCK(mutex_debugmsgsave); } /** * \brief get string describing the error code * \param errnum The error code * \return the appropriate description string, otherwise a NULL pointer * if the error code is unknown. * * Returns a string describing the error code passed in the argument \a * errnum. * * \todo support gettext/localization */ const char *HAMLIB_API rigerror2(int errnum) // returns single-line message { errnum = abs(errnum); if (errnum >= ERROR_TBL_SZ) { // This should not happen, but if it happens don't return NULL return "ERR_OUT_OF_RANGE"; } static char msg[DEBUGMSGSAVE_SIZE / 2]; snprintf(msg, sizeof(msg), "%s\n", rigerror_table[errnum]); return msg; } const char *HAMLIB_API rigerror(int errnum) { errnum = abs(errnum); if (errnum >= ERROR_TBL_SZ) { // This should not happen, but if it happens don't return NULL return "ERR_OUT_OF_RANGE"; } static char msg[DEBUGMSGSAVE_SIZE]; #if 0 // we have to remove LF from debugmsgsave since calling function controls LF char *p = &debugmsgsave[strlen(debugmsgsave) - 1]; if (*p == '\n') { *p = 0; } #endif #if 0 SNPRINTF(msg, sizeof(msg), "%.80s\n%.15000s%.15000s%.15000s", rigerror_table[errnum], debugmsgsave3, debugmsgsave2, debugmsgsave); #else snprintf(msg, sizeof(msg), "%s\n", rigerror_table[errnum]); add2debugmsgsave(msg); snprintf(msg, sizeof(msg), "%s", debugmsgsave); #endif return msg; } // We use a couple of defined pointer to determine if the shared library changes void *caps_test_rig_model = &caps_test.rig_model; void *caps_test_macro_name = &caps_test.macro_name; // check and show WARN if rig_caps structure doesn't match // this tests for shared library incompatibility static int rig_check_rig_caps() { int rc = RIG_OK; if (&caps_test.rig_model != caps_test_rig_model) { rc = -RIG_EINTERNAL; rig_debug(RIG_DEBUG_WARN, "%s: shared library change#1\n", __func__); } if (&caps_test.macro_name != caps_test_macro_name) { rc = -RIG_EINTERNAL; rig_debug(RIG_DEBUG_WARN, "%s: shared library change#2\n", __func__); } //if (rc != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: p1=%p, p2=%p, rig_model=%p, macro_name=%p\n", __func__, caps_test_rig_model, caps_test_macro_name, &caps_test.rig_model, &caps_test.macro_name); } return (rc); } /** * \brief Allocate a new #RIG handle. * \param rig_model The rig model for this new handle * * Allocates a new RIG handle and initializes the associated data * for \a rig_model. * * \return a pointer to the #RIG handle otherwise NULL if memory allocation * failed or \a rig_model is unknown (e.g. backend autoload failed). * * \sa rig_cleanup(), rig_open() */ RIG *HAMLIB_API rig_init(rig_model_t rig_model) { RIG *rig; const struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *rp, *pttp, *dcdp; struct rig_cache *cachep; int i; if (rig_test_2038(NULL)) { rig_debug(RIG_DEBUG_WARN, "%s: 2038 time test failed....some time values may be incorrect\n", __func__); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: 2038 time test passed\n", __func__); } rig_check_rig_caps(); rig_check_backend(rig_model); caps = rig_get_caps(rig_model); if (!caps) { return (NULL); } rig_debug(RIG_DEBUG_VERBOSE, "%s: rig_model=%s %s %s\n", __func__, caps->mfg_name, caps->model_name, caps->version); if (caps->hamlib_check_rig_caps != NULL) { if (caps->hamlib_check_rig_caps[0] != 'H' || strncmp(caps->hamlib_check_rig_caps, HAMLIB_CHECK_RIG_CAPS, strlen(caps->hamlib_check_rig_caps)) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Error validating integrity of rig_caps\nPossible hamlib DLL incompatibility\n", __func__); return (NULL); } } else { rig_debug(RIG_DEBUG_WARN, "%s: backend for %s does not contain hamlib_check_rig_caps\n", __func__, caps->model_name); } /* * okay, we've found it. Allocate some memory and set it to zeros, * and especially the callbacks */ rig = calloc(1, sizeof(RIG)); if (rig == NULL) { /* * FIXME: how can the caller know it's a memory shortage, * and not "rig not found" ? */ return (NULL); } /* caps is const, so we need to tell compiler that we know what we are doing */ rig->caps = (struct rig_caps *) caps; /* * populate the rig->state * TODO: read the Preferences here! */ rs = STATE(rig); #if defined(HAVE_PTHREAD) pthread_mutex_init(&rs->mutex_set_transaction, NULL); #endif //TODO Allocate and link ports // For now, use the embedded ones rp = RIGPORT(rig); pttp = PTTPORT(rig); dcdp = DCDPORT(rig); //TODO Ditto for cache cachep = CACHE(rig); rs->rig_model = caps->rig_model; rs->priv = NULL; rs->async_data_enabled = 0; // rs->depth = 1; rs->comm_state = 0; rs->comm_status = RIG_COMM_STATUS_CONNECTING; rs->tuner_control_pathname = DEFAULT_TUNER_CONTROL_PATHNAME; strncpy(rs->client_version, "Hamlib", sizeof(rs->client_version)); rp->fd = -1; pttp->fd = -1; #if 0 // extra debug if needed rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %p rs->comm_state==0?=%d\n", __func__, __LINE__, &rs->comm_state, rs->comm_state); #endif rp->type.rig = caps->port_type; /* default from caps */ #if defined(HAVE_PTHREAD) rp->asyncio = 0; #endif switch (caps->port_type) { case RIG_PORT_SERIAL: strncpy(rp->pathname, DEFAULT_SERIAL_PORT, HAMLIB_FILPATHLEN - 1); rp->parm.serial.rate = caps->serial_rate_max; /* fastest ! */ rp->parm.serial.data_bits = caps->serial_data_bits; rp->parm.serial.stop_bits = caps->serial_stop_bits; rp->parm.serial.parity = caps->serial_parity; rp->parm.serial.handshake = caps->serial_handshake; break; case RIG_PORT_PARALLEL: strncpy(rp->pathname, DEFAULT_PARALLEL_PORT, HAMLIB_FILPATHLEN - 1); break; /* Adding support for CM108 GPIO. This is compatible with CM108 series * USB audio chips from CMedia and SSS1623 series USB audio chips from 3S */ case RIG_PORT_CM108: strncpy(rp->pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); if (rp->parm.cm108.ptt_bitnum == 0) { rp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; pttp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; } break; case RIG_PORT_GPIO: strncpy(rp->pathname, DEFAULT_GPIO_PORT, HAMLIB_FILPATHLEN); break; case RIG_PORT_NETWORK: case RIG_PORT_UDP_NETWORK: strncpy(rp->pathname, "127.0.0.1:4532", HAMLIB_FILPATHLEN - 1); break; default: strncpy(rp->pathname, "", HAMLIB_FILPATHLEN - 1); } rp->write_delay = caps->write_delay; rp->post_write_delay = caps->post_write_delay; // since we do two timeouts now we can cut the timeout in half for serial if (caps->port_type == RIG_PORT_SERIAL && caps->timeout_retry >= 0) { rp->timeout = caps->timeout / 2; } rp->retry = caps->retry; if (caps->timeout_retry < 0) { // Rigs may disable read timeout retries rp->timeout_retry = 0; } else if (caps->timeout_retry == 0) { // Default to 1 retry for read timeouts rp->timeout_retry = 1; } else { rp->timeout_retry = caps->timeout_retry; } pttp->type.ptt = caps->ptt_type; dcdp->type.dcd = caps->dcd_type; rs->vfo_comp = 0.0; /* override it with preferences */ rs->current_vfo = RIG_VFO_CURR; /* we don't know yet! */ rs->vfo_ops = caps->vfo_ops; rs->rx_vfo = RIG_VFO_CURR; /* we don't know yet! */ rs->tx_vfo = RIG_VFO_CURR; /* we don't know yet! */ rs->poll_interval = 1000; // enable polling by default #if 0 rs->multicast_data_addr = "224.0.0.1"; // do not enable multicast data publishing by default rs->multicast_cmd_addr = "224.0.0.2"; // enable multicast command server by default #else rs->multicast_data_addr = "0.0.0.0"; // do not enable multicast data publishing by default rs->multicast_cmd_addr = "0.0.0.0"; // enable multicast command server by default #endif rs->multicast_data_port = 4532; rs->multicast_cmd_port = 4532; rs->lo_freq = 0; cachep->timeout_ms = 500; // 500ms cache timeout by default cachep->ptt = 0; rs->targetable_vfo = rig->caps->targetable_vfo; rs->model_name = rig->caps->model_name; rs->mfg_name = rig->caps->mfg_name; rs->version = rig->caps->version; rs->copyright = rig->caps->copyright; rs->status = rig->caps->status; // We are using range_list1 as the default // Eventually we will have separate model number for different rig variations // So range_list1 will become just range_list (per model) // See ic9700.c for a 5-model example // Every rig should have a rx_range // Rig backends need updating for new range_list format memcpy(rs->rx_range_list, caps->rx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->tx_range_list, caps->tx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); // if we don't have list1 we'll try list2 if (rs->rx_range_list[0].startf == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rx_range_list1 is empty, using rx_range_list2\n", __func__); memcpy(rs->tx_range_list, caps->rx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->tx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); } if (rs->tx_range_list[0].startf == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig does not have tx_range!!\n", __func__); //return(NULL); // this is not fatal } //if (rs->level_gran) { memcpy(rs->level_gran, rig->caps->level_gran, sizeof(rs->level_gran)); } #if 0 // this is no longer applicable -- replace it with something? // we need to be able to figure out what model radio we have // before we can set up the rig_state with the rig's specific freq range // if we can't figure out what model rig we have this is impossible // so we will likely have to make this a parameter the user provides // or eliminate this logic entirely and make specific RIG_MODEL entries switch (rs->itu_region) { case RIG_ITU_REGION1: memcpy(rs->tx_range_list, caps->tx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; case RIG_ITU_REGION2: case RIG_ITU_REGION3: default: memcpy(rs->tx_range_list, caps->tx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; } #endif rs->vfo_list = 0; rs->mode_list = 0; for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(caps->rx_range_list1[i]); i++) { rs->vfo_list |= caps->rx_range_list1[i].vfo; rs->mode_list |= caps->rx_range_list1[i].modes; } for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(caps->tx_range_list1[i]); i++) { rs->vfo_list |= caps->tx_range_list1[i].vfo; rs->mode_list |= caps->tx_range_list1[i].modes; } for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(caps->rx_range_list2[i]); i++) { rs->vfo_list |= caps->rx_range_list2[i].vfo; rs->mode_list |= caps->rx_range_list2[i].modes; } for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(caps->tx_range_list2[i]); i++) { rs->vfo_list |= caps->tx_range_list2[i].vfo; rs->mode_list |= caps->tx_range_list2[i].modes; } if (rs->vfo_list & RIG_VFO_A) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_A\n", __func__); } if (rs->vfo_list & RIG_VFO_B) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_B\n", __func__); } if (rs->vfo_list & RIG_VFO_C) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_C\n", __func__); } if (rs->vfo_list & RIG_VFO_SUB_A) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_SUB_A\n", __func__); } if (rs->vfo_list & RIG_VFO_SUB_B) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_SUB_B\n", __func__); } if (rs->vfo_list & RIG_VFO_MAIN_A) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_MAIN_A\n", __func__); } if (rs->vfo_list & RIG_VFO_MAIN_B) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_MAIN_B\n", __func__); } if (rs->vfo_list & RIG_VFO_SUB) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_SUB\n", __func__); } if (rs->vfo_list & RIG_VFO_MAIN) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_MAIN\n", __func__); } if (rs->vfo_list & RIG_VFO_MEM) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has VFO_MEM\n", __func__); } memcpy(rs->preamp, caps->preamp, sizeof(int)*HAMLIB_MAXDBLSTSIZ); memcpy(rs->attenuator, caps->attenuator, sizeof(int)*HAMLIB_MAXDBLSTSIZ); memcpy(rs->tuning_steps, caps->tuning_steps, sizeof(struct tuning_step_list)*HAMLIB_TSLSTSIZ); memcpy(rs->filters, caps->filters, sizeof(struct filter_list)*HAMLIB_FLTLSTSIZ); memcpy(&rs->str_cal, &caps->str_cal, sizeof(cal_table_t)); memcpy(rs->chan_list, caps->chan_list, sizeof(chan_t)*HAMLIB_CHANLSTSIZ); rs->has_get_func = caps->has_get_func; rs->has_set_func = caps->has_set_func; rs->has_get_level = caps->has_get_level; rs->has_set_level = caps->has_set_level; rs->has_get_parm = caps->has_get_parm; rs->has_set_parm = caps->has_set_parm; /* emulation by frontend */ if ((caps->has_get_level & RIG_LEVEL_STRENGTH) == 0 && (caps->has_get_level & RIG_LEVEL_RAWSTR) == RIG_LEVEL_RAWSTR) { rs->has_get_level |= RIG_LEVEL_STRENGTH; } memcpy(rs->level_gran, caps->level_gran, sizeof(gran_t)*RIG_SETTING_MAX); memcpy(rs->parm_gran, caps->parm_gran, sizeof(gran_t)*RIG_SETTING_MAX); rs->max_rit = caps->max_rit; rs->max_xit = caps->max_xit; rs->max_ifshift = caps->max_ifshift; rs->announces = caps->announces; rp->fd = pttp->fd = dcdp->fd = -1; // some rigs (like SDR) behave different when checking for power on // So we assume power is on until one of the backends KNOWS it is off rs->powerstat = RIG_POWER_ON; // default to power on until proven otherwise // we have to copy rs to rig->state_deprecated for DLL backwards compatibility memcpy(&rig->state_deprecated, rs, sizeof(rig->state_deprecated)); // Set up lock for any API entry point // If available, use a recursive mutex. Else, fall back on the // depth count. pthread_mutexattr_t api_attr; pthread_mutexattr_init(&api_attr); #if USE_RECURSIVE_MUTEX pthread_mutexattr_settype(&api_attr, PTHREAD_MUTEX_RECURSIVE); HAMLIB_TRACE; #endif pthread_mutex_init(&rs->api_mutex, &api_attr); pthread_mutexattr_destroy(&api_attr); /* * Give the backend a chance to setup his private data * This must be done only once defaults are setup, * so the backend init can override rig_state. */ if (caps->rig_init != NULL) { int retcode = caps->rig_init(rig); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: backend_init failed!\n", __func__); /* cleanup and exit */ free(rig); return (NULL); } } return (rig); } /** * \brief open the communication to the rig * \param rig The #RIG handle of the radio to be opened * * Opens communication to a radio which \a RIG handle has been passed * by argument. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \retval RIG_EINVAL \a rig is NULL or inconsistent. * \retval RIG_ENIMPL port type communication is not implemented yet. * * \sa rig_init(), rig_close() */ int HAMLIB_API rig_open(RIG *rig) { struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *rp, *pttp, *dcdp; int status = RIG_OK; value_t parm_value; //unsigned int net1, net2, net3, net4, net5, net6, net7, net8, port; int is_network = 0; int retval = 0; ENTERFUNC2; if (!rig || !rig->caps) { RETURNFUNC2(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); rp = RIGPORT(rig); pttp = PTTPORT(rig); dcdp = DCDPORT(rig); rp->rig = rig; rs->rigport_deprecated.rig = rig; if (strcmp(rp->pathname, "USB") == 0) { rig_debug(RIG_DEBUG_ERR, "%s: 'USB' is not a valid COM port name\n", __func__); errno = 2; RETURNFUNC2(-RIG_EINVAL); } // rigctl/rigctld may have deprecated values -- backwards compatibility if (rs->rigport_deprecated.pathname[0] != 0) { strcpy(rp->pathname, rs->rigport_deprecated.pathname); } if (rs->pttport_deprecated.type.ptt != RIG_PTT_NONE) { pttp->type.ptt = rs->pttport_deprecated.type.ptt; } if (rs->dcdport_deprecated.type.dcd != RIG_DCD_NONE) { dcdp->type.dcd = rs->dcdport_deprecated.type.dcd; } if (rs->pttport_deprecated.pathname[0] != 0) { strcpy(pttp->pathname, rs->pttport_deprecated.pathname); } if (rs->dcdport_deprecated.pathname[0] != 0) { strcpy(dcdp->pathname, rs->dcdport_deprecated.pathname); } rig_settings_load_all(NULL); // load default .hamlib_settings // Read in our settings char *cwd = calloc(1, 4096); if (getcwd(cwd, 4096) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: getcwd: %s\n", __func__, strerror(errno)); } else { //rig_debug(RIG_DEBUG_VERBOSE, "%s: cwd=%s\n", __func__, cwd); char *path = calloc(1, 8192); extern char settings_file[4096]; const char *xdgpath = getenv("XDG_CONFIG_HOME"); strcpy(settings_file, "hamlib_settings"); if (xdgpath) { sprintf(path, "%s/%s/%s", xdgpath, cwd, settings_file); } else { sprintf(path, "%s/%s", cwd, settings_file); } const FILE *fp = fopen(path, "r"); if (fp == NULL) { //rig_debug(RIG_DEBUG_VERBOSE, "%s: %s %s\n", __func__, path, strerror(errno)); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading settings from %s\n", __func__, path); } free(path); } free(cwd); // Enable async data only if it's enabled through conf settings *and* supported by the backend rig_debug(RIG_DEBUG_TRACE, "%s: async_data_enable=%d, async_data_supported=%d\n", __func__, rs->async_data_enabled, caps->async_data_supported); rs->async_data_enabled = rs->async_data_enabled && caps->async_data_supported; rp->asyncio = rs->async_data_enabled; if (strlen(rp->pathname) > 0) { char hoststr[256], portstr[6]; status = parse_hoststr(rp->pathname, sizeof(rp->pathname), hoststr, portstr); if (status == RIG_OK) { is_network = 1; } } #if 0 // determine if we have a network address // is_network |= sscanf(rp->pathname, "%u.%u.%u.%u:%u", &net1, &net2, &net3, &net4, &port) == 5; is_network |= sscanf(rp->pathname, ":%u", &port) == 1; is_network |= sscanf(rp->pathname, "%u::%u:%u:%u:%u:%u", &net1, &net2, &net3, &net4, &net5, &port) == 6; is_network |= sscanf(rp->pathname, "%u:%u:%u:%u:%u:%u:%u:%u:%u", &net1, &net2, &net3, &net4, &net5, &net6, &net7, &net8, &port) == 9; // if we haven't met one of the condition above then we must have a hostname if (!is_network && (token = strtok_r(rp->pathname, ":", &strtokp))) { rig_debug(RIG_DEBUG_TRACE, "%s: token1=%s\n", __func__, token); token = strtok_r(strtokp, ":", &strtokp); if (token) { rig_debug(RIG_DEBUG_TRACE, "%s: token2=%s\n", __func__, token); if (sscanf(token, "%u", &port)) { is_network |= 1; } } } #endif if (is_network) { rig_debug(RIG_DEBUG_TRACE, "%s: using network address %s\n", __func__, rp->pathname); rp->type.rig = RIG_PORT_NETWORK; if (rig->caps->rig_model == RIG_MODEL_SMARTSDR_A || rig->caps->rig_model == RIG_MODEL_SMARTSDR_B || rig->caps->rig_model == RIG_MODEL_SMARTSDR_C || rig->caps->rig_model == RIG_MODEL_SMARTSDR_D || rig->caps->rig_model == RIG_MODEL_SMARTSDR_E || rig->caps->rig_model == RIG_MODEL_SMARTSDR_F || rig->caps->rig_model == RIG_MODEL_SMARTSDR_G || rig->caps->rig_model == RIG_MODEL_SMARTSDR_H ) { if (strstr(rp->pathname, "127.0.0.1")) { rig_debug_clear(); rig_debug(RIG_DEBUG_ERR, "%s: Do not use 127.0.0.1 for SmartSDR. Network Server entry needs to be the Radio's IP address, no port necessary\n", __func__); return -RIG_EINVAL; } } if (RIG_BACKEND_NUM(rig->caps->rig_model) == RIG_ICOM) { // Xiegu X6100 does TCP and does not support UDP spectrum that I know of #if 0 if (rig->caps->rig_model != RIG_MODEL_X6100) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): Icom rig UDP network enabled\n", __FILE__, __LINE__); rp->type.rig = RIG_PORT_UDP_NETWORK; } #endif } } if (rs->comm_state) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %p rs->comm_state==1?=%d\n", __func__, __LINE__, &rs->comm_state, rs->comm_state); port_close(rp, rp->type.rig); rs->comm_state = 0; RETURNFUNC2(-RIG_EINVAL); } rs->comm_status = RIG_COMM_STATUS_CONNECTING; rp->fd = -1; if (rp->type.rig == RIG_PORT_SERIAL) { if (rp->parm.serial.rts_state != RIG_SIGNAL_UNSET && rp->parm.serial.handshake == RIG_HANDSHAKE_HARDWARE) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set RTS with hardware handshake \"%s\"\n", __func__, rp->pathname); RETURNFUNC2(-RIG_ECONF); } if ('\0' == pttp->pathname[0] || !strcmp(pttp->pathname, rp->pathname)) { /* check for control line conflicts */ if (rp->parm.serial.rts_state != RIG_SIGNAL_UNSET && pttp->type.ptt == RIG_PTT_SERIAL_RTS) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set RTS with PTT by RTS \"%s\"\n", __func__, rp->pathname); RETURNFUNC2(-RIG_ECONF); } if (rp->parm.serial.dtr_state != RIG_SIGNAL_UNSET && pttp->type.ptt == RIG_PTT_SERIAL_DTR) { rig_debug(RIG_DEBUG_ERR, "%s: cannot set DTR with PTT by DTR \"%s\"\n", __func__, rp->pathname); RETURNFUNC2(-RIG_ECONF); } } } rp->timeout = caps->timeout; status = port_open(rp); if (status < 0) { //rig_debug(RIG_DEBUG_VERBOSE, "%s: rs->comm_state==0?=%d\n", __func__, rs->comm_state); rs->comm_state = 0; rs->comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); } switch (pttp->type.ptt) { case RIG_PTT_NONE: case RIG_PTT_RIG: case RIG_PTT_RIG_MICDATA: break; case RIG_PTT_SERIAL_RTS: case RIG_PTT_SERIAL_DTR: if (pttp->pathname[0] == '\0' && rp->type.rig == RIG_PORT_SERIAL) { strcpy(pttp->pathname, rp->pathname); } if (!strcmp(pttp->pathname, rp->pathname)) { pttp->fd = rp->fd; /* Needed on Linux because the serial port driver sets RTS/DTR on open - only need to address the PTT line as we offer config parameters to control the other (dtr_state & rts_state) */ if (pttp->type.ptt == RIG_PTT_SERIAL_DTR) { status = ser_set_dtr(pttp, 0); } if (pttp->type.ptt == RIG_PTT_SERIAL_RTS) { status = ser_set_rts(pttp, 0); } } else { pttp->fd = ser_open(pttp); if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, pttp->pathname); status = -RIG_EIO; } if (RIG_OK == status && (pttp->type.ptt == RIG_PTT_SERIAL_DTR || pttp->type.ptt == RIG_PTT_SERIAL_RTS)) { /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both low since we offer no control of the non-PTT line and low is better than high */ status = ser_set_dtr(pttp, 0); if (RIG_OK == status) { status = ser_set_rts(pttp, 0); } } ser_close(pttp); } break; case RIG_PTT_PARALLEL: pttp->fd = par_open(pttp); if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, pttp->pathname); status = -RIG_EIO; } else { par_ptt_set(pttp, RIG_PTT_OFF); } break; case RIG_PTT_CM108: pttp->fd = cm108_open(pttp); strncpy(rp->pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN); if (rp->parm.cm108.ptt_bitnum == 0) { rp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; pttp->parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM; } if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, pttp->pathname); status = -RIG_EIO; } else { cm108_ptt_set(pttp, RIG_PTT_OFF); } break; case RIG_PTT_GPIO: case RIG_PTT_GPION: pttp->fd = gpio_open(pttp, 1, RIG_PTT_GPION == pttp->type.ptt ? 0 : 1); if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"GPIO%s\"\n", __func__, pttp->pathname); status = -RIG_EIO; } else { gpio_ptt_set(pttp, RIG_PTT_OFF); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, pttp->type.ptt); status = -RIG_ECONF; } switch (dcdp->type.dcd) { case RIG_DCD_NONE: case RIG_DCD_RIG: break; case RIG_DCD_SERIAL_DSR: case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_CAR: if (dcdp->pathname[0] == '\0' && rp->type.rig == RIG_PORT_SERIAL) { strcpy(dcdp->pathname, rp->pathname); } if (strcmp(dcdp->pathname, rp->pathname) == 0) { dcdp->fd = rp->fd; } else { dcdp->fd = ser_open(dcdp); } if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"%s\"\n", __func__, dcdp->pathname); status = -RIG_EIO; } break; case RIG_DCD_PARALLEL: dcdp->fd = par_open(dcdp); if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"%s\"\n", __func__, dcdp->pathname); status = -RIG_EIO; } break; case RIG_DCD_GPIO: case RIG_DCD_GPION: dcdp->fd = gpio_open(dcdp, 0, RIG_DCD_GPION == dcdp->type.dcd ? 0 : 1); if (dcdp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open DCD device \"GPIO%s\"\n", __func__, dcdp->pathname); status = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported DCD type %d\n", __func__, dcdp->type.dcd); status = -RIG_ECONF; } if (status < 0) { port_close(rp, rp->type.rig); rs->comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); } rs->comm_state = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: %p rs->comm_state==1?=%d\n", __func__, &rs->comm_state, rs->comm_state); hl_usleep(100 * 1000); // wait a bit after opening to give some serial ports time /* * Maybe the backend has something to initialize * In case of failure, just close down and report error code. */ int retry_save = rp->retry; rp->retry = 0; if (caps->rig_open != NULL) { if (caps->get_powerstat != NULL && !skip_init) { powerstat_t powerflag; status = rig_get_powerstat(rig, &powerflag); if (status == RIG_OK && (powerflag == RIG_POWER_OFF || powerflag == RIG_POWER_STANDBY) && rs->auto_power_on == 0) { // rig_open() should succeed even if the rig is powered off, so simply log power status rig_debug(RIG_DEBUG_ERR, "%s: rig power is off, use --set-conf=auto_power_on=1 or set_powerstat if power on is wanted\n", __func__); } // don't need auto_power_on if power is already on if (status == RIG_OK && powerflag == RIG_POWER_ON) { STATE(rig)->auto_power_on = 0; } if (status == -RIG_ETIMEOUT) { // rig_open() should succeed even if get_powerstat() fails, // as many rigs cannot get power status while powered off rig_debug(RIG_DEBUG_ERR, "%s: Some rigs cannot get_powerstat while off\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: Known rigs: K3, K3S\n", __func__); } } status = caps->rig_open(rig); if (status != RIG_OK) { remove_opened_rig(rig); port_close(rp, rp->type.rig); memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); rs->comm_state = 0; rs->comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); } } /* * trigger state->current_vfo first retrieval */ if (caps->get_vfo && rig_get_vfo(rig, &rs->current_vfo) == RIG_OK) { rs->tx_vfo = rs->current_vfo; } else { // No get_vfo available, so set some sensible defaults rs->tx_vfo = RIG_VFO_TX; // If we haven't gotten the VFO by now we will default to VFO_CURR if (rs->current_vfo == RIG_VFO_NONE) { rs->current_vfo = RIG_VFO_CURR; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_curr=%s, tx_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo), rig_strvfo(rs->tx_vfo)); if (rig->caps->set_vfo == NULL) { // for non-Icom rigs if there's no set_vfo then we need to set one rs->current_vfo = vfo_fixup(rig, RIG_VFO_A, CACHE(rig)->split); rig_debug(RIG_DEBUG_TRACE, "%s: No set_vfo function rig so default vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); } else { rig_debug(RIG_DEBUG_TRACE, "%s: default vfo = %s\n", __func__, rig_strvfo(rs->current_vfo)); } } if (skip_init) { RETURNFUNC2(RIG_OK); } #if defined(HAVE_PTHREAD) status = async_data_handler_start(rig); if (status < 0) { port_close(rp, rp->type.rig); rs->comm_status = RIG_COMM_STATUS_ERROR; RETURNFUNC2(status); } // Some models don't support CW so don't need morse handler if (rig->caps->send_morse) { status = morse_data_handler_start(rig); if (status < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cw_data_handler_start failed: %.23000s\n", __func__, rigerror(status)); port_close(rp, rp->type.rig); RETURNFUNC2(status); } } #endif if (rs->auto_disable_screensaver) { // try to turn off the screensaver if possible // don't care about the return here...it's just a nice-to-have parm_value.i = 0; HAMLIB_TRACE; rig_set_parm(rig, RIG_PARM_SCREENSAVER, parm_value); } // read frequency, mode and split to update internal status // don't care about the command return values here -- if they don't succeed, so be it freq_t freq; if (rig->caps->get_freq) { vfo_t myvfo = RIG_VFO_A; if (ICOM_EXCEPTIONS) { myvfo = RIG_VFO_MAIN_A; } if ((STATE(rig)->vfo_list & RIG_VFO_VFO) == RIG_VFO_VFO) { myvfo = RIG_VFO_VFO; } retval = rig_get_freq(rig, myvfo, &freq); if (retval == RIG_OK && rig->caps->rig_model != RIG_MODEL_F6K && ((STATE(rig)->vfo_list & RIG_VFO_VFO) == RIG_VFO_VFO)) { split_t split = RIG_SPLIT_OFF; vfo_t tx_vfo = RIG_VFO_NONE; myvfo = RIG_VFO_B; if (ICOM_EXCEPTIONS) { myvfo = RIG_VFO_MAIN_B; } rig_get_freq(rig, myvfo, &freq); rig_get_split_vfo(rig, RIG_VFO_RX, &split, &tx_vfo); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Current split=%d, tx_vfo=%s\n", __func__, __LINE__, split, rig_strvfo(tx_vfo)); rmode_t mode; pbwidth_t width = 2400; // use 2400Hz as default width if (rig->caps->get_mode) { myvfo = RIG_VFO_A; if (ICOM_EXCEPTIONS) { myvfo = RIG_VFO_MAIN_A; } rig_get_mode(rig, myvfo, &mode, &width); if (split) { myvfo = RIG_VFO_B; if (ICOM_EXCEPTIONS) { myvfo = RIG_VFO_MAIN_A; } rig_debug(RIG_DEBUG_VERBOSE, "xxxsplit=%d\n", split); HAMLIB_TRACE; rig_get_mode(rig, myvfo, &mode, &width); } } } } rp->retry = retry_save; memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); memcpy(&rs->pttport_deprecated, pttp, sizeof(hamlib_port_t_deprecated)); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(hamlib_port_t_deprecated)); int timesave = rs->timeout; rs->timeout = 0; rig_flush_force(rp, 1); rs->timeout = timesave; #if defined(HAVE_PTHREAD) enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE | RIG_MULTICAST_SPECTRUM; retval = network_multicast_publisher_start(rig, rs->multicast_data_addr, rs->multicast_data_port, items); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_publisher_start failed: %.23000s\n", __FILE__, rigerror(retval)); // we will consider this non-fatal for now } retval = network_multicast_receiver_start(rig, rs->multicast_cmd_addr, rs->multicast_cmd_port); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_receiver_start failed: %.23000s\n", __FILE__, rigerror(retval)); // we will consider this non-fatal for now } retval = rig_poll_routine_start(rig); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_poll_routine_start failed: %.23000s\n", __FILE__, rigerror(retval)); // we will consider this non-fatal for now } #endif rs->comm_status = RIG_COMM_STATUS_OK; add_opened_rig(rig); RETURNFUNC2(RIG_OK); } /** * \brief close the communication to the rig * \param rig The #RIG handle of the radio to be closed * * Closes communication to a radio which \a RIG handle has been passed * by argument that was previously open with rig_open(). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_cleanup(), rig_open() */ int HAMLIB_API rig_close(RIG *rig) { const struct rig_caps *caps; hamlib_port_t *rp, *pttp, *dcdp; struct rig_state *rs; if (!rig || !rig->caps) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; rs = STATE(rig); rp = RIGPORT(rig); pttp = PTTPORT(rig); dcdp = DCDPORT(rig); if (!rs->comm_state) { RETURNFUNC(-RIG_EINVAL); } remove_opened_rig(rig); rs->comm_status = RIG_COMM_STATUS_DISCONNECTED; #if defined(HAVE_PTHREAD) if (!skip_init) { morse_data_handler_stop(rig); async_data_handler_stop(rig); rig_poll_routine_stop(rig); network_multicast_receiver_stop(rig); network_multicast_publisher_stop(rig); } #endif // Let the backend say 73 to the rig. // and ignore the return code. if (caps->rig_close) { caps->rig_close(rig); } /* * FIXME: what happens if PTT and rig ports are the same? * (eg. ptt_type = RIG_PTT_SERIAL) */ switch (pttp->type.ptt) { case RIG_PTT_NONE: case RIG_PTT_RIG: case RIG_PTT_RIG_MICDATA: break; case RIG_PTT_SERIAL_RTS: // If port is already closed, do nothing if (pttp->fd > -1) { ser_set_rts(pttp, 0); if (pttp->fd != rp->fd) { port_close(pttp, RIG_PORT_SERIAL); memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } } break; case RIG_PTT_SERIAL_DTR: // If port is already closed, do nothing if (pttp->fd > -1) { ser_set_dtr(pttp, 0); if (pttp->fd != rp->fd) { port_close(pttp, RIG_PORT_SERIAL); memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } } break; case RIG_PTT_PARALLEL: par_ptt_set(pttp, RIG_PTT_OFF); par_close(pttp); break; case RIG_PTT_CM108: cm108_ptt_set(pttp, RIG_PTT_OFF); cm108_close(pttp); break; case RIG_PTT_GPIO: case RIG_PTT_GPION: gpio_ptt_set(pttp, RIG_PTT_OFF); gpio_close(pttp); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT type %d\n", __func__, pttp->type.ptt); } switch (dcdp->type.dcd) { case RIG_DCD_NONE: case RIG_DCD_RIG: break; case RIG_DCD_SERIAL_DSR: case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_CAR: if (dcdp->fd != rp->fd) { port_close(dcdp, RIG_PORT_SERIAL); memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); } break; case RIG_DCD_PARALLEL: par_close(dcdp); break; case RIG_DCD_GPIO: case RIG_DCD_GPION: gpio_close(dcdp); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported DCD type %d\n", __func__, dcdp->type.dcd); } dcdp->fd = pttp->fd = -1; port_close(rp, rp->type.rig); // zero split so it will allow it to be set again on open for rigctld CACHE(rig)->split = 0; rs->comm_state = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %p rs->comm_state==0?=%d\n", __func__, __LINE__, &rs->comm_state, rs->comm_state); RETURNFUNC(RIG_OK); } /** * \brief release a rig handle and free associated memory * \param rig The #RIG handle of the radio to be closed * * Releases a rig struct which port has eventually been closed already * with rig_close(). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_init(), rig_close() */ int HAMLIB_API rig_cleanup(RIG *rig) { if (!rig || !rig->caps) { return (-RIG_EINVAL); } /* * check if they forgot to close the rig */ if (STATE(rig)->comm_state) { rig_close(rig); } /* * basically free up the priv struct */ if (rig->caps->rig_cleanup) { rig->caps->rig_cleanup(rig); } //pthread_mutex_destroy(&STATE(rig)->api_mutex); //TODO Release and null any allocated data - // state, ports, cache, etc. free(rig); return (RIG_OK); } /** * \brief timeout (secs) to stop rigctld when VFO is manually changed * \param rig The rig handle * \param seconds The timeout to set to * * timeout seconds to stop rigctld when VFO is manually changed * turns on/off the radio. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_twiddle() */ int HAMLIB_API rig_set_twiddle(RIG *rig, int seconds) { if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; STATE(rig)->twiddle_timeout = seconds; RETURNFUNC(RIG_OK); } /** * \brief For GPredict to avoid reading frequency on uplink VFO * \param rig The rig handle * \param val 1=Ignore Sub, 2=Ignore Main * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_set_uplink(RIG *rig, int val) { if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; STATE(rig)->uplink = val; RETURNFUNC(RIG_OK); } /** * \brief get the twiddle timeout value (secs) * \param rig The rig handle * \param seconds The timeout value * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_twiddle() */ int HAMLIB_API rig_get_twiddle(RIG *rig, int *seconds) { if (CHECK_RIG_ARG(rig) || !seconds) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps or seconds is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; *seconds = STATE(rig)->twiddle_timeout; RETURNFUNC(RIG_OK); } // detect if somebody is twiddling the VFO // indicator is last set freq doesn't match current freq // so we have to query freq every time we set freq or vfo to handle this static int twiddling(RIG *rig) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); if (rs->twiddle_timeout == 0) { return 0; } // don't detect twiddling ENTERFUNC2; caps = rig->caps; if (caps->get_freq) // gotta have get_freq of course { freq_t curr_freq = 0; int retval2; int elapsed; HAMLIB_TRACE; retval2 = caps->get_freq(rig, RIG_VFO_CURR, &curr_freq); if (retval2 == RIG_OK && rs->current_freq != curr_freq) { rig_debug(RIG_DEBUG_TRACE, "%s: Somebody twiddling the VFO? last_freq=%.0f, curr_freq=%.0f\n", __func__, rs->current_freq, curr_freq); if (rs->current_freq == 0) { rs->current_freq = curr_freq; RETURNFUNC2(0); // not twiddling as first time freq is being set } rs->twiddle_time = time(NULL); // update last twiddle time rs->current_freq = curr_freq; // we have a new freq to remember rig_set_cache_freq(rig, RIG_VFO_CURR, curr_freq); } elapsed = time(NULL) - rs->twiddle_time; if (elapsed < rs->twiddle_timeout) { rig_debug(RIG_DEBUG_TRACE, "%s: Twiddle elapsed < %d, elapsed=%d\n", __func__, rs->twiddle_timeout, elapsed); rs->twiddle_state = TWIDDLE_ON; // gets turned off in rig_set_freq; RETURNFUNC2(1); // would be better as error but other software won't handle it } } RETURNFUNC2(0); } #include "band_changed.c" // for rigs that do not have targetable VFO // skip setting frequency on the non-active vfo // this allow gpredict to work correctly on these rigs // but we might have trou static int skip_freq(RIG *rig, vfo_t vfo) { struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); int retval = 0; // if option is not select do not skip // WSJT-X needs set all the time....gpredict can skip // This is due to their behavior...WSJT-X sets TX VFO before PTT // gpredict needs to set Doppler all the time so causes VFO flashing on rigs without TARGETABLE_FREQ if (rs->freq_skip == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: not skipping set_freq on vfo %s\n", __func__, rig_strvfo(vfo)); return 0; } if (cachep->ptt && cachep->split && ((rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) == 0) && (vfo == RIG_VFO_RX || vfo == rs->rx_vfo)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: skip setting frequency on RX vfo when PTT is on\n", __func__); retval = 1; } if ((!cachep->ptt) && cachep->split && ((rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) == 0) && (vfo == RIG_VFO_TX || vfo == rs->tx_vfo)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: skip setting frequency on TX vfo when PTT is not on\n", __func__); retval = 1; } return retval; } /** * \brief set the frequency of the target VFO * \param rig The rig handle * \param vfo The target VFO * \param freq The frequency to set to * * Sets the frequency of the target VFO. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_freq() */ #if BUILTINFUNC #undef rig_set_freq int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq, const char *func) #define rig_set_freq(r,v,f) rig_set_freq(r,v,f,__builtin_FUNCTION()) #else int rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) #endif { const struct rig_caps *caps; struct rig_cache *cachep; struct rig_state *rs; int retcode; freq_t freq_new = freq; vfo_t vfo_save; static int last_band = -1; int curr_band; int band_changing = 0; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } cachep = CACHE(rig); rs = STATE(rig); curr_band = rig_get_band(rig, freq, -1); if (rs->tx_vfo == vfo && curr_band != last_band) { struct rig_cache *cachep = CACHE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: band changing to %s\n", __func__, rig_get_band_str(rig, curr_band, 0)); band_changing = 1; //rig_band_changed(rig, curr_band); last_band = curr_band; if (cachep->ptt) { rig_set_ptt(rig, RIG_VFO_CURR, RIG_PTT_OFF); hl_usleep(200); // make sure PTT is off } } ELAPSED1; ENTERFUNC; LOCK(1); #if BUILTINFUNC rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, freq=%.0f, called from %s\n", __func__, rig_strvfo(vfo), freq, func); #else rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, freq=%.0f\n", __func__, rig_strvfo(vfo), freq); #endif if (rs->doppler == 0) { if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN || (vfo == RIG_VFO_CURR && rs->current_vfo == RIG_VFO_A)) { if (cachep->freqMainA != freq && (((int)freq % 10) != 0) && (((int)freq % 100) != 55)) { rs->doppler = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, cachep->freqMainA); } freq += rs->offset_vfoa; } else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && rs->current_vfo == RIG_VFO_B)) { if (cachep->freqMainB != freq && ((int)freq % 10) != 0 && (((int)freq % 100) != 55)) { rs->doppler = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): potential doppler detected because old freq %f != new && new freq has 1Hz or such values\n", __func__, __LINE__, cachep->freqMainB); } freq += rs->offset_vfob; } } if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq += rs->offset_vfoa; } else if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { freq += rs->offset_vfob; } if (rs->twiddle_state == TWIDDLE_ON) { // we keep skipping set_freq while the vfo knob is in motion rig_debug(RIG_DEBUG_VERBOSE, "%s: Twiddle on so skipping this set_freq request one time\n", __func__); rs->twiddle_state = TWIDDLE_OFF; } caps = rig->caps; if (rs->lo_freq != 0.0) { freq -= rs->lo_freq; } if (rs->vfo_comp != 0.0) { freq += (freq_t)((double)rs->vfo_comp * freq); } if (caps->set_freq == NULL) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } vfo_save = rs->current_vfo; vfo = vfo_fixup(rig, vfo, cachep->split); if (vfo == RIG_VFO_CURR) { vfo = vfo_save; } if (skip_freq(rig, vfo)) { ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } if ((caps->targetable_vfo & RIG_TARGETABLE_FREQ) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { if (twiddling(rig)) { rig_debug(RIG_DEBUG_TRACE, "%s: Ignoring set_freq due to VFO twiddling\n", __func__); if (vfo != vfo_save && vfo != RIG_VFO_CURR) { HAMLIB_TRACE; rig_set_vfo(rig, vfo_save); } ELAPSED2; LOCK(0); RETURNFUNC( RIG_OK); // would be better as error but other software won't handle errors } rig_debug(RIG_DEBUG_TRACE, "%s: TARGETABLE_FREQ vfo=%s\n", __func__, rig_strvfo(vfo)); int retry = 3; freq_t tfreq = 0; do { retcode = caps->set_freq(rig, vfo, freq); if (band_changing) { rig_band_changed(rig, curr_band); } // disabling the freq check as of 2023-06-02 // seems unnecessary and slows down rigs unnecessarily tfreq = freq; // some rig will return -RIG_ENTARGET if cannot set ptt while transmitting // we will just return RIG_OK and the frequency set will be ignored if (retcode == -RIG_ENTARGET) { LOCK(0); RETURNFUNC(RIG_OK); } if (retcode != RIG_OK) { LOCK(0); RETURNFUNC(retcode); } // Unidirectional rigs do not reset cache if (rig->caps->rig_model != RIG_MODEL_FT736R) { rig_set_cache_freq(rig, vfo, (freq_t)0); } #if 0 // this verification seems to be causing bad behavior on some rigs if (caps->get_freq) { retcode = rig_get_freq(rig, vfo, &tfreq); // WSJT-X does a 55Hz check so we can stop early if that's the case if ((long long)freq % 100 == 55) { retry = 0; } if (retcode != RIG_OK) { LOCK(0); RETURNFUNC(retcode); } if (tfreq != freq) { hl_usleep(50 * 1000); rig_debug(RIG_DEBUG_WARN, "%s: freq not set correctly?? got %.0f asked for %.0f, retry=%d\n", __func__, (double)tfreq, (double)freq, retry); } } else { retry = 0; } tfreq = freq; #endif } while (tfreq != freq && retry-- > 0); if (retry == 0 && tfreq != freq) { rig_debug(RIG_DEBUG_ERR, "%s: unable to set frequency!!, asked for %.0f, got %.0f\n", __func__, freq, tfreq); } } else { rig_debug(RIG_DEBUG_TRACE, "%s: not a TARGETABLE_FREQ vfo=%s\n", __func__, rig_strvfo(vfo)); if (!caps->set_vfo) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } retcode = rig_set_vfo(rig, vfo); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_vfo failed: %.23000s\n", __func__, rigerror(retcode)); } if (twiddling(rig)) { rig_debug(RIG_DEBUG_TRACE, "%s: Ignoring set_freq due to VFO twiddling\n", __func__); if (vfo != vfo_save && vfo != RIG_VFO_CURR) { HAMLIB_TRACE; rig_set_vfo(rig, vfo_save); } ELAPSED2; LOCK(0); RETURNFUNC( RIG_OK); // would be better as error but other software won't handle errors } HAMLIB_TRACE; if (band_changing) { rig_band_changed(rig, curr_band); } retcode = caps->set_freq(rig, vfo, freq); } if (retcode == RIG_OK && caps->get_freq != NULL) { // verify our freq to ensure HZ mods are seen // some rigs truncate or round e.g. 1,2,5,10,20,100Hz intervals // we'll try this all the time and if it works out OK eliminate the #else if (((unsigned long long)freq % 100 != 0 // only need to do if < 100Hz interval || freq > 100e6) // or if we are in the VHF and up range #if 0 // do we need to only do this when cache is turned on? 2020-07-02 W9MDB && cachep->timeout_ms > 0 #endif ) { // some rigs we can skip this check for speed sake if (rs->rig_model == RIG_MODEL_MALACHITE) { rig_set_cache_freq(rig, vfo, freq); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } // Unidirectional rigs do not reset cache if (rig->caps->rig_model != RIG_MODEL_FT736R) { rig_set_cache_freq(rig, RIG_VFO_ALL, (freq_t)0); } HAMLIB_TRACE; retcode = rig_get_freq(rig, vfo, &freq_new); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } } if (freq_new != freq) { rig_debug(RIG_DEBUG_TRACE, "%s: Asked freq=%.0f, got freq=%.0f\n", __func__, freq, freq_new); } } // update our current freq too if (vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { rs->current_freq = freq_new; } rig_set_cache_freq(rig, vfo, freq_new); rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, save=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(vfo_save)); if (vfo != vfo_save && vfo != RIG_VFO_CURR) { HAMLIB_TRACE; rig_set_vfo(rig, vfo_save); } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief get the frequency of the target VFO * \param rig The rig handle * \param vfo The target VFO * \param freq The location where to store the current frequency * * Retrieves the frequency of the target VFO. * The value stored at \a freq location equals RIG_FREQ_NONE when the current * frequency of the VFO is not defined (e.g. blank memory). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_freq() */ #if BUILTINFUNC #undef rig_get_freq int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq, const char *func) #define rig_get_freq(r,v,f) rig_get_freq(r,v,f,__builtin_FUNCTION()) #else int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) #endif { const struct rig_caps *caps; struct rig_cache *cachep; struct rig_state *rs; int retcode; vfo_t curr_vfo; rmode_t mode; pbwidth_t width; int curr_band; int use_cache = 0; static int last_band = -1; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } rs = STATE(rig); cachep = CACHE(rig); ENTERFUNC; #if BUILTINFUNC rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, called from %s\n", __func__, rig_strvfo(vfo), func); #else rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); #endif ELAPSED1; if (!freq) { rig_debug(RIG_DEBUG_TRACE, "%s: freq ptr invalid\n", __func__); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) called vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); rig_cache_show(rig, __func__, __LINE__); curr_vfo = rs->current_vfo; // save vfo for restore later vfo = vfo_fixup(rig, vfo, cachep->split); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) vfo=%s, curr_vfo=%s\n", __FILE__, __LINE__, rig_strvfo(vfo), rig_strvfo(curr_vfo)); if (MUTEX_CHECK(&morse_mutex)) { use_cache = 1; } if (vfo == RIG_VFO_CURR) { vfo = curr_vfo; } // we ignore get_freq for the uplink VFO for gpredict to behave better if ((rs->uplink == 1 && vfo == RIG_VFO_SUB) || (rs->uplink == 2 && vfo == RIG_VFO_MAIN) || (vfo == RIG_VFO_TX && cachep->ptt == 0) || use_cache) { rig_debug(RIG_DEBUG_TRACE, "%s: uplink=%d, ignoring get_freq\n", __func__, rs->uplink); rig_debug(RIG_DEBUG_TRACE, "%s: split=%d, satmode=%d, tx_vfo=%s\n", __func__, cachep->split, cachep->satmode, rig_strvfo(rs->tx_vfo)); // always return the cached freq for this clause int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); ELAPSED2; RETURNFUNC(RIG_OK); } rig_cache_show(rig, __func__, __LINE__); LOCK(1); rig_debug(RIG_DEBUG_CACHE, "%s: depth=%d\n", __func__, rs->depth); // there are some rigs that can't get VFOA freq while VFOB is transmitting // so we'll return the cached VFOA freq for them // should we use the cached ptt maybe? No -- we have to be 100% sure we're in PTT to ignore this request if ((vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) && cachep->split && (rig->caps->rig_model == RIG_MODEL_FTDX101D || rig->caps->rig_model == RIG_MODEL_IC910)) { // if we're in PTT don't get VFOA freq -- otherwise we interrupt transmission ptt_t ptt; HAMLIB_TRACE; retcode = rig_get_ptt(rig, RIG_VFO_CURR, &ptt); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } if (ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: split is on so returning VFOA last known freq\n", __func__); *freq = cachep->freqMainA; ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } } int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); //rig_debug(RIG_DEBUG_TRACE, "%s: cache check1 age=%dms\n", __func__, cache_ms_freq); rig_cache_show(rig, __func__, __LINE__); // WSJT-X senses rig precision with 55 and 56 Hz values // We do not want to allow cache response with these values int wsjtx_special = ((long) * freq % 100) == 55 || ((long) * freq % 100) == 56; int rig_special = rig->caps->rig_model == RIG_MODEL_IC9100; if (!rig_special && !wsjtx_special && *freq != 0 && (cache_ms_freq < cachep->timeout_ms || (cachep->timeout_ms == HAMLIB_CACHE_ALWAYS || rs->use_cached_freq))) { rig_debug(RIG_DEBUG_TRACE, "%s: %s cache hit age=%dms, freq=%.0f, use_cached_freq=%d\n", __func__, rig_strvfo(vfo), cache_ms_freq, *freq, rs->use_cached_freq); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms, cached_vfo=%s, asked_vfo=%s, use_cached_freq=%d\n", __func__, cache_ms_freq, rig_strvfo(vfo), rig_strvfo(vfo), rs->use_cached_freq); } caps = rig->caps; if (caps->get_freq == NULL) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo_opt=%d, model=%u\n", __func__, __LINE__, rs->vfo_opt, rig->caps->rig_model); // If we're in vfo_mode then rigctld will do any VFO swapping we need // If we detected doppler we skip the frequency check to make timing more consistent for relay control if ((caps->targetable_vfo & RIG_TARGETABLE_FREQ) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo || (rs->vfo_opt == 1 && rig->caps->rig_model == RIG_MODEL_NETRIGCTL && rs->doppler == 0)) { // If rig does not have set_vfo we need to change vfo if (vfo == RIG_VFO_CURR && caps->set_vfo == NULL) { vfo = vfo_fixup(rig, RIG_VFO_A, cachep->split); rig_debug(RIG_DEBUG_TRACE, "%s: no set_vfo so vfo=%s\n", __func__, rig_strvfo(vfo)); } retcode = caps->get_freq(rig, vfo, freq); rig_cache_show(rig, __func__, __LINE__); // sometimes a network rig like FLRig will return freq=0 // so we'll just reuse the cache for that condition if (*freq == 0) { int freq_ms, mode_ms, width_ms; rig_get_cache(rig, vfo, freq, &freq_ms, &mode, &mode_ms, &width, &width_ms); } if (retcode == RIG_OK) { rig_set_cache_freq(rig, vfo, *freq); rig_cache_show(rig, __func__, __LINE__); } } else { int rc2; if (!caps->set_vfo) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } #if 1 // this seems redundant as we ask for freq a few lines below HAMLIB_TRACE; retcode = caps->get_freq(rig, vfo, freq); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } #endif retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } rig_cache_show(rig, __func__, __LINE__); HAMLIB_TRACE; retcode = caps->get_freq(rig, vfo, freq); /* try and revert even if we had an error above */ rc2 = RIG_OK; if (curr_vfo != RIG_VFO_NONE) { rc2 = caps->set_vfo(rig, curr_vfo); } if (RIG_OK == retcode) { rig_cache_show(rig, __func__, __LINE__); rig_set_cache_freq(rig, vfo, *freq); rig_cache_show(rig, __func__, __LINE__); /* Return the first error code */ retcode = rc2; } } /* VFO compensation */ if (rs->vfo_comp != 0.0) { *freq = (freq_t)(*freq / (1.0 + (double)rs->vfo_comp)); } if (retcode == RIG_OK && (vfo == RIG_VFO_CURR || vfo == rs->current_vfo)) { rs->current_freq = *freq; } if (rs->lo_freq != 0.0) { *freq += rs->lo_freq; } if (retcode == RIG_OK) { rig_cache_show(rig, __func__, __LINE__); } rig_set_cache_freq(rig, vfo, *freq); if (retcode == RIG_OK) { rig_cache_show(rig, __func__, __LINE__); } // we only want to look for band change on main vfo for now if (*freq != 0 && (rs->current_vfo == RIG_VFO_A || rs->current_vfo == RIG_VFO_MAIN)) { curr_band = rig_get_band(rig, *freq, -1); if (rs->tx_vfo == vfo && curr_band != last_band) { rig_debug(RIG_DEBUG_VERBOSE, "%s: band changing to %s\n", __func__, rig_get_band_str(rig, curr_band, 0)); rig_band_changed(rig, curr_band); last_band = curr_band; } } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief get the frequency of VFOA and VFOB * \param rig The rig handle * \param freqA The location where to store the VFOA/Main frequency * \param freqB The location where to store the VFOB/Sub frequency * * Retrieves the frequency of VFOA/Main and VFOB/Sub * The value stored at \a freq location equals RIG_FREQ_NONE when the current * frequency of the VFO is not defined (e.g. blank memory). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_freq() */ // cppcheck-suppress unusedFunction int HAMLIB_API rig_get_freqs(RIG *rig, freq_t *freqA, freq_t freqB) { // we will attempt to avoid vfo swapping in this routine return (-RIG_ENIMPL); } /** * \brief set the mode of the target VFO * \param rig The rig handle * \param vfo The target VFO * \param mode The mode to set to * \param width The passband width to set to * * Sets the mode and associated passband of the target VFO. The * passband \a width must be supported by the backend of the rig or * the special value RIG_PASSBAND_NOCHANGE which leaves the passband * unchanged from the current value or default for the mode determined * by the rig. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_mode() */ int HAMLIB_API rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct rig_caps *caps; struct rig_state *rs; int retcode; int locked_mode; struct rig_cache *cachep; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } rs = STATE(rig); cachep = CACHE(rig); ENTERFUNC; ELAPSED1; LOCK(1); rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s, mode=%s, width=%d, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width, rig_strvfo(rs->current_vfo)); rig_get_lock_mode(rig, &locked_mode); if (locked_mode) { ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } // do not mess with mode while PTT is on if (cachep->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s PTT on so set_mode ignored\n", __func__); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } caps = rig->caps; if (caps->set_mode == NULL) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (mode == RIG_MODE_NONE) { // Use the current mode to set width pbwidth_t twidth; rig_get_mode(rig, vfo, &mode, &twidth); } vfo = vfo_fixup(rig, vfo, cachep->split); // if we're not asking for bandwidth and the mode is already set we don't need to do it // this will prevent flashing on some rigs like the TS-870 if (caps->get_mode && width == RIG_PASSBAND_NOCHANGE) { rmode_t mode_curr; pbwidth_t width_curr; retcode = caps->get_mode(rig, vfo, &mode_curr, &width_curr); // For Icom rigs we may need to force the filter so we always set mode #if 0 // This should not be necessary anymore with the new filter method for Icom rigs // Hopefully fixes issue https://github.com/Hamlib/Hamlib/issues/1580 if (retcode == RIG_OK && mode == mode_curr && RIG_ICOM != RIG_BACKEND_NUM(rig->caps->rig_model)) #else if (retcode == RIG_OK && mode == mode_curr) #endif { rig_debug(RIG_DEBUG_VERBOSE, "%s: mode already %s and bw change not requested\n", __func__, rig_strrmode(mode)); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } } if ((caps->targetable_vfo & RIG_TARGETABLE_MODE) || vfo == rs->current_vfo) { HAMLIB_TRACE; retcode = caps->set_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: targetable retcode after set_mode(%s)=%d\n", __func__, rig_strrmode(mode), retcode); } else { int rc2; vfo_t curr_vfo; // If the rig does not support targetable mode, only set mode on an unselected if it is changing // to avoid unnecessary VFO swapping if (vfo != rs->current_vfo) { freq_t cache_freq; rmode_t cache_mode; pbwidth_t cache_width; int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, &cache_freq, &cache_ms_freq, &cache_mode, &cache_ms_mode, &cache_width, &cache_ms_width); if (cache_mode == mode) { rig_debug(RIG_DEBUG_TRACE, "%s: mode not changing, so ignoring\n", __func__); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode is not targetable, VFO swapping needed\n", __func__); if (!caps->set_vfo) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): curr_vfo=%s, vfo=%s\n", __func__, __LINE__, rig_strvfo(curr_vfo), rig_strvfo(vfo)); HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } retcode = caps->set_mode(rig, vfo, mode, width); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); /* Return the first error code */ if (retcode == RIG_OK) { retcode = rc2; } } if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: failed set_mode(%s)=%.23000s\n", __func__, rig_strrmode(mode), rigerror(retcode)); ELAPSED2; LOCK(0); RETURNFUNC(retcode); } rig_set_cache_mode(rig, vfo, mode, width); ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief get the mode of the target VFO * \param rig The rig handle * \param vfo The target VFO * \param mode The location where to store the current mode * \param width The location where to store the current passband width * * Retrieves the mode and passband of the target VFO. * If the backend is unable to determine the width, the \a width * will be set to RIG_PASSBAND_NORMAL as a default. * The value stored at \a mode location equals RIG_MODE_NONE when the current * mode of the VFO is not defined (e.g. blank memory). * * Note that if either \a mode or \a width is NULL, -RIG_EINVAL is returned. * Both must be given even if only one is actually wanted. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_mode() */ int HAMLIB_API rig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct rig_caps *caps; struct rig_state *rs; int retcode; int use_cache = 0; freq_t freq; vfo_t curr_vfo; struct rig_cache *cachep; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!mode || !width) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); if (caps->get_mode == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; vfo = vfo_fixup(rig, vfo, cachep->split); if (vfo == RIG_VFO_CURR) { vfo = curr_vfo; } *mode = RIG_MODE_NONE; rig_cache_show(rig, __func__, __LINE__); int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, &freq, &cache_ms_freq, mode, &cache_ms_mode, width, &cache_ms_width); rig_debug(RIG_DEBUG_TRACE, "%s: %s cache check age=%dms\n", __func__, rig_strvfo(vfo), cache_ms_mode); rig_cache_show(rig, __func__, __LINE__); if (MUTEX_CHECK(&morse_mutex)) { use_cache = 1; } if (cachep->timeout_ms == HAMLIB_CACHE_ALWAYS || rs->use_cached_mode || use_cache) { rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age mode=%dms, width=%dms\n", __func__, cache_ms_mode, cache_ms_width); ELAPSED2; RETURNFUNC(RIG_OK); } if ((*mode != RIG_MODE_NONE && cache_ms_mode < cachep->timeout_ms) && cache_ms_width < cachep->timeout_ms) { rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age mode=%dms, width=%dms\n", __func__, cache_ms_mode, cache_ms_width); ELAPSED2; RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age mode=%dms, width=%dms\n", __func__, cache_ms_mode, cache_ms_width); } LOCK(1); // we let the caching work before we lock things if ((caps->targetable_vfo & RIG_TARGETABLE_MODE) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { HAMLIB_TRACE; retcode = caps->get_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: retcode after get_mode=%d\n", __func__, retcode); rig_cache_show(rig, __func__, __LINE__); } else { int rc2; if (!caps->set_vfo) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } rig_debug(RIG_DEBUG_TRACE, "%s(%d): vfo=%s, curr_vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(curr_vfo)); HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); rig_cache_show(rig, __func__, __LINE__); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_mode(rig, vfo, mode, width); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } } if (retcode == RIG_OK && (vfo == RIG_VFO_CURR || vfo == rs->current_vfo)) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): debug\n", __func__, __LINE__); rs->current_mode = *mode; rs->current_width = *width; rig_cache_show(rig, __func__, __LINE__); } if (*width == RIG_PASSBAND_NORMAL && *mode != RIG_MODE_NONE) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): debug\n", __func__, __LINE__); *width = rig_passband_normal(rig, *mode); } rig_set_cache_mode(rig, vfo, *mode, *width); rig_cache_show(rig, __func__, __LINE__); LOCK(0); ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the normal passband of a mode * \param rig The rig handle * \param mode The mode to get the passband * * Returns the normal (default) passband for the given \a mode. * * \return the passband in Hz if the operation has been successful, * or a 0 if an error occurred (passband not found, whatever). * * \sa rig_passband_narrow(), rig_passband_wide() */ pbwidth_t HAMLIB_API rig_passband_normal(RIG *rig, rmode_t mode) { const struct rig_state *rs; int i; if (!rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return (RIG_PASSBAND_NORMAL); /* huhu! */ } ENTERFUNC; rs = STATE(rig); // return CW for CWR and RTTY for RTTYR if (mode == RIG_MODE_CWR) { mode = RIG_MODE_CW; } if (mode == RIG_MODE_RTTYR) { mode = RIG_MODE_RTTY; } for (i = 0; i < HAMLIB_FLTLSTSIZ && rs->filters[i].modes; i++) { if (rs->filters[i].modes & mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Return filter#%d, width=%d\n", __func__, i, (int)rs->filters[i].width); RETURNFUNC(rs->filters[i].width); } } rig_debug(RIG_DEBUG_VERBOSE, "%s: filter not found...returning %d\n", __func__, 0); RETURNFUNC(0); } /** * \brief get the narrow passband of a mode * \param rig The rig handle * \param mode The mode to get the passband * * Returns the narrow (closest) passband for the given \a mode. * EXAMPLE: rig_set_mode(my_rig, RIG_MODE_LSB, * rig_passband_narrow(my_rig, RIG_MODE_LSB) ); * * \return the passband in Hz if the operation has been successful, * or a 0 if an error occurred (passband not found, whatever). * * \sa rig_passband_normal(), rig_passband_wide() */ pbwidth_t HAMLIB_API rig_passband_narrow(RIG *rig, rmode_t mode) { const struct rig_state *rs; pbwidth_t normal; int i; if (!rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return (0); /* huhu! */ } ENTERFUNC; rs = STATE(rig); for (i = 0; i < HAMLIB_FLTLSTSIZ - 1 && rs->filters[i].modes; i++) { if (rs->filters[i].modes & mode) { normal = rs->filters[i].width; for (i++; i < HAMLIB_FLTLSTSIZ && rs->filters[i].modes; i++) { if ((rs->filters[i].modes & mode) && (rs->filters[i].width < normal)) { RETURNFUNC(rs->filters[i].width); } } RETURNFUNC(0); } } RETURNFUNC(0); } /** * \brief get the wide passband of a mode * \param rig The rig handle * \param mode The mode to get the passband * * Returns the wide (default) passband for the given \a mode. * EXAMPLE: rig_set_mode(my_rig, RIG_MODE_AM, * rig_passband_wide(my_rig, RIG_MODE_AM) ); * * \return the passband in Hz if the operation has been successful, * or a 0 if an error occurred (passband not found, whatever). * * \sa rig_passband_narrow(), rig_passband_normal() */ pbwidth_t HAMLIB_API rig_passband_wide(RIG *rig, rmode_t mode) { const struct rig_state *rs; pbwidth_t normal; int i; if (!rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return 0 ; /* huhu! */ } ENTERFUNC; rs = STATE(rig); for (i = 0; i < HAMLIB_FLTLSTSIZ - 1 && rs->filters[i].modes; i++) { if (rs->filters[i].modes & mode) { normal = rs->filters[i].width; for (i++; i < HAMLIB_FLTLSTSIZ && rs->filters[i].modes; i++) { if ((rs->filters[i].modes & mode) && (rs->filters[i].width > normal)) { RETURNFUNC(rs->filters[i].width); } } RETURNFUNC(0); } } RETURNFUNC(0); } /** * \brief set the current VFO * \param rig The rig handle * \param vfo The VFO to set to * * Sets the current VFO. The VFO can be RIG_VFO_A, RIG_VFO_B, RIG_VFO_C * for VFOA, VFOB, VFOC respectively or RIG_VFO_MEM for Memory mode. * Supported VFOs depends on rig capabilities. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_vfo() */ #if BUILTINFUNC #undef rig_set_vfo int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo, const char *func) #define rig_set_vfo(r,v) rig_set_vfo(r,v,__builtin_FUNCTION()) #else int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo) #endif { const struct rig_caps *caps; struct rig_cache *cachep; struct rig_state *rs; int retcode; freq_t curr_freq; vfo_t curr_vfo = RIG_VFO_CURR, tmp_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } rs = STATE(rig); cachep = CACHE(rig); ELAPSED1; ENTERFUNC; #if BUILTINFUNC rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, called from %s\n", __func__, rig_strvfo(vfo), func); #else rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); #endif if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); } vfo = vfo_fixup(rig, vfo, cachep->split); if (vfo == RIG_VFO_CURR) { ELAPSED2; RETURNFUNC(RIG_OK); } if (rig->caps->get_vfo) { retcode = rig_get_vfo(rig, &curr_vfo); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: rig_get_vfo error=%.23000s\n", __func__, rigerror(retcode)); } if (curr_vfo == vfo) { RETURNFUNC(RIG_OK); } } vfo = vfo_fixup(rig, vfo, cachep->split); caps = rig->caps; if (caps->set_vfo == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (twiddling(rig)) { rig_debug(RIG_DEBUG_TRACE, "%s: Ignoring set_vfo due to VFO twiddling\n", __func__); ELAPSED2; RETURNFUNC( RIG_OK); // would be better as error but other software won't handle errors } HAMLIB_TRACE; vfo_t vfo_save = rs->current_vfo; LOCK(1); if (vfo != RIG_VFO_CURR) { rs->current_vfo = vfo; } retcode = caps->set_vfo(rig, vfo); if (retcode == RIG_OK) { vfo = rs->current_vfo; // vfo may change in the rig backend cachep->vfo = vfo; elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_SET); rig_debug(RIG_DEBUG_TRACE, "%s: rs->current_vfo=%s\n", __func__, rig_strvfo(vfo)); } else { rig_debug(RIG_DEBUG_ERR, "%s: set_vfo %s failed with '%.10000s'\n", __func__, rig_strvfo(vfo), rigerror(retcode)); rs->current_vfo = vfo_save; } // we need to update our internal freq to avoid getting detected as twiddling // we only get the freq if we set the vfo OK if (retcode == RIG_OK && caps->get_freq) { HAMLIB_TRACE; retcode = caps->get_freq(rig, vfo, &curr_freq); rig_debug(RIG_DEBUG_TRACE, "%s: retcode from rig_get_freq = %d\n", __func__, retcode); rig_set_cache_freq(rig, vfo, curr_freq); } else { // if no get_freq clear all cache to be sure we refresh whatever we can rig_set_cache_freq(rig, RIG_VFO_ALL, (freq_t)0); } if (vfo != rs->current_vfo && rig_get_vfo(rig, &tmp_vfo) == -RIG_ENAVAIL) { rig_debug(RIG_DEBUG_TRACE, "%s: Expiring all cache due to VFO change and no get_vfo\n", __func__); // expire all cached items when we switch VFOs and get_vfo does not work rig_set_cache_freq(rig, RIG_VFO_ALL, 0); } rig_debug(RIG_DEBUG_TRACE, "%s: returning %d, vfo=%s, curr_vfo=%s\n", __func__, retcode, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief get the current VFO * \param rig The rig handle * \param vfo The location where to store the current VFO * * Retrieves the current VFO. The VFO can be RIG_VFO_A, RIG_VFO_B, RIG_VFO_C * for VFOA, VFOB, VFOC respectively or RIG_VFO_MEM for Memory mode. * Supported VFOs depends on rig capabilities. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_vfo() */ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo) { const struct rig_caps *caps; struct rig_cache *cachep; struct rig_state *rs; int retcode = -RIG_EINTERNAL; int cache_ms; int use_cache = 0; if (CHECK_RIG_ARG(rig) || !vfo) { rig_debug(RIG_DEBUG_ERR, "%s: rig or *vfo is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; ELAPSED1; caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // if (caps->get_vfo == NULL && RIG_ICOM != RIG_BACKEND_NUM(rig->caps->rig_model)) if (caps->get_vfo == NULL) { rig_debug(RIG_DEBUG_WARN, "%s: no get_vfo\n", __func__); ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } cache_ms = elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_GET); //rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms); if (MUTEX_CHECK(&morse_mutex)) { use_cache = 1; } if (cache_ms < cachep->timeout_ms || use_cache) { *vfo = cachep->vfo; rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms, vfo=%s\n", __func__, cache_ms, rig_strvfo(*vfo)); ELAPSED2; RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms); } HAMLIB_TRACE; LOCK(1); if (rig->caps->get_vfo) { retcode = rig->caps->get_vfo(rig, vfo); if (retcode == RIG_OK) { rs->current_vfo = *vfo; cachep->vfo = *vfo; //cache_ms = elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_SET); } else { if (RIG_ICOM == RIG_BACKEND_NUM(rig->caps->rig_model)) { rig->caps->get_vfo = NULL; *vfo = RIG_VFO_A; LOCK(0); RETURNFUNC(RIG_OK); } //cache_ms = elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_INVALIDATE); } } if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: returning %d(%.10000s)\n", __func__, retcode, rigerror(retcode)); } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief set PTT on/off * \param rig The rig handle * \param vfo The target VFO * \param ptt The PTT status to set to * * Sets "Push-To-Talk" on/off. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ptt() */ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *rp, *pttp; struct rig_cache *cachep; int retcode = RIG_OK; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); rp = RIGPORT(rig); pttp = PTTPORT(rig); LOCK(1); switch (pttp->type.ptt) { case RIG_PTT_RIG: if (ptt == RIG_PTT_ON_MIC || ptt == RIG_PTT_ON_DATA) { ptt = RIG_PTT_ON; } /* fall through */ case RIG_PTT_RIG_MICDATA: if (caps->set_ptt == NULL) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENIMPL); } if ((caps->targetable_vfo & RIG_TARGETABLE_PTT) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { int retry = 3; ptt_t tptt; do { HAMLIB_TRACE; retcode = caps->set_ptt(rig, vfo, ptt); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } #if 0 hl_usleep(50 * 1000); // give PTT a chance to do its thing // don't use the cached value and check to see if it worked elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_INVALIDATE); tptt = -1; // IC-9700 is failing on get_ptt right after set_ptt in split mode retcode = rig_get_ptt(rig, vfo, &tptt); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_ptt failed: %s\b", __func__, rigerror(retcode)); retcode = RIG_OK; // fake the retcode so we retry } if (tptt != ptt) { rig_debug(RIG_DEBUG_WARN, "%s: failed, retry=%d\n", __func__, retry); } #else tptt = ptt; #endif } while (tptt != ptt && retry-- > 0 && retcode == RIG_OK); } else { vfo_t curr_vfo; int backend_num; int targetable_ptt; if (!caps->set_vfo) { LOCK(0); ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; HAMLIB_TRACE; backend_num = RIG_BACKEND_NUM(rig->caps->rig_model); switch (backend_num) { // most rigs have only one PTT VFO so we can set that flag here case RIG_ICOM: case RIG_KENWOOD: case RIG_YAESU: targetable_ptt = 1; } if (!targetable_ptt) { retcode = caps->set_vfo(rig, vfo); } if (retcode == RIG_OK) { int rc2; int retry = 3; ptt_t tptt; do { HAMLIB_TRACE; retcode = caps->set_ptt(rig, vfo, ptt); if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } #if 0 retcode = rig_get_ptt(rig, vfo, &tptt); if (tptt != ptt) { rig_debug(RIG_DEBUG_WARN, "%s: failed, retry=%d\n", __func__, retry); } #else tptt = ptt; #endif } while (tptt != ptt && retry-- > 0 && retcode == RIG_OK); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = RIG_OK; if (!targetable_ptt) { rc2 = caps->set_vfo(rig, curr_vfo); } /* Return the first error code */ if (RIG_OK == retcode) { retcode = rc2; } } } break; case RIG_PTT_SERIAL_DTR: /* when the PTT port is not the control port we want to free the port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ if (strcmp(pttp->pathname, rp->pathname) && pttp->fd < 0 && RIG_PTT_OFF != ptt) { pttp->fd = ser_open(pttp); if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, pttp->pathname); ELAPSED2; LOCK(0); RETURNFUNC(-RIG_EIO); } /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both since we offer no control of the non-PTT line and low is better than high */ retcode = ser_set_rts(pttp, 0); if (RIG_OK != retcode) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } } retcode = ser_set_dtr(pttp, ptt != RIG_PTT_OFF); rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%s, pttport=%s, ptt_share=%d\n", __func__, rp->pathname, pttp->pathname, rs->ptt_share); if (strcmp(pttp->pathname, rp->pathname) && ptt == RIG_PTT_OFF && rs->ptt_share != 0) { /* free the port */ ser_close(pttp); } break; case RIG_PTT_SERIAL_RTS: /* when the PTT port is not the control port we want to free the port when PTT is reset and seize the port when PTT is set, this allows limited sharing of the PTT port between applications so long as there is no contention */ if (strcmp(pttp->pathname, rp->pathname) && pttp->fd < 0 && RIG_PTT_OFF != ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: PTT RTS debug#1\n", __func__); pttp->fd = ser_open(pttp); if (pttp->fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot open PTT device \"%s\"\n", __func__, pttp->pathname); ELAPSED2; LOCK(0); RETURNFUNC(-RIG_EIO); } /* Needed on Linux because the serial port driver sets RTS/DTR high on open - set both since we offer no control of the non-PTT line and low is better than high */ retcode = ser_set_dtr(pttp, 0); if (RIG_OK != retcode) { rig_debug(RIG_DEBUG_ERR, "%s: ser_set_dtr retcode=%d\n", __func__, retcode); ELAPSED2; LOCK(0); RETURNFUNC(retcode); } } retcode = ser_set_rts(pttp, ptt != RIG_PTT_OFF); rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%s, pttport=%s, ptt_share=%d\n", __func__, rp->pathname, pttp->pathname, rs->ptt_share); if (strcmp(pttp->pathname, rp->pathname) && ptt == RIG_PTT_OFF && rs->ptt_share != 0) { /* free the port */ ser_close(pttp); } break; case RIG_PTT_PARALLEL: retcode = par_ptt_set(pttp, ptt); break; case RIG_PTT_CM108: retcode = cm108_ptt_set(pttp, ptt); break; case RIG_PTT_GPIO: case RIG_PTT_GPION: retcode = gpio_ptt_set(pttp, ptt); break; case RIG_PTT_NONE: // allowed for use with VOX and WSJT-X break; default: rig_debug(RIG_DEBUG_WARN, "%s: unknown PTT type=%d\n", __func__, pttp->type.ptt); ELAPSED2; LOCK(0); RETURNFUNC(-RIG_EINVAL); } if (RIG_OK == retcode) { rs->transmit = ptt != RIG_PTT_OFF; } // some rigs like the FT-2000 with the SCU-17 need just a bit of time to let the relays work // can affect fake it mode in WSJT-X when the rig is still in transmit and freq change // is requested on a rig that can't change freq on a transmitting VFO if (ptt != RIG_PTT_ON) { hl_usleep(50 * 1000); } cachep->ptt = ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Return code=%d\n", __func__, retcode); } memcpy(&rs->pttport_deprecated, pttp, sizeof(rs->pttport_deprecated)); if (rs->post_ptt_delay > 0) { hl_usleep(rs->post_ptt_delay * 1000); } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } /** * \brief get the status of the PTT * \param rig The rig handle * \param vfo The target VFO * \param ptt The location where to store the status of the PTT * * Retrieves the status of PTT (are we on the air?). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ptt() */ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *rp, *pttp; struct rig_cache *cachep; int retcode = RIG_OK; int status; vfo_t curr_vfo; int cache_ms; int targetable_ptt = 0; int backend_num; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } rs = STATE(rig); cachep = CACHE(rig); rp = RIGPORT(rig); pttp = PTTPORT(rig); ELAPSED1; ENTERFUNC; if (!ptt) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } cache_ms = elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_GET); rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms); if (cache_ms < cachep->timeout_ms) { rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms); *ptt = cachep->ptt; ELAPSED2; RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms); } caps = rig->caps; LOCK(1); switch (pttp->type.ptt) { case RIG_PTT_RIG: case RIG_PTT_RIG_MICDATA: if (!caps->get_ptt) { *ptt = rs->transmit ? RIG_PTT_ON : RIG_PTT_OFF; ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } if ((caps->targetable_vfo & RIG_TARGETABLE_PTT) || vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { cachep->ptt = *ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; HAMLIB_TRACE; backend_num = RIG_BACKEND_NUM(rig->caps->rig_model); switch (backend_num) { // most rigs have only one PTT VFO so we can set that flag here case 0: case RIG_ICOM: case RIG_KENWOOD: case RIG_YAESU: targetable_ptt = 1; } if (!targetable_ptt) { retcode = caps->set_vfo(rig, vfo); } if (retcode != RIG_OK) { ELAPSED2; LOCK(0); RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); /* try and revert even if we had an error above */ if (!targetable_ptt) { int rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; cachep->ptt = *ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); } } ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_SERIAL_RTS: #if 0 // do not use caps->get_ptt https://github.com/Hamlib/Hamlib/issues/1241 if (caps->get_ptt) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } LOCK(0); ELAPSED2; RETURNFUNC(retcode); } #endif if (strcmp(pttp->pathname, rp->pathname) && pttp->fd < 0) { /* port is closed so assume PTT off */ *ptt = RIG_PTT_OFF; } else { retcode = ser_get_rts(pttp, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } cachep->ptt = *ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_SERIAL_DTR: #if 0 // do not use caps->get_ptt https://github.com/Hamlib/Hamlib/issues/1241 if (caps->get_ptt) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } #endif if (strcmp(pttp->pathname, rp->pathname) && pttp->fd < 0) { /* port is closed so assume PTT off */ *ptt = RIG_PTT_OFF; } else { retcode = ser_get_dtr(pttp, &status); *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } cachep->ptt = *ptt; elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_PARALLEL: if (caps->get_ptt) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } retcode = par_ptt_get(pttp, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_CM108: if (caps->get_ptt) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } retcode = cm108_ptt_get(pttp, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_GPIO: case RIG_PTT_GPION: if (caps->get_ptt) { HAMLIB_TRACE; retcode = caps->get_ptt(rig, vfo, ptt); if (retcode == RIG_OK) { elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); cachep->ptt = *ptt; } ELAPSED2; LOCK(0); RETURNFUNC(retcode); } elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); retcode = gpio_ptt_get(pttp, ptt); ELAPSED2; LOCK(0); RETURNFUNC(retcode); case RIG_PTT_NONE: ELAPSED2; LOCK(0); RETURNFUNC(-RIG_ENAVAIL); /* not available */ default: ELAPSED2; LOCK(0); RETURNFUNC(-RIG_EINVAL); } elapsed_ms(&cachep->time_ptt, HAMLIB_ELAPSED_SET); ELAPSED2; LOCK(0); RETURNFUNC(RIG_OK); } /** * \brief get the status of the DCD * \param rig The rig handle * \param vfo The target VFO * \param dcd The location where to store the status of the DCD * * Retrieves the status of DCD (is squelch open?). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { const struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *dcdp; int retcode, rc2, status; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!dcd) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); dcdp = DCDPORT(rig); switch (dcdp->type.dcd) { case RIG_DCD_RIG: if (caps->get_dcd == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENIMPL); } if (vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { HAMLIB_TRACE; retcode = caps->get_dcd(rig, vfo, dcd); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_dcd(rig, vfo, dcd); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); break; case RIG_DCD_SERIAL_CTS: retcode = ser_get_cts(dcdp, &status); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(rs->dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_SERIAL_DSR: retcode = ser_get_dsr(dcdp, &status); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(rs->dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_SERIAL_CAR: retcode = ser_get_car(dcdp, &status); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(rs->dcdport_deprecated)); *dcd = status ? RIG_DCD_ON : RIG_DCD_OFF; ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_PARALLEL: retcode = par_dcd_get(dcdp, dcd); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(rs->dcdport_deprecated)); ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_GPIO: case RIG_DCD_GPION: retcode = gpio_dcd_get(dcdp, dcd); memcpy(&rs->dcdport_deprecated, dcdp, sizeof(rs->dcdport_deprecated)); ELAPSED2; RETURNFUNC(retcode); case RIG_DCD_NONE: ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); /* not available */ default: ELAPSED2; RETURNFUNC(-RIG_EINVAL); } ELAPSED2; RETURNFUNC(RIG_OK); } /** * \brief set the repeater shift * \param rig The rig handle * \param vfo The target VFO * \param rptr_shift The repeater shift to set to * * Sets the current repeater shift. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_rptr_shift() */ int HAMLIB_API rig_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; caps = rig->caps; if (caps->set_rptr_shift == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_rptr_shift(rig, vfo, rptr_shift); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->set_rptr_shift(rig, vfo, rptr_shift); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the current repeater shift * \param rig The rig handle * \param vfo The target VFO * \param rptr_shift The location where to store the current repeater shift * * Retrieves the current repeater shift. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_rptr_shift() */ int HAMLIB_API rig_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!rptr_shift) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_rptr_shift == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_rptr_shift(rig, vfo, rptr_shift); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_rptr_shift(rig, vfo, rptr_shift); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the repeater offset * \param rig The rig handle * \param vfo The target VFO * \param rptr_offs The VFO to set to * * Sets the current repeater offset. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_rptr_offs() */ int HAMLIB_API rig_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; caps = rig->caps; if (caps->set_rptr_offs == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_rptr_offs(rig, vfo, rptr_offs); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } retcode = caps->set_rptr_offs(rig, vfo, rptr_offs); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the current repeater offset * \param rig The rig handle * \param vfo The target VFO * \param rptr_offs The location where to store the current repeater offset * * Retrieves the current repeater offset. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_rptr_offs() */ int HAMLIB_API rig_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!rptr_offs) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_rptr_offs == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_rptr_offs(rig, vfo, rptr_offs); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } retcode = caps->get_rptr_offs(rig, vfo, rptr_offs); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the split frequencies * \param rig The rig handle * \param vfo The target VFO * \param tx_freq The transmit split frequency to set to * * Sets the split(TX) frequency. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_split_freq(), rig_set_split_vfo() */ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { const struct rig_caps *caps; const struct rig_state *rs; struct rig_cache *cachep; int retcode, rc2; vfo_t curr_vfo, tx_vfo = RIG_VFO_CURR; freq_t tfreq = 0; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC2; ELAPSED1; rs = STATE(rig); caps = rig->caps; cachep = CACHE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, curr_vfo=%s, tx_freq=%.0f\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo), tx_freq); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Turn split on if not enabled already retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF)); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode); ELAPSED2; RETURNFUNC2(retcode); } } // TX VFO may change after enabling split tx_vfo = rs->tx_vfo; rig_get_freq(rig, tx_vfo, &tfreq); if (tfreq == tx_freq) { rig_debug(RIG_DEBUG_TRACE, "%s: freq set not needed\n", __func__); ELAPSED2; RETURNFUNC2(RIG_OK); } // Use set_split_freq directly if implemented and frequency is targetable if (caps->set_split_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { HAMLIB_TRACE; retcode = caps->set_split_freq(rig, tx_vfo, tx_freq); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, tx_freq); } RETURNFUNC2(retcode); } // Alternatively, use set_freq if frequency is targetable if (caps->set_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { int retry = 3; do { HAMLIB_TRACE; retcode = rig_set_freq(rig, tx_vfo, tx_freq); if (retcode != RIG_OK) { RETURNFUNC2(retcode); } #if 0 // this verification seems to be causing bad behavior on some rigs retcode = rig_get_freq(rig, tx_vfo, &tfreq); #else tfreq = tx_freq; #endif } while (tfreq != tx_freq && retry-- > 0 && retcode == RIG_OK); ELAPSED2; RETURNFUNC2(retcode); } // Assisted mode: Swap VFOs and try either set_split_freq or set_freq curr_vfo = rs->current_vfo; vfo = vfo_fixup(rig, vfo, cachep->split); if (caps->set_vfo) { HAMLIB_TRACE; retcode = caps->set_vfo(rig, tx_vfo); } else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op) { retcode = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } else { ELAPSED2; RETURNFUNC2(-RIG_ENAVAIL); } if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC2(retcode); } int retry = 3; do { // doing get_freq seems to break on some rigs that can't read freq immediately after set if (caps->set_split_freq) { HAMLIB_TRACE; retcode = caps->set_split_freq(rig, vfo, tx_freq); } else { HAMLIB_TRACE; retcode = rig_set_freq(rig, RIG_VFO_CURR, tx_freq); } tfreq = tx_freq; } while (tfreq != tx_freq && retry-- > 0 && retcode == RIG_OK); if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, tx_freq); } /* try and revert even if we had an error above */ if (caps->set_vfo) { HAMLIB_TRACE; rc2 = RIG_OK; if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { rc2 = caps->set_vfo(rig, curr_vfo); } } else { rc2 = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC2(retcode); } /** * \brief get the current split frequencies * \param rig The rig handle * \param vfo The target VFO * \param tx_freq The location where to store the current transmit split frequency * * Retrieves the current split(TX) frequency. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_split_freq() */ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { const struct rig_caps *caps; const struct rig_state *rs; struct rig_cache *cachep; int retcode = -RIG_EPROTO, rc2; vfo_t tx_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!tx_freq) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Split frequency not available if split is off *tx_freq = 0; ELAPSED2; RETURNFUNC(RIG_OK); } // Use get_split_freq directly if implemented and frequency is targetable if (caps->get_split_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { HAMLIB_TRACE; retcode = caps->get_split_freq(rig, tx_vfo, tx_freq); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, *tx_freq); } RETURNFUNC(retcode); } // Alternatively, use get_freq if frequency is targetable if (caps->get_freq && (caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { HAMLIB_TRACE; retcode = caps->get_freq(rig, tx_vfo, tx_freq); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, *tx_freq); } RETURNFUNC(retcode); } // Assisted mode: Swap VFOs and try either get_split_freq or get_freq vfo = vfo_fixup(rig, vfo, cachep->split); if (caps->set_vfo) { // if the underlying rig has OP_XCHG we don't need to set VFO if (!rig_has_vfo_op(rig, RIG_OP_XCHG) && !(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { HAMLIB_TRACE; retcode = caps->set_vfo(rig, tx_vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } } retcode = RIG_OK; } else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op) { retcode = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } else { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } if (caps->get_split_freq) { HAMLIB_TRACE; retcode = caps->get_split_freq(rig, vfo, tx_freq); } else { HAMLIB_TRACE; retcode = caps->get_freq ? caps->get_freq(rig, RIG_VFO_CURR, tx_freq) : -RIG_ENIMPL; } if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, *tx_freq); } /* try and revert even if we had an error above */ if (caps->set_vfo) { vfo_t save_vfo; // If we started with RIG_VFO_CURR we need to choose VFO_A/MAIN as appropriate to return to //rig_debug(RIG_DEBUG_TRACE, "%s: save_vfo=%s, hasmainsub=%d\n",__func__, rig_strvfo(save_vfo), VFO_HAS_MAIN_SUB); save_vfo = VFO_HAS_MAIN_SUB ? RIG_VFO_MAIN : RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: restoring vfo=%s\n", __func__, rig_strvfo(save_vfo)); HAMLIB_TRACE; if (!rig_has_vfo_op(rig, RIG_OP_XCHG) && !(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { rc2 = caps->set_vfo(rig, save_vfo); } else { rc2 = RIG_OK; } } else { rc2 = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } rig_debug(RIG_DEBUG_TRACE, "%s: tx_freq=%.0f\n", __func__, *tx_freq); ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the split modes * \param rig The rig handle * \param vfo The target VFO * \param tx_mode The transmit split mode to set to * \param tx_width The transmit split width to set to or the special * value RIG_PASSBAND_NOCHANGE which leaves the passband unchanged * from the current value or default for the mode determined by the * rig. * * Sets the split(TX) mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_split_mode() */ int HAMLIB_API rig_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { const struct rig_caps *caps; const struct rig_state *rs; struct rig_cache *cachep; int retcode, rc2; vfo_t curr_vfo, tx_vfo, rx_vfo; freq_t cache_freq; rmode_t cache_mode; pbwidth_t cache_width; int cache_ms_freq, cache_ms_mode, cache_ms_width; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Turn split on if not enabled already retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF)); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode); ELAPSED2; RETURNFUNC(retcode); } } // TX VFO may change after enabling split tx_vfo = rs->tx_vfo; // do not mess with mode while PTT is on if (cachep->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s PTT on so set_split_mode ignored\n", __func__); ELAPSED2; RETURNFUNC(RIG_OK); } if (tx_mode == RIG_MODE_NONE) { // Get TX VFO mode from cache to avoid extra VFO swapping rig_get_cache(rig, tx_vfo, &cache_freq, &cache_ms_freq, &cache_mode, &cache_ms_mode, &cache_width, &cache_ms_width); tx_mode = cache_mode; } // Use set_split_mode directly if implemented and mode is targetable if (caps->set_split_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE)) { HAMLIB_TRACE; retcode = caps->set_split_mode(rig, tx_vfo, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width); } RETURNFUNC(retcode); } curr_vfo = rs->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(curr_vfo), rig_strvfo(tx_vfo)); // Alternatively, use set_mode if mode is targetable if (caps->set_mode && ((caps->targetable_vfo & RIG_TARGETABLE_MODE) || (rig->caps->rig_model == RIG_MODEL_NETRIGCTL))) { HAMLIB_TRACE; retcode = caps->set_mode(rig, tx_vfo, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width); } RETURNFUNC(retcode); } // some rigs exhibit undesirable flashing when swapping vfos in split // so we turn it off, do our thing, and turn split back on rx_vfo = vfo; if (tx_vfo == RIG_VFO_B || tx_vfo == RIG_VFO_SUB) { rx_vfo = RIG_VFO_A; } if (vfo == RIG_VFO_CURR && tx_vfo == RIG_VFO_B) { rx_vfo = RIG_VFO_A; } else if (vfo == RIG_VFO_CURR && tx_vfo == RIG_VFO_A) { rx_vfo = RIG_VFO_B; } else if (vfo == RIG_VFO_CURR && tx_vfo == RIG_VFO_MAIN) { rx_vfo = RIG_VFO_SUB; } else if (vfo == RIG_VFO_CURR && tx_vfo == RIG_VFO_SUB) { rx_vfo = RIG_VFO_MAIN; } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): rx_vfo=%s, tx_vfo=%s\n", __func__, __LINE__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo)); // If mode is not targetable, we will reuse cached mode/passband instead of trying to set them again rig_get_cache(rig, tx_vfo, &cache_freq, &cache_ms_freq, &cache_mode, &cache_ms_mode, &cache_width, &cache_ms_width); if ((tx_mode == cache_mode || tx_mode == RIG_MODE_NONE) && (tx_width == cache_width || tx_width == RIG_PASSBAND_NOCHANGE)) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): mode=%s and width=%ld already set for vfo=%s, ignoring\n", __func__, __LINE__, rig_strrmode(tx_mode), tx_width, rig_strvfo(tx_vfo)); ELAPSED2; RETURNFUNC(RIG_OK); } if (tx_vfo & (RIG_VFO_CURR | RIG_VFO_TX)) { rig_debug(RIG_DEBUG_WARN, "%s(%d): Unhandled TXVFO=%s, tx_mode=%s\n", __func__, __LINE__, rig_strvfo(tx_vfo), rig_strrmode(tx_mode)); } // code below here should be dead code now -- but maybe we have VFO situation we need to handle if (caps->rig_model == RIG_MODEL_NETRIGCTL) { // special handling for netrigctl to avoid set_vfo retcode = caps->set_split_mode(rig, tx_vfo, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width); } RETURNFUNC(retcode); } // Assisted mode: Turn split off, swap VFOs and try either set_split_mode or set_mode rig_set_split_vfo(rig, rx_vfo, RIG_SPLIT_OFF, rx_vfo); if (caps->set_vfo) { HAMLIB_TRACE; retcode = caps->set_vfo(rig, tx_vfo); } else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op) { retcode = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } else { rig_debug(RIG_DEBUG_WARN, "%s: rig does not have set_vfo or vfo_op. Assuming mode already set\n", __func__); ELAPSED2; RETURNFUNC(RIG_OK); } if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } if (caps->set_split_mode) { HAMLIB_TRACE; retcode = caps->set_split_mode(rig, vfo, tx_mode, tx_width); } else { HAMLIB_TRACE; retcode = caps->set_mode ? caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width) : -RIG_ENIMPL; } if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width); } /* try and revert even if we had an error above */ if (caps->set_vfo) { HAMLIB_TRACE; rc2 = caps->set_vfo(rig, rx_vfo); } else { rc2 = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } rig_set_split_vfo(rig, rx_vfo, RIG_SPLIT_ON, tx_vfo); ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the current split modes * \param rig The rig handle * \param vfo The target VFO * \param tx_mode The location where to store the current transmit split mode * \param tx_width The location where to store the current transmit split width * * Retrieves the current split(TX) mode and passband. * If the backend is unable to determine the width, the \a tx_width * will be set to RIG_PASSBAND_NORMAL as a default. * The value stored at \a tx_mode location equals RIG_MODE_NONE * when the current mode of the VFO is not defined (e.g. blank memory). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_split_mode() */ int HAMLIB_API rig_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { const struct rig_caps *caps; const struct rig_state *rs; struct rig_cache *cachep; int retcode, rc2; vfo_t curr_vfo, tx_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!tx_mode || !tx_width) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Split mode and filter width are not available if split is off *tx_mode = RIG_MODE_NONE; *tx_width = 0; ELAPSED2; RETURNFUNC(RIG_OK); } // Use get_split_mode directly if implemented and mode is targetable if (caps->get_split_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE)) { HAMLIB_TRACE; retcode = caps->get_split_mode(rig, tx_vfo, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width); } RETURNFUNC(retcode); } // Alternatively, use get_mode if mode is targetable if (caps->get_mode && (caps->targetable_vfo & RIG_TARGETABLE_MODE)) { HAMLIB_TRACE; retcode = caps->get_mode(rig, tx_vfo, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width); } RETURNFUNC(retcode); } // Assisted mode: Swap VFOs and try either get_split_mode or get_mode curr_vfo = rs->current_vfo; if (caps->set_vfo) { HAMLIB_TRACE; retcode = caps->set_vfo(rig, tx_vfo); } else if (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op) { HAMLIB_TRACE; retcode = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } else { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } if (caps->get_split_mode) { HAMLIB_TRACE; retcode = caps->get_split_mode(rig, vfo, tx_mode, tx_width); } else { HAMLIB_TRACE; retcode = caps->get_mode ? caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width) : -RIG_ENIMPL; } if (retcode == RIG_OK) { rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width); } /* try and revert even if we had an error above */ if (caps->set_vfo) { HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); } else { rc2 = caps->vfo_op(rig, vfo, RIG_OP_TOGGLE); } if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } if (*tx_width == RIG_PASSBAND_NORMAL && *tx_mode != RIG_MODE_NONE) { *tx_width = rig_passband_normal(rig, *tx_mode); } ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the split frequency and mode * \param rig The rig handle * \param vfo The target VFO * \param tx_freq The transmit frequency to set to * \param tx_mode The transmit split mode to set to * \param tx_width The transmit split width to set to or the special * value RIG_PASSBAND_NOCHANGE which leaves the passband unchanged * from the current value or default for the mode determined by the * rig. * * Sets the split(TX) frequency and mode. * * This function maybe optimized on some rig back ends, where the TX * VFO cannot be directly addressed, to reduce the number of times * the rig VFOs have to be exchanged or swapped to complete this * combined function. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_split_freq(), rig_set_split_mode(), rig_get_split_freq_mode() */ int HAMLIB_API rig_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width) { const struct rig_caps *caps; const struct rig_state *rs; vfo_t tx_vfo; struct rig_cache *cachep; int retcode; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Turn split on if not enabled already retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig, RIG_VFO_OTHER, RIG_SPLIT_OFF)); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error turning split on: result=%d\n", __func__, retcode); ELAPSED2; RETURNFUNC(retcode); } } // TX VFO may change after enabling split tx_vfo = rs->tx_vfo; vfo = vfo_fixup(rig, RIG_VFO_TX, cachep->split); // get the TX VFO rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, tx_freq=%.0f, tx_mode=%s, tx_width=%d\n", __func__, rig_strvfo(vfo), tx_freq, rig_strrmode(tx_mode), (int)tx_width); if (caps->set_split_freq_mode) { #if 0 freq_t tfreq; int retry = 3; int retcode2; #endif HAMLIB_TRACE; retcode = caps->set_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width); #if 0 // this verification seems to be causing bad behavior on some rigs // we query freq after set to ensure it really gets done do { retcode = caps->set_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width); retcode2 = rig_get_split_freq(rig, vfo, &tfreq); if (tfreq != tx_freq) { rig_debug(RIG_DEBUG_ERR, "%s: txfreq!=tfreq %.0f!=%.0f, retry=%d, rc1=%d, rc2=%d\n", __func__, tx_freq, tfreq, retry, retcode, retcode2); hl_usleep(50 * 1000); // 50ms sleep may help here } tfreq = tx_freq; retcode2 = RIG_OK; } while (tfreq != tx_freq && retry-- > 0 && retcode == RIG_OK && retcode2 == RIG_OK); if (tfreq != tx_freq) { retcode = -RIG_EPROTO; } #endif ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, tx_freq); rig_set_cache_mode(rig, tx_vfo, tx_mode, tx_width); } RETURNFUNC(retcode); } else { HAMLIB_TRACE; retcode = rig_set_split_freq(rig, vfo, tx_freq); } if (RIG_OK == retcode) { rig_set_cache_freq(rig, vfo, tx_freq); HAMLIB_TRACE; retcode = rig_set_split_mode(rig, vfo, tx_mode, tx_width); } ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the current split frequency and mode * \param rig The rig handle * \param vfo The target VFO * \param tx_freq The location where to store the current transmit frequency * \param tx_mode The location where to store the current transmit split mode * \param tx_width The location where to store the current transmit split width * * Retrieves the current split(TX) frequency, mode and passband. * If the backend is unable to determine the width, the \a tx_width * will be set to RIG_PASSBAND_NORMAL as a default. * The value stored at \a tx_mode location equals RIG_MODE_NONE * when the current mode of the VFO is not defined (e.g. blank memory). * * This function maybe optimized on some rig back ends, where the TX * VFO cannot be directly addressed, to reduce the number of times * the rig VFOs have to be exchanged or swapped to complete this * combined function. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_split_freq(), rig_get_split_mode(), rig_set_split_freq_mode() */ int HAMLIB_API rig_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width) { const struct rig_caps *caps; const struct rig_state *rs; struct rig_cache *cachep; vfo_t tx_vfo; int retcode; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!tx_freq || !tx_mode || !tx_width) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); // Always use the previously selected TX VFO for split. The targeted VFO will have no effect. tx_vfo = rs->tx_vfo; if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { // Split frequency, mode and filter width are not available if split is off *tx_freq = 0; *tx_mode = RIG_MODE_NONE; *tx_width = 0; ELAPSED2; RETURNFUNC(RIG_OK); } if (caps->get_split_freq_mode) { retcode = caps->get_split_freq_mode(rig, tx_vfo, tx_freq, tx_mode, tx_width); ELAPSED2; if (retcode == RIG_OK) { rig_set_cache_freq(rig, tx_vfo, *tx_freq); rig_set_cache_mode(rig, tx_vfo, *tx_mode, *tx_width); } RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = rig_get_split_freq(rig, vfo, tx_freq); if (RIG_OK == retcode) { HAMLIB_TRACE; retcode = rig_get_split_mode(rig, vfo, tx_mode, tx_width); } ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the split mode * \param rig The rig handle * \param rx_vfo The receive VFO * \param split The split mode to set to * \param tx_vfo The transmit VFO * * Sets the current split mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_split_vfo() */ int HAMLIB_API rig_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { const struct rig_caps *caps; struct rig_cache *cachep; int retcode; struct rig_state *rs; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); ELAPSED1; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: rx_vfo=%s, split=%d, tx_vfo=%s, cache.split=%d\n", __func__, rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), cachep->split); if (caps->set_split_vfo == NULL) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (cachep->ptt) { rig_debug(RIG_DEBUG_WARN, "%s: cannot execute when PTT is on\n", __func__); ELAPSED2; RETURNFUNC(RIG_OK); } if (rx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_NONE) { ELAPSED2; RETURNFUNC(-RIG_EINVAL); } // We fix up vfos for non-satmode rigs only if (caps->has_get_func & RIG_FUNC_SATMODE) { if (tx_vfo == RIG_VFO_CURR) { tx_vfo = rs->current_vfo; rx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, split); } // Fix up only special cases to allow ambiguous parameters if (rx_vfo == tx_vfo) { switch (tx_vfo) { case RIG_VFO_MAIN: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_SUB : RIG_VFO_MAIN; break; case RIG_VFO_A: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_B : RIG_VFO_A; break; case RIG_VFO_SUB: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_MAIN : RIG_VFO_SUB; break; case RIG_VFO_B: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_A : RIG_VFO_B; break; default: tx_vfo = rs->current_vfo; rx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, split); break; } } rig_debug(RIG_DEBUG_TRACE, "%s: rig supports satmode, not fixing up vfos: rx=%s tx=%s\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo)); } else { switch (tx_vfo) { case RIG_VFO_MAIN: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_SUB : RIG_VFO_MAIN; break; case RIG_VFO_A: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_B : RIG_VFO_A; break; case RIG_VFO_SUB: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_MAIN : RIG_VFO_SUB; break; case RIG_VFO_B: rx_vfo = split != RIG_SPLIT_OFF ? RIG_VFO_A : RIG_VFO_B; break; default: break; } rx_vfo = vfo_fixup(rig, rx_vfo, split); tx_vfo = vfo_fixup(rig, tx_vfo, split); rig_debug(RIG_DEBUG_VERBOSE, "%s: final rx_vfo=%s, tx_vfo=%s, split=%d\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split); } // set rig to the the requested RX VFO HAMLIB_TRACE; if ((!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) && (!(caps->rig_model == RIG_MODEL_NETRIGCTL))) { rig_set_vfo(rig, rx_vfo); } // Check if RX VFO is the currently active VFO and we don't need to change the VFO if (rx_vfo == RIG_VFO_CURR || rx_vfo == rs->current_vfo) { // for non-targetable VFOs we will not set split again if (cachep->split == split && cachep->split_vfo == tx_vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): split already on, ignoring\n", __func__, __LINE__); RETURNFUNC(RIG_OK); } HAMLIB_TRACE; retcode = caps->set_split_vfo(rig, rx_vfo, split, tx_vfo); if (retcode == RIG_OK) { // Only update cache on success rs->rx_vfo = rs->current_vfo; cachep->split = split; if (split == RIG_SPLIT_OFF) { rs->tx_vfo = rs->current_vfo; cachep->split_vfo = rs->current_vfo; } else { rs->tx_vfo = tx_vfo; cachep->split_vfo = tx_vfo; } } elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_SET); ELAPSED2; RETURNFUNC(retcode); } // RX VFO change required if (!caps->set_vfo) { ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; HAMLIB_TRACE; if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { retcode = caps->set_vfo(rig, rx_vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } } HAMLIB_TRACE; retcode = caps->set_split_vfo(rig, rx_vfo, split, tx_vfo); /* try and revert VFO change even if we had an error above */ if (!(caps->targetable_vfo & RIG_TARGETABLE_FREQ)) { int rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } } if (retcode == RIG_OK) { // Only update cache on success cachep->split = split; if (split == RIG_SPLIT_OFF) { if (caps->targetable_vfo & RIG_TARGETABLE_FREQ) { rs->rx_vfo = rx_vfo; rs->tx_vfo = rx_vfo; cachep->split_vfo = rx_vfo; } else { rs->rx_vfo = rs->current_vfo; rs->tx_vfo = rs->current_vfo; cachep->split_vfo = rs->current_vfo; } } else { rs->rx_vfo = rx_vfo; rs->tx_vfo = tx_vfo; cachep->split_vfo = tx_vfo; } } elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_SET); ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the current split mode * \param rig The rig handle * \param vfo The target VFO * \param split The location where to store the current split mode * \param tx_vfo The transmit VFO * * Retrieves the current split mode. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_split_vfo() */ int HAMLIB_API rig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct rig_caps *caps; struct rig_state *rs; struct rig_cache *cachep; int retcode; int cache_ms; int use_cache = 0; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ELAPSED1; ENTERFUNC; if (!split || !tx_vfo) { rig_debug(RIG_DEBUG_ERR, "%s: split or tx_vfo is null, split=%p, tx_vfo=%p\n", __func__, split, tx_vfo); ELAPSED2; RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; rs = STATE(rig); cachep = CACHE(rig); if (MUTEX_CHECK(&morse_mutex)) { use_cache = 1; } if (caps->get_split_vfo == NULL || use_cache) { rig_debug(RIG_DEBUG_TRACE, "%s: ?get_split_vfo=%d use_cache=%d\n", __func__, caps->get_split_vfo != NULL, use_cache); // if we can't get the vfo we will return whatever we have cached *split = cachep->split; *tx_vfo = cachep->split_vfo; ELAPSED2; RETURNFUNC(RIG_OK); } cache_ms = elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_GET); rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms); if (cache_ms < cachep->timeout_ms) { *split = cachep->split; *tx_vfo = cachep->split_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms, split=%d, tx_vfo=%s\n", __func__, cache_ms, *split, rig_strvfo(*tx_vfo)); ELAPSED2; RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms); } HAMLIB_TRACE; retcode = caps->get_split_vfo(rig, vfo, split, tx_vfo); if (retcode == RIG_OK) { // Only update cache on success rs->tx_vfo = *tx_vfo; cachep->split = *split; cachep->split_vfo = *tx_vfo; elapsed_ms(&cachep->time_split, HAMLIB_ELAPSED_SET); rig_debug(RIG_DEBUG_TRACE, "%s(%d): cache.split=%d\n", __func__, __LINE__, cachep->split); } ELAPSED2; RETURNFUNC(retcode); } /** * \brief set the RIT * \param rig The rig handle * \param vfo The target VFO * \param rit The RIT offset to adjust to * * Sets the current RIT offset. A value of 0 for \a rit disables RIT. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_rit() */ int HAMLIB_API rig_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->set_rit == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if ((caps->targetable_vfo & RIG_TARGETABLE_RITXIT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_rit(rig, vfo, rit); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->set_rit(rig, vfo, rit); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief get the current RIT offset * \param rig The rig handle * \param vfo The target VFO * \param rit The location where to store the current RIT offset * * Retrieves the current RIT offset. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_rit() */ int HAMLIB_API rig_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_rit == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if ((caps->targetable_vfo & RIG_TARGETABLE_RITXIT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_rit(rig, vfo, rit); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_rit(rig, vfo, rit); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief set the XIT * \param rig The rig handle * \param vfo The target VFO * \param xit The XIT offset to adjust to * * Sets the current XIT offset. A value of 0 for \a xit disables XIT. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_xit() */ int HAMLIB_API rig_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->set_xit == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if ((caps->targetable_vfo & RIG_TARGETABLE_RITXIT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_xit(rig, vfo, xit); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->set_xit(rig, vfo, xit); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief get the current XIT offset * \param rig The rig handle * \param vfo The target VFO * \param xit The location where to store the current XIT offset * * Retrieves the current XIT offset. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_xit() */ int HAMLIB_API rig_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (!xit) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_xit == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if ((caps->targetable_vfo & RIG_TARGETABLE_RITXIT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_xit(rig, vfo, xit); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_xit(rig, vfo, xit); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief set the Tuning Step * \param rig The rig handle * \param vfo The target VFO * \param ts The tuning step to set to * * Sets the Tuning Step. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ts() */ int HAMLIB_API rig_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->set_ts == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_ts(rig, vfo, ts); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->set_ts(rig, vfo, ts); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief get the current Tuning Step * \param rig The rig handle * \param vfo The target VFO * \param ts The location where to store the current tuning step * * Retrieves the current tuning step. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ts() */ int HAMLIB_API rig_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (!ts) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_ts == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_ts(rig, vfo, ts); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_ts(rig, vfo, ts); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief set the antenna * \param rig The rig handle * \param vfo The target VFO * \param ant The antenna to select * \param option An option that the ant command for the rig recognizes * * Select the antenna connector. \code rig_set_ant(rig, RIG_VFO_CURR, RIG_ANT_1); // apply to both TX&RX rig_set_ant(rig, RIG_VFO_RX, RIG_ANT_2); \endcode * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_ant() */ int HAMLIB_API rig_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->set_ant == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if ((caps->targetable_vfo & RIG_TARGETABLE_ANT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->set_ant(rig, vfo, ant, option); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->set_ant(rig, vfo, ant, option); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief get the current antenna * \param rig The rig handle * \param vfo The target VFO * \param ant The antenna to query option for * \param option The option value for the antenna, rig specific. * \param ant_curr The currently selected antenna * \param ant_tx The currently selected TX antenna * \param ant_rx The currently selected RX antenna * * Retrieves the current antenna. * * If \a ant_tx and/or \a ant_rx are unused by the rig they will be set to * RIG_ANT_UNKNOWN and only \a ant_curr will be set. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_ant() */ int HAMLIB_API rig_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (ant_curr == NULL || ant_tx == NULL || ant_rx == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: null pointer in ant_curr=%p, ant_tx=%p, ant_rx=%p\n", __func__, ant_curr, ant_tx, ant_rx); RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->get_ant == NULL) { RETURNFUNC(-RIG_ENAVAIL); } /* Set antenna default to unknown and clear option. * So we have sane defaults for all backends */ *ant_tx = *ant_rx = *ant_curr = RIG_ANT_UNKNOWN; option->i = 0; if ((caps->targetable_vfo & RIG_TARGETABLE_ANT) || vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { HAMLIB_TRACE; retcode = caps->get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief conversion utility from relative range to absolute in mW * \param rig The rig handle * \param mwpower The location where to store the converted power in mW * \param power The relative power * \param freq The frequency where the conversion should take place * \param mode The mode where the conversion should take place * * Converts a power value expressed in a range on a [0.0 .. 1.0] relative * scale to the real transmit power in milli Watts the radio would emit. * The \a freq and \a mode where the conversion should take place must be * also provided since the relative power is peculiar to a specific * freq and mode range of the radio. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_mW2power() */ int HAMLIB_API rig_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const freq_range_t *txrange; char buf[32]; if (!rig || !rig->caps || !mwpower || power < 0.0 || power > 1.0) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps or mwpower or power is funky\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (rig->caps->power2mW != NULL) { RETURNFUNC(rig->caps->power2mW(rig, mwpower, power, freq, mode)); } txrange = rig_get_range(STATE(rig)->tx_range_list, freq, mode); // check all the range lists if (txrange == NULL) { txrange = rig_get_range(rig->caps->tx_range_list1, freq, mode); } if (txrange == NULL) { txrange = rig_get_range(rig->caps->tx_range_list2, freq, mode); } if (txrange == NULL) { txrange = rig_get_range(rig->caps->tx_range_list3, freq, mode); } if (txrange == NULL) { txrange = rig_get_range(rig->caps->tx_range_list4, freq, mode); } if (txrange == NULL) { txrange = rig_get_range(rig->caps->tx_range_list5, freq, mode); } if (txrange == NULL) { /* * freq is not on the tx range! */ rig_debug(RIG_DEBUG_ERR, "%s: freq not in tx range\n", __func__); RETURNFUNC(-RIG_EINVAL); } snprintf(buf, sizeof(buf), "%.0f", power * txrange->high_power); *mwpower = atoi(buf); //*mwpower = (unsigned int)(power * txrange->high_power); RETURNFUNC(RIG_OK); } /** * \brief conversion utility from absolute in mW to relative range * \param rig The rig handle * \param power The location where to store the converted relative power * \param mwpower The power in mW * \param freq The frequency where the conversion should take place * \param mode The mode where the conversion should take place * * Converts a power value expressed in the real transmit power in milli Watts * the radio would emit to a range on a [0.0 .. 1.0] relative scale. * The \a freq and \a mode where the conversion should take place must be * also provided since the relative power is peculiar to a specific * freq and mode range of the radio. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_power2mW() */ int HAMLIB_API rig_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { const freq_range_t *txrange; int limited = 0; if (!rig || !rig->caps || !power || mwpower == 0) { return -RIG_EINVAL; } ENTERFUNC2; if (rig->caps->mW2power != NULL) { RETURNFUNC2(rig->caps->mW2power(rig, power, mwpower, freq, mode)); } txrange = rig_get_range(STATE(rig)->tx_range_list, freq, mode); if (!txrange) { /* * freq is not on the tx range! */ RETURNFUNC2(-RIG_EINVAL); /* could be RIG_EINVAL ? */ } if (txrange->high_power == 0) { *power = 0.0; RETURNFUNC2(RIG_OK); } *power = (float)mwpower / (float) txrange->high_power; if (*power > 1.0) { *power = 1.0; limited = 1; } else if (*power < 0.0) { *power = 0; limited = 1; } RETURNFUNC2(limited ? RIG_ETRUNC : RIG_OK); } /** * \brief get the best frequency resolution of the rig * \param rig The rig handle * \param mode The mode where the conversion should take place * * Returns the best frequency resolution of the rig, for a given \a mode. * * \return the frequency resolution in Hertz if the operation * has been successful, otherwise a negative value if an error occurred. * */ shortfreq_t HAMLIB_API rig_get_resolution(RIG *rig, rmode_t mode) { const struct rig_state *rs; int i; if (!rig || !rig->caps || !mode) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps or mode is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; rs = STATE(rig); for (i = 0; i < HAMLIB_TSLSTSIZ && rs->tuning_steps[i].ts; i++) { if (rs->tuning_steps[i].modes & mode) { RETURNFUNC(rs->tuning_steps[i].ts); } } RETURNFUNC(-RIG_EINVAL); } /** * \brief turn on/off the radio * \param rig The rig handle * \param status The status to set to * * turns on/off the radio. * See #RIG_POWER_ON, #RIG_POWER_OFF and #RIG_POWER_STANDBY defines * for the \a status. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_powerstat() */ int HAMLIB_API rig_set_powerstat(RIG *rig, powerstat_t status) { int retcode; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, status); if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; ELAPSED1; if (rig->caps->set_powerstat == NULL) { rig_debug(RIG_DEBUG_WARN, "%s set_powerstat not implemented\n", __func__); STATE(rig)->powerstat = RIG_POWER_ON; // assume we are on if we can't set_powerstat RETURNFUNC(-RIG_ENAVAIL); } HAMLIB_TRACE; retcode = rig->caps->set_powerstat(rig, status); if (retcode == RIG_OK) { STATE(rig)->powerstat = status; } // if anything is queued up flush it rig_flush_force(RIGPORT(rig), 1); ELAPSED2; RETURNFUNC(retcode); } /** * \brief get the on/off status of the radio * \param rig The rig handle * \param status The location where to store the current status * * Retrieve the status of the radio. See #RIG_POWER_ON, #RIG_POWER_OFF and * #RIG_POWER_STANDBY defines for the \a status. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_powerstat() */ int HAMLIB_API rig_get_powerstat(RIG *rig, powerstat_t *status) { int retcode; if (CHECK_RIG_ARG(rig)) { *status = RIG_POWER_ON; // default to power on if not available return -RIG_EINVAL; } ENTERFUNC; if (!status) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->get_powerstat == NULL) { *status = RIG_POWER_ON; // default to power if not available RETURNFUNC(RIG_OK); } *status = RIG_POWER_OFF; // default now to power off until proven otherwise in get_powerstat HAMLIB_TRACE; retcode = rig->caps->get_powerstat(rig, status); if (retcode == RIG_OK) { STATE(rig)->powerstat = *status; } else { // if failed, assume power is on *status = RIG_POWER_ON; } RETURNFUNC(retcode); } /** * \brief reset the radio * \param rig The rig handle * \param reset The reset operation to perform * * Resets the radio. * See #RIG_RESET_NONE, #RIG_RESET_SOFT and #RIG_RESET_MCALL defines * for the \a reset. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_reset(RIG *rig, reset_t reset) { int retcode; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (rig->caps->reset == NULL) { RETURNFUNC(-RIG_ENAVAIL); } retcode = rig->caps->reset(rig, reset); RETURNFUNC(retcode); } //! @cond Doxygen_Suppress extern int rig_probe_first(hamlib_port_t *p); extern int rig_probe_all_backends(hamlib_port_t *p, rig_probe_func_t cfunc, rig_ptr_t data); //! @endcond /** * \brief try to guess a rig * \param port A pointer describing a port linking the host to the rig * * Try to guess what is the model of the first rig attached to the port. * It can be very buggy, and mess up the radio at the other end. * (but fun if it works!) * * \warning this is really Experimental, It has been tested only * with IC-706MkIIG. any feedback welcome! --SF * * \return the rig model id according to the rig_model_t type if found, * otherwise RIG_MODEL_NONE if unable to determine rig model. */ rig_model_t HAMLIB_API rig_probe(hamlib_port_t *port) { if (!port) { return (RIG_MODEL_NONE); } return rig_probe_first(port); } /** * \brief try to guess rigs * \param port A pointer describing a port linking the host to the rigs * \param cfunc Function to be called each time a rig is found * \param data Arbitrary data passed to cfunc * * Try to guess what are the model of all rigs attached to the port. * It can be very buggy, and mess up the radio at the other end. * (but fun if it works!) * * \warning this is really Experimental, It has been tested only * with IC-706MkIIG. any feedback welcome! --SF * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_probe_all(hamlib_port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) { if (!port) { return (-RIG_EINVAL); } return rig_probe_all_backends(port, cfunc, data); } /** * \brief check retrieval ability of VFO operations * \param rig The rig handle * \param op The VFO op * * Checks if a rig is capable of executing a VFO operation. * Since the \a op is an OR'ed bitmap argument, more than * one op can be checked at the same time. * * EXAMPLE: if (rig_has_vfo_op(my_rig, RIG_OP_CPY)) disp_VFOcpy_btn(); * * \return a bit map mask of supported op settings that can be retrieved, * otherwise 0 if none supported. * * \sa rig_vfo_op() */ vfo_op_t HAMLIB_API rig_has_vfo_op(RIG *rig, vfo_op_t op) { int retcode; if (!rig || !rig->caps) { return (0); } retcode = STATE(rig)->vfo_ops & op; return retcode; } /** * \brief perform Memory/VFO operations * \param rig The rig handle * \param vfo The target VFO * \param op The Memory/VFO operation to perform * * Performs Memory/VFO operation. * See #vfo_op_t for more information. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_vfo_op() */ int HAMLIB_API rig_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; ELAPSED1; caps = rig->caps; if (caps->vfo_op == NULL || rig_has_vfo_op(rig, op) == 0) { rig_debug(RIG_DEBUG_WARN, "%s: vfo_op=%p, has_vfo_op=%d\n", __func__, caps->vfo_op, rig_has_vfo_op(rig, op)); ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = caps->vfo_op(rig, vfo, op); ELAPSED2; RETURNFUNC(retcode); } if (!caps->set_vfo) { rig_debug(RIG_DEBUG_WARN, "%s: no set_vfo\n", __func__); ELAPSED2; RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { ELAPSED2; RETURNFUNC(retcode); } retcode = caps->vfo_op(rig, vfo, op); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } ELAPSED2; RETURNFUNC(retcode); } /** * \brief check availability of scanning functions * \param rig The rig handle * \param scan The scan op * * Checks if a rig is capable of performing a scan operation. * Since the \a scan parameter is an OR'ed bitmap argument, more than * one op can be checked at the same time. * * EXAMPLE: if (rig_has_scan(my_rig, RIG_SCAN_PRIO)) disp_SCANprio_btn(); * * \return a bit map of supported scan settings that can be retrieved, * otherwise 0 if none supported. * * \sa rig_scan() */ scan_t HAMLIB_API rig_has_scan(RIG *rig, scan_t scan) { int retcode; if (!rig || !rig->caps) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is NULL\n", __func__); return (0); } ENTERFUNC; retcode = rig->caps->scan_ops & scan; RETURNFUNC(retcode); } /** * \brief perform Memory/VFO operations * \param rig The rig handle * \param vfo The target VFO * \param scan The scanning operation to perform * \param ch Optional channel argument used for the scan. * * Performs scanning operation. * See #scan_t for more information. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_has_scan() */ int HAMLIB_API rig_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->scan == NULL || (scan != RIG_SCAN_STOP && !rig_has_scan(rig, scan))) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = caps->scan(rig, vfo, scan, ch); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->scan(rig, vfo, scan, ch); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief send DTMF digits * \param rig The rig handle * \param vfo The target VFO * \param digits Digits to be send * * Sends DTMF digits. * See DTMF change speed, etc. (TODO). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (!digits) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->send_dtmf == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = caps->send_dtmf(rig, vfo, digits); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->send_dtmf(rig, vfo, digits); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief receive DTMF digits * \param rig The rig handle * \param vfo The target VFO * \param digits Location where the digits are to be stored * \param length in: max length of buffer, out: number really read. * * Receives DTMF digits (not blocking). * See DTMF change speed, etc. (TODO). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; if (!digits || !length) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->recv_dtmf == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = caps->recv_dtmf(rig, vfo, digits, length); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->recv_dtmf(rig, vfo, digits, length); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief send morse code * \param rig The rig handle * \param vfo The target VFO * \param msg Message to be sent * * Sends morse message. * See keyer change speed, etc. (TODO). * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_send_morse(RIG *rig, vfo_t vfo, const char *msg) { const struct rig_caps *caps; struct rig_state *rs; int retcode = RIG_EINTERNAL, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; rs = STATE(rig); if (!msg) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (caps->send_morse == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (caps->get_mode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: rig does not have get_mode\n", __func__); RETURNFUNC(-RIG_EINVAL); } rmode_t mode; pbwidth_t width; rig_get_mode(rig, RIG_VFO_CURR, &mode, &width); if ((mode & (RIG_MODE_CW | RIG_MODE_CWR)) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: rig is in mode %s, not in CW/CWR mode\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { #if 0 LOCK(1); retcode = caps->send_morse(rig, vfo, msg); LOCK(0); #else retcode = push(rs->fifo_morse, msg); #endif RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } HAMLIB_TRACE; retcode = caps->send_morse(rig, vfo, msg); /* try and revert even if we had an error above */ rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief stop morse code * \param rig The rig handle * \param vfo The target VFO * * Stops the send morse message. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_stop_morse(RIG *rig, vfo_t vfo) { const struct rig_caps *caps; struct rig_state *rs; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; rs = STATE(rig); if (caps->stop_morse == NULL) { RETURNFUNC(-RIG_ENAVAIL); } resetFIFO(rs->fifo_morse); // clear out the CW queue LOCK(1); if (vfo == RIG_VFO_CURR || vfo == rs->current_vfo) { retcode = caps->stop_morse(rig, vfo); LOCK(0); RETURNFUNC(retcode); } if (!caps->set_vfo) { LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = rs->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { LOCK(0); RETURNFUNC(retcode); } retcode = caps->stop_morse(rig, vfo); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } LOCK(0); RETURNFUNC(retcode); } /* * wait_morse_ptt * generic routine to wait for ptt=0 * should work on any full break-in CW morse send * Assumes rig!=NULL, msg!=NULL */ static int wait_morse_ptt(RIG *rig, vfo_t vfo) { ptt_t pttStatus = RIG_PTT_OFF; int loops = 0; ENTERFUNC; hl_usleep(200 * 1000); // give little time for CW to start PTT do { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: loop#%d until ptt=0, ptt=%d\n", __func__, loops, pttStatus); elapsed_ms(&CACHE(rig)->time_ptt, HAMLIB_ELAPSED_INVALIDATE); HAMLIB_TRACE; retval = rig_get_ptt(rig, vfo, &pttStatus); if (retval != RIG_OK) { RETURNFUNC(retval); } // every 25ms should be short enough hl_usleep(50 * 1000); ++loops; } while (pttStatus == RIG_PTT_ON && loops <= 600); RETURNFUNC(RIG_OK); } /** * \brief wait morse code * \param rig The rig handle * \param vfo The target VFO * * waits for the end of the morse message to be sent. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_wait_morse(RIG *rig, vfo_t vfo) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; LOCK(1); if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = wait_morse_ptt(rig, vfo); LOCK(0); RETURNFUNC(retcode); } if (!caps->set_vfo) { LOCK(0); RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { LOCK(0); RETURNFUNC(retcode); } retcode = wait_morse_ptt(rig, vfo); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } LOCK(0); RETURNFUNC(retcode); } /** * \brief send voice memory content * \param rig The rig handle * \param vfo The target VFO * \param ch Voice memory number to be sent * * Sends voice memory content. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { const struct rig_caps *caps; int retcode, rc2; vfo_t curr_vfo; if CHECK_RIG_ARG(rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->send_voice_mem == NULL) { RETURNFUNC(-RIG_ENAVAIL); } if (vfo == RIG_VFO_CURR || vfo == STATE(rig)->current_vfo) { retcode = caps->send_voice_mem(rig, vfo, ch); RETURNFUNC(retcode); } if (!caps->set_vfo) { RETURNFUNC(-RIG_ENAVAIL); } curr_vfo = STATE(rig)->current_vfo; HAMLIB_TRACE; retcode = caps->set_vfo(rig, vfo); if (retcode != RIG_OK) { RETURNFUNC(retcode); } retcode = caps->send_voice_mem(rig, vfo, ch); /* try and revert even if we had an error above */ HAMLIB_TRACE; rc2 = caps->set_vfo(rig, curr_vfo); if (RIG_OK == retcode) { /* Return the first error code */ retcode = rc2; } RETURNFUNC(retcode); } /** * \brief stop sending voice memory * \param rig The rig handle * \param vfo The target VFO * * Stops sending voice memory content. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * */ int HAMLIB_API rig_stop_voice_mem(RIG *rig, vfo_t vfo) { const struct rig_caps *caps; int retcode; if CHECK_RIG_ARG(rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; caps = rig->caps; if (caps->stop_voice_mem == NULL) { RETURNFUNC(-RIG_ENAVAIL); } retcode = caps->stop_voice_mem(rig, vfo); RETURNFUNC(retcode); } /** * \brief find the freq_range of freq/mode * \param range_list The range list to search from * \param freq The frequency that will be part of this range * \param mode The mode that will be part of this range * * Returns a pointer to the #freq_range_t including \a freq and \a mode. * Works for rx and tx range list as well. * * \return the location of the #freq_range_t if found, * otherwise NULL if not found or if \a range_list is invalid. * */ const freq_range_t *HAMLIB_API rig_get_range(const freq_range_t *range_list, freq_t freq, rmode_t mode) { int i; if (range_list == NULL) { return (NULL); } for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { if (range_list[i].startf == 0 && range_list[i].endf == 0) { return (NULL); } if (freq >= range_list[i].startf && freq <= range_list[i].endf && (range_list[i].modes & mode)) { const freq_range_t *f = &range_list[i]; return (f); } } return (NULL); } /** * \brief set the vfo option for rigctld * \param status 1=On, 0=Off * * Returns RIG_OK or -RIG_EPROTO; * */ int HAMLIB_API rig_set_vfo_opt(RIG *rig, int status) { int retcode; if CHECK_RIG_ARG(rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; ELAPSED1; // Only netrigctl has this function // We allow the status to be set for rigctl use if (rig->caps->set_vfo_opt == NULL) { ELAPSED2; STATE(rig)->vfo_opt = status; //RETURNFUNC(-RIG_ENAVAIL); RETURNFUNC(RIG_OK); } retcode = rig->caps->set_vfo_opt(rig, status); ELAPSED2; RETURNFUNC(retcode); } /** * \brief get general information from the radio * \param rig The rig handle * * Retrieves some general information from the radio. * This can include firmware revision, exact model name, or just nothing. * * \return a pointer to memory containing the ASCIIZ string * if the operation has been successful, otherwise NULL if an error occurred * or if get_info is not part of the capabilities. */ const char *HAMLIB_API rig_get_info(RIG *rig) { if (CHECK_RIG_ARG(rig)) { return (NULL); } if (rig->caps->get_info == NULL) { return (NULL); } HAMLIB_TRACE; return (rig->caps->get_info(rig)); } #if 0 static void make_crc_table(unsigned long crcTable[]) { unsigned long POLYNOMIAL = 0xEDB88320; unsigned char b = 0; // Start with the data byte unsigned long remainder = b; unsigned long bit; for (bit = 8; bit > 0; --bit) { if (remainder & 1) { remainder = (remainder >> 1) ^ POLYNOMIAL; } else { remainder = (remainder >> 1); } } crcTable[(size_t)b] = remainder; } static unsigned long crcTable[256]; static unsigned long gen_crc(unsigned char *p, size_t n) { unsigned long crc = 0xfffffffful; size_t i; if (crcTable[0] == 0) { make_crc_table(crcTable); } for (i = 0; i < n; i++) { crc = crcTable[*p++ ^ (crc & 0xff)] ^ (crc >> 8); } return ((~crc) & 0xffffffff); } #endif /** * \brief get freq/mode/width for requested VFO * \param rig The rig handle * * \returns a string for all known VFOs plus rig split status and satellite mode status */ int HAMLIB_API rig_get_rig_info(RIG *rig, char *response, int max_response_len) { vfo_t vfoA, vfoB; freq_t freqA, freqB; rmode_t modeA, modeB; char *modeAstr, *modeBstr; pbwidth_t widthA, widthB; split_t split; int satmode; int ret; int rxa, txa, rxb, txb; struct rig_cache *cachep; if (CHECK_RIG_ARG(rig) || !response) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } cachep = CACHE(rig); response[0] = 0; ELAPSED1; ENTERFUNC2; vfoA = vfo_fixup(rig, RIG_VFO_A, cachep->split); vfoB = vfo_fixup(rig, RIG_VFO_B, cachep->split); ret = rig_get_vfo_info(rig, vfoA, &freqA, &modeA, &widthA, &split, &satmode); if (ret != RIG_OK) { ELAPSED2; RETURNFUNC2(ret); } // we need both vfo and mode targetable to avoid vfo swapping if ((rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) && (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE)) { ret = rig_get_vfo_info(rig, vfoB, &freqB, &modeB, &widthB, &split, &satmode); if (ret != RIG_OK) { ELAPSED2; RETURNFUNC2(ret); } } else { // we'll use cached info instead of doing the vfo swapping int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfoB, &freqB, &cache_ms_freq, &modeB, &cache_ms_mode, &widthB, &cache_ms_width); } modeAstr = (char *)rig_strrmode(modeA); modeBstr = (char *)rig_strrmode(modeB); if (modeAstr[0] == 0) { modeAstr = "None"; } if (modeBstr[0] == 0) { modeBstr = "None"; } rxa = 1; txa = split == 0; rxb = !rxa; txb = split == 1; SNPRINTF(response, max_response_len - strlen("CRC=0x00000000\n"), "VFO=%s Freq=%.0f Mode=%s Width=%d RX=%d TX=%d\nVFO=%s Freq=%.0f Mode=%s Width=%d RX=%d TX=%d\nSplit=%d SatMode=%d\nRig=%s\nApp=%s\nVersion=20241103 1.1.0\nModel=%u\n", rig_strvfo(vfoA), freqA, modeAstr, (int)widthA, rxa, txa, rig_strvfo(vfoB), freqB, modeBstr, (int)widthB, rxb, txb, split, satmode, rig->caps->model_name, STATE(rig)->client_version, rig->caps->rig_model); unsigned long crc = CRC32_function((unsigned char *)response, strlen(response)); char tmpstr[32]; SNPRINTF(tmpstr, sizeof(tmpstr), "CRC=0x%08lx\n", crc); strcat(response, tmpstr); if (strlen(response) >= max_response_len - 1) { rig_debug(RIG_DEBUG_ERR, "%s(%d): response len exceeded max %d chars\n", __FILE__, __LINE__, max_response_len); ELAPSED2; RETURNFUNC2(-RIG_EINTERNAL); } ELAPSED2; RETURNFUNC2(RIG_OK); } /** * \brief get freq/mode/width for requested VFO * \param rig The rig handle * \param vfo The VFO to get * \param *freq frequency answer * \param *mode mode answer * \param *width bandwidth answer * * Gets the current VFO information. The VFO can be RIG_VFO_A, RIG_VFO_B, RIG_VFO_C * for VFOA, VFOB, VFOC respectively or RIG_VFO_MEM for Memory mode. * Supported VFOs depends on rig capabilities. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case use rigerror(return) * for error message). * */ int HAMLIB_API rig_get_vfo_info(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width, split_t *split, int *satmode) { int retval; struct rig_cache *cachep; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if (CHECK_RIG_ARG(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } cachep = CACHE(rig); ELAPSED1; ENTERFUNC; //if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } vfo = vfo_fixup(rig, vfo, cachep->split); // we can't use the cached values as some clients may only call this function // like Log4OM which mostly does polling HAMLIB_TRACE; retval = rig_get_freq(rig, vfo, freq); if (retval != RIG_OK) { RETURNFUNC(retval); } // we will ask for other vfo mode just once if not targetable int allTheTimeA = vfo & (RIG_VFO_A | RIG_VFO_CURR | RIG_VFO_MAIN_A | RIG_VFO_SUB_A); int allTheTimeB = (vfo & (RIG_VFO_B | RIG_VFO_SUB)) && (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE); int justOnceB = (vfo & (RIG_VFO_B | RIG_VFO_SUB)) && (cachep->modeMainB == RIG_MODE_NONE); if (allTheTimeA || allTheTimeB || justOnceB) { HAMLIB_TRACE; retval = rig_get_mode(rig, vfo, mode, width); if (retval != RIG_OK) { ELAPSED2; RETURNFUNC(retval); } } else // we'll just us VFOA so we don't swap vfos -- freq is what's important { *mode = cachep->modeMainA; *width = cachep->widthMainA; } *satmode = cachep->satmode; // we should only need to ask for VFO_CURR to minimize display swapping HAMLIB_TRACE; vfo_t tx_vfo; retval = rig_get_split_vfo(rig, RIG_VFO_CURR, split, &tx_vfo); if (retval != RIG_OK) { ELAPSED2; RETURNFUNC(retval); } ELAPSED2; RETURNFUNC(RIG_OK); } /** * \brief get list of available vfos * \param rig The rig handle * \param buf char buffer to hold result * \param buflen max length of char buffer * * Retrieves all usable vfo entries for the rig * * \return a pointer to a string, e.g. "VFOA VFOB Mem" * if the operation has been successful, otherwise NULL if an error occurred */ int HAMLIB_API rig_get_vfo_list(RIG *rig, char *buf, int buflen) { if (CHECK_RIG_CAPS(rig)) { rig_debug(RIG_DEBUG_ERR, "%s: rig or rig->caps is null\n", __func__); return -RIG_EINVAL; } ENTERFUNC; rig_sprintf_vfo(buf, buflen - 1, STATE(rig)->vfo_list); RETURNFUNC(RIG_OK); } /** * \brief set the rig's clock * */ int HAMLIB_API rig_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { ENTERFUNC2; if (rig->caps->set_clock == NULL) { return -RIG_ENIMPL; } RETURNFUNC2(rig->caps->set_clock(rig, year, month, day, hour, min, sec, msec, utc_offset)); } /** * \brief get the rig's clock * */ int HAMLIB_API rig_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval; if (rig->caps->get_clock == NULL) { return -RIG_ENIMPL; } ENTERFUNC2; retval = rig->caps->get_clock(rig, year, month, day, hour, min, sec, msec, utc_offset); RETURNFUNC2(retval); } /** * \brief get the Hamlib license * */ const char *HAMLIB_API rig_license() { return hamlib_license; } /** * \brief get the Hamlib version * */ const char *HAMLIB_API rig_version() { return hamlib_version2; } /** * \brief get the Hamlib copyright * */ const char *HAMLIB_API rig_copyright() { return hamlib_copyright2; } /** * \brief get a cookie to grab rig control * \param rig Not used * \param cookie_cmd The command to execute on \a cookie. * \param cookie The cookie to operate on, cannot be NULL or RIG_EINVAL will be returned. * \param cookie_len The length of the cookie, must be #HAMLIB_COOKIE_SIZE or larger. * * #RIG_COOKIE_GET will set \a cookie with a cookie. * #RIG_COOKIE_RENEW will update the timeout with 1 second. * #RIG_COOKIE_RELEASE will release the cookie and allow a new one to be grabbed. * * Cookies should only be used when needed to keep commands sequenced correctly * For example, when setting both VFOA and VFOB frequency and mode * Example to wait for cookie, do rig commands, and release * \code * while((rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie))) != RIG_OK) * hl_usleep(10*1000); * * //Pseudo code * set_freq A;set mode A;set freq B;set modeB; * * rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie))); * \endcode */ int HAMLIB_API rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie, int cookie_len) { // only 1 client can have the cookie so these can be static // this should also prevent problems with DLLs & shared libraries // the debug_msg is another non-thread-safe which this will help fix static char cookie_save[HAMLIB_COOKIE_SIZE]; // only one client can have the cookie static double time_last_used; struct timespec tp; int ret; MUTEX(mutex_rig_cookie); /* This is not needed for RIG_COOKIE_RELEASE but keep it simple. */ if (cookie_len < HAMLIB_COOKIE_SIZE) { rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie_len < %d\n", __FILE__, __LINE__, HAMLIB_COOKIE_SIZE); return -RIG_EINVAL; } if (!cookie) { rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie == NULL\n", __FILE__, __LINE__); return -RIG_EINVAL; // nothing to do } /* Accessing cookie_save and time_last_used must be done with lock held. * So keep code simple and lock it during the whole operation. */ MUTEX_LOCK(mutex_rig_cookie); switch (cookie_cmd) { case RIG_COOKIE_RELEASE: if (cookie_save[0] != 0 && strcmp(cookie, cookie_save) == 0) // matching cookie so we'll clear it { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s cookie released\n", __FILE__, __LINE__, cookie_save); memset(cookie_save, 0, sizeof(cookie_save)); ret = RIG_OK; } else // not the right cookie!! { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s can't release cookie as cookie %s is active\n", __FILE__, __LINE__, cookie, cookie_save); ret = -RIG_BUSBUSY; } break; case RIG_COOKIE_RENEW: rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s comparing renew request to %s==%d\n", __FILE__, __LINE__, cookie, cookie_save, strcmp(cookie, cookie_save)); if (cookie_save[0] != 0 && strcmp(cookie, cookie_save) == 0) // matching cookie so we'll renew it { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) %s renew request granted\n", __FILE__, __LINE__, cookie); clock_gettime(CLOCK_REALTIME, &tp); time_last_used = tp.tv_sec + tp.tv_nsec / 1e9; ret = RIG_OK; } else { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s renew request refused %s is active\n", __FILE__, __LINE__, cookie, cookie_save); ret = -RIG_EINVAL; // wrong cookie } break; case RIG_COOKIE_GET: // the way we expire cookies is if somebody else asks for one and the last renewal is > 1 second ago // a polite client will have released the cookie // we are just allow for a crashed client that fails to release:q clock_gettime(CLOCK_REALTIME, &tp); double time_curr = tp.tv_sec + tp.tv_nsec / 1e9; if (cookie_save[0] != 0 && (strcmp(cookie_save, cookie) == 0) && (time_curr - time_last_used < 1)) // then we will deny the request { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s cookie is in use\n", __FILE__, __LINE__, cookie_save); ret = -RIG_BUSBUSY; } else { if (cookie_save[0] != 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s cookie has expired after %.3f seconds....overriding with new cookie\n", __FILE__, __LINE__, cookie_save, time_curr - time_last_used); } date_strget(cookie, cookie_len, 0); size_t len = strlen(cookie); // add on our random number to ensure uniqueness // The cookie should never be longer than HAMLIB_COOKIE_SIZE SNPRINTF(cookie + len, HAMLIB_COOKIE_SIZE - len, " %d\n", rand()); strcpy(cookie_save, cookie); time_last_used = time_curr; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s new cookie request granted\n", __FILE__, __LINE__, cookie_save); ret = RIG_OK; } break; default: rig_debug(RIG_DEBUG_ERR, "%s(%d): unknown cmd!!\n'", __FILE__, __LINE__); ret = -RIG_EPROTO; break; } MUTEX_UNLOCK(mutex_rig_cookie); return ret; } #if defined(HAVE_PTHREAD) static pthread_mutex_t initializer = PTHREAD_MUTEX_INITIALIZER; #endif HAMLIB_EXPORT(void) sync_callback(int lock) { #if defined(HAVE_PTHREAD) pthread_mutex_t client_lock = initializer; if (lock) { pthread_mutex_lock(&client_lock); rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock engaged\n", __func__); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock disengaged\n", __func__); pthread_mutex_unlock(&client_lock); } #endif } void rig_lock(RIG *rig, int lock) { #if defined(HAVE_PTHREAD) struct rig_state *rs = STATE(rig); if (lock) { pthread_mutex_lock(&rs->api_mutex); rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock engaged\n", __func__); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock disengaged\n", __func__); pthread_mutex_unlock(&rs->api_mutex); } #endif } /*! @} */ #define MAX_FRAME_LENGTH 1024 #if defined(HAVE_PTHREAD) static int async_data_handler_start(RIG *rig) { struct rig_state *rs = STATE(rig); async_data_handler_priv_data *async_data_handler_priv; ENTERFUNC; if (!rs->async_data_enabled) { rig_debug(RIG_DEBUG_TRACE, "%s: async data support disabled since async_data_enabled=%d\n", __func__, rs->async_data_enabled); RETURNFUNC(RIG_OK); } sleep(2); // give other things a chance to finish opening up the rig rs->async_data_handler_thread_run = 1; rs->async_data_handler_priv_data = calloc(1, sizeof(async_data_handler_priv_data)); if (rs->async_data_handler_priv_data == NULL) { RETURNFUNC(-RIG_ENOMEM); } async_data_handler_priv = (async_data_handler_priv_data *) rs->async_data_handler_priv_data; async_data_handler_priv->args.rig = rig; int err = pthread_create(&async_data_handler_priv->thread_id, NULL, async_data_handler, &async_data_handler_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(RIG_OK); } #endif #if defined(HAVE_PTHREAD) static int morse_data_handler_start(RIG *rig) { struct rig_state *rs = STATE(rig); morse_data_handler_priv_data *morse_data_handler_priv; ENTERFUNC; rs->morse_data_handler_thread_run = 1; rs->morse_data_handler_priv_data = calloc(1, sizeof(morse_data_handler_priv_data)); if (rs->morse_data_handler_priv_data == NULL) { RETURNFUNC(-RIG_ENOMEM); } morse_data_handler_priv = (morse_data_handler_priv_data *) rs->morse_data_handler_priv_data; morse_data_handler_priv->args.rig = rig; value_t keyspd; keyspd.i = 25; // default value if KEYSPD doesn't work rig_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_KEYSPD, &keyspd); morse_data_handler_priv->keyspd = keyspd.i; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); int err = pthread_create(&morse_data_handler_priv->thread_id, NULL, morse_data_handler, &morse_data_handler_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(RIG_OK); } #endif #if defined(HAVE_PTHREAD) static int async_data_handler_stop(RIG *rig) { struct rig_state *rs = STATE(rig); async_data_handler_priv_data *async_data_handler_priv; ENTERFUNC; rs->async_data_handler_thread_run = 0; async_data_handler_priv = (async_data_handler_priv_data *) rs->async_data_handler_priv_data; if (async_data_handler_priv != NULL) { if (async_data_handler_priv->thread_id != 0) { // all cleanup is done in this function so we can kill thread // Windows was taking 30 seconds to stop without this pthread_cancel(async_data_handler_priv->thread_id); int err = pthread_join(async_data_handler_priv->thread_id, NULL); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_join error: %s\n", __func__, strerror(errno)); // just ignore the error } async_data_handler_priv->thread_id = 0; } free(rs->async_data_handler_priv_data); rs->async_data_handler_priv_data = NULL; } RETURNFUNC(RIG_OK); } #endif #if defined(HAVE_PTHREAD) static int morse_data_handler_stop(RIG *rig) { struct rig_state *rs = STATE(rig); morse_data_handler_priv_data *morse_data_handler_priv; ENTERFUNC; rs->morse_data_handler_thread_run = 0; morse_data_handler_priv = (morse_data_handler_priv_data *) rs->morse_data_handler_priv_data; // wait until fifo queue is flushed //HAMLIB_TRACE; hl_usleep(100 * 1000); //HAMLIB_TRACE; while (peek(rs->fifo_morse) >= 0) { HAMLIB_TRACE; rig_debug(RIG_DEBUG_TRACE, "%s: waiting for fifo queue to flush\n", __func__); hl_usleep(100 * 1000); } //HAMLIB_TRACE; hl_usleep(100 * 1000); //HAMLIB_TRACE; if (morse_data_handler_priv != NULL) { if (morse_data_handler_priv->thread_id != 0) { // all cleanup is done in this function so we can kill thread // Windows was taking 30 seconds to stop without this pthread_cancel(morse_data_handler_priv->thread_id); int err = pthread_join(morse_data_handler_priv->thread_id, NULL); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_join error: %s\n", __func__, strerror(errno)); // just ignore the error } morse_data_handler_priv->thread_id = 0; } free(rs->morse_data_handler_priv_data); rs->morse_data_handler_priv_data = NULL; } RETURNFUNC(RIG_OK); } #endif #if defined(HAVE_PTHREAD) void *async_data_handler(void *arg) { struct async_data_handler_args_s *args = (struct async_data_handler_args_s *) arg; RIG *rig = args->rig; unsigned char frame[MAX_FRAME_LENGTH]; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting async data handler thread\n", __func__); // TODO: check how to enable "transceive" on recent Kenwood/Yaesu rigs // TODO: add initial support for async in Kenwood kenwood_transaction (+one) functions -> add transaction_active flag usage // TODO: add initial support for async in Yaesu newcat_get_cmd/set_cmd (+validate) functions -> add transaction_active flag usage while (rs->async_data_handler_thread_run) { int frame_length; int async_frame; int result; result = rig->caps->read_frame_direct(rig, sizeof(frame), frame); if (result < 0) { // Timeouts occur always if there is nothing to receive, so they are not really errors in this case if (result != -RIG_ETIMEOUT) { // TODO: it may be necessary to have mutex locking on transaction_active flag if (rs->transaction_active) { unsigned char data = (unsigned char) result; write_block_sync_error(RIGPORT(rig), &data, 1); } // TODO: error handling -> store errors in rig state -> to be exposed in async snapshot packets rig_debug(RIG_DEBUG_ERR, "%s: read_frame_direct() failed, result=%d\n", __func__, result); hl_usleep(500 * 1000); } hl_usleep(20 * 1000); continue; } frame_length = result; async_frame = rig->caps->is_async_frame(rig, frame_length, frame); rig_debug(RIG_DEBUG_VERBOSE, "%s: received frame: len=%d async=%d\n", __func__, frame_length, async_frame); if (async_frame) { result = rig->caps->process_async_frame(rig, frame_length, frame); if (result < 0) { // TODO: error handling -> store errors in rig state -> to be exposed in async snapshot packets rig_debug(RIG_DEBUG_ERR, "%s: process_async_frame() failed, result=%d\n", __func__, result); continue; } } else { static int busy_retry = 2; again: result = write_block_sync(RIGPORT(rig), frame, frame_length); if (result < 0) { // TODO: error handling? can writing to a pipe really fail in ways we can recover from? rig_debug(RIG_DEBUG_ERR, "%s: write_block_sync() failed, result=%d\n", __func__, result); if (result == EBUSY && --busy_retry > 0) // we can try again { hl_usleep(200 * 1000); goto again; } continue; } } } rig_debug(RIG_DEBUG_VERBOSE, "%s: Stopping async data handler thread\n", __func__); pthread_exit(NULL); return NULL; } #endif #if defined(HAVE_PTHREAD) void *morse_data_handler(void *arg) { struct morse_data_handler_args_s *args = (struct morse_data_handler_args_s *) arg; RIG *rig = args->rig; const struct rig_state *rs = STATE(rig); int result; rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting morse data handler thread\n", __func__); if (STATE(rig)->fifo_morse == NULL) { // Can't use rs-> 'cuz it's const STATE(rig)->fifo_morse = calloc(1, sizeof(FIFO_RIG)); } initFIFO(rs->fifo_morse); char *c; int qsize = rig->caps->morse_qsize; // if backend overrides qsize if (qsize == 0) { qsize = 20; } // shortest length of any rig's CW morse capability c = calloc(1, qsize + 1); while (rs->morse_data_handler_thread_run || (peek(rs->fifo_morse) >= 0)) { int n = 0; memset(c, 0, qsize); for (n = 0; n < qsize; n++) { int d = peek(rs->fifo_morse); if (d < 0) { break; } d = pop(rs->fifo_morse); c[n] = (char) d; } if (n > 0) { #if 0 // this does not work well at all -- rigs do not queue keyspd so any change is immediate // don't know if we can ever implement this char *p; // if we have + or - we will adjust speed and send before/speed/after which hopefully works // I suspect some rigs will change speed immediately and not wait for queued character to flush morse_data_handler_priv_data *morse_data_handler_priv = (morse_data_handler_priv_data *) rs->morse_data_handler_priv_data; value_t keyspd; keyspd.i = morse_data_handler_priv->keyspd; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); if ((p = strchr(c, '+')) || (p = strchr(c, '-'))) { HAMLIB_TRACE; char spdchg = *p; *p = 0; if (strlen(c) > 0) { rig->caps->send_morse(rig, RIG_VFO_CURR, c); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); keyspd.i += spdchg == '+' ? 5 : -5; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); while (p[1] == '+' || p[1] == '-') { HAMLIB_TRACE; keyspd.i += p[1] == '+' ? 5 : -5; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); p++; } p++; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): keyspd=%d\n", __func__, __LINE__, keyspd.i); rig_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_KEYSPD, keyspd); morse_data_handler_priv->keyspd = keyspd.i; memmove(c, p, p - c + 1); } #endif if (strlen(c) > 0) { int nloops = 10; MUTEX_LOCK(morse_mutex); // wait until the write is idle rig_lock(rig, 1); do { result = rig->caps->send_morse(rig, RIG_VFO_CURR, c); if (result != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error: %.23971s\n", __func__, rigerror(result)); if (result == -RIG_EINVAL) { // severe error -- so flush it and stop resetFIFO(rs->fifo_morse); nloops = 0; } hl_usleep(100 * 1000); } //wait_morse_ptt(rig, RIG_VFO_CURR); nloops--; } while (result != RIG_OK && STATE(rig)->fifo_morse->flush == 0 && --nloops > 0); rig_lock(rig,0); MUTEX_UNLOCK(morse_mutex); if (nloops == 0) { rig_debug(RIG_DEBUG_ERR, "%s: send_morse failed\n", __func__); } } } rs->fifo_morse->flush = 0; // reset flush flag hl_usleep(100 * 1000); } free(STATE(rig)->fifo_morse); free(c); STATE(rig)->fifo_morse = NULL; pthread_exit(NULL); return NULL; } #endif HAMLIB_EXPORT(int) rig_password(RIG *rig, const char *key1) { int retval = -RIG_EPROTO; ENTERFUNC; if (rig->caps->password != NULL) { retval = rig->caps->password(rig, key1); //retval = RIG_OK; } RETURNFUNC(retval); } extern int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); // Returns # of bytes read // reply_len should be max bytes expected + 1 // if term is null then will read reply_len bytes exactly and reply will not be null terminated HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, int send_len, unsigned char *reply, int reply_len, unsigned char *term) { int nbytes; int retval; hamlib_port_t *rp = RIGPORT(rig); int simulate = rig->caps->rig_model == RIG_MODEL_DUMMY || rig->caps->rig_model == RIG_MODEL_NONE || rp->rig == RIG_PORT_NONE; ENTERFUNC; ELAPSED1; rig_debug(RIG_DEBUG_VERBOSE, "%s: writing %d bytes\n", __func__, send_len); set_transaction_active(rig); if (simulate) { rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", __func__, rig->caps->model_name); memcpy(reply, send, send_len); retval = send_len; ELAPSED2; RETURNFUNC(retval); } else { retval = write_block(rp, send, send_len); if (retval < 0) { // TODO: error handling? can writing to a pipe really fail in ways we can recover from? rig_debug(RIG_DEBUG_ERR, "%s: write_block_sync() failed, result=%d\n", __func__, retval); } } if (reply) { unsigned char buf[200]; if (simulate) { // Simulate a response by copying the command memcpy(buf, send, send_len); nbytes = send_len + 1; } else { if (term == NULL) { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading binary frame\n", __func__); retval = read_string(rp, buf, reply_len, NULL, 0, 0, 1); } else if (*term == 0xfd) // then we want an Icom frame { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading icom frame\n", __func__); retval = read_icom_frame(rp, buf, sizeof(buf)); } else // we'll assume the provided terminator works { rig_debug(RIG_DEBUG_VERBOSE, "%s: reading frame terminated by 0x%x\n", __func__, *term); retval = read_string(rp, buf, sizeof(buf), (const char *)term, 1, 0, 1); } if (retval < RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: read_string, result=%d\n", __func__, retval); rig_flush_force(rp, 1); set_transaction_inactive(rig); ELAPSED2; RETURNFUNC(retval); } nbytes = retval; if (nbytes >= reply_len) { rig_debug(RIG_DEBUG_ERR, "%s: reply_len(%d) less than reply from rig(%d)\n", __func__, reply_len, nbytes); rig_flush_force(rp, 1); set_transaction_inactive(rig); ELAPSED2; RETURNFUNC(-RIG_EINVAL); } } memcpy(reply, buf, reply_len - 1); } else { rig_flush_force(rp, 1); set_transaction_inactive(rig); ELAPSED2; RETURNFUNC(retval); } rig_flush_force(rp, 1); set_transaction_inactive(rig); ELAPSED2; RETURNFUNC(nbytes >= 0 ? nbytes : -RIG_EPROTO); } HAMLIB_EXPORT(int) rig_set_lock_mode(RIG *rig, int mode) { int retcode; if (rig->caps->set_lock_mode) { retcode = rig->caps->set_lock_mode(rig, mode); } else { STATE(rig)->lock_mode = mode; retcode = RIG_OK; } return (retcode); } HAMLIB_EXPORT(int) rig_get_lock_mode(RIG *rig, int *mode) { int retcode; if (rig->caps->get_lock_mode) { retcode = rig->caps->get_lock_mode(rig, mode); } else { *mode = STATE(rig)->lock_mode; retcode = RIG_OK; } return (retcode); } HAMLIB_EXPORT(int) rig_is_model(RIG *rig, rig_model_t model) { int is_rig; //a bit too verbose so disable this unless needed //rig_debug(RIG_DEBUG_TRACE, "%s(%d):%s called\n", __FILE__, __LINE__, __func__); is_rig = (model == rig->caps->rig_model) ? 1 : 0; return (is_rig); // RETURN is too verbose here } #if defined(HAVE_PTHREAD) int morse_data_handler_set_keyspd(RIG *rig, int keyspd) { struct rig_state *rs = STATE(rig); morse_data_handler_priv_data *morse_data_handler_priv = (morse_data_handler_priv_data *) rs->morse_data_handler_priv_data; morse_data_handler_priv->keyspd = keyspd; rig_debug(RIG_DEBUG_VERBOSE, "%s: keyspd=%d\n", __func__, keyspd); return RIG_OK; } #endif /* * \brief Get the address of a Hamlib data structure * \param rig Pointer to main data anchor * \param idx enum for which pointer requested * * Get the address of a structure without relying on changeable * internal data organization. * * \retval The address of the enumed structure, NULL if error * * Note: This is meant for use by the HAMLIB_???PORT macros mostly. Only * compatibility with them is supported. * * \sa amp_data_pointer, rot_data_pointer */ HAMLIB_EXPORT(void *) rig_data_pointer(RIG *rig, rig_ptrx_t idx) { if (!rig) { rig_debug(RIG_DEBUG_ERR, "%s: missing rig\n", __func__); return NULL; } switch (idx) { case RIG_PTRX_RIGPORT: return RIGPORT(rig); case RIG_PTRX_PTTPORT: return PTTPORT(rig); case RIG_PTRX_DCDPORT: return DCDPORT(rig); case RIG_PTRX_CACHE: return CACHE(rig); case RIG_PTRX_STATE: return STATE(rig); default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid data index=%d\n", __func__, idx); return NULL; } } hamlib-4.6.5/src/network.c0000664000175000017500000015127315056640443011111 /* * Hamlib Interface - network communication low-level support * Copyright (c) 2021-2023 by Mikael Nousiainen * Copyright (c) 2000-2012 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \brief Network port IO * \file network.c */ /* Forcing WINVER in MinGW yanks in getaddrinfo(), but locks out Win95/Win98 */ /* #define WINVER 0x0501 */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #include #include #ifdef HAVE_NETINET_IN_H # include #endif #if HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_SYS_IOCTL_H) # include # include #elif HAVE_WS2TCPIP_H #undef _WIN32_WINNT // We need inet_pton to get defined and 0x0600 does it // Eventually we should be able to get rid of this hack #define _WIN32_WINNT 0x0600 # include #undef _WIN32_WINNT // Then we'll go back to Server 2003 #define _WIN32_WINNT 0x0502 # if defined(HAVE_WSPIAPI_H) # include # endif #endif #include #include "network.h" #include "misc.h" #include "asyncpipe.h" #include "snapshot_data.h" #ifdef HAVE_WINDOWS_H // cppcheck-suppress missingInclude #include "io.h" #endif #ifdef __MINGW32__ #include #include #include static int wsstarted; static int is_networked(char *address, int address_length); #endif //! @cond Doxygen_Suppress #define NET_BUFFER_SIZE 8192 //! @endcond #define MULTICAST_PUBLISHER_DATA_PACKET_TYPE_POLL 0x01 #define MULTICAST_PUBLISHER_DATA_PACKET_TYPE_TRANSCEIVE 0x02 #define MULTICAST_PUBLISHER_DATA_PACKET_TYPE_SPECTRUM 0x03 #pragma pack(push,1) typedef struct multicast_publisher_data_packet_s { uint8_t type; uint8_t padding; uint16_t data_length; } __attribute__((packed)) multicast_publisher_data_packet; #pragma pack(pop) typedef struct multicast_publisher_args_s { RIG *rig; int socket_fd; const char *multicast_addr; int multicast_port; #if defined(WIN32) && defined(HAVE_WINDOWS_H) hamlib_async_pipe_t *data_pipe; #else int data_write_fd; int data_read_fd; #endif #ifdef HAVE_PTHREAD pthread_mutex_t write_lock; #endif } multicast_publisher_args; typedef struct multicast_publisher_priv_data_s { pthread_t thread_id; multicast_publisher_args args; } multicast_publisher_priv_data; typedef struct multicast_receiver_args_s { RIG *rig; int socket_fd; const char *multicast_addr; int multicast_port; } multicast_receiver_args; typedef struct multicast_receiver_priv_data_s { pthread_t thread_id; multicast_receiver_args args; } multicast_receiver_priv_data; static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } #define TRACE rig_debug(RIG_DEBUG_ERR, "TRACE %s(%d)\n", __func__,__LINE__); int network_init() { int retval = -RIG_EINTERNAL; #ifdef __MINGW32__ WSADATA wsadata; if (wsstarted == 0) { retval = WSAStartup(MAKEWORD(1, 1), &wsadata); if (retval == 0) { wsstarted = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: WSAStartup OK\n", __func__); } else { rig_debug(RIG_DEBUG_ERR, "%s: error creating socket, WSAStartup ret=%d\n", __func__, retval); return (-RIG_EIO); } } else // already started { retval = RIG_OK; } #else retval = RIG_OK; #endif return retval; } /** * \brief Open network port using STATE(rig) data * * Open network port using STATE(rig) data. * NB: The signal PIPE will be ignored for the whole application. * * \param rp Port data structure (must spec port id eg hostname:port) * \param default_port Default network socket port * \return RIG_OK or < 0 if error */ int network_open(hamlib_port_t *rp, int default_port) { int fd; /* File descriptor for the port */ int status; struct addrinfo hints, *res, *saved_res; struct in6_addr serveraddr; struct sockaddr_in client; char hoststr[256], portstr[6] = ""; #ifdef __MINGW32__ status = network_init(); if (status != RIG_OK) { return (status); } #endif if (!rp) { return (-RIG_EINVAL); } memset(&hints, 0, sizeof(hints)); hints.ai_flags = NI_NUMERICSERV; hints.ai_family = AF_UNSPEC; if (rp->type.rig == RIG_PORT_UDP_NETWORK) { hints.ai_socktype = SOCK_DGRAM; rig_debug(RIG_DEBUG_VERBOSE, "%s: UDP connect\n", __func__); } else { hints.ai_socktype = SOCK_STREAM; rig_debug(RIG_DEBUG_VERBOSE, "%s: TCP connect\n", __func__); } if (rp->pathname[0] == ':' && rp->pathname[1] != ':') { SNPRINTF(portstr, sizeof(portstr) - 1, "%s", rp->pathname + 1); } else { if (strlen(rp->pathname)) { status = parse_hoststr(rp->pathname, sizeof(rp->pathname), hoststr, portstr); if (status != RIG_OK) { return (status); } rig_debug(RIG_DEBUG_TRACE, "%s: hoststr=%s, portstr=%s\n", __func__, hoststr, portstr); } if (strlen(portstr) == 0) { SNPRINTF(portstr, sizeof(portstr), "%d", default_port); } } status = inet_pton(AF_INET, hoststr, &serveraddr); if (status == 1) /* valid IPv4 address */ { hints.ai_family = AF_INET; hints.ai_flags |= AI_NUMERICHOST; } else { status = inet_pton(AF_INET6, hoststr, &serveraddr); if (status == 1) /* valid IPv6 address */ { hints.ai_family = AF_INET6; hints.ai_flags |= AI_NUMERICHOST; } } status = getaddrinfo(hoststr, portstr, &hints, &res); if (status == 0 && res->ai_family == AF_INET6) { rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV6\n", __func__); //inet_pton(AF_INET6, hoststr, &h_addr.sin6_addr); } if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get host \"%s\": %s\n", __func__, rp->pathname, gai_strerror(status)); return (-RIG_ECONF); } saved_res = res; /* we don't want a signal when connection get broken */ #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif do { char msg[1024]; fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { handle_error(RIG_DEBUG_ERR, "socket"); freeaddrinfo(saved_res); return (-RIG_EIO); } if (connect(fd, res->ai_addr, res->ai_addrlen) == 0) { break; } SNPRINTF(msg, sizeof(msg), "connect to %s failed, (trying next interface)", rp->pathname); handle_error(RIG_DEBUG_WARN, msg); #ifdef __MINGW32__ closesocket(fd); #else close(fd); #endif } while ((res = res->ai_next) != NULL); freeaddrinfo(saved_res); if (NULL == res) { rig_debug(RIG_DEBUG_ERR, "%s: failed to connect to %s\n", __func__, rp->pathname); return (-RIG_EIO); } rp->fd = fd; socklen_t clientLen = sizeof(client); getsockname(rp->fd, (struct sockaddr *)&client, &clientLen); rig_debug(RIG_DEBUG_TRACE, "%s: client port=%d\n", __func__, client.sin_port); rp->client_port = client.sin_port; return (RIG_OK); } // flush and keep what gets flushed based on stopset // Used by SmartSDR backend for example // return # of bytes read int network_flush2(hamlib_port_t *rp, unsigned char *stopset, char *buf, int buf_len) { #ifdef __MINGW32__ ULONG len; #else uint len; #endif #ifdef __MINGW32__ int ret = ioctlsocket(rp->fd, FIONREAD, &len); #else int ret = ioctl(rp->fd, FIONREAD, &len); #endif if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl err '%s'\n", __func__, strerror(errno)); return 0; } if (len > 0) { buf[0] = 0; if (len > buf_len) { len = buf_len - 1; } read_string(rp, (unsigned char *)buf, len + 1, (char *)stopset, 1, 0, 1); } return len; } /** * \brief Clears any data in the read buffer of the socket * * \param rp Port data structure */ void network_flush(hamlib_port_t *rp) { #ifdef __MINGW32__ ULONG len; #else uint len; #endif char buffer[NET_BUFFER_SIZE] = { 0 }; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (;;) { int ret; len = 0; #ifdef __MINGW32__ ret = ioctlsocket(rp->fd, FIONREAD, &len); #else ret = ioctl(rp->fd, FIONREAD, &len); #endif if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl err '%s'\n", __func__, strerror(errno)); break; } if (len > 0) { int len_read = 0; rig_debug(RIG_DEBUG_WARN, "%s: network data clear d: ret=%d, len=%d, '%s'\n", __func__, ret, (int)len, buffer); len_read = recv(rp->fd, buffer, len < NET_BUFFER_SIZE ? len : NET_BUFFER_SIZE, 0); if (len_read < 0) // -1 indicates error occurred { rig_debug(RIG_DEBUG_ERR, "%s: read error '%s'\n", __func__, strerror(errno)); break; } rig_debug(RIG_DEBUG_WARN, "%s: network data cleared: ret=%d, len_read=%d/0x%x\n", __func__, ret, len_read, len_read); dump_hex((unsigned char *)buffer, len_read); } else { break; } } } //! @cond Doxygen_Suppress int network_close(hamlib_port_t *rp) { int ret = 0; if (rp->fd > 0) { #ifdef __MINGW32__ ret = closesocket(rp->fd); #else ret = close(rp->fd); #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: close socket ret=%d\n", __func__, ret); rp->fd = 0; } #ifdef __MINGW32__ if (wsstarted) { ret = WSACleanup(); rig_debug(RIG_DEBUG_VERBOSE, "%s: WSACleanup ret=%d\n", __func__, ret); wsstarted = 0; } #endif return (ret); } //! @endcond extern void sync_callback(int lock); #ifdef HAVE_PTHREAD //! @cond Doxygen_Suppress #define MULTICAST_DATA_PIPE_TIMEOUT_MILLIS 1000 #define MULTICAST_DATA_PIPE_TIMEOUT_USEC 100000 #if defined(WIN32) && defined(HAVE_WINDOWS_H) static int multicast_publisher_create_data_pipe(multicast_publisher_priv_data *mcast_publisher_priv) { int status; status = async_pipe_create(&mcast_publisher_priv->args.data_pipe, PIPE_BUFFER_SIZE_DEFAULT, MULTICAST_DATA_PIPE_TIMEOUT_MILLIS); if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: multicast publisher data pipe creation failed with status=%d, err=%s\n", __func__, status, strerror(errno)); return (-RIG_EINTERNAL); } return (RIG_OK); } static void multicast_publisher_close_data_pipe(multicast_publisher_priv_data *mcast_publisher_priv) { if (mcast_publisher_priv->args.data_pipe != NULL) { async_pipe_close(mcast_publisher_priv->args.data_pipe); mcast_publisher_priv->args.data_pipe = NULL; } } static int multicast_publisher_write_data(multicast_publisher_args *mcast_publisher_args, size_t length, const unsigned char *data) { ssize_t result; result = async_pipe_write(mcast_publisher_args->data_pipe, data, length, MULTICAST_DATA_PIPE_TIMEOUT_MILLIS); if (result < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error writing to multicast publisher data pipe, result=%d\n", __func__, (int)result); return (-RIG_EIO); } if (result != length) { rig_debug(RIG_DEBUG_ERR, "%s: could not write to multicast publisher data pipe, expected %d bytes, wrote %d bytes\n", __func__, (int)length, (int)result); return (-RIG_EIO); } return (RIG_OK); } static int multicast_publisher_read_data(multicast_publisher_args const *mcast_publisher_args, size_t length, unsigned char *data) { ssize_t result; result = async_pipe_wait_for_data(mcast_publisher_args->data_pipe, 100); if (result < 0) { // Timeout is expected when there is no data if (result != -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_ERR, "%s: error waiting for multicast publisher data, result=%ld\n", __func__, (long) result); } return (result); } result = async_pipe_read(mcast_publisher_args->data_pipe, data, length, MULTICAST_DATA_PIPE_TIMEOUT_MILLIS); if (result < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error reading multicast publisher data, result=%ld\n", __func__, (long) result); return (-RIG_EIO); } if (result != length) { rig_debug(RIG_DEBUG_ERR, "%s: could not read from multicast publisher data pipe, expected %ld bytes, read %ld bytes\n", __func__, (long) length, (long) result); return (-RIG_EIO); } return (RIG_OK); } #else static int multicast_publisher_create_data_pipe(multicast_publisher_priv_data *mcast_publisher_priv) { int data_pipe_fds[2]; int status; status = pipe(data_pipe_fds); if (status != 0) { rig_debug(RIG_DEBUG_ERR, "%s: multicast publisher data pipe creation failed with status=%d, err=%s\n", __func__, status, strerror(errno)); return (-RIG_EINTERNAL); } int flags = fcntl(data_pipe_fds[0], F_GETFD); flags |= O_NONBLOCK; if (fcntl(data_pipe_fds[0], F_SETFD, flags)) { rig_debug(RIG_DEBUG_ERR, "%s: error setting O_NONBLOCK on pipe=%s\n", __func__, strerror(errno)); } mcast_publisher_priv->args.data_read_fd = data_pipe_fds[0]; mcast_publisher_priv->args.data_write_fd = data_pipe_fds[1]; return (RIG_OK); } static void multicast_publisher_close_data_pipe(multicast_publisher_priv_data *mcast_publisher_priv) { if (mcast_publisher_priv->args.data_read_fd != -1) { close(mcast_publisher_priv->args.data_read_fd); mcast_publisher_priv->args.data_read_fd = -1; } if (mcast_publisher_priv->args.data_write_fd != -1) { close(mcast_publisher_priv->args.data_write_fd); mcast_publisher_priv->args.data_write_fd = -1; } } static int multicast_publisher_write_data(const multicast_publisher_args *mcast_publisher_args, size_t length, const unsigned char *data) { int fd = mcast_publisher_args->data_write_fd; ssize_t result; result = write(fd, data, length); if (result < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error writing to multicast publisher data pipe, result=%d, err=%s\n", __func__, (int)result, strerror(errno)); return (-RIG_EIO); } if (result != length) { rig_debug(RIG_DEBUG_ERR, "%s: could not write to multicast publisher data pipe, expected %ld bytes, wrote %ld bytes\n", __func__, (long) length, (long) result); return (-RIG_EIO); } return (RIG_OK); } static int multicast_publisher_read_data(const multicast_publisher_args *mcast_publisher_args, size_t length, unsigned char *data) { int fd = mcast_publisher_args->data_read_fd; fd_set rfds, efds; struct timeval timeout; ssize_t result; int retval; int retries = 2; size_t offset = 0; size_t length_left = length; retry: timeout.tv_sec = 0; timeout.tv_usec = MULTICAST_DATA_PIPE_TIMEOUT_USEC; FD_ZERO(&rfds); FD_SET(fd, &rfds); efds = rfds; retval = select(fd + 1, &rfds, NULL, &efds, &timeout); if (retval == 0) { return (-RIG_ETIMEOUT); } if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(): select() failed when reading multicast publisher data: %s\n", __func__, strerror(errno)); return -RIG_EIO; } if (FD_ISSET(fd, &efds)) { rig_debug(RIG_DEBUG_ERR, "%s(): fd error when reading multicast publisher data: %s\n", __func__, strerror(errno)); return -RIG_EIO; } result = read(fd, data + offset, length_left); if (result < 0) { if (errno == EAGAIN) { return (-RIG_ETIMEOUT); } rig_debug(RIG_DEBUG_ERR, "%s: error reading multicast publisher data: %s\n", __func__, strerror(errno)); return (-RIG_EIO); } offset += result; length_left -= result; if (length_left > 0) { if (retries > 0) { // Execution of this routine may time out between writes to pipe, retry to get more data rig_debug(RIG_DEBUG_VERBOSE, "%s: could not read from multicast publisher data pipe, expected %ld bytes, read %ld bytes, retrying...\n", __func__, (long) length, (long) offset); retries--; goto retry; } rig_debug(RIG_DEBUG_ERR, "%s: could not read from multicast publisher data pipe even after retries, expected %ld bytes, read %ld bytes\n", __func__, (long) length, (long) offset); return (-RIG_EIO); } return (RIG_OK); } #endif static void multicast_publisher_write_lock(RIG *rig) { struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *priv_data = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; pthread_mutex_lock(&priv_data->args.write_lock); } static void multicast_publisher_write_unlock(RIG *rig) { struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *priv_data = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; pthread_mutex_unlock(&priv_data->args.write_lock); } static int multicast_publisher_write_packet_header(RIG *rig, multicast_publisher_data_packet *packet) { struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *mcast_publisher_priv; multicast_publisher_args *mcast_publisher_args; ssize_t result; if (rs->multicast_publisher_priv_data == NULL) { // Silently ignore if multicast publisher is not enabled return RIG_OK; } mcast_publisher_priv = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; mcast_publisher_args = &mcast_publisher_priv->args; result = multicast_publisher_write_data( mcast_publisher_args, sizeof(multicast_publisher_data_packet), (unsigned char *) packet); if (result != RIG_OK) { return result; } return RIG_OK; } // cppcheck-suppress unusedFunction int network_publish_rig_poll_data(RIG *rig) { const struct rig_state *rs = STATE(rig); int result; multicast_publisher_data_packet packet = { .type = MULTICAST_PUBLISHER_DATA_PACKET_TYPE_POLL, .padding = 0, .data_length = 0, }; if (rs->multicast_publisher_priv_data == NULL) { // Silently ignore call if multicast publisher is not enabled return RIG_OK; } multicast_publisher_write_lock(rig); result = multicast_publisher_write_packet_header(rig, &packet); multicast_publisher_write_unlock(rig); return result; } // cppcheck-suppress unusedFunction int network_publish_rig_transceive_data(RIG *rig) { const struct rig_state *rs = STATE(rig); int result; multicast_publisher_data_packet packet = { .type = MULTICAST_PUBLISHER_DATA_PACKET_TYPE_TRANSCEIVE, .padding = 0, .data_length = 0, }; if (rs->multicast_publisher_priv_data == NULL) { // Silently ignore call if multicast publisher is not enabled return RIG_OK; } multicast_publisher_write_lock(rig); result = multicast_publisher_write_packet_header(rig, &packet); multicast_publisher_write_unlock(rig); return result; } int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line) { int result; struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *mcast_publisher_priv; multicast_publisher_args *mcast_publisher_args; multicast_publisher_data_packet packet = { .type = MULTICAST_PUBLISHER_DATA_PACKET_TYPE_SPECTRUM, .padding = 0, .data_length = sizeof(struct rig_spectrum_line) + line->spectrum_data_length, }; if (rs->multicast_publisher_priv_data == NULL) { // Silently ignore call if multicast publisher is not enabled return RIG_OK; } // Acquire write lock to write all data in one go to the pipe multicast_publisher_write_lock(rig); result = multicast_publisher_write_packet_header(rig, &packet); if (result != RIG_OK) { multicast_publisher_write_unlock(rig); RETURNFUNC2(result); } mcast_publisher_priv = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; mcast_publisher_args = &mcast_publisher_priv->args; result = multicast_publisher_write_data( mcast_publisher_args, sizeof(struct rig_spectrum_line), (unsigned char *) line); if (result != RIG_OK) { multicast_publisher_write_unlock(rig); RETURNFUNC2(result); } result = multicast_publisher_write_data( mcast_publisher_args, line->spectrum_data_length, line->spectrum_data); multicast_publisher_write_unlock(rig); if (result != RIG_OK) { RETURNFUNC2(result); } RETURNFUNC2(RIG_OK); } static int multicast_publisher_read_packet(multicast_publisher_args const *mcast_publisher_args, uint8_t *type, struct rig_spectrum_line *spectrum_line, unsigned char *spectrum_data) { int result; multicast_publisher_data_packet packet; result = multicast_publisher_read_data(mcast_publisher_args, sizeof(packet), (unsigned char *) &packet); if (result < 0) { return (result); } switch (packet.type) { case MULTICAST_PUBLISHER_DATA_PACKET_TYPE_POLL: case MULTICAST_PUBLISHER_DATA_PACKET_TYPE_TRANSCEIVE: break; case MULTICAST_PUBLISHER_DATA_PACKET_TYPE_SPECTRUM: result = multicast_publisher_read_data( mcast_publisher_args, sizeof(struct rig_spectrum_line), (unsigned char *) spectrum_line); if (result < 0) { return (result); } if (packet.data_length - sizeof(struct rig_spectrum_line) != spectrum_line->spectrum_data_length) { rig_debug(RIG_DEBUG_ERR, "%s: multicast publisher data error, expected %d bytes of spectrum data, got %d bytes\n", __func__, (int)spectrum_line->spectrum_data_length, (int)(packet.data_length - sizeof(struct rig_spectrum_line))); return (-RIG_EPROTO); } spectrum_line->spectrum_data = spectrum_data; result = multicast_publisher_read_data(mcast_publisher_args, spectrum_line->spectrum_data_length, spectrum_data); if (result < 0) { return (result); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected multicast publisher data packet type: %d\n", __func__, packet.type); return (-RIG_EPROTO); } *type = packet.type; return (RIG_OK); } void *multicast_publisher(void *arg) { unsigned char spectrum_data[HAMLIB_MAX_SPECTRUM_DATA]; char snapshot_buffer[HAMLIB_MAX_SNAPSHOT_PACKET_SIZE]; #ifdef __MINGW32__ char ip4[32]; #endif struct multicast_publisher_args_s *args = (struct multicast_publisher_args_s *) arg; RIG *rig = args->rig; struct rig_state *rs = STATE(rig); struct rig_spectrum_line spectrum_line; uint8_t packet_type = MULTICAST_PUBLISHER_DATA_PACKET_TYPE_SPECTRUM; multicast_publisher_priv_data *mcast_publisher_priv = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; struct sockaddr_in dest_addr; int socket_fd = args->socket_fd; ssize_t send_result; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast publisher\n", __FILE__, __LINE__); #ifdef __MINGW32__ if (!is_networked(ip4, sizeof(ip4))) { rig_debug(RIG_DEBUG_WARN, "%s: no IPV4 network detected...multicast disabled\n", __func__); return NULL; } #endif snapshot_init(); memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr); dest_addr.sin_port = htons(args->multicast_port); rs->multicast_publisher_run = 1; while (rs->multicast_publisher_run) { int result; result = multicast_publisher_read_packet(args, &packet_type, &spectrum_line, spectrum_data); if (result != RIG_OK) { if (result == -RIG_ETIMEOUT) { continue; } // TODO: how to detect closing of pipe, indicate with error code // TODO: error handling, flush pipe in case of error? hl_usleep(100 * 1000); continue; } result = snapshot_serialize(sizeof(snapshot_buffer), snapshot_buffer, rig, packet_type == MULTICAST_PUBLISHER_DATA_PACKET_TYPE_SPECTRUM ? &spectrum_line : NULL); if (result != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error serializing rig snapshot data, result=%d\n", __func__, result); continue; } rig_debug(RIG_DEBUG_CACHE, "%s: sending rig snapshot data: %s\n", __func__, snapshot_buffer); send_result = sendto( socket_fd, snapshot_buffer, strlen(snapshot_buffer), 0, (struct sockaddr *) &dest_addr, sizeof(dest_addr) ); if (send_result < 0) { static int flag = 0; if (errno != 0 || flag == 0) { rig_debug(RIG_DEBUG_ERR, "%s: error sending UDP packet: %s, send result=%d\n", __func__, strerror(errno), (int)send_result); flag = 1; } } } rs->multicast_publisher_run = 0; mcast_publisher_priv->thread_id = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopped multicast publisher\n", __FILE__, __LINE__); return NULL; } #ifdef __MINGW32__ static int is_networked(char *address, int address_length) { int count = 0; DWORD dwSize = 0; DWORD dwRetVal = 0; ULONG flags = GAA_FLAG_INCLUDE_PREFIX; PIP_ADAPTER_ADDRESSES pAddresses = NULL; PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; char ipString[INET6_ADDRSTRLEN]; // large enough for both IPv4 and IPv6 address[0] = 0; // First call to determine actual memory size needed GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &dwSize); pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(dwSize); // Second call to get the actual data dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &dwSize); if (dwRetVal == NO_ERROR) { for (pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next) { // if (pCurrAddresses->IfType == IF_TYPE_IEEE80211) // Wireless adapter { char friendlyName[256]; wcstombs(friendlyName, pCurrAddresses->FriendlyName, sizeof(friendlyName)); rig_debug(RIG_DEBUG_VERBOSE, "%s: network IfType = %d, name=%s\n", __func__, (int)pCurrAddresses->IfType, friendlyName); for (pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast != NULL; pUnicast = pUnicast->Next) { void *addr = NULL; if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) // IPv4 address { struct sockaddr_in *sa_in = (struct sockaddr_in *)pUnicast->Address.lpSockaddr; addr = &(sa_in->sin_addr); } #if 0 // going to skip IPV6 for now -- should never need it on a local network else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6) // IPv6 address { struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) pUnicast->Address.lpSockaddr; addr = &(sa_in6->sin6_addr); } #endif // Convert IP address to string and ignore bad ones if (addr) { if (inet_ntop(pUnicast->Address.lpSockaddr->sa_family, addr, ipString, sizeof(ipString)) != NULL) { // Use IP address if not 169.x.x.x if (strncmp(ipString, "169", 3) != 0) { count++; if (count > 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: more than 1 address found...multicast may not work\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s: Address: %s\n", ipString, ipString); strncpy(address, ipString, address_length); } } } } free(pAddresses); return 1; // Wireless and addresses printed } } } if (pAddresses) { free(pAddresses); } return 0; // Not wireless or no addresses found } int is_wireless() { DWORD dwSize = 0; DWORD dwRetVal = 0; ULONG flags = GAA_FLAG_INCLUDE_PREFIX; PIP_ADAPTER_ADDRESSES pAddresses = NULL, pCurrAddresses = NULL; // First call to determine actual memory size needed GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &dwSize); pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(dwSize); // Second call to get the actual data dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &dwSize); if (dwRetVal == NO_ERROR) { for (pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next) { // printf("Adapter name: %s\n", pCurrAddresses->AdapterName); // printf("Adapter description: %ls\n", pCurrAddresses->Description); // printf("Adapter type: "); if (pCurrAddresses->IfType == IF_TYPE_IEEE80211) { // printf("Wireless\n\n"); return 1; } else { // printf("Not Wireless\n\n"); } } } else { //printf("GetAdaptersAddresses failed with error: %lu\n", dwRetVal); } if (pAddresses) { free(pAddresses); } return 0; } #else #include #include #include #include int is_networked(char *ipv4, int ipv4_length) { struct ifaddrs *interfaces, *iface; char addr_str[INET_ADDRSTRLEN]; // Get a list of all network interfaces if (getifaddrs(&interfaces) == -1) { perror("getifaddrs"); exit(EXIT_FAILURE); } // Iterate through the list of interfaces for (iface = interfaces; iface != NULL; iface = iface->ifa_next) { if (iface->ifa_addr && iface->ifa_addr->sa_family == AF_INET) // Check it is IP4 { // Convert the linked list of interfaces to a human readable string struct sockaddr_in *sa = (struct sockaddr_in *) iface->ifa_addr; inet_ntop(AF_INET, &(sa->sin_addr), addr_str, INET_ADDRSTRLEN); if (strncmp(addr_str, "127", 3) == 0 && ipv4[0] == 0) { strncpy(ipv4, addr_str, ipv4_length); rig_debug(RIG_DEBUG_VERBOSE, "%s: Can use %s\n", __func__, ipv4); } else if (strncmp(addr_str, "127", 3) != 0) { strncpy(ipv4, addr_str, ipv4_length); rig_debug(RIG_DEBUG_VERBOSE, "%s: Will use %s\n", __func__, ipv4); } } } freeifaddrs(interfaces); // Free the linked list return strlen(ipv4) > 0 ; } #ifdef __linux__ #include int is_wireless_linux(const char *ifname) { int sock = socket(AF_INET, SOCK_DGRAM, 0); struct iwreq pwrq; memset(&pwrq, 0, sizeof(pwrq)); strncpy(pwrq.ifr_name, ifname, IFNAMSIZ - 1); if (ioctl(sock, SIOCGIWNAME, &pwrq) != -1) { close(sock); return 1; // Wireless } close(sock); return 0; // Not wireless } int is_wireless() { struct ifaddrs *ifaddr, *ifa; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); return 0; } for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) { continue; } int iswireless = is_wireless_linux(ifa->ifa_name); //printf("%s is %s\n", ifa->ifa_name, iswireless ? "wireless" : "not wireless"); if (iswireless) {freeifaddrs(ifaddr); return 1;} } freeifaddrs(ifaddr); return 0; } #endif #endif void *multicast_receiver(void *arg) { char data[4096]; char ip4[INET6_ADDRSTRLEN]; struct multicast_receiver_args_s *args = (struct multicast_receiver_args_s *) arg; RIG *rig = args->rig; struct rig_state *rs = STATE(rig); multicast_receiver_priv_data *mcast_receiver_priv = (multicast_receiver_priv_data *) rs->multicast_receiver_priv_data; struct sockaddr_in dest_addr; int socket_fd = args->socket_fd; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast receiver\n", __FILE__, __LINE__); if (!is_networked(ip4, sizeof(ip4))) { rig_debug(RIG_DEBUG_WARN, "%s: no network detected...disabling multicast receive\n", __func__); return NULL; } int optval = 1; #ifdef __MINGW32__ if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (PCHAR)&optval, sizeof(optval)) < 0) #else if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) #endif { rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP address reuse: %s\n", __func__, strerror(errno)); return NULL; } // Windows does not have SO_REUSEPORT. However, SO_REUSEADDR works in a similar way. #if defined(SO_REUSEPORT) if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP port reuse: %s\n", __func__, strerror(errno)); return NULL; } #endif memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; #ifdef __MINGW32__ // Windows wireless cannot bind to multicast group addresses for some unknown reason // Update: it's not wireless causing the error we see but we'll leave the detection in place if (is_wireless()) { rig_debug(RIG_DEBUG_VERBOSE, "%s: wireless detected\n", __func__); // dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no wireless detected so INADDR_ANY is being used\n", __func__); } #else // dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr); dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr); #endif dest_addr.sin_port = htons(args->multicast_port); if (bind(socket_fd, (struct sockaddr *) &dest_addr, sizeof(dest_addr)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error binding UDP socket to %s:%d: %s\n", __func__, args->multicast_addr, args->multicast_port, strerror(errno)); return NULL; } struct ip_mreq mreq; memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = inet_addr(args->multicast_addr); #ifdef __MINGW32__ // we're not worrying about IPV6 right now as that will likely never occur on home network if (strlen(ip4) > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: multicast binding to %s\n", __func__, ip4); mreq.imr_interface.s_addr = inet_addr(ip4); } else #endif { rig_debug(RIG_DEBUG_VERBOSE, "%s: multicast binding to INADDR_ANY\n", __func__); mreq.imr_interface.s_addr = htonl(INADDR_ANY); } #ifdef __MINGW32__ if (setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (PCHAR)&mreq, sizeof(mreq)) < 0) #else if (setsockopt(socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) #endif { rig_debug(RIG_DEBUG_ERR, "%s: error joining multicast group %s:%d: %s\n", __func__, args->multicast_addr, args->multicast_port, strerror(errno)); if (errno != 0) { return NULL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: errno==0 so trying to continue\n", __func__); } rs->multicast_receiver_run = 1; while (rs->multicast_receiver_run) { struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); fd_set rfds, efds; struct timeval timeout; int select_result; ssize_t result; timeout.tv_sec = 0; timeout.tv_usec = MULTICAST_DATA_PIPE_TIMEOUT_USEC; FD_ZERO(&rfds); FD_SET(socket_fd, &rfds); efds = rfds; select_result = select(socket_fd + 1, &rfds, NULL, &efds, &timeout); if (!rs->multicast_receiver_run) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): pselect signal\n", __func__, __LINE__); break; } if (select_result == 0) { // Select timed out //rig_debug(RIG_DEBUG_ERR, "%s: select timeout\n", __FILE__); continue; } if (select_result <= 0) { rig_debug(RIG_DEBUG_ERR, "%s((%d): select() failed when reading UDP multicast socket data: %s\n", __func__, __LINE__, strerror(errno)); break; } if ((result = FD_ISSET(socket_fd, &efds))) { rig_debug(RIG_DEBUG_ERR, "%s(%d): fd error when reading UDP multicast socket data: (%d)=%s\n", __func__, __LINE__, (int)result, strerror(errno)); break; } result = recvfrom(socket_fd, data, sizeof(data), 0, (struct sockaddr *) &client_addr, &client_len); if (result <= 0) { if (result < 0) { if (errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK) { continue; } rig_debug(RIG_DEBUG_ERR, "%s: error receiving from UDP socket %s:%d: %s\n", __func__, args->multicast_addr, args->multicast_port, strerror(errno)); } break; } // TODO: handle commands from multicast clients rig_debug(RIG_DEBUG_VERBOSE, "%s: received %ld bytes of data: %.*s\n", __func__, (long) result, (int) result, data); // TODO: if a new snapshot needs to be sent, call network_publish_rig_poll_data() and the publisher routine will send out a snapshot // TODO: new logic in publisher needs to be written for other types of responses } rs->multicast_receiver_run = 0; mcast_receiver_priv->thread_id = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopped multicast receiver\n", __FILE__, __LINE__); return NULL; } //! @endcond /** * \brief Start multicast publisher * * Start multicast publisher. * * \param multicast_addr UDP address * \param multicast_port UDP socket port * \return RIG_OK or < 0 if error */ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items) { struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *mcast_publisher_priv; int socket_fd; int status; int mutex_status; #ifdef __MINGW32__ char ip4[32]; #endif ENTERFUNC; if (rs->multicast_publisher_priv_data != NULL) { rig_debug(RIG_DEBUG_WARN, "%s(%d): multicast publisher already running\n", __FILE__, __LINE__); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): multicast publisher address=%s, port=%d\n", __FILE__, __LINE__, multicast_addr, multicast_port); #ifdef __MINGW32__ if (!is_networked(ip4, sizeof(ip4))) { rig_debug(RIG_DEBUG_WARN, "%s: No network found...multicast disabled\n", __func__); RETURNFUNC(RIG_OK); } #endif if (multicast_addr == NULL || strcmp(multicast_addr, "0.0.0.0") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): not starting multicast publisher\n", __FILE__, __LINE__); RETURNFUNC(RIG_OK); } status = network_init(); #ifdef __MINGW32__ // always RIG_OK if not Windows if (status != RIG_OK) { RETURNFUNC(status); } #endif socket_fd = socket(AF_INET, SOCK_DGRAM, 0); if (socket_fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error opening new UDP socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } // Enable non-blocking mode u_long mode = 1; #ifdef __MINGW32__ if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } #else if (ioctl(socket_fd, FIONBIO, &mode) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } #endif if (items & RIG_MULTICAST_TRANSCEIVE) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__, __LINE__); } if (items & RIG_MULTICAST_SPECTRUM) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_SPECTRUM enabled\n", __FILE__, __LINE__); } rs->snapshot_packet_sequence_number = 0; rs->multicast_publisher_run = 0; rs->multicast_publisher_priv_data = calloc(1, sizeof(multicast_publisher_priv_data)); if (rs->multicast_publisher_priv_data == NULL) { close(socket_fd); RETURNFUNC(-RIG_ENOMEM); } mcast_publisher_priv = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; mcast_publisher_priv->args.socket_fd = socket_fd; mcast_publisher_priv->args.multicast_addr = multicast_addr; mcast_publisher_priv->args.multicast_port = multicast_port; mcast_publisher_priv->args.rig = rig; mutex_status = pthread_mutex_init(&mcast_publisher_priv->args.write_lock, NULL); status = multicast_publisher_create_data_pipe(mcast_publisher_priv); if (status < 0 || mutex_status != 0) { free(rs->multicast_publisher_priv_data); rs->multicast_publisher_priv_data = NULL; close(socket_fd); rig_debug(RIG_DEBUG_ERR, "%s: multicast publisher data pipe creation failed, result=%d\n", __func__, status); RETURNFUNC(-RIG_EINTERNAL); } int err = pthread_create(&mcast_publisher_priv->thread_id, NULL, multicast_publisher, &mcast_publisher_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__, strerror(errno)); multicast_publisher_close_data_pipe(mcast_publisher_priv); free(mcast_publisher_priv); rs->multicast_publisher_priv_data = NULL; close(socket_fd); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(RIG_OK); } /** * \brief Stop multicast publisher * * Stop multicast publisher * * \return RIG_OK or < 0 if error */ int network_multicast_publisher_stop(RIG *rig) { struct rig_state *rs = STATE(rig); multicast_publisher_priv_data *mcast_publisher_priv; ENTERFUNC; rs->multicast_publisher_run = 0; mcast_publisher_priv = (multicast_publisher_priv_data *) rs->multicast_publisher_priv_data; if (mcast_publisher_priv == NULL) { RETURNFUNC(RIG_OK); } if (mcast_publisher_priv->thread_id != 0) { int err = pthread_join(mcast_publisher_priv->thread_id, NULL); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d): pthread_join error %s\n", __FILE__, __LINE__, strerror(errno)); // just ignore it } mcast_publisher_priv->thread_id = 0; } multicast_publisher_close_data_pipe(mcast_publisher_priv); if (mcast_publisher_priv->args.socket_fd >= 0) { close(mcast_publisher_priv->args.socket_fd); mcast_publisher_priv->args.socket_fd = -1; } pthread_mutex_destroy(&mcast_publisher_priv->args.write_lock); free(rs->multicast_publisher_priv_data); rs->multicast_publisher_priv_data = NULL; RETURNFUNC(RIG_OK); } /** * \brief Start multicast receiver * * Start multicast receiver. * * \param multicast_addr UDP address * \param multicast_port UDP socket port * \return RIG_OK or < 0 if error */ int network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port) { struct rig_state *rs = STATE(rig); multicast_receiver_priv_data *mcast_receiver_priv; int socket_fd; int status; ENTERFUNC; if (rs->multicast_receiver_priv_data != NULL) { rig_debug(RIG_DEBUG_ERR, "%s(%d): multicast receiver already running\n", __FILE__, __LINE__); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): multicast receiver address=%s, port=%d\n", __FILE__, __LINE__, multicast_addr, multicast_port); if (multicast_addr == NULL || strcmp(multicast_addr, "0.0.0.0") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): not starting multicast receiver\n", __FILE__, __LINE__); RETURNFUNC(RIG_OK); } status = network_init(); if (status != RIG_OK) { RETURNFUNC(status); } socket_fd = socket(AF_INET, SOCK_DGRAM, 0); if (socket_fd < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error opening new UDP socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } // Enable non-blocking mode u_long mode = 1; #ifdef __MINGW32__ if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } #else if (ioctl(socket_fd, FIONBIO, &mode) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__, strerror(errno)); RETURNFUNC(-RIG_EIO); } #endif rs->multicast_receiver_run = 0; rs->multicast_receiver_priv_data = calloc(1, sizeof(multicast_receiver_priv_data)); if (rs->multicast_receiver_priv_data == NULL) { close(socket_fd); RETURNFUNC(-RIG_ENOMEM); } mcast_receiver_priv = (multicast_receiver_priv_data *) rs->multicast_receiver_priv_data; mcast_receiver_priv->args.socket_fd = socket_fd; mcast_receiver_priv->args.multicast_addr = multicast_addr; mcast_receiver_priv->args.multicast_port = multicast_port; mcast_receiver_priv->args.rig = rig; int err = pthread_create(&mcast_receiver_priv->thread_id, NULL, multicast_receiver, &mcast_receiver_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__, strerror(errno)); free(mcast_receiver_priv); rs->multicast_receiver_priv_data = NULL; close(socket_fd); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(RIG_OK); } /** * \brief Stop multicast receiver * * Stop multicast receiver * * \return RIG_OK or < 0 if error */ int network_multicast_receiver_stop(RIG *rig) { struct rig_state *rs = STATE(rig); multicast_receiver_priv_data *mcast_receiver_priv; ENTERFUNC; rs->multicast_receiver_run = 0; mcast_receiver_priv = (multicast_receiver_priv_data *) rs->multicast_receiver_priv_data; if (mcast_receiver_priv == NULL) { RETURNFUNC(RIG_OK); } // Close the socket first to stop the routine if (mcast_receiver_priv->args.socket_fd >= 0) { #ifdef __MINGW32__ shutdown(mcast_receiver_priv->args.socket_fd, SD_BOTH); #else shutdown(mcast_receiver_priv->args.socket_fd, SHUT_RDWR); #endif close(mcast_receiver_priv->args.socket_fd); } if (mcast_receiver_priv->thread_id != 0) { int err = pthread_join(mcast_receiver_priv->thread_id, NULL); if (err) { rig_debug(RIG_DEBUG_ERR, "%s(%d): pthread_join error %s\n", __FILE__, __LINE__, strerror(errno)); // just ignore it } mcast_receiver_priv->thread_id = 0; } if (mcast_receiver_priv->args.socket_fd >= 0) { mcast_receiver_priv->args.socket_fd = -1; } free(rs->multicast_receiver_priv_data); rs->multicast_receiver_priv_data = NULL; RETURNFUNC(RIG_OK); } #endif /** @} */ hamlib-4.6.5/src/rot_reg.c0000664000175000017500000002655615056640443011066 /* * Hamlib Interface - provides registering for dynamically loadable backends. * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \brief Dynamic registration of rotator backends * \file rot_reg.c * * Similar to register.c * doc todo: Let's explain what's going on here! */ #include #include #include #include #include #include #include #include "register.h" //! @cond Doxygen_Suppress #ifndef PATH_MAX # define PATH_MAX 1024 #endif #define ROT_BACKEND_MAX 32 #define DEFINE_INITROT_BACKEND(backend) \ int MAKE_VERSIONED_FN(PREFIX_INITROTS, \ ABI_VERSION, \ backend(void *be_handle)); \ rig_model_t MAKE_VERSIONED_FN(PREFIX_PROBEROTS, \ ABI_VERSION, \ backend(hamlib_port_t *port, \ rig_probe_func_t cfunc, \ rig_ptr_t data)) #define ROT_FUNCNAMA(backend) MAKE_VERSIONED_FN(PREFIX_INITROTS, ABI_VERSION, backend) #define ROT_FUNCNAMB(backend) MAKE_VERSIONED_FN(PREFIX_PROBEROTS, ABI_VERSION, backend) #define ROT_FUNCNAM(backend) ROT_FUNCNAMA(backend),ROT_FUNCNAMB(backend) DEFINE_INITROT_BACKEND(dummy); DEFINE_INITROT_BACKEND(easycomm); DEFINE_INITROT_BACKEND(fodtrack); DEFINE_INITROT_BACKEND(rotorez); DEFINE_INITROT_BACKEND(sartek); DEFINE_INITROT_BACKEND(gs232a); DEFINE_INITROT_BACKEND(kit); DEFINE_INITROT_BACKEND(heathkit); DEFINE_INITROT_BACKEND(spid); DEFINE_INITROT_BACKEND(m2); DEFINE_INITROT_BACKEND(ars); DEFINE_INITROT_BACKEND(amsat); DEFINE_INITROT_BACKEND(ts7400); DEFINE_INITROT_BACKEND(celestron); DEFINE_INITROT_BACKEND(ether6); DEFINE_INITROT_BACKEND(cnctrk); DEFINE_INITROT_BACKEND(prosistel); DEFINE_INITROT_BACKEND(meade); DEFINE_INITROT_BACKEND(ioptron); DEFINE_INITROT_BACKEND(satel); DEFINE_INITROT_BACKEND(radant); #if HAVE_LIBINDI DEFINE_INITROT_BACKEND(indi); #endif #if defined(ANDROID) || defined(__ANDROID__) DEFINE_INITROT_BACKEND(androidsensor); #endif DEFINE_INITROT_BACKEND(grbltrk); DEFINE_INITROT_BACKEND(flir); DEFINE_INITROT_BACKEND(apex); DEFINE_INITROT_BACKEND(saebrtrack); DEFINE_INITROT_BACKEND(skywatcher); //! @endcond /** * \def rot_backend_list * \brief Static list of rotator models. * * This is a NULL terminated list of available rotator backends. Each entry * in the list consists of two fields: The branch number, which is an integer, * and the branch name, which is a character string. * An external library, loaded dynamically, could add its own functions * pointers in this array. */ static struct { int be_num; const char *be_name; int (*be_init)(void *); rot_model_t (*be_probe)(hamlib_port_t *); } rot_backend_list[ROT_BACKEND_MAX] = { { ROT_DUMMY, ROT_BACKEND_DUMMY, ROT_FUNCNAMA(dummy) }, { ROT_EASYCOMM, ROT_BACKEND_EASYCOMM, ROT_FUNCNAMA(easycomm) }, { ROT_FODTRACK, ROT_BACKEND_FODTRACK, ROT_FUNCNAMA(fodtrack) }, { ROT_ROTOREZ, ROT_BACKEND_ROTOREZ, ROT_FUNCNAMA(rotorez) }, { ROT_SARTEK, ROT_BACKEND_SARTEK, ROT_FUNCNAMA(sartek) }, { ROT_GS232A, ROT_BACKEND_GS232A, ROT_FUNCNAMA(gs232a) }, { ROT_KIT, ROT_BACKEND_KIT, ROT_FUNCNAMA(kit) }, { ROT_HEATHKIT, ROT_BACKEND_HEATHKIT, ROT_FUNCNAMA(heathkit) }, { ROT_SPID, ROT_BACKEND_SPID, ROT_FUNCNAMA(spid) }, { ROT_M2, ROT_BACKEND_M2, ROT_FUNCNAMA(m2) }, { ROT_ARS, ROT_BACKEND_ARS, ROT_FUNCNAMA(ars) }, { ROT_AMSAT, ROT_BACKEND_AMSAT, ROT_FUNCNAMA(amsat) }, { ROT_TS7400, ROT_BACKEND_TS7400, ROT_FUNCNAMA(ts7400) }, { ROT_CELESTRON, ROT_BACKEND_CELESTRON, ROT_FUNCNAMA(celestron) }, { ROT_ETHER6, ROT_BACKEND_ETHER6, ROT_FUNCNAMA(ether6) }, { ROT_CNCTRK, ROT_BACKEND_CNCTRK, ROT_FUNCNAMA(cnctrk) }, { ROT_PROSISTEL, ROT_BACKEND_PROSISTEL, ROT_FUNCNAMA(prosistel) }, { ROT_MEADE, ROT_BACKEND_MEADE, ROT_FUNCNAMA(meade) }, { ROT_IOPTRON, ROT_BACKEND_IOPTRON, ROT_FUNCNAMA(ioptron) }, { ROT_SATEL, ROT_BACKEND_SATEL, ROT_FUNCNAMA(satel) }, { ROT_RADANT, ROT_BACKEND_RADANT, ROT_FUNCNAMA(radant)}, #if HAVE_LIBINDI { ROT_INDI, ROT_BACKEND_INDI, ROT_FUNCNAMA(indi) }, #endif #if defined(ANDROID) || defined(__ANDROID__) { ROT_ANDROIDSENSOR, ROT_BACKEND_ANDROIDSENSOR, ROT_FUNCNAMA(androidsensor) }, #endif { ROT_GRBLTRK, ROT_BACKEND_GRBLTRK, ROT_FUNCNAMA(grbltrk) }, { ROT_FLIR, ROT_BACKEND_FLIR, ROT_FUNCNAMA(flir) }, { ROT_APEX, ROT_BACKEND_APEX, ROT_FUNCNAMA(apex) }, { ROT_SAEBRTRACK, ROT_BACKEND_SAEBRTRACK, ROT_FUNCNAMA(saebrtrack)}, { ROT_SKYWATCHER, ROT_BACKEND_SKYWATCHER, ROT_FUNCNAMA(skywatcher)}, { 0, NULL }, /* end */ }; // Apparently, no rotator can be probed. /* * ROT_BACKEND_LIST is here, please keep it up to date, * i.e. each time you implement a new backend. */ /* * This struct to keep track of known rot models. * It is chained, and used in a hash table, see below. */ //! @cond Doxygen_Suppress struct rot_list { const struct rot_caps *caps; struct rot_list *next; }; //! @endcond //! @cond Doxygen_Suppress #define ROTLSTHASHSZ 16 #define HASH_FUNC(a) ((a)%ROTLSTHASHSZ) //! @endcond /* * The rot_hash_table is a hash table pointing to a list of next==NULL * terminated caps. */ static struct rot_list *rot_hash_table[ROTLSTHASHSZ] = { NULL, }; static int rot_lookup_backend(rot_model_t rot_model); /* * Basically, this is a hash insert function that doesn't check for dup! */ //! @cond Doxygen_Suppress int HAMLIB_API rot_register(const struct rot_caps *caps) { int hval; struct rot_list *p; if (!caps) { return -RIG_EINVAL; } rot_debug(RIG_DEBUG_VERBOSE, "rot_register (%d)\n", caps->rot_model); #ifndef DONT_WANT_DUP_CHECK if (rot_get_caps(caps->rot_model) != NULL) { return -RIG_EINVAL; } #endif p = (struct rot_list *)calloc(1, sizeof(struct rot_list)); if (!p) { return -RIG_ENOMEM; } hval = HASH_FUNC(caps->rot_model); p->caps = caps; // p->handle = NULL; p->next = rot_hash_table[hval]; rot_hash_table[hval] = p; return RIG_OK; } //! @endcond /* * Get rot capabilities. * i.e. rot_hash_table lookup */ //! @cond Doxygen_Suppress const struct rot_caps *HAMLIB_API rot_get_caps(rot_model_t rot_model) { struct rot_list *p; for (p = rot_hash_table[HASH_FUNC(rot_model)]; p; p = p->next) { if (p->caps->rot_model == rot_model) { return p->caps; } } return NULL; /* sorry, caps not registered! */ } //! @endcond /* * lookup for backend index in rot_backend_list table, * according to BACKEND_NUM * return -1 if not found. */ static int rot_lookup_backend(rot_model_t rot_model) { int i; for (i = 0; i < ROT_BACKEND_MAX && rot_backend_list[i].be_name; i++) { if (ROT_BACKEND_NUM(rot_model) == rot_backend_list[i].be_num) { return i; } } return -1; } /* * rot_check_backend * check the backend declaring this model has been loaded * and if not loaded already, load it! * This permits seamless operation in rot_init. */ //! @cond Doxygen_Suppress int HAMLIB_API rot_check_backend(rot_model_t rot_model) { const struct rot_caps *caps; int be_idx; int retval; /* already loaded ? */ caps = rot_get_caps(rot_model); if (caps) { return RIG_OK; } be_idx = rot_lookup_backend(rot_model); /* * Never heard about this backend family! */ if (be_idx == -1) { rot_debug(RIG_DEBUG_VERBOSE, "%s: unsupported backend %d for model %d\n", __func__, ROT_BACKEND_NUM(rot_model), rot_model); return -RIG_ENAVAIL; } retval = rot_load_backend(rot_backend_list[be_idx].be_name); return retval; } //! @endcond //! @cond Doxygen_Suppress int HAMLIB_API rot_unregister(rot_model_t rot_model) { int hval; struct rot_list *p, *q; hval = HASH_FUNC(rot_model); q = NULL; for (p = rot_hash_table[hval]; p; p = p->next) { if (p->caps->rot_model == rot_model) { if (q == NULL) { rot_hash_table[hval] = p->next; } else { q->next = p->next; } free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* sorry, caps not registered! */ } //! @endcond /* * rot_list_foreach * executes cfunc on all the elements stored in the rot hash list */ //! @cond Doxygen_Suppress int HAMLIB_API rot_list_foreach(int (*cfunc)(const struct rot_caps *, rig_ptr_t), rig_ptr_t data) { struct rot_list *p; int i; if (!cfunc) { return -RIG_EINVAL; } for (i = 0; i < ROTLSTHASHSZ; i++) { for (p = rot_hash_table[i]; p; p = p->next) if ((*cfunc)(p->caps, data) == 0) { return RIG_OK; } } return RIG_OK; } //! @endcond /* * rot_probe_all * called straight by rot_probe */ //! @cond Doxygen_Suppress rot_model_t HAMLIB_API rot_probe_all(hamlib_port_t *p) { int i; rot_model_t rot_model; for (i = 0; i < ROT_BACKEND_MAX && rot_backend_list[i].be_name; i++) { if (rot_backend_list[i].be_probe) { rot_model = (*rot_backend_list[i].be_probe)(p); if (rot_model != ROT_MODEL_NONE) { return rot_model; } } } return ROT_MODEL_NONE; } //! @endcond //! @cond Doxygen_Suppress int rot_load_all_backends() { int i; for (i = 0; i < ROT_BACKEND_MAX && rot_backend_list[i].be_name; i++) { rot_load_backend(rot_backend_list[i].be_name); } return RIG_OK; } //! @endcond /* * rot_load_backend * Dynamically load a rot backend through dlopen mechanism */ //! @cond Doxygen_Suppress int HAMLIB_API rot_load_backend(const char *be_name) { int status; int (*be_init)(rig_ptr_t); int i; for (i = 0; i < ROT_BACKEND_MAX && rot_backend_list[i].be_name; i++) { if (!strcmp(be_name, rot_backend_list[i].be_name)) { be_init = rot_backend_list[i].be_init; if (be_init == NULL) { printf("Null\n"); return -EINVAL; } status = (*be_init)(NULL); return status; } } return -EINVAL; } //! @endcond hamlib-4.6.5/src/misc.h0000664000175000017500000002135115056640443010351 /* * Hamlib Interface - toolbox header * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _MISC_H #define _MISC_H 1 #include #include /* */ #ifdef HAVE_PTHREAD #include #define set_transaction_active(rig) {pthread_mutex_lock(&STATE(rig)->mutex_set_transaction);STATE(rig)->transaction_active = 1;} #define set_transaction_inactive(rig) {STATE(rig)->transaction_active = 0;pthread_mutex_unlock(&STATE(rig)->mutex_set_transaction);} #else #define set_transaction_active(rig) {STATE(rig)->transaction_active = 1;} #define set_transaction_inactive(rig) {STATE(rig)->transaction_active = 0;} #endif __BEGIN_DECLS // a function to return just a string of spaces for indenting rig debug lines HAMLIB_EXPORT (const char *) spaces(int len); /* * Do a hex dump of the unsigned char array. */ void dump_hex(const unsigned char ptr[], size_t size); /* * BCD conversion routines. * * to_bcd() converts a long long int to a little endian BCD array, * and return a pointer to this array. * * from_bcd() converts a little endian BCD array to long long int * representation, and return it. * * bcd_len is the number of digits in the BCD array. */ extern HAMLIB_EXPORT(unsigned char *) to_bcd(unsigned char bcd_data[], unsigned long long freq, unsigned bcd_len); extern HAMLIB_EXPORT(unsigned long long) from_bcd(const unsigned char bcd_data[], unsigned bcd_len); /* * same as to_bcd() and from_bcd(), but in Big Endian mode */ extern HAMLIB_EXPORT(unsigned char *) to_bcd_be(unsigned char bcd_data[], unsigned long long freq, unsigned bcd_len); extern HAMLIB_EXPORT(unsigned long long) from_bcd_be(const unsigned char bcd_data[], unsigned bcd_len); extern HAMLIB_EXPORT(size_t) to_hex(size_t source_length, const unsigned char *source_data, size_t dest_length, char *dest_data); extern HAMLIB_EXPORT(double) morse_code_dot_to_millis(int wpm); extern HAMLIB_EXPORT(int) dot10ths_to_millis(int dot10ths, int wpm); extern HAMLIB_EXPORT(int) millis_to_dot10ths(int millis, int wpm); extern HAMLIB_EXPORT(int) sprintf_freq(char *str, int str_len, freq_t); /* flag that determines if AI mode should be restored on exit on applicable rigs - See rig_no_restore_ai() */ extern int no_restore_ai; /* check if it's any of CR or LF */ #define isreturn(c) ((c) == 10 || (c) == 13) /* needs config.h included beforehand in .c file */ #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif extern HAMLIB_EXPORT(int) rig_check_cache_timeout(const struct timeval *tv, int timeout); extern HAMLIB_EXPORT(void) rig_force_cache_timeout(struct timeval *tv); extern HAMLIB_EXPORT(setting_t) rig_idx2setting(int i); extern HAMLIB_EXPORT(int) hl_usleep(rig_useconds_t usec); extern HAMLIB_EXPORT(double) elapsed_ms(struct timespec *start, int start_flag); extern HAMLIB_EXPORT(vfo_t) vfo_fixup(RIG *rig, vfo_t vfo, split_t split); extern HAMLIB_EXPORT(vfo_t) vfo_fixup2a(RIG *rig, vfo_t vfo, split_t split, const char *func, const int line); #define vfo_fixup(r,v,s) vfo_fixup2a(r,v,s,__func__,__LINE__) extern HAMLIB_EXPORT(int) parse_hoststr(char *hoststr, int hoststr_len, char host[256], char port[6]); extern HAMLIB_EXPORT(uint32_t) CRC32_function(uint8_t *buf, uint32_t len); extern HAMLIB_EXPORT(char *)date_strget(char *buf, int buflen, int localtime); #ifdef PRId64 /** \brief printf(3) format to be used for long long (64bits) type */ # define PRIll PRId64 # define PRXll PRIx64 #else # ifdef FBSD4 # define PRIll "qd" # define PRXll "qx" # else # define PRIll "lld" # define PRXll "lld" # endif #endif #ifdef SCNd64 /** \brief scanf(3) format to be used for long long (64bits) type */ # define SCNll SCNd64 # define SCNXll SCNx64 #else # ifdef FBSD4 # define SCNll "qd" # define SCNXll "qx" # else # define SCNll "lld" # define SCNXll "llx" # endif #endif #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) void errmsg(int err, char *s, const char *func, const char *file, int line); #define ERRMSG(err, s) errmsg(err, s, __func__, __FILENAME__, __LINE__) #define ENTERFUNC { ++STATE(rig)->depth; \ rig_debug(RIG_DEBUG_VERBOSE, "%s%d:%s(%d):%s entered\n", spaces(STATE(rig)->depth), STATE(rig)->depth, __FILENAME__, __LINE__, __func__); \ } #define ENTERFUNC2 { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):%s entered\n", __FILENAME__, __LINE__, __func__); \ } // we need to refer to rc just once as it // could be a function call #define RETURNFUNC(rc) {do { \ int rctmp = rc; \ rig_debug(RIG_DEBUG_VERBOSE, "%s%d:%s(%d):%s returning(%ld) %s\n", spaces(STATE(rig)->depth), STATE(rig)->depth, __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ --STATE(rig)->depth; \ return (rctmp); \ } while(0);} #define RETURNFUNC2(rc) {do { \ int rctmp = rc; \ rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):%s returning2(%ld) %s\n", __FILENAME__, __LINE__, __func__, (long int) (rctmp), rctmp<0?rigerror2(rctmp):""); \ return (rctmp); \ } while(0);} #define CACHE_RESET {\ elapsed_ms(&CACHE(rig)->time_freqMainA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_freqMainB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_freqSubA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_freqSubB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_vfo, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeMainA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeMainB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeMainC, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeSubA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeSubB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_modeSubC, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthMainA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthMainB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthMainC, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthSubA, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthSubB, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_widthSubC, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_ptt, HAMLIB_ELAPSED_INVALIDATE);\ elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_INVALIDATE);\ } typedef enum settings_value_e { e_CHAR, e_INT, e_LONG, e_FLOAT, e_DOUBLE } settings_value_t; extern HAMLIB_EXPORT(int) rig_settings_save(const char *setting, void *value, settings_value_t valuet); extern HAMLIB_EXPORT(int) rig_settings_load(char *setting, void *value, settings_value_t valuet); extern HAMLIB_EXPORT(int) rig_settings_load_all(char *settings_file); extern int check_level_param(RIG *rig, setting_t level, value_t val, gran_t **gran); extern int queue_deferred_config(deferred_config_header_t *head, hamlib_token_t token, const char *val); // Takes rig-specific band result and maps it the bandlist int the rig's backend extern HAMLIB_EXPORT(hamlib_band_t) rig_get_band(RIG *rig, freq_t freq, int band); extern HAMLIB_EXPORT(const char*) rig_get_band_str(RIG *rig, hamlib_band_t band, int which); extern HAMLIB_EXPORT(int) rig_get_band_rig(RIG *rig, freq_t freq, const char *band); extern HAMLIB_EXPORT(int) rig_test_2038(RIG *rig); __END_DECLS #endif /* _MISC_H */ hamlib-4.6.5/src/microham.h0000664000175000017500000000226715056640443011222 /* * Hamlib Interface - Microham device support for POSIX systems * Copyright (c) 2017 by Christoph van Wüllen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // // declaration of functions implemented in microham.c // // extern int uh_open_radio(int baud, int databits, int stopbits, int rtscts); extern int uh_open_ptt(); extern void uh_close_wkey(); extern void uh_set_ptt(int ptt); extern int uh_get_ptt(); extern void uh_close_radio(); extern void uh_close_ptt(); hamlib-4.6.5/src/cal.h0000664000175000017500000000215615056640443010157 /* * Hamlib Interface - calibration header * Copyright (c) 2000,2001 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _CAL_H #define _CAL_H 1 #include extern HAMLIB_EXPORT(float) rig_raw2val(int rawval, const cal_table_t *cal); extern HAMLIB_EXPORT(float) rig_raw2val_float(int rawval, const cal_table_float_t *cal); #endif /* _CAL_H */ hamlib-4.6.5/src/conf.c0000664000175000017500000012172415056640443010343 /** * \addtogroup rig * @{ */ /** * \file src/conf.c * \brief Rig configuration interface * \author Stephane Fillod * \date 2000-2012 */ /* * Hamlib Interface - configuration interface * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include #include "token.h" /* * Configuration options available in the STATE(rig) struct. */ static const struct confparams frontend_cfg_params[] = { { TOK_PATHNAME, "rig_pathname", "Rig path name", "Path name to the device file of the rig", "/dev/rig", RIG_CONF_STRING, }, { TOK_WRITE_DELAY, "write_delay", "Write delay", "Delay in ms between each byte sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_POST_WRITE_DELAY, "post_write_delay", "Post write delay", "Delay in ms between each command sent out", "0", RIG_CONF_NUMERIC, { .n = { 0, 1000, 1 } } }, { TOK_POST_PTT_DELAY, "post_ptt_delay", "Post ptt delay", "Delay in ms after PTT is asserted", "0", RIG_CONF_NUMERIC, { .n = { 0, 2000, 1 } } // 2000ms should be more than enough }, { TOK_TIMEOUT, "timeout", "Timeout", "Timeout in ms", "0", RIG_CONF_NUMERIC, { .n = { 0, 10000, 1 } } }, { TOK_RETRY, "retry", "Retry", "Max number of retry", "0", RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_TIMEOUT_RETRY, "timeout_retry", "Number of retries for read timeouts", "Set the # of retries for read timeouts that may occur with some serial interfaces", "1", RIG_CONF_NUMERIC, { .n = { 0, 100, 1 } } }, { TOK_RANGE_SELECTED, "Selected range list", "Range list#", "The tx/rx range list in use", "0", RIG_CONF_NUMERIC, { .n = { 1, 5, 1 } } }, { TOK_RANGE_NAME, "Selected range list", "Range list name", "The tx/rx range list name", "Default", RIG_CONF_STRING }, { TOK_DEVICE_ID, "device_id", "Device ID", "User-specified device ID for multicast state data and commands", "", RIG_CONF_STRING, }, { TOK_VFO_COMP, "vfo_comp", "VFO compensation", "VFO compensation in ppm", "0", RIG_CONF_NUMERIC, { .n = { 0.0, 1000.0, .001 } } }, { TOK_POLL_INTERVAL, "poll_interval", "Rig state poll interval in ms", "Polling interval in ms for transceive emulation, defaults to 1000, value of 0 disables polling", "1000", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } } }, { TOK_PTT_TYPE, "ptt_type", "PTT type", "Push-To-Talk interface type override", "RIG", RIG_CONF_COMBO, { .c = {{ "RIG", "RIGMICDATA", "DTR", "RTS", "Parallel", "CM108", "GPIO", "GPION", "None", NULL }} } }, { TOK_PTT_PATHNAME, "ptt_pathname", "PTT path name", "Path to the device of the Push-To-Talk", "/dev/rig", RIG_CONF_STRING, }, { TOK_PTT_BITNUM, "ptt_bitnum", "PTT bit [0-7]", "Push-To-Talk GPIO bit number", "2", RIG_CONF_NUMERIC, { .n = { 0, 7, 1 } } }, { TOK_DCD_TYPE, "dcd_type", "DCD type", "Data Carrier Detect (or squelch) interface type override", "RIG", RIG_CONF_COMBO, { .c = {{ "RIG", "DSR", "CTS", "CD", "Parallel", "CM108", "GPIO", "GPION", "None", NULL }} } }, { TOK_DCD_PATHNAME, "dcd_pathname", "DCD path name", "Path to the device of the Data Carrier Detect (or squelch)", "/dev/rig", RIG_CONF_STRING, }, { TOK_LO_FREQ, "lo_freq", "LO Frequency", "Frequency to add to the VFO frequency for use with a transverter", "0", RIG_CONF_NUMERIC, { .n = {0.0, 1e9, .1}} }, { TOK_CACHE_TIMEOUT, "cache_timeout", "Cache timeout value in ms", "Cache timeout, value of 0 disables caching", "500", RIG_CONF_NUMERIC, { .n = {0, 5000, 1}} }, { TOK_AUTO_POWER_ON, "auto_power_on", "Auto power on", "True enables compatible rigs to be powered up on open", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_AUTO_POWER_OFF, "auto_power_off", "Auto power off", "True enables compatible rigs to be powered down on close", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_AUTO_DISABLE_SCREENSAVER, "auto_disable_screensaver", "Auto disable screen saver", "True enables compatible rigs to have their screen saver disabled on open", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_DISABLE_YAESU_BANDSELECT, "disable_yaesu_bandselect", "Disable Yaesu band select logic", "True disables the automatic band select on band change for Yaesu rigs", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_PTT_SHARE, "ptt_share", "Share ptt port with other apps", "True enables ptt port to be shared with other apps", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_FLUSHX, "flushx", "Flush with read instead of TCFLUSH", "True enables flushing serial port with read instead of TCFLUSH -- MicroHam", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_TWIDDLE_TIMEOUT, "twiddle_timeout", "Timeout(secs) to resume VFO polling when twiddling VFO", "For satellite ops when VFOB is twiddled will pause VFOB commands until timeout", "Unset", RIG_CONF_COMBO, { .c = {{ "Unset", "ON", "OFF", NULL }} } }, { TOK_TWIDDLE_RIT, "twiddle_rit", "RIT twiddle", "Suppress get_freq on VFOB for RIT tuning satellites", "Unset", RIG_CONF_COMBO, { .c = {{ "Unset", "ON", "OFF", NULL }} } }, { TOK_ASYNC, "async", "Asynchronous data transfer support", "True enables async data for rigs that support it to allow use of transceive and spectrum data", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_TUNER_CONTROL_PATHNAME, "tuner_control_pathname", "Tuner script/program path name", "Path to a program to control a tuner with 1 argument of 0/1 for Tuner Off/On", "hamlib_tuner_control", RIG_CONF_STRING, }, { TOK_OFFSET_VFOA, "offset_vfoa", "Offset value in Hz", "Add Hz to VFOA/Main frequency set", "0", RIG_CONF_NUMERIC, { .n = {0, 1e12, 1}} }, { TOK_OFFSET_VFOB, "offset_vfob", "Offset value in Hz", "Add Hz to VFOB/Sub frequency set", "0", RIG_CONF_NUMERIC, { .n = {0, 1e12, 1}} }, { TOK_MULTICAST_DATA_ADDR, "multicast_data_addr", "Multicast data UDP address", "Multicast data UDP address for publishing rig data and state, value of 0.0.0.0 disables multicast data publishing", "0.0.0.0", RIG_CONF_STRING, }, { TOK_MULTICAST_DATA_PORT, "multicast_data_port", "Multicast data UDP port", "Multicast data UDP port for publishing rig data and state", "4532", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } } }, { TOK_MULTICAST_CMD_ADDR, "multicast_cmd_addr", "Multicast command server UDP address", "Multicast command UDP address for sending commands to rig, value of 0.0.0.0 disables multicast command server", "0.0.0.0", RIG_CONF_STRING, }, { TOK_MULTICAST_CMD_PORT, "multicast_cmd_port", "Multicast command server UDP port", "Multicast data UDP port for sending commands to rig", "4532", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } } }, { TOK_FREQ_SKIP, "freq_skip", "Skip setting freq on non-active VFO", "True enables skipping setting the TX_VFO when RX_VFO is receiving and skips RX_VFO when TX_VFO is transmitting", "0", RIG_CONF_CHECKBUTTON, { } }, { TOK_CLIENT, "client", "Set client name for special handling", "Knows about WSJTX and GPREDICT as of 20240702", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; static const struct confparams frontend_serial_cfg_params[] = { #include "serial_cfg_params.h" }; /* * frontend_set_conf * assumes rig!=NULL, val!=NULL */ static int frontend_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct rig_caps *caps; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); hamlib_port_t *pttp = PTTPORT(rig); hamlib_port_t *dcdp = DCDPORT(rig); long val_i; caps = rig->caps; rs = STATE(rig); switch (token) { case TOK_PATHNAME: strncpy(rp->pathname, val, HAMLIB_FILPATHLEN - 1); if (strstr(rig->caps->model_name, "SmartSDR Slice")) { // override any port selection to prevent user errors/questions char *val2 = strdup(val); char *p = strchr(val2, ':'); // port in here? if (p) { *p = 0; // terminate it rig_debug(RIG_DEBUG_WARN, "%s: overriding port and changing to 4992\n", __func__); } sprintf(rs->rigport_deprecated.pathname, "%s:%s", val2, "4992"); strcpy(rp->pathname, rs->rigport_deprecated.pathname); rig_debug(RIG_DEBUG_WARN, "%s: pathname=%s\n", __func__, rp->pathname); free(val2); } else { strncpy(rs->rigport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); } break; case TOK_WRITE_DELAY: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->write_delay = val_i; rs->rigport_deprecated.write_delay = val_i; break; case TOK_POST_WRITE_DELAY: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->post_write_delay = val_i; rs->rigport_deprecated.post_write_delay = val_i; break; case TOK_POST_PTT_DELAY: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rs->post_ptt_delay = val_i; break; case TOK_TIMEOUT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->timeout = val_i; rs->rigport_deprecated.timeout = val_i; break; case TOK_RETRY: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->retry = val_i; rs->rigport_deprecated.retry = val_i; break; case TOK_SERIAL_SPEED: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->parm.serial.rate = val_i; rs->rigport_deprecated.parm.serial.rate = val_i; break; case TOK_DATA_BITS: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->parm.serial.data_bits = val_i; rs->rigport_deprecated.parm.serial.data_bits = val_i; break; case TOK_STOP_BITS: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } rp->parm.serial.stop_bits = val_i; rs->rigport_deprecated.parm.serial.stop_bits = val_i; break; case TOK_PARITY: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "None")) { rp->parm.serial.parity = RIG_PARITY_NONE; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Odd")) { rp->parm.serial.parity = RIG_PARITY_ODD; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Even")) { rp->parm.serial.parity = RIG_PARITY_EVEN; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Mark")) { rp->parm.serial.parity = RIG_PARITY_MARK; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else if (!strcmp(val, "Space")) { rp->parm.serial.parity = RIG_PARITY_SPACE; rs->rigport_deprecated.parm.serial.parity = RIG_PARITY_SPACE; } else { return -RIG_EINVAL; } break; case TOK_HANDSHAKE: if (rp->type.rig != RIG_PORT_SERIAL) { rig_debug(RIG_DEBUG_ERR, "%s: setting handshake is invalid for non-serial port rig type\n", __func__); return -RIG_EINVAL; } if (!strcmp(val, "None")) { rp->parm.serial.handshake = RIG_HANDSHAKE_NONE; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else if (!strcmp(val, "XONXOFF")) { rp->parm.serial.handshake = RIG_HANDSHAKE_XONXOFF; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else if (!strcmp(val, "Hardware")) { rp->parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; rs->rigport_deprecated.parm.serial.handshake = RIG_HANDSHAKE_HARDWARE; } else { return -RIG_EINVAL; } break; case TOK_RTS_STATE: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { rp->parm.serial.rts_state = RIG_SIGNAL_UNSET; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { rp->parm.serial.rts_state = RIG_SIGNAL_ON; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { rp->parm.serial.rts_state = RIG_SIGNAL_OFF; rs->rigport_deprecated.parm.serial.rts_state = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } break; case TOK_DTR_STATE: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } if (!strcmp(val, "Unset")) { rp->parm.serial.dtr_state = RIG_SIGNAL_UNSET; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_UNSET; } else if (!strcmp(val, "ON")) { rp->parm.serial.dtr_state = RIG_SIGNAL_ON; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_ON; } else if (!strcmp(val, "OFF")) { rp->parm.serial.dtr_state = RIG_SIGNAL_OFF; rs->rigport_deprecated.parm.serial.dtr_state = RIG_SIGNAL_OFF; } else { return -RIG_EINVAL; } break; case TOK_RANGE_SELECTED: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } switch (val_i) { case 1: memcpy(rs->tx_range_list, caps->tx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list1, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; case 2: memcpy(rs->tx_range_list, caps->tx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list2, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; case 3: memcpy(rs->tx_range_list, caps->tx_range_list3, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list3, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; case 4: memcpy(rs->tx_range_list, caps->tx_range_list4, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list4, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; case 5: memcpy(rs->tx_range_list, caps->tx_range_list5, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); memcpy(rs->rx_range_list, caps->rx_range_list5, sizeof(struct freq_range_list)*HAMLIB_FRQRANGESIZ); break; default: return -RIG_EINVAL; } break; case TOK_PTT_TYPE: if (!strcmp(val, "RIG")) { pttp->type.ptt = RIG_PTT_RIG; caps->ptt_type = RIG_PTT_RIG; } else if (!strcmp(val, "RIGMICDATA")) { pttp->type.ptt = RIG_PTT_RIG_MICDATA; caps->ptt_type = RIG_PTT_RIG_MICDATA; } else if (!strcmp(val, "DTR")) { pttp->type.ptt = RIG_PTT_SERIAL_DTR; caps->ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(val, "RTS")) { pttp->type.ptt = RIG_PTT_SERIAL_RTS; caps->ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(val, "Parallel")) { pttp->type.ptt = RIG_PTT_PARALLEL; caps->ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(val, "CM108")) { pttp->type.ptt = RIG_PTT_CM108; caps->ptt_type = RIG_PTT_CM108; } else if (!strcmp(val, "GPIO")) { pttp->type.ptt = RIG_PTT_GPIO; } else if (!strcmp(val, "GPION")) { pttp->type.ptt = RIG_PTT_GPION; caps->ptt_type = RIG_PTT_GPION; } else if (!strcmp(val, "None")) { pttp->type.ptt = RIG_PTT_NONE; caps->ptt_type = RIG_PTT_NONE; } else { return -RIG_EINVAL; } // JTDX and WSJTX currently use state.pttport to check for PTT_NONE rs->pttport_deprecated.type.ptt = pttp->type.ptt; break; case TOK_PTT_PATHNAME: strncpy(pttp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->pttport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; case TOK_PTT_BITNUM: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL;//value format error } pttp->parm.cm108.ptt_bitnum = val_i; rp->parm.cm108.ptt_bitnum = val_i; rs->pttport_deprecated.parm.cm108.ptt_bitnum = val_i; break; case TOK_DCD_TYPE: if (!strcmp(val, "RIG")) { dcdp->type.dcd = RIG_DCD_RIG; rs->dcdport_deprecated.type.dcd = RIG_DCD_RIG; } else if (!strcmp(val, "DSR")) { dcdp->type.dcd = RIG_DCD_SERIAL_DSR; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_DSR; } else if (!strcmp(val, "CTS")) { dcdp->type.dcd = RIG_DCD_SERIAL_CTS; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_CTS; } else if (!strcmp(val, "CD")) { dcdp->type.dcd = RIG_DCD_SERIAL_CAR; rs->dcdport_deprecated.type.dcd = RIG_DCD_SERIAL_CAR; } else if (!strcmp(val, "Parallel")) { dcdp->type.dcd = RIG_DCD_PARALLEL; rs->dcdport_deprecated.type.dcd = RIG_DCD_PARALLEL; } else if (!strcmp(val, "CM108")) { dcdp->type.dcd = RIG_DCD_CM108; rs->dcdport_deprecated.type.dcd = RIG_DCD_CM108; } else if (!strcmp(val, "GPIO")) { dcdp->type.dcd = RIG_DCD_GPIO; rs->dcdport_deprecated.type.dcd = RIG_DCD_GPIO; } else if (!strcmp(val, "GPION")) { dcdp->type.dcd = RIG_DCD_GPION; rs->dcdport_deprecated.type.dcd = RIG_DCD_GPION; } else if (!strcmp(val, "None")) { dcdp->type.dcd = RIG_DCD_NONE; rs->dcdport_deprecated.type.dcd = RIG_DCD_NONE; } else { return -RIG_EINVAL; } break; case TOK_DCD_PATHNAME: strncpy(dcdp->pathname, val, HAMLIB_FILPATHLEN - 1); strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1); break; case TOK_DEVICE_ID: strncpy(rs->device_id, val, HAMLIB_RIGNAMSIZ - 1); break; case TOK_VFO_COMP: rs->vfo_comp = atof(val); break; case TOK_POLL_INTERVAL: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rs->poll_interval = val_i; // Make sure cache times out before next poll cycle rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, atol(val)); break; case TOK_LO_FREQ: rs->lo_freq = atof(val); break; case TOK_CACHE_TIMEOUT: rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, atol(val)); break; case TOK_AUTO_POWER_ON: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->auto_power_on = val_i ? 1 : 0; break; case TOK_AUTO_POWER_OFF: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->auto_power_off = val_i ? 1 : 0; break; case TOK_AUTO_DISABLE_SCREENSAVER: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->auto_disable_screensaver = val_i ? 1 : 0; break; case TOK_DISABLE_YAESU_BANDSELECT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->disable_yaesu_bandselect = val_i ? 1 : 0; break; case TOK_PTT_SHARE: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->ptt_share = val_i ? 1 : 0; break; case TOK_FLUSHX: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rp->flushx = val_i ? 1 : 0; break; case TOK_TWIDDLE_TIMEOUT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->twiddle_timeout = val_i; break; case TOK_TWIDDLE_RIT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->twiddle_rit = val_i ? 1 : 0; break; case TOK_ASYNC: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->async_data_enabled = val_i ? 1 : 0; break; case TOK_TUNER_CONTROL_PATHNAME: rs->tuner_control_pathname = strdup(val); // yeah -- need to free it break; case TOK_TIMEOUT_RETRY: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rp->timeout_retry = val_i; break; case TOK_OFFSET_VFOA: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->offset_vfoa = val_i; rig_debug(RIG_DEBUG_VERBOSE, "%s: offset_vfoa=%ld\n", __func__, val_i); break; case TOK_OFFSET_VFOB: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; //value format error } rs->offset_vfob = val_i; rig_debug(RIG_DEBUG_VERBOSE, "%s: offset_vfob=%ld\n", __func__, val_i); break; case TOK_MULTICAST_DATA_ADDR: rs->multicast_data_addr = strdup(val); break; case TOK_MULTICAST_DATA_PORT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rs->multicast_data_port = val_i; break; case TOK_MULTICAST_CMD_ADDR: rs->multicast_cmd_addr = strdup(val); break; case TOK_MULTICAST_CMD_PORT: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rs->multicast_cmd_port = val_i; break; case TOK_FREQ_SKIP: if (1 != sscanf(val, "%ld", &val_i)) { return -RIG_EINVAL; } rs->freq_skip = val_i != 0; break; case TOK_CLIENT: rig_debug(RIG_DEBUG_VERBOSE, "%s: Client claims to be %s\n", __func__, val); if (strcasecmp(val, "WSJTX") == 0) { rs->client = RIG_CLIENT_WSJTX; } else if (strcasecmp(val, "GPREDICT") == 0) { rs->client = RIG_CLIENT_GPREDICT; } else { rs->client = RIG_CLIENT_UNKNOWN; rig_debug(RIG_DEBUG_ERR, "%s: unknown client=%s\n", __func__, val); } break; default: return -RIG_EINVAL; } return RIG_OK; } /* * frontend_get_conf * assumes rig!=NULL, val!=NULL */ static int frontend_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct rig_state *rs; const char *s = ""; hamlib_port_t *rp = RIGPORT(rig); hamlib_port_t *pttp = PTTPORT(rig); hamlib_port_t *dcdp = DCDPORT(rig); rs = STATE(rig); switch (token) { case TOK_PATHNAME: SNPRINTF(val, val_len, "%s", rp->pathname); break; case TOK_WRITE_DELAY: SNPRINTF(val, val_len, "%d", rp->write_delay); break; case TOK_POST_WRITE_DELAY: SNPRINTF(val, val_len, "%d", rp->post_write_delay); break; case TOK_POST_PTT_DELAY: SNPRINTF(val, val_len, "%d", rs->post_ptt_delay); break; case TOK_TIMEOUT: SNPRINTF(val, val_len, "%d", rp->timeout); break; case TOK_RETRY: SNPRINTF(val, val_len, "%d", rp->retry); break; case TOK_CLIENT: { char *client = "UNKNOWN"; switch (rs->client) { case RIG_CLIENT_UNKNOWN: break; case RIG_CLIENT_WSJTX: client = "WSJTX"; break; case RIG_CLIENT_GPREDICT: client = "GPREDICT"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown client=%d\n", __func__, rs->client); rs->client = RIG_CLIENT_UNKNOWN; } SNPRINTF(val, val_len, "%s", client); } break; #if 0 // needs to be replace? case TOK_ITU_REGION: SNPRINTF(val, val_len, "%d", rs->itu_region == 1 ? RIG_ITU_REGION1 : RIG_ITU_REGION2); break; #endif case TOK_SERIAL_SPEED: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rp->parm.serial.rate); break; case TOK_DATA_BITS: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rp->parm.serial.data_bits); break; case TOK_STOP_BITS: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } SNPRINTF(val, val_len, "%d", rp->parm.serial.stop_bits); break; case TOK_PARITY: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (rp->parm.serial.parity) { case RIG_PARITY_NONE: s = "None"; break; case RIG_PARITY_ODD: s = "Odd"; break; case RIG_PARITY_EVEN: s = "Even"; break; case RIG_PARITY_MARK: s = "Mark"; break; case RIG_PARITY_SPACE: s = "Space"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_HANDSHAKE: if (rp->type.rig != RIG_PORT_SERIAL) { rig_debug(RIG_DEBUG_ERR, "%s: getting handshake is invalid for non-serial port rig type\n", __func__); return -RIG_EINVAL; } switch (rp->parm.serial.handshake) { case RIG_HANDSHAKE_NONE: s = "None"; break; case RIG_HANDSHAKE_XONXOFF: s = "XONXOFF"; break; case RIG_HANDSHAKE_HARDWARE: s = "Hardware"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_RTS_STATE: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (rp->parm.serial.rts_state) { case RIG_SIGNAL_UNSET: s = "Unset"; break; case RIG_SIGNAL_ON: s = "ON"; break; case RIG_SIGNAL_OFF: s = "OFF"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_DTR_STATE: if (rp->type.rig != RIG_PORT_SERIAL) { return -RIG_EINVAL; } switch (rp->parm.serial.dtr_state) { case RIG_SIGNAL_UNSET: s = "Unset"; break; case RIG_SIGNAL_ON: s = "ON"; break; case RIG_SIGNAL_OFF: s = "OFF"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_DEVICE_ID: SNPRINTF(val, val_len, "%s", rs->device_id); break; case TOK_VFO_COMP: SNPRINTF(val, val_len, "%f", rs->vfo_comp); break; case TOK_POLL_INTERVAL: SNPRINTF(val, val_len, "%d", rs->poll_interval); break; case TOK_PTT_TYPE: switch (pttp->type.ptt) { case RIG_PTT_RIG: s = "RIG"; break; case RIG_PTT_RIG_MICDATA: s = "RIGMICDATA"; break; case RIG_PTT_SERIAL_DTR: s = "DTR"; break; case RIG_PTT_SERIAL_RTS: s = "RTS"; break; case RIG_PTT_PARALLEL: s = "Parallel"; break; case RIG_PTT_CM108: s = "CM108"; break; case RIG_PTT_GPIO: s = "GPIO"; break; case RIG_PTT_GPION: s = "GPION"; break; case RIG_PTT_NONE: s = "None"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_PTT_PATHNAME: strcpy(val, pttp->pathname); break; case TOK_PTT_BITNUM: SNPRINTF(val, val_len, "%d", pttp->parm.cm108.ptt_bitnum); break; case TOK_DCD_TYPE: switch (dcdp->type.dcd) { case RIG_DCD_RIG: s = "RIG"; break; case RIG_DCD_SERIAL_DSR: s = "DSR"; break; case RIG_DCD_SERIAL_CTS: s = "CTS"; break; case RIG_DCD_SERIAL_CAR: s = "CD"; break; case RIG_DCD_PARALLEL: s = "Parallel"; break; case RIG_DCD_CM108: s = "CM108"; break; case RIG_DCD_GPIO: s = "GPIO"; break; case RIG_DCD_GPION: s = "GPION"; break; case RIG_DCD_NONE: s = "None"; break; default: return -RIG_EINVAL; } strcpy(val, s); break; case TOK_DCD_PATHNAME: strcpy(val, dcdp->pathname); break; case TOK_LO_FREQ: SNPRINTF(val, val_len, "%g", rs->lo_freq); break; case TOK_CACHE_TIMEOUT: SNPRINTF(val, val_len, "%d", rig_get_cache_timeout_ms(rig, HAMLIB_CACHE_ALL)); break; case TOK_AUTO_POWER_ON: SNPRINTF(val, val_len, "%d", rs->auto_power_on); break; case TOK_AUTO_POWER_OFF: SNPRINTF(val, val_len, "%d", rs->auto_power_off); break; case TOK_AUTO_DISABLE_SCREENSAVER: SNPRINTF(val, val_len, "%d", rs->auto_disable_screensaver); break; case TOK_PTT_SHARE: SNPRINTF(val, val_len, "%d", rs->ptt_share); break; case TOK_FLUSHX: SNPRINTF(val, val_len, "%d", rp->flushx); break; case TOK_DISABLE_YAESU_BANDSELECT: SNPRINTF(val, val_len, "%d", rs->disable_yaesu_bandselect); break; case TOK_TWIDDLE_TIMEOUT: SNPRINTF(val, val_len, "%d", rs->twiddle_timeout); break; case TOK_TWIDDLE_RIT: SNPRINTF(val, val_len, "%d", rs->twiddle_rit); break; case TOK_ASYNC: SNPRINTF(val, val_len, "%d", rs->async_data_enabled); break; case TOK_TIMEOUT_RETRY: SNPRINTF(val, val_len, "%d", rp->timeout_retry); break; case TOK_MULTICAST_DATA_ADDR: SNPRINTF(val, val_len, "%s", rs->multicast_data_addr); break; case TOK_MULTICAST_DATA_PORT: SNPRINTF(val, val_len, "%d", rs->multicast_data_port); break; case TOK_MULTICAST_CMD_ADDR: SNPRINTF(val, val_len, "%s", rs->multicast_cmd_addr); break; case TOK_MULTICAST_CMD_PORT: SNPRINTF(val, val_len, "%d", rs->multicast_cmd_port); break; default: return -RIG_EINVAL; } memcpy(&rs->rigport_deprecated, rp, sizeof(hamlib_port_t_deprecated)); return RIG_OK; } /** * \brief call a function against each configuration token of a rig * \param rig The rig handle * \param cfunc The function to perform on each token * \param data Any data to be passed to cfunc() * * Executes \a cfunc() on all the elements stored in the conf table. * rig_token_foreach starts first with backend conf table, then finish * with frontend table. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). */ int HAMLIB_API rig_token_foreach(RIG *rig, int (*cfunc)(const struct confparams *, rig_ptr_t), rig_ptr_t data) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps || !cfunc) { return -RIG_EINVAL; } for (cfp = frontend_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } if (rig->caps->port_type == RIG_PORT_SERIAL) { for (cfp = frontend_serial_cfg_params; cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } } for (cfp = rig->caps->cfgparams; cfp && cfp->name; cfp++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } for (cfp = rig->caps->extlevels; cfp && cfp->name; cfp ++) { if ((*cfunc)(cfp, data) == 0) { return RIG_OK; } } return RIG_OK; } /** * \brief lookup a confparam struct * \param rig The rig handle * \param name The name of the configuration parameter * * Lookup conf token by its name. * * \return a pointer to the confparams struct if found, otherwise NULL. */ const struct confparams *HAMLIB_API rig_confparam_lookup(RIG *rig, const char *name) { const struct confparams *cfp; hamlib_token_t token; if (!rig || !rig->caps) { if (rig) { rig_debug(RIG_DEBUG_ERR, "%s: rig->caps is NULL\n", __func__); } else { rig_debug(RIG_DEBUG_ERR, "%s: rig is NULL\n", __func__); } return NULL; } if (!name) { rig_debug(RIG_DEBUG_ERR, "%s: name is NULL\n", __func__); return NULL; } /* 0 returned for invalid format */ token = strtol(name, NULL, 0); for (cfp = rig->caps->cfgparams; cfp && cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, cfp->name); return cfp; } } for (cfp = frontend_cfg_params; cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, cfp->name); return cfp; } } if (rig->caps->port_type == RIG_PORT_SERIAL) { for (cfp = frontend_serial_cfg_params; cfp->name; cfp++) { if (!strcmp(cfp->name, name) || token == cfp->token) { rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, cfp->name); return cfp; } } } rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s and not found\n", __func__, name); return NULL; } /** * \brief lookup a token id * \param rig The rig handle * \param name The name of the configuration parameter * * Simple lookup returning token id associated with name. * * \return the token id if found, otherwise RIG_CONF_END */ hamlib_token_t HAMLIB_API rig_token_lookup(RIG *rig, const char *name) { const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, name); cfp = rig_confparam_lookup(rig, name); if (!cfp) { return RIG_CONF_END; } return cfp->token; } /** * \brief set a radio configuration parameter * \param rig The rig handle * \param token The parameter * \param val The value to set the parameter to * * Sets a configuration parameter. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_get_conf() */ int HAMLIB_API rig_set_conf(RIG *rig, hamlib_token_t token, const char *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps) { return -RIG_EINVAL; } // Some parameters can be ignored if (token == TOK_HANDSHAKE && (RIGPORT(rig)->type.rig != RIG_PORT_SERIAL)) { rig_debug(RIG_DEBUG_WARN, "%s: handshake is not valid for non-serial port rig\n", __func__); return RIG_OK; // this allows rigctld to continue and just print a warning instead of error } if (rig_need_debug(RIG_DEBUG_VERBOSE)) { const struct confparams *cfp; char tokenstr[12]; SNPRINTF(tokenstr, sizeof(tokenstr), "%ld", token); cfp = rig_confparam_lookup(rig, tokenstr); if (!cfp) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: %s='%s'\n", __func__, cfp->name, val); } if (IS_TOKEN_FRONTEND(token)) { return frontend_set_conf(rig, token, val); } if (rig->caps->set_conf == NULL) { return -RIG_ENAVAIL; } return rig->caps->set_conf(rig, token, val); } /** * \brief get the value of a configuration parameter * \param rig The rig handle * \param token The parameter * \param val The location where to store the value of config \a token * * Retrieves the value of a configuration parameter associated with \a token. * The location pointed to by val must be large enough to hold the value of the config. * * \return RIG_OK if the operation has been successful, otherwise * a negative value if an error occurred (in which case, cause is * set appropriately). * * \sa rig_set_conf() */ int HAMLIB_API rig_get_conf(RIG *rig, hamlib_token_t token, char *val) { return rig_get_conf2(rig, token, val, 128); } int HAMLIB_API rig_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !rig->caps || !val) { return -RIG_EINVAL; } if (IS_TOKEN_FRONTEND(token)) { return frontend_get_conf2(rig, token, val, val_len); } if (rig->caps->get_conf2) { return rig->caps->get_conf2(rig, token, val, val_len); } if (rig->caps->get_conf == NULL) { return -RIG_ENAVAIL; } return rig->caps->get_conf(rig, token, val); } /*! @} */ hamlib-4.6.5/src/hamlibdatetime.h0000664000175000017500000000017315056640474012372 /* This date time is from the last non-merge commit to Hamlib. */ #define HAMLIBDATETIME "2025-09-05T19:49:48Z SHA=8a6bd5" hamlib-4.6.5/src/cal.c0000664000175000017500000001144515056640443010153 /* * Hamlib Interface - calibration routines * Copyright (c) 2000-2009 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \file cal.c * \brief Calibration routines. */ #include #include #include "cal.h" /* add rig_set_cal(cal_table), rig_get_calstat(rawmin,rawmax,cal_table), */ /** * \brief Convert raw data to a calibrated integer value, according to a * calibration table. * * \param rawval Input value. * \param cal Calibration table, * * cal_table_t is a data type suited to hold linear calibration. * * cal_table_t.size is the number of plots cal_table_t.table contains. * * If a value is below or equal to cal_table_t.table[0].raw, * rig_raw2val() will return cal_table_t.table[0].val. * * If a value is greater or equal to * cal_table_t.table[cal_table_t.size-1].raw, rig_raw2val() will return * cal_table_t.table[cal_table_t.size-1].val. * * \return Calibrated integer value. */ float HAMLIB_API rig_raw2val(int rawval, const cal_table_t *cal) { #ifdef WANT_CHEAP_WNO_FP int interpolation; #else float interpolation; #endif int i; /* ASSERT(cal != NULL) */ /* ASSERT(cal->size <= HAMLIB_MAX_CAL_LENGTH) */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (cal->size == 0) { return rawval; } for (i = 0; i < cal->size; i++) { if (rawval < cal->table[i].raw) { break; } } if (rawval == cal->table[i - 1].raw) { return cal->table[i - 1].val; } if (i == 0) { return cal->table[0].val; } if (i >= cal->size) { return cal->table[i - 1].val; } /* catch divide by 0 error */ if (cal->table[i].raw == cal->table[i - 1].raw) { return cal->table[i].val; } #ifdef WANT_CHEAP_WNO_FP /* cheap, less accurate, but no fp needed */ interpolation = ((cal->table[i].raw - rawval) * (cal->table[i].val - cal->table[i - 1].val)) / (cal->table[i].raw - cal->table[i - 1].raw); return cal->table[i].val - interpolation; #else interpolation = ((cal->table[i].raw - rawval) * (float)(cal->table[i].val - cal->table[i - 1].val)) / (float)(cal->table[i].raw - cal->table[i - 1].raw); #endif return cal->table[i].val - interpolation; } /** * \brief Convert raw data to a calibrated floating-point value, according to * a calibration table. * * \param rawval Input value. * \param cal Calibration table. * * cal_table_float_t is a data type suited to hold linear calibration. * * cal_table_float_t.size tell the number of plot cal_table_t.table contains. * * If a value is below or equal to cal_table_float_t.table[0].raw, * rig_raw2val_float() will return cal_table_float_t.table[0].val. * * If a value is greater or equal to * cal_table_float_t.table[cal_table_float_t.size-1].raw, rig_raw2val_float() * will return cal_table_float_t.table[cal_table_float_t.size-1].val. * * \return calibrated floating-point value */ float HAMLIB_API rig_raw2val_float(int rawval, const cal_table_float_t *cal) { float interpolation; int i; /* ASSERT(cal != NULL) */ /* ASSERT(cal->size <= HAMLIB_MAX_CAL_LENGTH) */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (cal->size == 0) { return rawval; } for (i = 0; i < cal->size; i++) { if (rawval < cal->table[i].raw) { break; } } if (i == 0) { return cal->table[0].val; } if (i >= cal->size) { return cal->table[i - 1].val; } /* catch divide by 0 error */ if (cal->table[i].raw == cal->table[i - 1].raw) { return cal->table[i].val; } interpolation = ((cal->table[i].raw - rawval) * (float)(cal->table[i].val - cal->table[i - 1].val)) / (float)(cal->table[i].raw - cal->table[i - 1].raw); return cal->table[i].val - interpolation; } /** @} */ hamlib-4.6.5/src/band_changed.c0000664000175000017500000000340415056640443011765 // This is currently included in rig.c // Can customize during build // Eventually should improved this for external actions when // rigctld gets integrated as a service within Hamlib int HAMLIB_API rig_band_changed(RIG *rig, hamlib_bandselect_t band) { // See band_changed.c // Examples: // rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TUNER, 1); // rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TUNER, 0); // value_t v; // rig_set_ant(rig, RIG_VFO_CURR, 1, v); switch (band) { case RIG_BANDSELECT_2200M: break; case RIG_BANDSELECT_600M: break; case RIG_BANDSELECT_160M: break; case RIG_BANDSELECT_80M: break; case RIG_BANDSELECT_60M: break; case RIG_BANDSELECT_40M: break; case RIG_BANDSELECT_30M: break; case RIG_BANDSELECT_20M: break; case RIG_BANDSELECT_17M: break; case RIG_BANDSELECT_15M: break; case RIG_BANDSELECT_12M: break; case RIG_BANDSELECT_10M: break; case RIG_BANDSELECT_6M: break; case RIG_BANDSELECT_WFM: break; case RIG_BANDSELECT_MW: break; case RIG_BANDSELECT_AIR: break; case RIG_BANDSELECT_2M: break; case RIG_BANDSELECT_1_25M: break; case RIG_BANDSELECT_70CM: break; case RIG_BANDSELECT_33CM: break; case RIG_BANDSELECT_23CM: break; case RIG_BANDSELECT_13CM: break; case RIG_BANDSELECT_9CM: break; case RIG_BANDSELECT_5CM: break; case RIG_BANDSELECT_3CM: break; case RIG_BANDSELECT_GEN: break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown band=%d\n", __func__, band); } return RIG_OK; } hamlib-4.6.5/src/Makefile.am0000775000175000017500000000640715056640443011311 BUILT_SOURCES = $(builddir)/hamlibdatetime.h DISTCLEANFILES = hamlibdatetime.h RIGSRC = hamlibdatetime.h rig.c serial.c serial.h misc.c misc.h register.c register.h event.c \ event.h cal.c cal.h conf.c tones.c tones.h rotator.c locator.c rot_reg.c \ rot_conf.c rot_conf.h rot_settings.c rot_ext.c iofunc.c iofunc.h ext.c \ mem.c settings.c parallel.c parallel.h usb_port.c usb_port.h debug.c \ network.c network.h cm108.c cm108.h gpio.c gpio.h idx_builtin.h token.h \ par_nt.h microham.c microham.h amplifier.c amp_reg.c amp_conf.c \ amp_conf.h amp_settings.c extamp.c sleep.c sleep.h sprintflst.c \ sprintflst.h cache.c cache.h snapshot_data.c snapshot_data.h fifo.c fifo.h \ serial_cfg_params.h mutex.h if VERSIONDLL RIGSRC += \ version_dll.rc endif lib_LTLIBRARIES = libhamlib.la libhamlib_la_SOURCES = $(RIGSRC) $(VERSIONDLL) libhamlib_la_LDFLAGS = $(WINLDFLAGS) $(OSXLDFLAGS) -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) libhamlib_la_LIBADD = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/libsecurity.la \ $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS) $(INDI_LIBS) libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(top_builddir)/security/libsecurity.la $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) EXTRA_DIST = Android.mk hamlibdatetime.h.in band_changed.c # Rule to build the dependencies of libhamlib.la that are in other directories $(libhamlib_la_DEPENDENCIES): $(MAKE) -C $(@D) $(@F) # If we have a .git directory then we will generate the hamlibdate.h # file and replace it if it is different. Fall back to a copy of a # generic hamlibdatetime.h.in in the source tree. Build looks in build # directory before the source directory for the hamlibdatetime.h # header. hamlibdatetime.h: FORCE @if test -x $(top_srcdir)/.git ; then \ echo "/* This date time is from the last non-merge commit to Hamlib. */" > $(builddir)/$(@F).tmp ;\ echo "#define HAMLIBDATETIME "\"$$(TZ=UTC git --git-dir=$(top_srcdir)/.git log --no-merges --date='format-local:%Y-%m-%dT%H:%M:%SZ SHA=' --format='%cd' -n 1)$$(git --git-dir=$(top_srcdir)/.git log --no-merges -n 1 | head -n 1 | cut -c8-13)\" >> $(builddir)/$(@F).tmp ;\ diff -qN $(builddir)/$(@F).tmp $(builddir)/$(@F) ; test $$? -eq 0 || { echo "Generating SCS header \"$(builddir)/$(@F)\"" ; mv -f $(builddir)/$(@F).tmp $(builddir)/$(@F) ; } ;\ rm -f $(builddir)/$(@F).tmp ;\ touch -c $(top_srcdir)/src/version_dll.rc ;\ else \ test -f $(srcdir)/$(@F) || cp $(srcdir)/$(@F).in $(srcdir)/$(@F) ;\ fi RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" .rc.o: $(RCCOMPILE) -O coff -i "$<" -o "$@" .mc.rc: $(WINDMC) "$<" #version.la: version.rc # windres $(srcdir)/version.rc -o $(builddir)/version.o FORCE: # If we are making a distribution out-of-source and we have generated # a hamlibdatetime.h; then copy it to the tests directory of the # source tarball so that downstream builds pick up the version # information we know about. dist-hook: test ./ -ef $(srcdir)/ || test ! -f hamlibdatetime.h || cp -f hamlibdatetime.h $(srcdir)/ hamlib-4.6.5/src/rot_conf.h0000664000175000017500000000217215056640443011227 /* * Hamlib Interface - configuration header * Copyright (c) 2000,2001,2002 by Stephane Fillod and Frank Singleton * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_CONF_H #define _ROT_CONF_H 1 #include int frontrot_set_conf(ROT *rot, hamlib_token_t token, const char *val); int frontrot_get_conf(ROT *rot, hamlib_token_t token, char *val, int val_len); #endif /* _ROT_CONF_H */ hamlib-4.6.5/src/sleep.h0000664000175000017500000000206515056640443010527 /* * Hamlib Interface - sleep header * Copyright (c) 2020 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _HL_SLEEP_H #define _HL_SLEEP_H 1 #include #include "iofunc.h" __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int hl_usleep(rig_useconds_t usec); __END_DECLS #endif /* _HL_SLEEP_H */ hamlib-4.6.5/src/network.h0000664000175000017500000000354415056640443011113 /* * Hamlib Interface - network communication header * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _NETWORK_H #define _NETWORK_H 1 #include #include "iofunc.h" __BEGIN_DECLS /* Hamlib internal use, see rig.c */ int network_open(hamlib_port_t *p, int default_port); int network_close(hamlib_port_t *rp); void network_flush(hamlib_port_t *rp); int network_flush2(hamlib_port_t *rp, unsigned char *stopset, char *buf, int buf_len); int network_publish_rig_poll_data(RIG *rig); int network_publish_rig_transceive_data(RIG *rig); int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line); int network_publish_rig_status_change(RIG *rig, int32_t status); HAMLIB_EXPORT(int) network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items); HAMLIB_EXPORT(int) network_multicast_publisher_stop(RIG *rig); HAMLIB_EXPORT(int) network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port); HAMLIB_EXPORT(int) network_multicast_receiver_stop(RIG *rig); __END_DECLS #endif /* _NETWORK_H */ hamlib-4.6.5/src/snapshot_data.h0000664000175000017500000000030015056640443012235 #ifndef _SNAPSHOT_DATA_H #define _SNAPSHOT_DATA_H void snapshot_init(); int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line); #endif hamlib-4.6.5/src/serial.c0000664000175000017500000010007115056640443010665 /* * Hamlib Interface - serial communication low-level support * Copyright (c) 2000-2013 by Stephane Fillod * Copyright (c) 2000-2003 by Frank Singleton * Parts of the PTT handling are derived from soundmodem, an excellent * ham packet softmodem written by Thomas Sailer, HB9JNX. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup rig_internal * @{ */ /** * \brief Serial port IO * \file serial.c */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #include #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_TERMIOS_H # include /* POSIX terminal control definitions */ #else # ifdef HAVE_TERMIO_H # include # else /* sgtty */ # ifdef HAVE_SGTTY_H # include # endif # endif #endif #include //! @cond Doxygen_Suppress #if defined(WIN32) && !defined(HAVE_TERMIOS_H) # include "win32termios.h" # define HAVE_TERMIOS_H 1 /* we have replacement */ #else # define OPEN open # define CLOSE close # define IOCTL ioctl #endif //! @endcond #include "serial.h" #include "misc.h" #ifdef HAVE_SYS_IOCCOM_H # include #endif #include "microham.h" static int uh_ptt_fd = -1; static int uh_radio_fd = -1; //! @cond Doxygen_Suppress typedef struct term_options_backup { int fd; #if defined(HAVE_TERMIOS_H) struct termios options; #elif defined(HAVE_TERMIO_H) struct termio options; #elif defined(HAVE_SGTTY_H) struct sgttyb sg; #endif struct term_options_backup *next; } term_options_backup_t; //! @endcond static term_options_backup_t *term_options_backup_head = NULL; /* * This function simply returns TRUE if the argument matches uh_radio_fd and * is >= 0 * * This function is only used in the WIN32 case and implements access "from * outside" to uh_radio_fd. */ //! @cond Doxygen_Suppress int is_uh_radio_fd(int fd) { if (uh_radio_fd >= 0 && uh_radio_fd == fd) { return 1; } else { return 0; } } //! @endcond #if defined(WIN32) #include #include void WinErrorShow(LPCTSTR lpszFunction, DWORD dw) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; // DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof( TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); //MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); rig_debug(RIG_DEBUG_ERR, "%s: %s", __func__, (char *)lpDisplayBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } enum serial_status { SER_NO_EXIST, SER_IN_USE, SER_UNKNOWN_ERR, SER_AVAILABLE }; int check_com_port_in_use(const char *port) { char device[1024]; snprintf(device, sizeof(device), "\\\\.\\%s", port); HANDLE hCom = CreateFileA( device, GENERIC_READ | GENERIC_WRITE, 0, // No sharing NULL, // Default security OPEN_EXISTING, 0, // Non-overlapped mode NULL // No template file ); if (hCom == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); if (error == ERROR_FILE_NOT_FOUND) { return SER_NO_EXIST; } else if (error == ERROR_ACCESS_DENIED) { return SER_IN_USE; } else { WinErrorShow("serial error on CreateFileA: ", error); return SER_IN_USE; } } CloseHandle(hCom); return SER_AVAILABLE; } #endif /** * \brief Open serial port using STATE(rig) data * \param rp port data structure (must spec port id eg /dev/ttyS1) * \return RIG_OK or < 0 if error */ int HAMLIB_API serial_open(hamlib_port_t *rp) { int fd; /* File descriptor for the port */ int err; if (!rp) { return (-RIG_EINVAL); } #if defined(WIN32) int retcode = check_com_port_in_use(rp->pathname); switch (retcode) { case SER_IN_USE: rig_debug(RIG_DEBUG_ERR, "%s: serial port %s is already open\n", __func__, rp->pathname); return -RIG_EACCESS; case SER_NO_EXIST: rig_debug(RIG_DEBUG_ERR, "%s: serial port %s does not exist\n", __func__, rp->pathname); return -RIG_EIO; case SER_AVAILABLE: rig_debug(RIG_DEBUG_VERBOSE, "%s: serial port %s is OK\n", __func__, rp->pathname); break; } #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rp->pathname); if (!strncmp(rp->pathname, "uh-rig", 6)) { /* * If the pathname is EXACTLY "uh-rig", try to use a microHam device * rather than a conventional serial port. * The microHam devices ALWAYS use "no parity", and can either use no handshake * or hardware handshake. Return with error if something else is requested. */ if (rp->parm.serial.parity != RIG_PARITY_NONE) { return (-RIG_EIO); } if ((rp->parm.serial.handshake != RIG_HANDSHAKE_HARDWARE) && (rp->parm.serial.handshake != RIG_HANDSHAKE_NONE)) { return (-RIG_EIO); } /* * Note that serial setup is also don in uh_open_radio. * So we need to dig into serial_setup(). */ fd = uh_open_radio( rp->parm.serial.rate, // baud rp->parm.serial.data_bits, // databits rp->parm.serial.stop_bits, // stopbits (rp->parm.serial.handshake == RIG_HANDSHAKE_HARDWARE)); // rtscts if (fd == -1) { return (-RIG_EIO); } rp->fd = fd; /* * Remember the fd in a global variable. We can do read(), write() and select() * on fd but whenever it is tried to do an ioctl(), we have to catch it * (e.g. setting DTR or tcflush on this fd does not work) * While this may look dirty, it is certainly easier and more efficient than * to check whether fd corresponds to a serial line or a socket everywhere. * * CAVEAT: for WIN32, it might be necessary to use win_serial_read() instead * of read() for serial lines in iofunc.c. Therefore, we have to * export uh_radio_fd to iofunc.c because in the case of sockets, * read() must be used also in the WIN32 case. * This is why uh_radio_fd is declared globally in microham.h. * Notes from Joe Subich about microham behavior * Microham debug tags * A-RX ; Asynchronous data received (data not responsive to any * poll from host or Router) - Set AI0; * H2-RX; Data received in response to poll from Host 2 poll (2nd CAT port). * H2-TX; Data poll/command from Host 2 (2nd CAT Port) * R-RX; Data received in response to poll by microHAM USB Device Router * R-TX; Router poll * Note: R-TX; and R-RX; data is not passed to Host ports. * 1) Router only polls when it has not seen a poll for FA; FB; and IF; * (or equivalent for other manufacturers) within its timeout period. * 2) The results of router's polling are not passed to the Host/apps. * 3) Router only polls when there is no activity from the applications. * 4) Router is designed to be transparent as far as the applications * are concerned. The only exception is when the user chooses to * run two applications (CAT and 2nd CAT) at the same time and has * "auto-information" or CI-V enabled. In that case asynchronous data * from the transceiver will be returned to both applications. */ uh_radio_fd = fd; return (RIG_OK); } /* * Open in Non-blocking mode. Watch for EAGAIN errors! */ int i = 1; do // some serial ports fail to open 1st time for some unknown reason { fd = OPEN(rp->pathname, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) // some serial ports fail to open 1st time for some unknown reason { rig_debug(RIG_DEBUG_WARN, "%s(%d): open failed#%d %s\n", __func__, __LINE__, i, strerror(errno)); hl_usleep(500 * 1000); fd = OPEN(rp->pathname, O_RDWR | O_NOCTTY | O_NDELAY); } } while (++i <= 4 && fd == -1 && errno != ENOENT && errno != EPERM); if (fd == -1) { /* Could not open the port. */ rig_debug(RIG_DEBUG_ERR, "%s: Unable to open %s - %s\n", __func__, rp->pathname, strerror(errno)); return (-RIG_EIO); } rp->fd = fd; err = serial_setup(rp); if (err != RIG_OK) { CLOSE(fd); return (err); } hl_usleep(50 * 1000); // give a little time for MicroKeyer to finish serial_flush(rp); // ensure nothing is there when we open return (RIG_OK); } /** * \brief Set up Serial port according to requests in port * \param rp * \return RIG_OK or < 0 */ int HAMLIB_API serial_setup(hamlib_port_t *rp) { int fd; /* There's a lib replacement for termios under Mingw */ #if defined(HAVE_TERMIOS_H) speed_t speed; /* serial comm speed */ struct termios options, orig_options; #elif defined(HAVE_TERMIO_H) struct termio options, orig_options; #elif defined(HAVE_SGTTY_H) struct sgttyb sg, orig_sg; #else # error "No term control supported!" #endif term_options_backup_t *term_backup = NULL; if (!rp) { return (-RIG_EINVAL); } fd = rp->fd; // Linux sets pins high so we force them low once // This fails on Linux and MacOS with hardware flow control // Seems setting low disables hardware flow setting later // ser_set_rts(rp, 0); // ser_set_dtr(rp, 0); /* * Get the current options for the port... */ #if defined(HAVE_TERMIOS_H) rig_debug(RIG_DEBUG_TRACE, "%s: tcgetattr\n", __func__); tcgetattr(fd, &options); memcpy(&orig_options, &options, sizeof(orig_options)); #elif defined(HAVE_TERMIO_H) rig_debug(RIG_DEBUG_TRACE, "%s: IOCTL TCGETA\n", __func__); IOCTL(fd, TCGETA, &options); memcpy(&orig_options, &options, sizeof(orig_options)); #else /* sgtty */ rig_debug(RIG_DEBUG_TRACE, "%s: IOCTL TIOCGETP\n", __func__); IOCTL(fd, TIOCGETP, &sg); memcpy(&orig_sg, &sg, sizeof(orig_sg)); #endif #ifdef HAVE_CFMAKERAW /* Set serial port to RAW mode by default. */ rig_debug(RIG_DEBUG_TRACE, "%s: cfmakeraw\n", __func__); cfmakeraw(&options); #endif /* * Set the baud rates to requested values */ switch (rp->parm.serial.rate) { case 150: speed = B150; /* yikes... */ break; case 300: speed = B300; /* yikes... */ break; case 600: speed = B600; break; case 1200: speed = B1200; break; case 2400: speed = B2400; break; case 4800: speed = B4800; break; case 9600: speed = B9600; break; case 19200: speed = B19200; break; case 38400: speed = B38400; break; case 57600: speed = B57600; /* cool.. */ break; case 115200: speed = B115200; /* awesome! */ break; #ifdef B230400 case 230400: speed = B230400; /* super awesome! */ break; #endif #ifdef B460800 case 460800: speed = B460800; /* extra super awesome! */ break; #endif #ifdef B500000 case 500000: speed = B500000; /* extra super awesome! */ break; #endif #ifdef B576000 case 576000: speed = B576000; /* out of adverbs */ break; #endif #ifdef B921600 case 921600: speed = B921600; break; #endif #ifdef B1000000 case 1000000: speed = B1000000; break; #endif #ifdef B1152000 case 1152000: speed = B1152000; break; #endif #ifdef B1500000 case 1500000: speed = B1500000; break; #endif #ifdef B2000000 case 2000000: speed = B2000000; break; #endif #ifdef B2500000 case 2500000: speed = B2500000; break; #endif #ifdef B3000000 case 3000000: speed = B3000000; break; #endif #ifdef B3500000 case 3500000: speed = B3500000; break; #endif #ifdef B4000000 case 4000000: speed = B4000000; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported rate specified: %d\n", __func__, rp->parm.serial.rate); CLOSE(fd); return (-RIG_ECONF); } /* TODO */ rig_debug(RIG_DEBUG_TRACE, "%s: cfsetispeed=%d,0x%04x\n", __func__, (int)rp->parm.serial.rate, (int)speed); cfsetispeed(&options, speed); rig_debug(RIG_DEBUG_TRACE, "%s: cfsetospeed=%d,0x%04x\n", __func__, (int)rp->parm.serial.rate, (int)speed); cfsetospeed(&options, speed); /* * Enable the receiver and set local mode... */ options.c_cflag |= (CLOCAL | CREAD); /* * close doesn't change modem signals */ options.c_cflag &= ~HUPCL; /* * Set data to requested values. * */ rig_debug(RIG_DEBUG_TRACE, "%s: data_bits=%d\n", __func__, rp->parm.serial.data_bits); switch (rp->parm.serial.data_bits) { case 7: options.c_cflag &= ~CSIZE; options.c_cflag |= CS7; break; case 8: options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported serial_data_bits specified: %d\n", __func__, rp->parm.serial.data_bits); CLOSE(fd); return (-RIG_ECONF); break; } /* * Set stop bits to requested values. * */ rig_debug(RIG_DEBUG_TRACE, "%s: stopbits=%d\n", __func__, rp->parm.serial.stop_bits); switch (rp->parm.serial.stop_bits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported serial_stop_bits specified: %d\n", __func__, rp->parm.serial.stop_bits); CLOSE(fd); return (-RIG_ECONF); break; } /* * Set parity to requested values. * */ rig_debug(RIG_DEBUG_TRACE, "%s: parity=%d\n", __func__, rp->parm.serial.parity); switch (rp->parm.serial.parity) { case RIG_PARITY_NONE: options.c_cflag &= ~PARENB; break; case RIG_PARITY_EVEN: options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; break; case RIG_PARITY_ODD: options.c_cflag |= PARENB; options.c_cflag |= PARODD; break; /* CMSPAR is not POSIX */ #ifdef CMSPAR case RIG_PARITY_MARK: options.c_cflag |= PARENB | CMSPAR; options.c_cflag |= PARODD; break; case RIG_PARITY_SPACE: options.c_cflag |= PARENB | CMSPAR; options.c_cflag &= ~PARODD; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported serial_parity specified: %d\n", __func__, rp->parm.serial.parity); CLOSE(fd); return (-RIG_ECONF); break; } /* * Set flow control to requested mode * */ switch (rp->parm.serial.handshake) { case RIG_HANDSHAKE_NONE: rig_debug(RIG_DEBUG_TRACE, "%s: Handshake=None\n", __func__); options.c_cflag &= ~CRTSCTS; options.c_iflag &= ~IXON; break; case RIG_HANDSHAKE_XONXOFF: rig_debug(RIG_DEBUG_TRACE, "%s: Handshake=Xon/Xoff\n", __func__); options.c_cflag &= ~CRTSCTS; options.c_iflag |= IXON; /* Enable Xon/Xoff software handshaking */ break; case RIG_HANDSHAKE_HARDWARE: rig_debug(RIG_DEBUG_TRACE, "%s: Handshake=Hardware\n", __func__); options.c_cflag |= CRTSCTS; /* Enable Hardware handshaking */ options.c_iflag &= ~IXON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported flow_control specified: %d\n", __func__, rp->parm.serial.handshake); CLOSE(fd); return (-RIG_ECONF); break; } /* * Choose raw input, no preprocessing please .. */ #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H) options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* * Choose raw output, no preprocessing please .. */ options.c_oflag &= ~OPOST; #else /* sgtty */ sg.sg_flags = RAW; #endif /* * VTIME in deciseconds, rp->timeout in milliseconds */ options.c_cc[VTIME] = (rp->timeout + 99) / 100; options.c_cc[VMIN] = 1; /* * Flush serial port */ tcflush(fd, TCIFLUSH); /* * Finally, set the new options for the port... */ #if defined(HAVE_TERMIOS_H) rig_debug(RIG_DEBUG_TRACE, "%s: tcsetattr TCSANOW\n", __func__); if (tcsetattr(fd, TCSANOW, &options) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: tcsetattr failed: %s\n", __func__, strerror(errno)); CLOSE(fd); return (-RIG_ECONF); /* arg, so close! */ } #elif defined(HAVE_TERMIO_H) rig_debug(RIG_DEBUG_TRACE, "%s: IOCTL TCSETA\n", __func__); if (IOCTL(fd, TCSETA, &options) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(TCSETA) failed: %s\n", __func__, strerror(errno)); CLOSE(fd); return (-RIG_ECONF); /* arg, so close! */ } #else rig_debug(RIG_DEBUG_TRACE, "%s: IOCTL TIOCSETP\n", __func__); /* sgtty */ if (IOCTL(fd, TIOCSETP, &sg) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(TIOCSETP) failed: %s\n", __func__, strerror(errno)); CLOSE(fd); return (-RIG_ECONF); /* arg, so close! */ } #endif // Store a copy of the original options for this FD, to be restored on close. term_backup = calloc(1, sizeof(term_options_backup_t)); term_backup-> fd = fd; #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H) memcpy(&term_backup->options, &orig_options, sizeof(orig_options)); #elif defined(HAVE_SGTTY_H) memcpy(&term_backup->sg, &orig_sg, sizeof(orig_sg)); #endif // insert at head of list term_backup->next = term_options_backup_head; term_options_backup_head = term_backup; return (RIG_OK); } /** * \brief Flush all characters waiting in RX buffer. * \param p * \return RIG_OK */ int HAMLIB_API serial_flush(hamlib_port_t *p) { int len; int timeout_save; short timeout_retry_save; unsigned char buf[4096]; #ifdef __WIN32__ struct termios_list *index; index = win32_serial_find_port(p->fd); if (!index) { rig_debug(RIG_DEBUG_ERR, "%s: No WIN32 index for port???\n", __func__); return -1; } PurgeComm(index->hComm, PURGE_RXCLEAR); return RIG_OK; #endif if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd || p->flushx) { /* * Catch microHam case: * if fd corresponds to a microHam device drain the line * (which is a socket) by reading until it is empty. */ int n, nbytes = 0; rig_debug(RIG_DEBUG_TRACE, "%s: flushing\n", __func__); while ((n = read(p->fd, buf, sizeof(buf))) > 0) { nbytes += n; //int i; //for (i = 0; i < n; ++i) { printf("0x%02x(%c) ", buf[i], isprint(buf[i]) ? buf[i] : '~'); } /* do nothing */ } rig_debug(RIG_DEBUG_TRACE, "read flushed %d bytes\n", nbytes); return (RIG_OK); } timeout_save = p->timeout; //rig_debug(RIG_DEBUG_ERR, "%s: p->timeout=%d\n", __func__, p->timeout); timeout_retry_save = p->timeout_retry; p->timeout = 0; p->timeout_retry = 0; do { // we pass an empty stopset so read_string can determine // the appropriate stopset for async data const char stopset[1]; len = read_string(p, buf, sizeof(buf) - 1, stopset, 0, 1, 1); if (len > 0) { int i, binary = 0; for (i = 0; i < len; ++i) { if (!isprint(buf[i])) { binary = 1; } } if (binary) { int bytes = len * 3 + 1; char *hbuf = calloc(bytes, 1); for (i = 0; i < len; ++i) { SNPRINTF(&hbuf[i * 3], bytes - (i * 3), "%02X ", buf[i]); } rig_debug(RIG_DEBUG_WARN, "%s: flush hex:%s\n", __func__, hbuf); free(hbuf); } else { rig_debug(RIG_DEBUG_WARN, "%s: flush string:%s\n", __func__, buf); } } } while (len > 0); p->timeout = timeout_save; p->timeout_retry = timeout_retry_save; // rig_debug(RIG_DEBUG_VERBOSE, "tcflush%s\n", ""); // we also do this flush https://github.com/Hamlib/Hamlib/issues/1241 tcflush(p->fd, TCIFLUSH); return RIG_OK; } /** * \brief Open serial port * \param p * \return fd */ int ser_open(hamlib_port_t *p) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called port=%s\n", __func__, p->pathname); if (!strncmp(p->pathname, "uh-rig", 6)) { /* * This should not happen: ser_open is only used for * DTR-only serial ports (ptt_pathname != rig_pathname). */ ret = -1; } else { if (!strncmp(p->pathname, "uh-ptt", 6)) { /* * Use microHam device for doing PTT. Although a valid file * descriptor is returned, it is not used for anything * but must be remembered in a global variable: * If it is tried later to set/unset DTR on this fd, we know * that we cannot use ioctl and must rather call our * PTT set/unset service routine. */ ret = uh_open_ptt(); uh_ptt_fd = ret; } else { /* * pathname is not uh_rig or uh_ptt: simply open() */ int i = 1; do // some serial ports fail to open 1st time { ret = OPEN(p->pathname, O_RDWR | O_NOCTTY | O_NDELAY); if (ret == -1) // some serial ports fail to open 1st time { rig_debug(RIG_DEBUG_WARN, "%s(%d): open failed#%d\n", __func__, __LINE__, i); hl_usleep(500 * 1000); ret = OPEN(p->pathname, O_RDWR | O_NOCTTY | O_NDELAY); } } while (++i <= 4 && ret == -1); } } p->fd = ret; return (ret); } /** * \brief Close serial port * \param p fd * \return RIG_OK or < 0 */ int ser_close(hamlib_port_t *p) { int rc; term_options_backup_t *term_backup, *term_backup_prev; //rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* * For microHam devices, do not close the * socket via close but call a service routine * (which might decide to keep the socket open). * However, unset p->fd and uh_ptt_fd/uh_radio_fd. */ if (p->fd == uh_ptt_fd) { uh_close_ptt(); uh_ptt_fd = -1; p->fd = -1; return (0); } if (p->fd == uh_radio_fd) { uh_close_radio(); uh_radio_fd = -1; p->fd = -1; return (0); } // Find backup termios options to restore before closing term_backup = term_options_backup_head; term_backup_prev = term_options_backup_head; while (term_backup) { if (term_backup->fd == p->fd) { // Found matching. Remove from list if (term_backup == term_options_backup_head) { term_options_backup_head = term_backup->next; } else { term_backup_prev->next = term_backup->next; } break; } term_backup_prev = term_backup; term_backup = term_backup->next; } // Restore backup termios if (term_backup) { rig_debug(RIG_DEBUG_VERBOSE, "%s: restoring options\n", __func__); #if defined(HAVE_TERMIOS_H) if (tcsetattr(p->fd, TCSANOW, &term_backup->options) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: tcsetattr restore failed: %s\n", __func__, strerror(errno)); } #elif defined(HAVE_TERMIO_H) if (IOCTL(p->fd, TCSETA, &term_backup->options) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(TCSETA) restore failed: %s\n", __func__, strerror(errno)); } #else /* sgtty */ if (IOCTL(p->fd, TIOCSETP, &term_backup->sg) == -1) { rig_debug(RIG_DEBUG_ERR, "%s: ioctl(TIOCSETP) restore failed: %s\n", __func__, strerror(errno)); } #endif free(term_backup); } else { rig_debug(RIG_DEBUG_TRACE, "%s: no options for fd to restore\n", __func__); } rc = CLOSE(p->fd); p->fd = -1; return (rc); } /** * \brief Set Request to Send (RTS) bit * \param p * \param state true/false * \return RIG_OK or < 0 */ int HAMLIB_API ser_set_rts(hamlib_port_t *p, int state) { unsigned int y = TIOCM_RTS; int rc; rig_debug(RIG_DEBUG_VERBOSE, "%s: RTS=%d\n", __func__, state); // ignore this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (RIG_OK); } #if defined(TIOCMBIS) && defined(TIOCMBIC) rc = IOCTL(p->fd, state ? TIOCMBIS : TIOCMBIC, &y); #else rc = IOCTL(p->fd, TIOCMGET, &y); if (rc >= 0) { if (state) { y |= TIOCM_RTS; } else { y &= ~TIOCM_RTS; } rc = IOCTL(p->fd, TIOCMSET, &y); } #endif if (rc < 0) { rig_debug(RIG_DEBUG_ERR, "%s: Cannot change RTS - %s\n", __func__, strerror(errno)); return (-RIG_EIO); } return (RIG_OK); } /** * \brief Get RTS bit * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_rts(hamlib_port_t *p, int *state) { int retcode; unsigned int y; // cannot do this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (-RIG_ENIMPL); } retcode = IOCTL(p->fd, TIOCMGET, &y); *state = (y & TIOCM_RTS) == TIOCM_RTS; return (retcode < 0 ? -RIG_EIO : RIG_OK); } /** * \brief Set Data Terminal Ready (DTR) bit * \param p * \param state true/false * \return RIG_OK or < 0 */ int HAMLIB_API ser_set_dtr(hamlib_port_t *p, int state) { unsigned int y = TIOCM_DTR; int rc; rig_debug(RIG_DEBUG_VERBOSE, "%s: DTR=%d\n", __func__, state); // silently ignore on microHam RADIO channel, // but (un)set ptt on microHam PTT channel. if (p->fd == uh_radio_fd) { return (RIG_OK); } if (p->fd == uh_ptt_fd) { uh_set_ptt(state); return (RIG_OK); } #if defined(TIOCMBIS) && defined(TIOCMBIC) rc = IOCTL(p->fd, state ? TIOCMBIS : TIOCMBIC, &y); #else rc = IOCTL(p->fd, TIOCMGET, &y); if (rc >= 0) { if (state) { y |= TIOCM_DTR; } else { y &= ~TIOCM_DTR; } rc = IOCTL(p->fd, TIOCMSET, &y); } #endif if (rc < 0) { rig_debug(RIG_DEBUG_ERR, "%s: Cannot change DTR - %s\n", __func__, strerror(errno)); return (-RIG_EIO); } return (RIG_OK); } /** * \brief Get DTR bit * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_dtr(hamlib_port_t *p, int *state) { int retcode; unsigned int y; // cannot do this for the RADIO port, return PTT state for the PTT port if (p->fd == uh_ptt_fd) { *state = uh_get_ptt(); return (RIG_OK); } if (p->fd == uh_radio_fd) { return (-RIG_ENIMPL); } retcode = IOCTL(p->fd, TIOCMGET, &y); *state = (y & TIOCM_DTR) == TIOCM_DTR; return (retcode < 0 ? -RIG_EIO : RIG_OK); } /** * \brief Set Break * \param p * \param state (ignored?) * \return RIG_OK or < 0 */ int HAMLIB_API ser_set_brk(const hamlib_port_t *p, int state) { // ignore this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (RIG_OK); } #if defined(TIOCSBRK) && defined(TIOCCBRK) return (IOCTL(p->fd, state ? TIOCSBRK : TIOCCBRK, 0) < 0 ? -RIG_EIO : RIG_OK); #else return (-RIG_ENIMPL); #endif } /** * \brief Get Carrier (CI?) bit * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_car(hamlib_port_t *p, int *state) { int retcode; unsigned int y; // cannot do this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (-RIG_ENIMPL); } retcode = IOCTL(p->fd, TIOCMGET, &y); *state = (y & TIOCM_CAR) == TIOCM_CAR; return (retcode < 0 ? -RIG_EIO : RIG_OK); } /** * \brief Get Clear to Send (CTS) bit * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_cts(hamlib_port_t *p, int *state) { int retcode; unsigned int y; // cannot do this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (-RIG_ENIMPL); } retcode = IOCTL(p->fd, TIOCMGET, &y); *state = (y & TIOCM_CTS) == TIOCM_CTS; return (retcode < 0 ? -RIG_EIO : RIG_OK); } /** * \brief Get Data Set Ready (DSR) bit * \param p supposed to be RIGPORT(rig) * \param state non-NULL */ int HAMLIB_API ser_get_dsr(hamlib_port_t *p, int *state) { int retcode; unsigned int y; // cannot do this for microHam ports if (p->fd == uh_ptt_fd || p->fd == uh_radio_fd) { return (-RIG_ENIMPL); } retcode = IOCTL(p->fd, TIOCMGET, &y); *state = (y & TIOCM_DSR) == TIOCM_DSR; return (retcode < 0 ? -RIG_EIO : RIG_OK); } /** @} */ hamlib-4.6.5/NEWS0000664000175000017500000012025115056640442007153 Hamlib -- History of visible changes. Copyright (C) 2000-2003 Frank Singleton Copyright (C) 2000-2023 Stephane Fillod, and others Copyright (C) 2000-2025 Michael Black W9MDB, and others Please send Hamlib bug reports to hamlib-developer@lists.sourceforge.net Version 5.x -- future * rig_get_conf deprecated and replaced by rig_get_conf2 * rot_get_conf deprecated and replaced by rot_get_conf2 * Change FT1000MP Mark V model names to align with FT1000MP Version 4.7.0 * 2025-12-01 (target) Version 4.6.5 * 2025-09-05 * Update Kenwood CW buffer max message size, fix one byte buffer overrun in icom.c. (TNX George Baltz). * Fix Segmentation Fault in rigs/dummy/netrigctl.c. (TNX Daniele Forsi) * Fix segfault with set_parm KEYERTYPE in rigctl_parse.c. (TNX Daniele Forsi) Version 4.6.4 * 2025-07-18--Hamlib's 25th birthday!!! * Fix handling of unprintable characters in kenwood.c that broke radios such as the TM-D710/TM-V71 that use EOM_TH (\r) as the command terminator. (TNX, Lars Kellogg-Stedman and George Baltz). * Fixed jrc_set_chan. (TNX Mark Fine). * Fix memory leak in rigctl_parse.c and use unique separator character for each rigctld connection--closes GitHub #1748. (TNX George Baltz). * Fix powerstat check for Icom R75 which rejects the command. (TNX Mark Fine). * Restore TS-590S/SG RIG_LEVEL_RFPOWER_METER, Fix rotctl \dump_caps output (TNX, George Baltz). * Add CW sending capability to Flex SmartSDR. (TNX Michael Morgan) * Handle spaces correctly for Fles SmartSDR. (TNX Michael Morgan) Version 4.6.3 * 2025-06-10 * Release dedicated to the memory of Michael Black, W9MDB (SK). Mike was a long-time contributor to Hamlib and led development of the project for over five years from 2020 to 2025. Mike passed away on March 28, 2025 due to complications from ALS (Lou Gehrig's disease). * Fix various typos in Doxygen tags. (TNX Daniele Forsi) * JRC: Removed RIG_FUNC_FAGC from 535D as erroneous, Added RIG_FUNC_NB2 functionality to both 535D and 545. (TNX Mark Fine) * Restore IC-7300 spectrum data callback - regression in 4.6 (n3gb) * Add locking to rig_[gs]et_level() - fixes sending CW from tlf (n3gb) * Fix attempt to use memory returned by setlocale() after being freed (TNX Mooneer Salem) * Language bindings configuration and build fixes (TNX Daniele Forsi) * Various build system and compilation fixes (TNX Daniele Forsi) * IC-705 filter selection bandwidth for FM and WFM (TNX Kenji Rikitake) * IC-705 COMP, VD, and ID meter calibration values (TNX Kenji Rikitake) * Fix ACLog thousands separator * Documentation updates, typo fixes, man page fixes (TNX Daniele Forsi) * Drop redundant token lookups and make local functions static (TNX George Baltz) * Fix rigctl showing hamlib_verson when connecting to rigctld * Add rig CODAN 2110 Version 4.6.2 * 2025-02-09 * Add missing levels for IC746/PRO RIG_LEVEL_RFPOWER_METER,RIG_LEVEL_RFPOWER_METER_WATTS,RIG_LEVEL_SWR,RIG_LEVEL_ALC * Fix IC905 for gpredict * Fix potential segfault on QMX * Fix pmr171 Version 4.6.1 * 2025-01-21 * Fix C++ builds failing on rig_list_foreach function * Fix IC9100 rigctld startup to end up on VFOA * Fix grig build by removing sys/socket.h -- apparently not needed * Add new QMX entry to fix incompability with QDX * Fix IC746/PROT to not use data byte * FLRig to add DATA-U DATA-L modes * Fix TS570 RIG_LEVEL_STRENGTH with cal table * Remove get_powerstat from IC785X -- not supported * Fix SDRConsole by removing lots of things it does not have Version 4.6 * 2024-12-24 * send_raw can now take hex digits as colon-separated -- e.g. send_raw icom xfe:xfe:x94:xe0:03:xfd * Add IC7760 * IC7300 Mode filter can now be set by # (i.e. 1,2,3) * Fixed AF6SA WRC rotor controller * Added Rhode&Schwarz XK852 * Added Xiegu X6200 * Added Commradio CTX-10 * Added Guoehe PMR-171 * Added csntechnoligies.net S.A.T Satellite rotor control * Added PSTRotator control * Added Flex SmartSDR slices A-H * Added Motorola Micom M2/M3 * Added SDR Radio SDRConsole -- TS-2000 is now hardware flow control so need separate entry * Added --set-conf=filter_usb, filter_usbd, and filter_cw to allow Icom rigs set mode to set filter number too * Added macros for applications to obtain pointers to Hamlib structures(issues #1445, #1420, #487). Internal conversion is still a WIP, but use of these macros will make the final cutover transparent to applications. * Added Guohe Q900 entry * Unify behavior of all rigctl split commands * Make the set_split_* commands modify the state of the specified split VFO -- the current or targeted VFO do not have any effect * Make the set_split_* commands enable split automatically if not enabled * Make the get_split_* commands return frequency of 0 Hz, mode NONE and filter of 0 Hz if split is not enabled * Allow all split commands to avoid VFO swapping if supported by the rig model * Improve Icom backend to set/get frequency, mode and filter without VFO swapping if supported by the rig model * Improve Yaesu newcat backend split handling * Expose "Targetable features" (RIG_TARGETABLE_*) in dump_caps output to allow clients to determine which commands can be executed without VFO swapping * Added RIG_FUNC_SYNC for FTDX101D/MP * Added Barrett 4100 * Added DL2MAN (tr)uSDX -- needs refinement * Added Thetis entry -- derived from FlexRadio/Apache PowerSDR * Added VOICE/CW memory capability to many rigs -- thanks to David Balharrie M0DGB/G8FKH * Add -# --skip_init option to rigctl to skip rig initialization -- useful for executing commands quickly * rig_caps is no longer constant -- this may break some 3rd party relying on the "const" declaration. Here's an example of how to handle compatibility. #ifdef RIGCAPS_NOT_CONST static int add_to_list(struct rig_caps* rc, void*) #else static int add_to_list(const struct rig_caps* rc, void*) #endif * IC7610 now has IPP, DPP, and TX_INHIBIT functions set/get * Hamlib now starts a multicast server that sends out rig information. Does not receive commands yet. See README.multicast * rigctld has new -b/bind-all option to try all interfaces -- restores original behavior. This was done to fix duplicate rigctld instances on Windows * Yaesu rigs can now use send_morse to send keyer message 1-5 or a CW message up to 50 chars (which will use memory 1) * rig set level METER can now take SWR,COMP,ALC,IC/ID,DB,PO,VDD,TEMP arguments to set which meter to display * reg get level displays meter number=name now * Added parm BANDSELECT for Yaesu rigs 'p BANDSELECT' returns current band of VFOA 'P BANDSELECT BAND160M' example selects the 160M band 'P BANDSELECT ?' shows bands available for the rig * Added rig_cm108_get/set_bit to API and get/set_gpio to rigctl(d) for GPIO1,2,3,4 access on CM108 * Added BG2FX FX4/C/CR/L * Fixed IC7610 to use new 0x25 0x26 command added in latest firmware * Fix W command in rigctld to work properly -- can take terminating char or # of bytes to expect * Add rig_set_debug_filename so Python can redirect debug stream * Fix Yaesu LBL_NR to use proper values * Add IC-905 * Add Anytone D578UVIII -- should work on any D558 model and perhaps others too * Add saebrtrack rotor https://sites.google.com/site/marklhammond/saebrtrack * Add offset_vfoa and offset_vfob applying to rig_set_freq * Fix K4 to put it in K40 mode when requesting ID * Fixes for M2 Rotors * Add rigctlsync utility to synchronize frequency from a rig to SDR# (or others) * Add SDR# rig for use with SDR#'s gpredict plugin -- can only get/set freq * Add Apex Shared Loop rotator -- unidirectional only so far * Add client_version to rigctld so client can report it's version for future use/compatibility/alternatives * Add --set-conf=tuner_control_pathname=hamlib_tuner_control (default) If file exists then it will be called with 0/1 (Off/On) argument with 'U TUNER 0' or 'U TUNER 1" Default path is for current directory * Add MDS 4710/9710 rigs * Add FLIR PTU-D48, E46, D100, D300 rotors * Fix FTDX3000 rig split Version 4.5.6 * Fix rigctld/rigctltcp information * Fix FT817 get/set_vfo Version 4.5.5 * 2023-04-05 * Add park to rotorez.c * Fix rig power on/off from rigctl cmd line and rigctld * Enable async mode by default to prevent WSJT-X crash on IC9700 with transceive on * Fix IC7610 get_powerstat to disable it -- cannot read power status * Fix K3 K22 command error for remote operations * Fix Gemini DX1200 gemini_set_level * Fix async I/O to not call flush * Change EX startup commands for Yaesu rigs to allow errors...Win4Yaesu not recognizing EX commands * Fix jst145 set_freq and get_freq * Restore tcflush as some odd behavior was seen that tclush fixes * Fix XG3 operations * Separate the validation cmd in newcat.c to allow rig post_write_delay to be in effect * Increase post_write to 20ms for FT710 * Add attenuator level control for TS890 * Update SMeter/SWR tables for TS890 * Add fix for TMD700 * Improve FT-857 get_vfo response when error occurs * Allow FT-857 to use cached vfo on get_vfo when error occurs reading EEPROM * Fix FTDX10 FT710 set_level AF * Fix FT-450D detection * Fix VFO A/B swapping for gpredict -- hopefully better behavior for VFO swapping rigs Should avoid setting RX freq while TX and avoid TX freq while RX * Fix QRP QDX PTT to new TQ command due to firmware changes * Remove EX103 check for FTDX5000 * Fix K3/K3S VFOB setting of mode/width * Fix AGC level display in rigctld * Change FTDX10 to no serial handshake * Add TS2000 to has_ps exception * Add FT991 to 60M exception * Fix get_powerstat bad call in rigctl_parse.c * Really fix CM108 ptt_bitnum usage * Fix Elecraft power2mW precision/accuracy * Fix power on/off/on for Icom rigs with rigctld power_on=0 Version 4.5.4 * 2023-01-10 * Fix CM108 ptt setting for non-default usage * Fix power on/off for Icom rigs with rigctld power_on=0 * Fix get_powerstat status return for non-PS kenwood rigs * Fix FT-710, FTDX10, FTDX101D/MP usage on 60M * Fix timing on NRD-535D * Fix AGC levels with rigctld * Fix FTDX3000 EX039 error * Fix Elecraft power2mW operation * Fix rig_power2mW so it checks all ranges * Allow rigctld to start with autopower_on=0 to avoid startup timeouts when rig is powered off * Fix dummy device to work with grig by disallowing empty "u" call * Fix ID5100 and promote to stable and hopefully ID4100 too * Remove get_powerstat from Icom ID-5100,ID-4100,ID-31,ID-51 and fix get/set freq in all Version 4.5.3 * 2022-12-31 * Fix serial.c for hardware flow control on Linux and MacOSy * Add QRPLabs QCX/QDX rig -- not quite a TS480 * Fix QRP QRDX firmware bugs in IF message so PTT works now * FTDX5000 will now remember startup front/read settings and restore it * Fix FTDX5000 write_delay with microham * Fix grep error on MingW build Version 4.5.2 * 2022-12-23 * Fix PowerSDR ability to do commands while powered off * Fix TX-500 operations * Fix FTDX5000 to return to MIC input on closing * Fix rig.c calling rig_get_mode when backend does not have get_mode * Fix kenwood_ts890_get_level * Add Prosistel D elevation CBOX az to fix problem with azimuth control * Fix FT736R gpredict usage by adding cached get_freq * Fix get_powerstat problem with Log4OM/Flex and others * Fix -R option to not need argument * Fix -R option to close rig on last rigctld client disconnect * Add FTDX1200 to rigs that need to ensure PTT is off before changing frequency * Add --disable-parallel configure option for mingw builds on Linux Version 4.5.1 * 2022-12-08 * FT2000, FTDX3000/D, FT891, FT991, FT950, FTDX5000 now set CAT TOT to 100ms * Add missing NB2 setting to FT-950, FTDX-1200, FT-2000, FTDX-3000, FTDX-5000, FTDX-9000 * Add missing meter reading to TS-890S -- thanks to Geore Baltz N3GB * Fix FT736 VFOB freq and mode set * Added send_raw to rigctl -- see rigctl man page * Fix AGC Level dumpcaps on most rigs * Fix rig_send_raw to return bytes read, fill buffer, and also work with fixed length response/null terminator * Change all Kenwood rigs to 500ms serial timeout * Fix dumpcaps filter printout to only show declared filters * Fix triggering PTT on XGComms device on Linux * Fix level_gran in all rigs * Add RIG_FUNC_TUNER to flrig.c * Fix FT-991 level_gran (needs to be done for lots of rigs) * Fix man page rigctl to show units for LEVEL items * Fix Flex6xxx if_len * Fix FLRig set_ptt * Fix missing KEYSPD to TS890 * rigctl 'W' command can now use a singled char terminator like ; that allows for variable length responses with no timeout -- e.g. W FA; ; * New RIG_LEVEL_USB_AF to control audio gain from rig to computer -- to allow AGC function in software using RF and USB_AF * Add RIG_LEVEL_AGC_TIME to allow AGC/OFF to be set for IC-7300, IC-9700, IC-705 * Add RIG_FUNC_OVF_STATUS to get overflow status for IC-7300, IC-9700, IC-705, and IC-R8600 Version 4.5 * 2022-10-30 * New rotator utility https://www.pianetaradio.it/blog/catrotator/ * Add FT-710 * Add Rohde&Schwartz EK89X receiver * Add Xeigu X5105 * Add Gemini DX-1200 HF-1K Amplifiers * Kenwood rigs should now support AI command packets * Add FT-990UNI for older 990 ROMs 1.2 and earlier * Add FT-650 * Add get_separator and set_separator and -S option for rigctld -- node-red applicability * Add GRBLTRK rotor project -- two axis rotor * Add SDRPlay SDRUno rig -- can now use Data/Pkt in WSJTX * Add ability to use cat_string to FLRig via the "w" and "W" commands * Add -B/--mapa2b to rigctlcom Allows rigctlcom to map set_freq on VFOA to VFOB instead This will allow CW Skimmer to work with some rigs (e.g. IC7300) using FM mode on VFOA and CW mode on VFOB and split mode transmit on VFOB. Clicking on CW Skimmer will change VFOB instead of VFOA to allow working dxpeditions where the fox is staying on frequency * Add password capability to rigctld via -A switch. rigctld -A will produce a consistent shared key for any specific password that can used in \password and rig_set_password TBD The shared key can also be placed in .hamlib_settings * Asynchronous rig data output handling to support transceive and spectrum data. Mikael, OH3BHX Example for the IC-7300 to multicast on port 20001 and provide async rig information rigctld --port=20001 --model=3073 --serial-speed=115200 --rig-file=/dev/serial/... --set-conf=rts_state=OFF --set-conf=dtr_state=OFF --multicast-addr=224.0.0.1 --multicast-port=20001 --set-conf=async=1 Also, spectrum data output needs to be enabled with: \set_func SPECTRUM 1 * See new set_conf option async for some Icom rigs * Multicast UDP packet output for asynchronous data. Mikael, OH3BHX * Rig state poll routine to serve commonly used data like frequency and mode from cache. Mikael, OH3BHX * deprecated hamlib_port_t at front of rig_state structure -- new one at end of structure * New rig_send_raw to send/read raw command to rig * New RIG_LEVEL_BAND_SELECT for Yaesu rigs * New rig_get_conf2 to replace rig_get_conf buffer overflow potential * New rot_get_conf2 to reaplce rot_get_conf buffer overflow potential * Added Barrett 4050 -- not functional yet * Added TCI 1.X -- not functional yet * Added TM-V71(A) * Added IC-F8101 * Added JRC JST-145 and JST-245 * Added Xiegu X108G, G90, and X6100 * Added CODAN Envoy and NGS * Added Lab599 TX-500 * Added GOMSPACE GS100 * Deprecated: rigctl commands \set_trn (A) and \get_trn (a) as they never worked as intended * Deprecated: field rig_caps.transceive and RIG_TRN_* macros Version 4.4 * 2021-12-02 * Icom rigs now default filter 2 when setting PKTUSB but user can override * Fix FTDX9000 meter readings * Add Android sensor as a rotator * Added rig_get_vfo to some Icom rigs that have XCHG or 0x25 command capability * Added ability to build hamlib with docker * Added M0NKA mcHF URP rig * Faster serial i/o noticeable on higher baud rates * IC7300/9700/7800/785x set_clock/get_clock routines added -- no auto set yet * Yaesu FT1200/891/991/DX10/DX101/DX101MP set_clock/get_clock routines added Version 4.3.1 * 2021-09-14 * Bug fix release - Do not do vfo_fixup on satmode rigs - Fix compilation of misc.c with gmtime_r replacement function for mingw - Fix python build. For some reason casting tp vfo_t in the RIG_VFO_N macro broke the swig parsing - Append the missing information to build hamlib v4.3 for Android NDK - Change set_icom_set_mode_with_data to not change mode unless necessary - Since Icom rigs default to filter 2 if a filter is not selected we will do the same when turning on data mode - Fix segfault in kenwood_set_vfo - scripts: Update example in readme, since 4.0 817 is 1020 - Make testlibusb.c compatible with libusb < 1.0.23 Note: On systems with libusb < 1.0.23 a warning will be emitted but compilation should proceed without error. - Update testlibusb.c warning to "may be" instead of "will be" - Change kenwood to only set VFOA default on 1st rig_open call Version 4.3 * 2021-09-01 * libusb-1.0.23 or greater is now required or use --without-libusb * Generating documentation now requires GNU source-highlighter. * Added IC-575 * Less VFO swapping of newer Icom rigs -- zero swapping in WSJTX and JTDX * Dual rotator control in rotctl -R option * Started work on simulators -- very crude right now but usable to debug some things * Overhaul of rig split -- reverse split (VFOA=RX VFOB=TX) should work for rigs capable of it Starting VFO does not matter -- rig will end up on RX VFO S VFOA 1 VFOB S VFOB 1 VFOA S Main 1 Sub S Sub 1 Main Version 4.2 * 2021-05-17 * New rig_get_mode_bandwidths -- returns token set for bandwidths for given mode Rig command: \get_mode_bandwidths CW Mode=CW Normal=500Hz Narrow=50Hz Wide=2400Hz * New rig_get_info -- returns token set for all vfos where order does not matter This is a string return to allow for easy future expansion without changing the API New tokens may be introduced and can be skipped if not used by clients Rig command: \get_rig_info VFO=Main Freq=145000000 Mode=None Width=0 RX=1 TX=1 VFO=VFOB Freq=145000000 Mode=FM Width=15000 RX=0 TX=0 Split=0 SatMode=0 Rig=Dummy App=Hamlib Version=20210429 CRC=0xf49f4708 * New rig_get_vfo_info Rig command: \get_vfo_info VFOA Freq: 145000000 Mode: None Width: 0 Split: 0 SatMode: 0 * FILPATHLEN has changed to HAMLIB_FILPATHLEN * USRP lib and gnuradio are deprecated and will be removed in 5.0 * Added Radan rotator * Added Malachite SDR * Major rework for PRM80 * Add twiddle_timeout and twiddle_rit --set-conf options rigctld --set-conf=twiddle_timeout=5,twiddle_rit=1 This will set the twiddle timeout to 5 seconds and turn on twiddle_rit For twiddle timeout VFOB will not be polled for 5 seconds after VFO twiddling is detected * rigctld --twiddle is deprecated and will be removed in 5.0 along with get_twiddle and set_twiddle * Rework Doxygen manual including default layout for Doxygen 1.9.1. So far the amplifier, rotator, and utilities API sections have been updated. The rig (radio) section remains to be updated. Version 4.1 2021-01-31 * rigctld and rigs should be more robust for disconnect problems * Several fixes for Icom and Yaesu rigs * Nobody should need to use rig->caps or rig->state anymore If you need a variable added please contact us. Note that rig->state abstraction is not implemented yet...no need known * New rig_get_caps_int and rig_get_caps_cptr functions to replace using caps-> values * New rig_get_function to replace using caps-> function pointers * Fix shared library problem with WSJTX, JTDX, and JS8Call * New model Barrett 950 Version 4.0 2020-11-29 * API/ABI changes, advance ABI to 4 0 0. * Add GPIO and GPION options for DCD. Jeroen Vreeken * New backend: ELAD FDM DUO. Giovanni, HB9EIK. * New RIG_LEVEL_RFPOWER_METER_WATTS level * All channel functions now take a vfo argument * New rotator backend: iOptron. Bob, KD8CGH * New model: Icom IC-R8600. Ekki, DF4OR * New utility: rigctlcom. Mike, W9MDB * New model: FT847UNI for unidirectional early serial numbers. Mike, W9MDB * Remove GNU Texinfo files and build system dependency. * Rig model numbers have changed to allow future growth * Fix a lot of static code analysis errors and warnings. Mike, W9MDB * Rearrange directory structure to put rigs and rotators sources under their own subdirectories. Mike, W9MDB * rig_get_channel changed to add read_only flag. * rigctl(d) f command also returns VFO now. * caching of vfo, frequency, mode, and ptt speeds up rigctld for all. * caching of kenwood/yaesu "IF" speeds up polling from WSJTX/JTDX. * rig_get_channel now has read_only flag but it still needs to be implemented based on rig behavior, so if you use rig_get_channel you may get a RIG_ENIMPL error to contact us for fixing it. * New rig backend for Elecraft K4. * New rig backend for PowerSDR (Flex and Apache users). * Many fixes and enhancements. Mike, W9MDB and many contributors * PTT port is no longer shared by default, use --set-conf=ptt_share=1 to enable Version 3.3 2018-08-12 * New models, R&S xk2100, TRXMAnager, Meade LX200 * HTML manual is now generated at 'make dist' so users don't need GNU Info tools installed. TNX Greg, N1DAM for the suggestion. * Handle longer udev generated file names up to 512 characters * Add debug time stamps with new '-Z' option and '--debug-time-stamps' options to rigctl, rotctl, rigctld, and rotctld utilities. * rigctld/rotctld continue working after serial or TCP device disappears. * Updates and fixes to FT-817, K3, IC-7300, AOR 3030, TM-D710, OMNI VII, TH-D72, Flrig, TS-590, piHPSDR, TS-2000, and netrigctl. * Update utility manual pages (section 1) and remove their reference material from the Info manual so it only needs to be update in one file. * Add new general project manual pages (section 7) and edit the Info manual to match. These should not change much so keeping them in sync should not be too much of a burden. The Info manual may be removed at some point in the future. * Last planned release of the present API/ABI. Future releases will require recompilation and relinking by client programs using the C library interface (programs that only use the network daemons should be unaffected). Version 3.2 2018-03-15 * New models, IC-7850/IC-7851 in IC-785x. Mike, W9MDB * Fix ft991_get_mode, Mike, W9MDB * New model, FT-891. Mike, W9MDB * New Barrett 2050 backend, Mike, W9MDB * New Flrig backend, Mike, W9MDB * New model, IC-M710, Mike, W9MDB * Build instructions and test script for Python3 * Rename autogen.sh to bootstrap and don't call configure * micro-ham support. Christoph, DL1YCF * New rotator, SPID MD-01/02 in ROT2 mode, Norvald Ryeng, LA6YKA * New model, Flex 6400/6600, Mike, W9MDB * New model, IC-7610, Mike, W9MDB * Add support for CM108B PTT, Max Lock * Many other bug fixes and enhancements Version 3.1 2016-12-31 * Fix kenwood_set_mode for ts590s and mode CW, RTTY or AM. Tks Tom, DL1JBE * Proper IPV6 and dual stack networking. Bill, G4WJS * Add a new command line option '--no-restore-ai' ('-n') to rigctl. Bill, G4WJS * Fix missing PKTUSB mode setting code for FT-817 & FT-897. Bill, G4WJS * New Prosistel rotor backend from IZ7CRX * Install daemon man files to man1. Nate, N0NB * Migrate from libusb-0.1 to libusb-1.0. Stephane, F8CFE * Added support for Icom IC-2730. robinolejnik * Added support for the Icom IC-7300. Mike, W9MDB * Add send_morse to icom rigs. Mike, W9MDB * added instructions how to compile on OSX. DH1TW * New Perseus model. Stephane, F8CFE * Added Lua binding and demo script. Ervin, HA2OS * Added test to support Flex 6300. Bill, KB4AAA * Many bug fixes and feature enhancements to the code base. See the Git commit log for complete details. Version 3.0 2015-09-20 * Kill RPC backends and rpc.rigd/rpc.rotd * Remove -e|--end-marker option from rigctld and rotctld * Build system updates--remove obsolete macros, autogen.sh now runs autoreconf to invoke Autotools to bootstrap the build system, libltdl is installed into the source tree as a part of the build system bootstrap and is included in the source tarball, ABI version is set to be compatible with the 1.2 series, all Autotools installed files are copied rather than symlinked and put in the build-aux directory, building rigmem and rigmatrix are now user selectable at configure run time, building static libraries are disabled by default. Fixed TCL binding installation, fixed Perl binding build so it is not invoked by 'make dist' and clean up build files. Cleaned up bindings builds to occur in alphabetical order. Use new ax_pkg_swig macro and update ax_python_devel macro. Test for presence of pkg-config before testing for pkg-config use. * Implement new RIT/XIT activation/deactivation through rig_get/set_func() * IC-PCR1500/2500 default write_delay to 0, IC-746/756, IC-PCR8500 fixes, pcr.c, pcr1500.c: Add DSP support. TNX Paul, KE7ZZ * WinRadio G313 updates. TNX Julian Campbel * Readline editing and history support added to rigctl interactive mode. Implement options for reading and writing history file. * Readline editing and history support added to rotctl interactive mode. Implement options for reading and writing history file. * A new manual draft written in Texinfo added. Both GNU Info and single HTML files are built and distributed, requires makeinfo. * Android build system support. See android/README.android. Android Makefile fragments are included in source tarballs. * Monolithic library, thanks to Remi Chateauneu for the majority of the work! This allows enabling of a single static library so static libs are enabled by default. Removes dependency on libltdl. * Fixes to easycomm, TNX Steve AI4QR. * Fixes to port handling allowing PTT and CAT on the same port. TNX Bill, G4WJS. * New Peaberry models V1 and V2 added to kit backend. TNX ON8VQ and R2AEE. * New IC-7100 model. TNX Martin, CT1IQI. * Use AC_CHECK_LIB macro to search for libusb rather than rely on pkg-config. Preserve environment variables LIBUSB_CFLAGS and LIBUSB_LIBS as user precious variables. Two features, --with-xml-support and --enable-usrp still rely on pkg-config so only invoke pkg-config when either or both of these features are selected. Only the Winradio g313 model uses libdl so test for it only when Winradio backend is enabled. * New IC-M700PRO, IC-M710, IC-M802. * New Icom ID-5100 model. * New rotor, cnctrk by KI4SBL * Many backend fixes and updates from many contributors (see Git log for complete details). Version 1.2.15.3 2012-11-01 * Fix configure.ac so that rigctld/rotcld work on Win32 platform * Add NSIS script to build executable installer on Win32 platform * Remove unsupported commands on IC-756 (non-Pro model) from AK6I * Fix set_split in netrigctl.c to properly accept the split value. TNX, N2ADR. * IC-R8500: Add RIG_LEVEL_AF to has_set_level. TNX John, EI7IG * ADAT updates from Frank, DG1SBG, needed for stable operation. Version 1.2.15.2 2012-08-05 * Read eeprom value for digital mode from FT-857 * Clean up TS-950 series commands and read mode using IF command * Fix GS-232A/B rotor command terminations * Fix warnings and other issues found by mingw-w64 * Allow seamless access to ports higher than COM9 on Windows * Fix ineffective packed attribute on WinRadio * Correct low signal strength S-meter error on AR7030+ * Updates to HiQSDR by Jim, N2ADR Version 1.2.15.1 2012-03-11 * HD-1780 rotor endpoint limit fix * Quell adat compile warnings * Sort rig/rot list output from rig/rotctl (-l) by model # * TenTec Jupiter (TT538) fixes * Include various backend notes files * Document sorted -l output for ctl[d] * Updates README.betatester and README.developer Version 1.2.15 2012-02-02 * New models: TT-599 Eagle, IC-RX7, IC-1275, HiQSDR, ADAT ADT-200A, DttSP UDP, TM-D710 * New rotator backends: Celestron (telescope mount) * Fixes and features: K3, various other rigs * Update LGPL/GPL header boilerplate * Quell various compiler errors * Add CM108 PTT capability Version 1.2.14 2011-08-01 * New models: SigFox Transfox, TH-D72A, IC-7410, IC-9100, IC-R9500, KX3, V4L2 API support (untested), * New rotator backends: IF-100, TS-7400 * Fixes and features: K3/KX3, Build Win32 from script, rigctld/rotctld ported to Mingw32, Win32 build fixes, remove obsolete bundled libtool files, rigctl improvements, FUNcube string test (works with V0.0 and V1.0), Yaesu newcat.c fixed to use rig->state.current_vfo to store vfo value, add a command to halt rigctld, select PTT source in Kenwood backends (TS-590S), make sure scan is stopped at IC-9000 opening, thd72 get channel data (alpha). See ChangeLog for a link to the online log. Correct typos and SF.net URIs. Version 1.2.13.1 * 2011-05-29 * Conversion to Git SCM and updated README documentation for Git SCM * Mingw32 build fixes * FUNcube dongle USB fixes for Win32 * Added kit/README.funcubedongle * Bug fix--K3 antenna selection function Version 1.2.13 2011-03-12 * New models: VX-1700, FUNcube Dongle, FiFi-SDR, KTH-SDR Si570, FT-DX5000, TS-590S, TH-F6A, PRM8060, SR-2200 * Rotor fixes and features: SPID * New Rotor backend: F1TE Tracker * Fixes and features: TS-440S, K2, K3, THF6A, THF7E, NewCAT rigs serial port defaults, TM-D700, FT-950, Si570 AVR-USB * Removed libtool tree from source tree * Removed old DocBook files * Allow USB device's VID/PID/Vendor/Product to be explicitly specified * Doxygen documentation updates and new style sheet Version 1.2.12 2010-09-03 * New models: PCR-2500, RX331, TRP 8255 S R * New rotator backends: DF9GR's ERC * Fixes and features: Paragon, TS-690S, FT-920, FT-990, FT-2000, Elektor SDR-USB, IC-7000, IC-7700, AR-8200, AR-8600 Version 1.2.11 2010-05-31 * New models: RA-3702, IC-738, IC-7600, IC-7700, AR 7030+, FT-980, TT-536 Delta-II, R&S EB200 * New rotator backends: GS-232B, GS-232 (not A or B), ARS RCI, M2 RC2800 * Fixes and features: TH-F7E, FT-847, FT-736, FT-920, FT767GX, FT-747, FT-950, FT-450, Yaesu NewCAT, PCR*, IC-706MkIIG, IC-7800, R-8A, Paragon * rigctld/rotctld * ltdl security update * IPv6 ready * bindings not built by default Version 1.2.10 2009-11-02 * New models: IC-7200, PCR-1500, RX-340, R&S ESMC, BC898T, Si570 AVR-USB, Paragon (skeleton) * New rotator backend: SPID * Fixes and features: TH-F7E, K2, FT-920, Yaesu NewCAT, IC-7000, IC-7800, IC-910, IC-718, IC-756PROIII, Tentec Orion, Jupiter, RX320, AOR-8000, PCR-1000, Video4Linux, all the kenwood backends, GS-232A * ABI version in backend symbols * expose PTT/DCD setup through rig_set_conf() * Parallel port PTT now following cwdaemon (STROBE+INIT) interface * bindings * ltdl update Version 1.2.9 2009-02-25 * New models: FT2000, FT9000, TT-588 Omni VII, FT-840, NRD525, Winradio G305, TRC-80 * New rotator backend: Heathkit HD 1780 Intellirotor * Fixes and features: IC-706*, IC-910, K2, K3, DWT, PCR-100, PCR-1000, RX-320, FT-450, FT-747, FT-817, FT-847, FT-857, FT-990, FT-1000D, Orion, netrot, Rotor-EZ, dummy rig and dummy rotator * Bug fix in qrb() * Better assisted split operation * ext_level/ext_parm examples * Documentation update Version 1.2.8 2008-11-02 * New models: BC235, BC250, BC780, PRO-2052, BCD396T, BCD996T, K3, FT950 * New pseudo models: netrigctl/netrotctl, backends ala rpcrig/rpcrot, but based on rigctld/rotctld * New rotator backend: GS232A, PcRotor * Removed microtune backend * Fixes: DttSP, IC-275, IC-475, IC-725, IC-735, IC-756PRO, IC-761, IC-775, IC-781, IC-706*, Kenwood TH/TM models, Orion, BC245, BC895, FT-100, FT757GX, FT-857, FT-897, FT-920 * Numerous bindings fixes, esp. for memory channel works * New commands available in rigctl * New rotctld to go with rigctld rig daemon. The protocol changed, but there's the compatibility option -e to pass to the daemon for previous protocol. Version 1.2.7.1 2008-04-11 * New model: miniVNA * Fixes: FT1000MP, Tentec Orion, Omni VI Plus * AOR: implemented scanning * Kenwood models TS2000, TS870S can now get/set antenna. TS2000 gained strength meter calibration. Version 1.2.7 2008-02-13 * Improved Documentation * New models: IC-820H, DttSP, Elektor SDR-USB, DDS-60, FT-450, FT-767GX * Fixes: IC-746, IC-765, IC-910, Kenwood, FT1000MP, FT817, .. * New rigsmtr toy to graph polar signal strength * New experimental rigctld rig daemon, with simple protocol Version 1.2.6.2 * Fixes: TS570 (Split, RIT/XIT), IC910H * Improved Tentec Orion,RX-320 functionality * Improved Winradio G-313 * Better man pages Version 1.2.6.1 * Icom protocol fixes * bindings build fixing Version 1.2.6 2006-12-22 * Bump version to 1.2.6 * no changes from 1.2.6rc1 Version 1.2.6rc1 2006-12-10 * Python 2.4 compatibility * Improved TS570 functionality * Improved Argonaut V functionality * New models: IC7000, G313i/G313e * Many Icom, Kenwood, and Tentec fixes. * Build system fixes Version 1.2.5 2006-02-26 * frontend API: support for clonable rigs - rigmem: CSV format change - rigctl: new send_cmd for protocol debugging purpose - easy USB devices support * new models: AR8600, AR2700, DWT (DLL based under Windows, need test under other OS) * fixes: big AOR update, AR7030, Orion, NRD-545, RX-320, FT-817, FT-990, TS-2000, Easycomm * port: BSD fix of parallel port support Version 1.2.4 2005-04-03 * frontend API: port_t renamed as hamlib_port_t * new models: TS-480, VR5000, FT1000MkV Fld * fixes: TS-570S, AR7030, AR3000A, Orion, FT-897, IC746 * port: fixed 64bit int handling which potentially fixes backends kenwood/alinco/pcr/uniden/aor/jrc/tentec, added xBSD parallel port support Version 1.2.3 2004-11-17 * frontend API: LEVEL_SQLSTAT marked as deprecated * new backends: Racal, V4L radio cards, Watkins-Johnson 8888 * new models: IC-78, IC-7800, IC-R20, IC-756PROIII * fixes: AOR 5k&8k: added S-Meter, 7030: fixed freq, IC-R8500: calibrated S-Meter, Jupiter and many others.. * port: mingw32 support with gcc 3.4 version Version 1.2.2 2004-08-23 * new models: Ten-Tec (Orion), AOR 3030, Yaesu FRG's, Skanti * fixes: JRC NRD435 & NRD535, Drake, AOR3000, and many other * port: Fixes for BRK/RTS/DTR handling under win32 (-> Elektor304) * bindings: updated Visual Basic wrapper file * rigswr: new command to measure VSWR vs frequency Version 1.2.1 2004-05-19 * API change: added RIG_AGC_MEDIUM enum * new backends: kit (Elektor304) * new models: Winradio (G303 under Win32), Kenwood (TMD700,R5000,..), Yaesu(FT757GX,FRG8800), Ten-Tec (Jupiter,RX340,RX350) * fixes: JRC NRD435 & NRD535, and many other * port: made rig.h more Visual C++ friendly, along an import lib Version 1.2.0 2004-02-16 * API change: - freq_t type changed from long long to double - setting_t changed from long long to long int. - locator and dec/dms interface rework - bump library CURRENT version info * new backends: Lowe (HF-235), FlexRadio (SDR-1000), skeleton TAPR (DSP-10), skeleton RFT, Ten-Tec models and many new models & fixes * new rotator backends: sartek * frontend: emulated transceive mode using polling * icom: implemented retry, esp. useful for CI-V * icom: pipelined tuning on Optoscan's * microtune: no need of root privileges anymore * bindings: added Python, new install method (perl is installed in $prefix) * rigmem: new command to load/store memory content from/to XML file * port: NetBSD & FreeBSD, mingw32(Windows) port, MacOSX ready Version 1.1.4 2003-04-28 * new backends: Drake (R8B), GNU Radio (experimental), microtune, and many new rig models * new rotator backends: fodtrack, rotorez * better doxygenized documentation * reworked perl and tcl bindings using swig * vfo_t rework * gcc-3.x compilance Version 1.1.3 2002-06-17 * new backend: JRC (NRD-545), and many new rig models * rotator frontend, new easycomm backend * added Kylix and perl bindings and completed tcl/tk support * networked (RPC) rig and rotator Version 1.1.2 2001-09-23 * License converted to LGPL * new backends: Alinco (DX-77), Uniden (BC895), Ten-Tec (RX320), Kachina (505DSP) * New port_t design, coming with easy rig auto-probe * mv_ctl replaced by vfo_op, set_vfo/get_vfo extended to RIG_VFO_MEM * set_conf/get_conf for opaque variable parameters setting * Better portability, esp. with libtool (DLL dlopen'ing works under Win32 !) * added C++ and tcl/tk bindings (not complete yet) * converted from hamlib-doc to doxygen in-source interface documenting Version 1.1.1 2001-05-26 * new backends: Kenwood (TS870S), WiNRADiO, PCR-1000, Dummy (for tests) * Hamlib frontend will take care of backends that can't target VFO. * Extended API: caps, levels, parms, etc. * rig_set_mode/rig_get_mode changed again, now use filter caps * more fields shadowed in rig->state, etc. * rigctl now works also non-interactively * get_channel/set_channel can be emulated and new dumpmem utility * will not compile on pure ANSI C compiler, because of gcc struct extension Version 1.1.0 2000-11-11 * First draft of a generic API, abstracting radios differences behind a set of capabilities. * Hamlib is (somewhat) conform to GNU coding standards, and so it uses configure script generated by Automake and Autoconf * Included hamlib-doc system to generate man pages, API references in html format. * 2 new backends: Icom (CI-V) with IC706 series, and AOR (AR8200) Version 1.0.0 Initial release. ------------------------------------------------------- Copying information: This file is licensed to you under the license specified in the included file `LICENSE'. Look there for further details. hamlib-4.6.5/rigs/0000775000175000017500000000000015056640501007473 5hamlib-4.6.5/rigs/racal/0000775000175000017500000000000015056640477010571 5hamlib-4.6.5/rigs/racal/ra37xx.h0000664000175000017500000000642015056640443012011 /* * Hamlib Racal backend - RA37XX header * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RA37XX_H #define _RA37XX_H 1 #include "hamlib/rig.h" #include "racal.h" #undef BACKEND_VER #define BACKEND_VER "20210911" extern const struct confparams ra37xx_cfg_params[]; /* Packet timeout at Master port, 5-9 */ #define RA37XX_TIMEOUT 1000 /* ms */ #define RA37XX_STR_CAL { 13, \ { \ { 97, 86 }, /* 120 dBuV */ \ { 109, 76 }, /* 110 dBuV */ \ { 120, 66 }, /* 100 dBuV */ \ { 132, 56 }, /* 90 dBuV */ \ { 144, 46 }, /* 80 dBuV */ \ { 155, 36 }, /* 70 dBuV */ \ { 167, 26 }, /* 60 dBuV */ \ { 179, 16 }, /* 50 dBuV */ \ { 190, 6 }, /* 40 dBuV */ \ { 202, -4 }, /* 30 dBuV */ \ { 214, -14 }, /* 20 dBuV */ \ { 225, -24 }, /* 10 dBuV */ \ { 255, -34 }, /* 0 dBuV */ \ } } #define RA37XX_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_CWPITCH, \ /* .flags = 1, */ \ } struct ra37xx_priv_data { int receiver_id; }; int ra37xx_set_conf(RIG *rig, hamlib_token_t token, const char *val); int ra37xx_get_conf(RIG *rig, hamlib_token_t token, char *val); int ra37xx_init(RIG *rig); int ra37xx_cleanup(RIG *rig); int ra37xx_open(RIG *rig); int ra37xx_close(RIG *rig); int ra37xx_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ra37xx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ra37xx_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ra37xx_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ra37xx_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ra37xx_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ra37xx_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ra37xx_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char* ra37xx_get_info(RIG *rig); int ra37xx_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int ra37xx_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int ra37xx_set_mem(RIG *rig, vfo_t vfo, int ch); int ra37xx_get_mem(RIG *rig, vfo_t vfo, int *ch); int ra37xx_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int ra37xx_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); #endif /* _RA37XX_H */ hamlib-4.6.5/rigs/racal/ra6790.c0000664000175000017500000000752715056640443011611 /* * Hamlib Racal backend - RA6790 description * Copyright (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "racal.h" /* FIXME: ISB */ #define RA6790_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AMS|RIG_MODE_FM) #define RA6790_FUNC (RIG_FUNC_NONE) #define RA6790_LEVEL_ALL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF) #define RA6790_PARM_ALL (RIG_PARM_NONE) #define RA6790_VFO (RIG_VFO_A) /* * ra6790 rig capabilities. * * Required A6A1 serial asynchronous interface * */ struct rig_caps ra6790_caps = { RIG_MODEL(RIG_MODEL_RA6790), .model_name = "RA6790/GM", .mfg_name = "Racal", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 7, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 10, .timeout = 2000, .retry = 3, .has_get_func = RA6790_FUNC, .has_set_func = RA6790_FUNC, .has_get_level = RA6790_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(RA6790_LEVEL_ALL), .has_get_parm = RA6790_PARM_ALL, .has_set_parm = RIG_PARM_SET(RA6790_PARM_ALL), .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(8), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 1, RA6790_MODES, -1, -1, RA6790_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 1, RA6790_MODES, -1, -1, RA6790_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RA6790_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* at -3dB */ {RIG_MODE_SSB, kHz(2.55)}, /* BW2 */ {RA6790_MODES, Hz(300)}, /* BW1 */ {RA6790_MODES, kHz(1)}, /* BW2 */ {RA6790_MODES, kHz(3.2)}, /* BW3 */ {RA6790_MODES, kHz(6)}, /* BW4 */ {RA6790_MODES, kHz(20)}, /* BW5 */ {RA6790_MODES, 0}, /* accept any BW */ RIG_FLT_END, }, .cfgparams = racal_cfg_params, .rig_init = racal_init, .rig_cleanup = racal_cleanup, .rig_open = racal_open, .rig_close = racal_close, .set_conf = racal_set_conf, .get_conf = racal_get_conf, .set_freq = racal_set_freq, .get_freq = racal_get_freq, .set_mode = racal_set_mode, .get_mode = racal_get_mode, .set_level = racal_set_level, .get_level = racal_get_level, .reset = racal_reset, .get_info = racal_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/racal/ra37xx.c0000664000175000017500000004474715056640443012022 /* * Hamlib Racal backend - RA37XX main file * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "ra37xx.h" const struct confparams ra37xx_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID, -1 to disable addressing", "-1", RIG_CONF_NUMERIC, { .n = { -1, 9, 1 } } }, { RIG_CONF_END, NULL, } }; /* packet framing, 5-8 */ #define BUFSZ 256 #define SOM "\x0a" /* LF */ #define EOM "\x0d" /* CR */ /* * modes */ #define MD_USB 1 #define MD_LSB 2 #define MD_AM 3 #define MD_FM 4 #define MD_CW 5 #define MD_FSK 6 /* option */ #define MD_ISB_USB 7 #define MD_ISB_LSB 8 #define MD_FSK_NAR 13 /* option */ #define MD_FSK_MED 14 /* option */ #define MD_FSK_WID 15 /* option */ /* * retries are handled by ra37xx_transaction() */ static int ra37xx_one_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { const struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ]; char respbuf[BUFSZ]; int retval; int pkt_header_len; struct timeval tv; gettimeofday(&tv, NULL); /* Packet Framing: - no Link Control Character - (optional) 1 Address Character - no Check Character */ if (priv->receiver_id != -1) { pkt_header_len = 2; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%d%s" EOM, priv->receiver_id, cmd); } else { pkt_header_len = 1; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%s" EOM, cmd); } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { return retval; } /* forward COMMAND frame? no data expected */ if (!data || !data_len) { return retval; } do { retval = read_string(rp, (unsigned char *) respbuf, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } /* drop short/invalid packets */ if (retval <= pkt_header_len + 1 || respbuf[0] != '\x0a') { if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_EPROTO; } } /* drop other receiver id, and "pause" (empty) packets */ if ((priv->receiver_id != -1 && (respbuf[1] - '0') != priv->receiver_id)) { if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_ETIMEOUT; } } if (retval >= pkt_header_len + 3 && !memcmp(respbuf + pkt_header_len, "ERR", 3)) { return -RIG_ERJCTED; } if (retval >= pkt_header_len + 5 && !memcmp(respbuf + pkt_header_len, "FAULT", 5)) { return -RIG_ERJCTED; } if (cmd[0] == 'Q' && (retval + pkt_header_len + 1 < strlen(cmd) || cmd[1] != respbuf[pkt_header_len])) { rig_debug(RIG_DEBUG_WARN, "%s: unexpected revertive frame\n", __func__); if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_ETIMEOUT; } } } while (retval < 0); /* Strip starting LF and ending CR */ memcpy(data, respbuf + pkt_header_len, retval - pkt_header_len - 1); *data_len = retval; return RIG_OK; } static int ra37xx_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { int retval, retry; retry = RIGPORT(rig)->retry; do { retval = ra37xx_one_transaction(rig, cmd, data, data_len); if (retval == RIG_OK) { break; } } while (retry-- > 0); return retval; } int ra37xx_init(RIG *rig) { struct ra37xx_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ra37xx_priv_data *)calloc(1, sizeof( struct ra37xx_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = -1; return RIG_OK; } /* */ int ra37xx_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int ra37xx_set_conf2(RIG *rig, hamlib_token_t token, const char *val, int val_len) { struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *)STATE(rig)->priv; int receiver_id; switch (token) { case TOK_RIGID: receiver_id = atoi(val); if (receiver_id < -1 || receiver_id > 9) { return -RIG_EINVAL; } priv->receiver_id = receiver_id; break; default: return -RIG_EINVAL; } return RIG_OK; } int ra37xx_set_conf(RIG *rig, hamlib_token_t token, const char *val) { return ra37xx_set_conf2(rig, token, val, 128); } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int ra37xx_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *) STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%d", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int ra37xx_get_conf(RIG *rig, hamlib_token_t token, char *val) { return ra37xx_get_conf2(rig, token, val, 128); } /* * ra37xx_open * Assumes rig!=NULL */ int ra37xx_open(RIG *rig) { /* Set Receiver to remote control */ return ra37xx_transaction(rig, "REM1", NULL, NULL); } /* * ra37xx_close * Assumes rig!=NULL */ int ra37xx_close(RIG *rig) { /* Set Receiver to local control */ return ra37xx_transaction(rig, "REM0", NULL, NULL); } /* * ra37xx_set_freq * Assumes rig!=NULL */ int ra37xx_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%lu", (unsigned long)freq); return ra37xx_transaction(rig, freqbuf, NULL, NULL); } int ra37xx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; int retval, len; double f; retval = ra37xx_transaction(rig, "QF", freqbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(freqbuf + 1, "%lf", &f); *freq = (freq_t)f; return RIG_OK; } /* * ra37xx_set_mode * Assumes rig!=NULL */ int ra37xx_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { //struct ra37xx_priv_data *priv = (struct ra37xx_priv_data*)STATE(rig)->priv; int ra_mode, widthtype, widthnum = 0; char buf[BUFSZ]; switch (mode) { case RIG_MODE_CW: widthtype = 1; ra_mode = MD_CW; break; case RIG_MODE_CWR: widthtype = 2; ra_mode = MD_CW; break; case RIG_MODE_USB: widthtype = 1; ra_mode = MD_USB; break; case RIG_MODE_LSB: widthtype = 2; ra_mode = MD_LSB; break; case RIG_MODE_AM: widthtype = 3; ra_mode = MD_AM; break; case RIG_MODE_FM: widthtype = 3; ra_mode = MD_FM; break; case RIG_MODE_RTTY: widthtype = 3; ra_mode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width == RIG_PASSBAND_NORMAL) { rig_passband_normal(rig, mode); } rig_debug(RIG_DEBUG_TRACE, "%s: widthtype = %i, widthnum = %i not implemented\n", __func__, widthtype, widthnum); #ifdef XXREMOVEDXX widthtype = 0; /* FIXME: no bandwidth for now */ widthnum = 0; /* width set using 'B', QBCON must be queried firsthand */ #endif #ifdef XXREMOVEDXX SNPRINTF(buf, sizeof(buf), "M%d;B%d,%d", ra_mode, widthtype, widthnum); #else SNPRINTF(buf, sizeof(buf), "M%d", ra_mode); #endif return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ], resbuf[BUFSZ]; int retval, len, ra_mode, widthtype, widthnum; retval = ra37xx_transaction(rig, "QM", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 1, "%d", &ra_mode); switch (ra_mode) { case MD_CW: widthtype = 1; *mode = RIG_MODE_CW; break; case MD_ISB_LSB: case MD_LSB: widthtype = 2; *mode = RIG_MODE_LSB; break; case MD_ISB_USB: case MD_USB: widthtype = 1; *mode = RIG_MODE_USB; break; case MD_FSK_NAR: case MD_FSK_MED: case MD_FSK_WID: case MD_FSK: widthtype = 3; *mode = RIG_MODE_RTTY; break; case MD_FM: widthtype = 3; *mode = RIG_MODE_FM; break; case MD_AM: widthtype = 3; *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(*mode)); return -RIG_EPROTO; } retval = ra37xx_transaction(rig, "QB", resbuf, &len); if (retval != RIG_OK) { return retval; } /* FIXME */ widthnum = 0; SNPRINTF(buf, sizeof(buf), "QBCON%d,%d", widthtype, widthnum); retval = ra37xx_transaction(rig, buf, resbuf, &len); if (retval != RIG_OK) { return retval; } /* TODO: width */ *width = 0; return RIG_OK; } int ra37xx_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; switch (func) { case RIG_FUNC_MUTE: SNPRINTF(cmdbuf, sizeof(cmdbuf), "MUTE%d", status ? 1 : 0); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return ra37xx_transaction(rig, cmdbuf, NULL, NULL); } int ra37xx_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char resbuf[BUFSZ]; int retval, len, i; switch (func) { case RIG_FUNC_MUTE: retval = ra37xx_transaction(rig, "QMUTE", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 4, "%d", &i); *status = i == 0 ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * ra37xx_set_level * Assumes rig!=NULL */ int ra37xx_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[BUFSZ]; int agc; switch (level) { case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AFL%d", (int)(val.f * 255)); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "RFAMP%d", val.i ? 1 : 0); break; case RIG_LEVEL_CWPITCH: /* BFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "BFO%d", val.i); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "CORL%d", (int)(val.f * 255)); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d", (int)(val.f * 255)); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = 0; break; case RIG_AGC_MEDIUM: agc = 1; break; case RIG_AGC_SLOW: agc = 2; break; case RIG_AGC_USER: agc = 0; break; default: return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "AGC%d,%d", val.i == RIG_AGC_USER ? 1 : 0, agc); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return ra37xx_transaction(rig, cmdbuf, NULL, NULL); } /* * ra37xx_get_level * Assumes rig!=NULL */ int ra37xx_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char resbuf[BUFSZ]; int retval, len, i; switch (level) { case RIG_LEVEL_AF: retval = ra37xx_transaction(rig, "QAFL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_CWPITCH: retval = ra37xx_transaction(rig, "QBFO", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &val->i); break; case RIG_LEVEL_PREAMP: retval = ra37xx_transaction(rig, "QRFAMP", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 5, "%d", &i); val->i = i ? STATE(rig)->preamp[0] : 0; break; case RIG_LEVEL_RAWSTR: retval = ra37xx_transaction(rig, "QRFL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &val->i); break; case RIG_LEVEL_SQL: retval = ra37xx_transaction(rig, "QCORL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 4, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_RF: retval = ra37xx_transaction(rig, "QG", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 1, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_AGC: retval = ra37xx_transaction(rig, "QAGC", resbuf, &len); if (retval != RIG_OK) { return retval; } if (resbuf[3] != '0') { val->i = RIG_AGC_USER; break; } switch (resbuf[5]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; default: return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } const char *ra37xx_get_info(RIG *rig) { static char infobuf[BUFSZ]; int res_len, retval; retval = ra37xx_transaction(rig, "QID", infobuf, &res_len); if (retval != RIG_OK || res_len < 2 || res_len >= BUFSZ) { return NULL; } infobuf[res_len] = '\0'; /* TODO: "QSW"? c.f. 5-43 */ /* skip "ID" */ return infobuf + 2; } int ra37xx_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char buf[BUFSZ]; int i_ant; switch (ant) { case RIG_ANT_1: i_ant = 1 << 0; break; case RIG_ANT_2: i_ant = 1 << 1; break; case RIG_ANT_3: i_ant = 1 << 2; break; case RIG_ANT_4: i_ant = 1 << 3; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported ant %#x", ant); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "ANT%d", i_ant); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char buf[BUFSZ]; int retval, buflen, ra_ant; retval = ra37xx_transaction(rig, "QANT", buf, &buflen); if (retval != RIG_OK) { return retval; } sscanf(buf + 3, "%d", &ra_ant); if (ra_ant < 0 || ra_ant > 15) { return -RIG_EPROTO; } *ant_curr = ((ra_ant & (1 << 0)) ? RIG_ANT_1 : 0) | ((ra_ant & (1 << 1)) ? RIG_ANT_2 : 0) | ((ra_ant & (1 << 2)) ? RIG_ANT_3 : 0) | ((ra_ant & (1 << 3)) ? RIG_ANT_4 : 0); return RIG_OK; } int ra37xx_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[BUFSZ]; /* NB: does a RIG_OP_TO_VFO!*/ SNPRINTF(buf, sizeof(buf), "CHAN%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_mem(RIG *rig, vfo_t vfo, int *ch) { char buf[BUFSZ]; int retval, buflen; retval = ra37xx_transaction(rig, "QCHAN", buf, &buflen); if (retval != RIG_OK) { return retval; } *ch = atoi(buf + 4); return RIG_OK; } int ra37xx_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char buf[BUFSZ]; int scantype; switch (scan) { case RIG_SCAN_STOP: scantype = 0; break; case RIG_SCAN_VFO: scantype = 1; break; case RIG_SCAN_MEM: scantype = 2; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported scan %#x", scan); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "SCAN%d,0", scantype); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[BUFSZ]; int ret, ch; switch (op) { case RIG_OP_FROM_VFO: ret = rig_get_mem(rig, vfo, &ch); if (ret < 0) { return ret; } SNPRINTF(buf, sizeof(buf), "STRE%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); case RIG_OP_TO_VFO: ret = rig_get_mem(rig, vfo, &ch); if (ret < 0) { return ret; } SNPRINTF(buf, sizeof(buf), "CHAN%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported op %#x", op); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/racal/racal.c0000664000175000017500000002716515056640443011743 /* * Hamlib Racal backend - main file * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "token.h" #include "racal.h" const struct confparams racal_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 99, 1 } } }, { RIG_CONF_END, NULL, } }; #define BUFSZ 32 #define SOM "$" #define EOM "\x0d" /* CR */ /* * modes */ #define MD_AM 1 #define MD_FM 2 #define MD_MCW 3 /* variable BFO */ #define MD_CW 4 /* BFO center */ #define MD_ISB 5 /* option */ #define MD_LSB 6 #define MD_USB 7 /* * racal_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * * TODO: Status Response handling with G/T commands */ static int racal_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ + 1]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%u%s" EOM, priv->receiver_id, cmd); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return retval; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval <= 0) { return retval; } /* strip CR from string */ if (data[retval - 1] == '\x0d') { data[--retval] = '\0'; /* chomp */ } *data_len = retval; return RIG_OK; } int racal_init(RIG *rig) { struct racal_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct racal_priv_data *)calloc(1, sizeof( struct racal_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = 0; priv->bfo = 0; priv->threshold = 0; return RIG_OK; } /* */ int racal_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int racal_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int racal_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int racal_get_conf(RIG *rig, hamlib_token_t token, char *val) { return racal_get_conf2(rig, token, val, 128); } /* * racal_open * Assumes rig!=NULL */ int racal_open(RIG *rig) { /* Set Receiver to remote control * * TODO: Perform the BITE routine (1mn!) at each open? * TODO: "S5" request values of IF bandwidth filters found? */ return racal_transaction(rig, "S2", NULL, NULL); } /* * racal_close * Assumes rig!=NULL */ int racal_close(RIG *rig) { /* Set Receiver to local control */ return racal_transaction(rig, "S1", NULL, NULL); } /* * racal_set_freq * Assumes rig!=NULL */ int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%0g", (double)(freq / MHz(1))); return racal_transaction(rig, freqbuf, NULL, NULL); } int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; int retval, len; double f; retval = racal_transaction(rig, "TF", freqbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || freqbuf[0] != 'F') { return -RIG_EPROTO; } sscanf(freqbuf + 1, "%lf", &f); *freq = (freq_t)f * MHz(1); return RIG_OK; } /* * racal_set_mode * Assumes rig!=NULL */ int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; int ra_mode; char buf[BUFSZ]; switch (mode) { case RIG_MODE_CW: ra_mode = (priv->bfo != 0) ? MD_MCW : MD_CW; break; case RIG_MODE_USB: ra_mode = MD_USB; break; case RIG_MODE_LSB: ra_mode = MD_LSB; break; case RIG_MODE_AM: ra_mode = MD_AM; break; case RIG_MODE_AMS: ra_mode = MD_ISB; break; /* TBC */ case RIG_MODE_FM: ra_mode = MD_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } SNPRINTF(buf, sizeof(buf), "D%dI%.0f", ra_mode, (double)(width / kHz(1))); } else { SNPRINTF(buf, sizeof(buf), "D%d", ra_mode); } return racal_transaction(rig, buf, NULL, NULL); } int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char resbuf[BUFSZ], *p; int retval, len; double f; retval = racal_transaction(rig, "TDI", resbuf, &len); if (retval < RIG_OK) { return retval; } p = strchr(resbuf, 'I'); if (len < 3 || resbuf[0] != 'D' || !p) { return -RIG_EPROTO; } switch (resbuf[1] - '0') { case MD_MCW: case MD_CW: *mode = RIG_MODE_CW; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_ISB: *mode = RIG_MODE_AMS; break; /* TBC */ case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(*mode)); return -RIG_EPROTO; } sscanf(p + 1, "%lf", &f); *width = (pbwidth_t)(f * kHz(1)); return RIG_OK; } /* * racal_set_level * Assumes rig!=NULL */ int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; char cmdbuf[BUFSZ]; int agc; switch (level) { case RIG_LEVEL_RF: /* Manually set threshold */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d", (int)(val.f * 120)); priv->threshold = val.f; break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%+0g", ((double)val.i) / kHz(1)); priv->bfo = val.i; break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_SLOW: agc = 3; break; case RIG_AGC_USER: agc = 4; break; default: return -RIG_EINVAL; } if (priv->threshold != 0 && agc != 4) { agc += 4; /* with manually set threshold */ } SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%d", agc); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return racal_transaction(rig, cmdbuf, NULL, NULL); } /* * racal_get_level * Assumes rig!=NULL */ int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; char resbuf[BUFSZ]; int retval, len, att; double f; switch (level) { case RIG_LEVEL_RF: /* Manually set threshold */ retval = racal_transaction(rig, "TA", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'A') { return -RIG_EPROTO; } sscanf(resbuf + 1, "%d", &att); val->f = priv->threshold = (float)att / 120; break; case RIG_LEVEL_IF: retval = racal_transaction(rig, "TB", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'B') { return -RIG_EPROTO; } sscanf(resbuf + 1, "%lf", &f); val->i = priv->bfo = (shortfreq_t)(f * kHz(1)); break; case RIG_LEVEL_AGC: retval = racal_transaction(rig, "TM", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'M') { return -RIG_EPROTO; } switch (resbuf[1] - '0') { case 1: case 5: val->i = RIG_AGC_FAST; break; case 2: case 6: val->i = RIG_AGC_MEDIUM; break; case 3: case 7: val->i = RIG_AGC_SLOW; break; case 4: val->i = RIG_AGC_USER; break; default: return -RIG_EINVAL; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int racal_reset(RIG *rig, reset_t reset) { /* Initiate BITE routine, takes 1 minute! */ return racal_transaction(rig, "S3", NULL, NULL); } const char *racal_get_info(RIG *rig) { static char infobuf[64]; char bitebuf[BUFSZ]; char filterbuf[BUFSZ]; int res_len, retval; /* get BITE results */ retval = racal_transaction(rig, "S6", bitebuf, &res_len); if (retval < 0) { return "IO error"; } if (bitebuf[1] == 'O' && bitebuf[2] == 'K') { bitebuf[3] = '\0'; } else { char *p = strstr(bitebuf, "END"); if (p) { *p = '\0'; } } /* get filters */ retval = racal_transaction(rig, "S5", filterbuf, &res_len); if (retval < 0) { strcpy(filterbuf, "IO error"); } SNPRINTF(infobuf, sizeof(infobuf), "BITE errors: %s, Filters: %s\n", bitebuf + 1, filterbuf); return infobuf; } /* * initrigs_racal is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(racal) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ra6790_caps); rig_register(&ra3702_caps); return RIG_OK; } hamlib-4.6.5/rigs/racal/ra3702.c0000664000175000017500000001101015056640443011555 /* * Hamlib Racal backend - RA3702 description * Copyright (c) 2010 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "ra37xx.h" /* TODO: ISB */ #define RA3702_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define RA3702_FUNC (RIG_FUNC_MUTE) #define RA3702_LEVEL_ALL (RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define RA3702_PARM_ALL (RIG_PARM_NONE) #define RA3702_VFO (RIG_VFO_A) #define RA3702_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define RA3702_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_VFO|RIG_SCAN_MEM) /* * ra3702 rig capabilities. * * Required A6A1 serial asynchronous interface * */ struct rig_caps ra3702_caps = { RIG_MODEL(RIG_MODEL_RA3702), .model_name = "RA3702", .mfg_name = "Racal", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 50, .serial_rate_max = 9600, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = RA37XX_TIMEOUT, .retry = 2, .has_get_func = RA3702_FUNC, .has_set_func = RA3702_FUNC, .has_get_level = RA3702_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(RA3702_LEVEL_ALL), .has_get_parm = RA3702_PARM_ALL, .has_set_parm = RIG_PARM_SET(RA3702_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .vfo_ops = RA3702_VFO_OPS, .scan_ops = RA3702_SCAN_OPS, .preamp = { 20, RIG_DBLST_END }, /* FIXME */ .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = RA37XX_STR_CAL, .chan_list = { { 0, 99, RIG_MTYPE_MEM, RA37XX_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(15), MHz(30) - 1, RA3702_MODES, -1, -1, RA3702_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(15), MHz(30) - 1, RA3702_MODES, -1, -1, RA3702_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RA3702_MODES, 1}, {RA3702_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* at -3dB */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.7)}, {RA3702_MODES, kHz(12)}, {RA3702_MODES, kHz(6)}, {RA3702_MODES, Hz(300)}, {RA3702_MODES, kHz(1)}, {RA3702_MODES, kHz(2.7)}, //{RA3702_MODES, 0}, /* accept any BW */ RIG_FLT_END, }, .cfgparams = ra37xx_cfg_params, .rig_init = ra37xx_init, .rig_cleanup = ra37xx_cleanup, .rig_open = ra37xx_open, .rig_close = ra37xx_close, .set_conf = ra37xx_set_conf, .get_conf = ra37xx_get_conf, .set_freq = ra37xx_set_freq, .get_freq = ra37xx_get_freq, .set_mode = ra37xx_set_mode, .get_mode = ra37xx_get_mode, .set_func = ra37xx_set_func, .get_func = ra37xx_get_func, .set_level = ra37xx_set_level, .get_level = ra37xx_get_level, .set_ant = ra37xx_set_ant, .get_ant = ra37xx_get_ant, .set_mem = ra37xx_set_mem, .get_mem = ra37xx_get_mem, .scan = ra37xx_scan, .vfo_op = ra37xx_vfo_op, .get_info = ra37xx_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/racal/racal.h0000664000175000017500000000367715056640443011752 /* * Hamlib Racal backend - main header * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RACAL_H #define _RACAL_H 1 #include "hamlib/rig.h" #include "token.h" #define BACKEND_VER "20200113" #define TOK_RIGID TOKEN_BACKEND(1) extern const struct confparams racal_cfg_params[]; struct racal_priv_data { unsigned receiver_id; int bfo; float threshold; /* attenuation */ }; int racal_set_conf(RIG *rig, hamlib_token_t token, const char *val); int racal_get_conf(RIG *rig, hamlib_token_t token, char *val); int racal_init(RIG *rig); int racal_cleanup(RIG *rig); int racal_open(RIG *rig); int racal_close(RIG *rig); int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int racal_reset(RIG *rig, reset_t reset); const char* racal_get_info(RIG *rig); extern struct rig_caps ra6790_caps; extern struct rig_caps ra3702_caps; #endif /* _RACAL_H */ hamlib-4.6.5/rigs/racal/Android.mk0000664000175000017500000000042315056640443012412 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ra6790.c ra3702.c racal.c ra37xx.c LOCAL_MODULE := racal LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/racal/Makefile.in0000664000175000017500000005350715056640453012562 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/racal ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_racal_la_LIBADD = am__objects_1 = ra6790.lo ra3702.lo ra37xx.lo racal.lo am_libhamlib_racal_la_OBJECTS = $(am__objects_1) libhamlib_racal_la_OBJECTS = $(am_libhamlib_racal_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ra3702.Plo ./$(DEPDIR)/ra37xx.Plo \ ./$(DEPDIR)/ra6790.Plo ./$(DEPDIR)/racal.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_racal_la_SOURCES) DIST_SOURCES = $(libhamlib_racal_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RACALSRC = ra6790.c ra3702.c ra37xx.c ra37xx.h racal.c racal.h noinst_LTLIBRARIES = libhamlib-racal.la libhamlib_racal_la_SOURCES = $(RACALSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/racal/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/racal/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-racal.la: $(libhamlib_racal_la_OBJECTS) $(libhamlib_racal_la_DEPENDENCIES) $(EXTRA_libhamlib_racal_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_racal_la_OBJECTS) $(libhamlib_racal_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra3702.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra37xx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra6790.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/racal.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ra3702.Plo -rm -f ./$(DEPDIR)/ra37xx.Plo -rm -f ./$(DEPDIR)/ra6790.Plo -rm -f ./$(DEPDIR)/racal.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ra3702.Plo -rm -f ./$(DEPDIR)/ra37xx.Plo -rm -f ./$(DEPDIR)/ra6790.Plo -rm -f ./$(DEPDIR)/racal.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/racal/Makefile.am0000664000175000017500000000025215056640443012535 RACALSRC = ra6790.c ra3702.c ra37xx.c ra37xx.h racal.c racal.h noinst_LTLIBRARIES = libhamlib-racal.la libhamlib_racal_la_SOURCES = $(RACALSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/prm80/0000775000175000017500000000000015056640477010455 5hamlib-4.6.5/rigs/prm80/prm8060.c0000664000175000017500000001177415056640443011660 /* * Hamlib PRM80 backend - PRM8060 description * Copyright (c) 2010,2021 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "prm80.h" #define PRM8060_ALL_MODES (RIG_MODE_FM) #define PRM8060_FUNC (RIG_FUNC_REV|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define PRM8060_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER) #define PRM8060_PARM_ALL (RIG_PARM_NONE) // RIG_OP_FROM_VFO RIG_OP_MCL ?? #define PRM8060_VFO_OPS (RIG_OP_NONE) #define PRM8060_VFO (RIG_VFO_MEM) // Calibration done on PRM8070 #define PRM8060_STR_CAL { 15, \ { \ { 0x14, -54 }, /* S0 */ \ { 0x1D, -48 }, /* S1 */ \ { 0x26, -42 }, /* S2 */ \ { 0x33, -36 }, /* S3 */ \ { 0x3F, -30 }, /* S4 */ \ { 0x4D, -24 }, /* S5 */ \ { 0x55, -18 }, /* S6 */ \ { 0x61, -12 }, /* S7 */ \ { 0x68, -6 }, /* S8 */ \ { 0x6C, 0 }, /* S9 */ \ { 0x81, 10 }, /* +10 */ \ { 0x8B, 20 }, /* +20 */ \ { 0x8C, 40 }, /* +40 */ \ { 0x8C, 50 }, /* +50 */ \ { 0xFF, 60 } /* +60 */ \ } } /* * PRM 8060 rig capabilities. * http://prm80.sourceforge.net/ * https://github.com/f4fez/prm80 */ struct rig_caps prm8060_caps = { RIG_MODEL(RIG_MODEL_PRM8060), .model_name = "PRM8060", .mfg_name = "Philips/Simoco", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = PRM8060_FUNC, .has_set_func = PRM8060_FUNC, .has_get_level = PRM8060_LEVEL_ALL | RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_SET(PRM8060_LEVEL_ALL), .has_get_parm = PRM8060_PARM_ALL, .has_set_parm = RIG_PARM_SET(PRM8060_PARM_ALL), .vfo_ops = PRM8060_VFO_OPS, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, PRM80_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146) - kHz(12.5), PRM8060_ALL_MODES, -1, -1, PRM8060_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146) - kHz(12.5), PRM8060_ALL_MODES, W(5), W(25), PRM8060_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148) - kHz(12.5), PRM8060_ALL_MODES, -1, -1, PRM8060_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148) - kHz(12.5), PRM8060_ALL_MODES, W(5), W(25), PRM8060_VFO}, RIG_FRNG_END, }, .tuning_steps = { {PRM8060_ALL_MODES, kHz(12.5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {PRM8060_ALL_MODES, kHz(12.5)}, RIG_FLT_END, }, .str_cal = PRM8060_STR_CAL, .rig_init = prm80_init, .rig_cleanup = prm80_cleanup, .get_mode = prm80_get_mode, .set_freq = prm80_set_freq, .get_freq = prm80_get_freq, .set_split_vfo = prm80_set_split_vfo, .get_split_vfo = prm80_get_split_vfo, .set_split_freq = prm80_set_split_freq, .get_split_freq = prm80_get_split_freq, .set_channel = prm80_set_channel, .get_channel = prm80_get_channel, .set_mem = prm80_set_mem, .get_mem = prm80_get_mem, .set_func = prm80_set_func, .get_func = prm80_get_func, .set_level = prm80_set_level, .get_level = prm80_get_level, .reset = prm80_reset, .get_dcd = prm80_get_dcd, .get_ptt = prm80_get_ptt, .get_info = prm80_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/prm80/prm80.h0000664000175000017500000000520015056640443011502 /* * Hamlib PRM80 backend - main header * Copyright (c) 2010,2021 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _PRM80_H #define _PRM80_H 1 #include #include #define BACKEND_VER "20231002.0" #define PRM80_MEM_CAP { \ .freq = 1, \ .rptr_shift = 1, \ .flags = 1, /* lockout */ \ } struct prm80_priv_data { freq_t rx_freq; /* last RX freq set */ freq_t tx_freq; /* last TX freq set */ split_t split; /* emulated split on/off */ struct timeval status_tv; /* date of last "E" command */ char cached_statebuf[32]; /* response of last "E" command */ }; int prm80_init(RIG *rig); int prm80_cleanup(RIG *rig); int prm80_reset(RIG *rig, reset_t reset); int prm80_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int prm80_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int prm80_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int prm80_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int prm80_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int prm80_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int prm80_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int prm80_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int prm80_set_mem(RIG *rig, vfo_t vfo, int ch); int prm80_get_mem(RIG *rig, vfo_t vfo, int *ch); int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); const char *prm80_get_info(RIG *rig); extern struct rig_caps prm8060_caps; #endif /* _PRM80_H */ hamlib-4.6.5/rigs/prm80/Android.mk0000664000175000017500000000040215056640443012273 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := prm8060.c prm80.c LOCAL_MODULE := prm80 LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/prm80/Makefile.in0000664000175000017500000005267115056640453012447 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/prm80 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_prm80_la_LIBADD = am__objects_1 = prm8060.lo prm80.lo am_libhamlib_prm80_la_OBJECTS = $(am__objects_1) libhamlib_prm80_la_OBJECTS = $(am_libhamlib_prm80_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/prm80.Plo ./$(DEPDIR)/prm8060.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_prm80_la_SOURCES) DIST_SOURCES = $(libhamlib_prm80_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PRM80SRC = prm8060.c prm80.c prm80.h noinst_LTLIBRARIES = libhamlib-prm80.la libhamlib_prm80_la_SOURCES = $(PRM80SRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/prm80/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/prm80/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-prm80.la: $(libhamlib_prm80_la_OBJECTS) $(libhamlib_prm80_la_DEPENDENCIES) $(EXTRA_libhamlib_prm80_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_prm80_la_OBJECTS) $(libhamlib_prm80_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prm80.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prm8060.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/prm80.Plo -rm -f ./$(DEPDIR)/prm8060.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/prm80.Plo -rm -f ./$(DEPDIR)/prm8060.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/prm80/prm80.c0000664000175000017500000007263615056640443011516 /* * Hamlib PRM80 backend - main file * Copyright (c) 2010,2021 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "misc.h" #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "prm80.h" #define LF "\x0a" #define BUFSZ 64 // Channel number min and max #define CHAN_MIN 0 #define CHAN_MAX 99 // "E" system state is cached for this time (ms) #define PRM80_CACHE_TIMEOUT 200 // Length (in bytes) of the response to the "E" command #define CMD_E_RSP_LEN 22 #define RX_IF_OFFSET MHz(21.4) // The rig's PLL only deals with freq in Hz divided by this value #define FREQ_DIV 12500. /* V5 based on V4 commands * retrieved from https://github.com/f4fez/prm80 * and https://github.com/f4fez/prm80/blob/master/doc/Computer_commands_V4.md * It used to be from https://sourceforge.net/projects/prm80/ * and https://sourceforge.net/p/prm80/wiki/Computer%20commands%20V4/ MessageVersion: IF TARGET EQ 8060 DB "PRM8060 V4.0" ELSEIF TARGET EQ 8070 DB "PRM8070 V4.0" ENDIF MessageAide: DB "H",0Dh,0Ah DB " Commandes disponibles :",0Dh,0Ah DB " [0] = Reset.",0Dh,0Ah DB " [1] a [5] = Show 80c552 port state P1 to P5.",0Dh,0Ah DB " [C] = Print channels list.",0Dh,0Ah DB " [D] = Set system byte.",0Dh,0Ah DB " [E] = Show system state (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq,RSSI).",0Dh,0Ah DB " [F] = Set squelch.",0Dh,0Ah DB " [H] = Print this help page.",0Dh,0Ah DB " [I] = Erase and init RAM and EEPROM.",0Dh,0Ah DB " [K] = Set lock byte.",0Dh,0Ah DB " [L] = Print latch state.",0Dh,0Ah DB " [M] = Edit external RAM manually.",0Dh,0Ah DB " [N] = Set current channel.",0Dh,0Ah DB " [O] = Set volume.",0Dh,0Ah DB " [P] = Edit/Add channel.",0Dh,0Ah DB " [Q] = Set channels number.",0Dh,0Ah DB " [R] = Set synthetiser frequencies.",0Dh,0Ah DB " [U] = Print 80c552 internal RAM.",0Dh,0Ah DB " [S] = Copy EEPROM to external RAM.",0Dh,0Ah DB " [T] = Set current channel state.",0Dh,0Ah DB " [V] = Print firmware version.",0Dh,0Ah DB " [X] = Copy external RAM to EEPROM.",0Dh,0Ah DB " [Y] = Print first 2 kb from the EEPROM I2C 24c16.",0Dh,0Ah DB " [Z] = Print external RAM ($0000 to $07FF).",0Dh,0Ah,0 */ /* [0] = Reset. [C] = Print channels list. [D] = Set system byte. [E] = Show system state (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq-RSSI). [F] = Set squelch. [H] = Print this help page. [K] = Set lock byte. [N] = Set current channel. [O] = Set volume. [P] = Edit/Add channel. [Q] = Set channels number. [R] = Set synthetiser frequencies. [T] = Set current channel state. [V] = Print firmware version. */ /* * Mode byte, which holds the state of system basic features: b0: Squelch mode is displayed on LCD if true. Channel mode if false. b1: Power level (High or Low mode) b2: Squelch open (Read only) b3: TX mode (Read only) b4: PLL locked (Read only) b5: Long key push (Internal) b6: Key bounce (Internal) b7: Force LCD refresh when set. Automatically cleared. Channel state byte: b0: Shift enable when true b1: Reverse mode when true b2: Positive shift when true. Negative if false b3: Scanning locked out channel if set b4-7: na. Lock byte, which disables user controls when connected to a computer b0: Keys disabled when true b1: TX disabled when true b2: Volume button disabled when true b3: RX disabled when true b4-b7: na. * ********************************************************************* */ static void prm80_force_cache_timeout(RIG *rig) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; rig_force_cache_timeout(&priv->status_tv); } /* * Read a prompt terminated by delimiter, then write an optional string s. */ static int read_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s, const char *delimiter, int space_after_delim) { char buf[BUFSZ]; int buflen, retval; /* no data wanted? flush it anyway by reading it */ if (data == NULL) { data = buf; } buflen = (data_len == NULL) ? sizeof(buf) : *data_len; retval = read_string(rigport, (unsigned char *) data, buflen, delimiter, 1, 0, 1); if (retval < 0) { return retval; } // Place an end of string data[(retval < buflen) ? retval : (buflen - 1)] = '\0'; if (data_len != NULL) { *data_len = retval; } // Read one (dummy) space character after the colon if (space_after_delim) { char spacebuf[4]; retval = read_block(rigport, (unsigned char *) spacebuf, 1); if (retval < 0 && retval != -RIG_ETIMEOUT) { return retval; } } // Here is the answer to the prompt retval = write_block(rigport, (unsigned char *) s, strlen(s)); return retval; } /* * Read a prompt terminated by ": ", then write an optional string s. */ static int read_colon_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s) { return read_prompt_and_send(rigport, data, data_len, s, ":", 1); } /* * Read a prompt terminated by "$" (without space afterwards), * then write an optional string s. */ static int read_dollar_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s) { return read_prompt_and_send(rigport, data, data_len, s, "$", 0); } /* * After each executed command, the rig generally sends "\r\n>" */ static int prm80_wait_for_prompt(hamlib_port_t *rigport) { char buf[BUFSZ * 2]; int retval; // Read up to the '>' prompt and discard content. retval = read_string(rigport, (unsigned char *) buf, sizeof(buf), ">", 1, 0, 1); if (retval < 0) { return retval; } return RIG_OK; } /* * * \param cmd is string of generally one letter (or digit) * \param arg1 is an optional string to send afterwards * \param wait_prompt boolean when non-nul, will wait for "\r\n>" afterwards */ static int prm80_transaction(RIG *rig, const char *cmd, const char *arg1, int wait_prompt) { int retval; hamlib_port_t *rp = RIGPORT(rig); // Get rid of possible prompt sent by the rig rig_flush(rp); // Start with the command retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { return retval; } if (arg1 != NULL) { retval = read_colon_prompt_and_send(rp, NULL, NULL, arg1); if (retval < 0) { return retval; } } if (wait_prompt) { prm80_wait_for_prompt(rp); } return RIG_OK; } int prm80_init(RIG *rig) { if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (void *)calloc(1, sizeof(struct prm80_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } return RIG_OK; } int prm80_cleanup(RIG *rig) { if (rig == NULL) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * prm80_reset * Assumes rig!=NULL */ int prm80_reset(RIG *rig, reset_t reset) { int retval; /* * Reset CPU */ retval = prm80_transaction(rig, "0", NULL, 1); if (retval != RIG_OK) { return retval; } prm80_force_cache_timeout(rig); return RIG_OK; } /* * Convert freq in Hz to the RX PLL value representation with PRM08 firmware */ static unsigned rx_freq_to_pll_value(freq_t rx_freq) { // UHF vs VHF if (rx_freq > MHz(300)) { return (unsigned)((rx_freq - RX_IF_OFFSET) / FREQ_DIV); } else { return (unsigned)((rx_freq + RX_IF_OFFSET) / FREQ_DIV); } } static freq_t pll_value_to_rx_freq(unsigned pll_value) { freq_t rx_freq; rx_freq = (freq_t)pll_value * FREQ_DIV; // UHF vs VHF if (rx_freq > MHz(300)) { rx_freq += RX_IF_OFFSET; } else { rx_freq -= RX_IF_OFFSET; } return rx_freq; } /* * Set RX and TX freq * * See https://github.com/f4fez/prm80/blob/master/doc/Computer_control.md * "Adding a new channel" regarding freq format. */ int prm80_set_rx_tx_freq(RIG *rig, freq_t rx_freq, freq_t tx_freq) { hamlib_port_t *rp = RIGPORT(rig); char rx_freq_buf[BUFSZ]; char tx_freq_buf[BUFSZ]; int rc; // for RX, compute the PLL word without the IF SNPRINTF(rx_freq_buf, sizeof(rx_freq_buf), "%04X", rx_freq_to_pll_value(rx_freq)); SNPRINTF(tx_freq_buf, sizeof(tx_freq_buf), "%04X", (unsigned)(tx_freq / FREQ_DIV)); // The protocol is like this : // "RX frequency : " XXXX // CRLF"TX frequency : " XXXX rc = prm80_transaction(rig, "R", rx_freq_buf, 0); if (rc != RIG_OK) { return rc; } // There's a second line to process after prm80_transaction() rc = read_colon_prompt_and_send(rp, NULL, NULL, tx_freq_buf); if (rc != RIG_OK) { return rc; } // quid timeout in trx waiting for freq ? // NB: the [R] command does not update the checksum of the RAM! prm80_wait_for_prompt(rp); return rc; } /* * Set (RX) freq */ int prm80_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; freq_t tx_freq; int rc; if (priv->split == RIG_SPLIT_OFF) { tx_freq = freq; } else { tx_freq = (priv->tx_freq == 0.) ? freq : priv->tx_freq; } rc = prm80_set_rx_tx_freq(rig, freq, tx_freq); if (rc == RIG_OK) { priv->rx_freq = freq; } prm80_force_cache_timeout(rig); return rc; } /* * Set TX freq depending on emulated split state */ int prm80_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; freq_t rx_freq; int rc; rx_freq = (priv->rx_freq == 0.) ? tx_freq : priv->rx_freq; rc = prm80_set_rx_tx_freq(rig, rx_freq, tx_freq); if (rc == RIG_OK) { priv->tx_freq = tx_freq; } prm80_force_cache_timeout(rig); return rc; } /* * Get RX freq depending on emulated split state */ int prm80_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *freq = chan.freq; priv->tx_freq = chan.tx_freq; return RIG_OK; } /* * Enable/disable Split * * Rem: don't care about vfo */ int prm80_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } /* * Get Split */ int prm80_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = RIG_VFO_CURR; return RIG_OK; } /* * Get TX freq */ int prm80_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *tx_freq = chan.tx_freq; priv->rx_freq = chan.freq; return RIG_OK; } /* * Basic helper to ease some generic applications */ int prm80_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { // Can only do FM *mode = RIG_MODE_FM; *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * prm80_set_mem * Assumes rig!=NULL */ int prm80_set_mem(RIG *rig, vfo_t vfo, int ch) { char chbuf[BUFSZ]; /* [N] = Set current channel. */ if (ch < CHAN_MIN || ch > CHAN_MAX) { return -RIG_EINVAL; } SNPRINTF(chbuf, sizeof(chbuf), "%02u", (unsigned)ch); prm80_force_cache_timeout(rig); // Send command, no answer expected from rig except ">" prompt return prm80_transaction(rig, "N", chbuf, 1); } /* * prm80_get_mem * Assumes rig!=NULL */ int prm80_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *ch = chan.channel_num; return RIG_OK; } /* * Convert first two hexadecimal digit to integer */ static unsigned hhtoi(const char *p) { char buf[4]; // it has to be hex digits if (!isxdigit(p[0]) || !isxdigit(p[1])) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected content '%s'\n", __func__, p); return 0; } buf[0] = p[0]; buf[1] = p[1]; buf[2] = '\0'; return (unsigned)strtol(buf, NULL, 16); } /** * Get system state [E] from rig into \a statebuf */ static int prm80_do_read_system_state(hamlib_port_t *rigport, char *statebuf) { char *p; int ret; // Get rid of possible prompt sent by the rig rig_flush(rigport); /* [E] = Show system state */ ret = write_block(rigport, (unsigned char *) "E", 1); if (ret < 0) { return (ret); } // The response length is fixed ret = read_block(rigport, (unsigned char *) statebuf, CMD_E_RSP_LEN); if (ret < 0) { return ret; } statebuf[ret] = '\0'; if (ret < CMD_E_RSP_LEN) { rig_debug(RIG_DEBUG_ERR, "%s: len=%d < %d, statebuf='%s'\n", __func__, ret, CMD_E_RSP_LEN, statebuf); return (-RIG_EPROTO); } p = strchr(statebuf, '>'); if (p) { int left_to_read = (p - statebuf) + 1; memmove(statebuf, p + 1, CMD_E_RSP_LEN - left_to_read); ret = read_block(rigport, (unsigned char *) statebuf + CMD_E_RSP_LEN - left_to_read, left_to_read); if (ret < 0) { return ret; } else { statebuf[CMD_E_RSP_LEN] = '\0'; } rig_debug(RIG_DEBUG_WARN, "%s: len=%d, statebuf='%s'\n", __func__, ret, statebuf); } prm80_wait_for_prompt(rigport); return RIG_OK; } /* * Layer to handle the cache to Get system state [E] */ static int prm80_read_system_state(RIG *rig, char *statebuf) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret = RIG_OK; if (rig_check_cache_timeout(&priv->status_tv, PRM80_CACHE_TIMEOUT)) { ret = prm80_do_read_system_state(RIGPORT(rig), statebuf); if (ret == RIG_OK) { strcpy(priv->cached_statebuf, statebuf); /* update cache date */ gettimeofday(&priv->status_tv, NULL); } } else { strcpy(statebuf, priv->cached_statebuf); } return ret; } /* * prm80_get_channel * Assumes rig!=NULL */ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; char statebuf[BUFSZ]; int ret, chanstate, mode_byte, lock_byte; if (chan->vfo == RIG_VFO_MEM) { ret = prm80_set_mem(rig, RIG_VFO_CURR, chan->channel_num); if (ret != RIG_OK) { return ret; } } ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } /* (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq-RSSI). */ /* Examples: 1240080AFF0033F02D40__ or 14000C00FD0079708020__ */ /* Current mode: ; b0: Squelch b1: power ; b2: Squelch open b3: TX ; b4: PLL locked b5: Long press memorize ; b6: Debouncing in effect b7: LCD refresh */ mode_byte = hhtoi(statebuf); chan->mode = RIG_MODE_FM; chan->width = rig_passband_normal(rig, chan->mode); chan->channel_num = hhtoi(statebuf + 2); chan->tx_mode = chan->mode; chan->tx_width = chan->width; /* Chan state: ; b0: shift enabled b1: reverse ; b2: shift + b3: lock out */ chanstate = hhtoi(statebuf + 4) & 0x0f; /* is it rptr_shift or split mode ? */ chan->rptr_shift = (chanstate & 0x01) == 0 ? RIG_RPT_SHIFT_NONE : (chanstate & 0x02) ? RIG_RPT_SHIFT_MINUS : (chanstate & 0x04) ? RIG_RPT_SHIFT_PLUS : RIG_RPT_SHIFT_NONE; chan->flags = (chanstate & 0x08) ? RIG_CHFLAG_SKIP : 0; // squelch is in low nibble chan->levels[LVL_SQL].f = ((float)(hhtoi(statebuf + 6) & 0x0F)) / 15.; // volume is hex "00" .. "10" chan->levels[LVL_AF].f = ((float)hhtoi(statebuf + 8)) / 16.; chan->levels[LVL_RFPOWER].f = (mode_byte & 0x02) ? 1.0 : 0.0; // new in FW V5 chan->levels[LVL_RAWSTR].i = hhtoi(statebuf + 20); chan->funcs = 0; chan->funcs |= (chanstate & 0x02) ? RIG_FUNC_REV : 0; lock_byte = hhtoi(statebuf + 10) & 0x0f; chan->funcs |= (lock_byte & 0x05) ? RIG_FUNC_LOCK : 0; chan->funcs |= (lock_byte & 0x08) ? RIG_FUNC_MUTE : 0; chan->freq = pll_value_to_rx_freq((hhtoi(statebuf + 12) << 8) + hhtoi( statebuf + 14)); chan->tx_freq = ((hhtoi(statebuf + 16) << 8) + hhtoi(statebuf + 18)) * FREQ_DIV; if (chan->rptr_shift != RIG_RPT_SHIFT_NONE) { chan->rptr_offs = chan->tx_freq - chan->freq; chan->split = RIG_SPLIT_OFF; } else { chan->rptr_offs = 0; chan->split = priv->split; // RIG_SPLIT_ON; ? } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_WARN, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_WARN, "%s: need to know if rig updates when channel read or not\n", __func__); //return -RIG_ENIMPL; } return RIG_OK; } /* * prm80_set_channel handles RIG_VFO_MEM and RIG_VFO_CURR */ int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char buf[BUFSZ]; int ret, chanstate; freq_t tx_freq; if (chan->vfo == RIG_VFO_MEM) { // setting channel without calling set_mem() if (chan->channel_num < CHAN_MIN || chan->channel_num > CHAN_MAX) { return -RIG_EINVAL; } /* [P] = Edit/Add channel */ /* Example Channel to set : 00 PLL value to load : $8020 Channel state : $00 Possibly: "This channel number doesn't exist. Add new channel (Y/N) ? " */ SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)chan->channel_num); ret = prm80_transaction(rig, "P", buf, 0); if (ret != RIG_OK) { return ret; } // Set the RX frequency as PLL word. SNPRINTF(buf, sizeof(buf), "%04X", rx_freq_to_pll_value(chan->freq)); // "PLL value to load : $" ret = read_dollar_prompt_and_send(rp, NULL, NULL, buf); if (ret != RIG_OK) { return ret; } // the channel status byte. switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE : chanstate = 0x00; break; case RIG_RPT_SHIFT_MINUS : chanstate = 0x03; break; case RIG_RPT_SHIFT_PLUS : chanstate = 0x05; break; default: chanstate = 0x00; break; } chanstate |= (chan->flags & RIG_CHFLAG_SKIP) ? 0x08 : 0; SNPRINTF(buf, sizeof(buf), "%02X", chanstate); // "Channel state : $" ret = read_dollar_prompt_and_send(rp, NULL, NULL, buf); if (ret != RIG_OK) { return ret; } // Determine if prompt came back (CRLF'>') or have to // handle the possible query from the rig: // "This channel number doesn't exist. Add new channel (Y/N) ? " ret = read_block(rp, (unsigned char *) buf, 3); if (ret < 0) { return ret; } if (ret == 3 && buf[2] == 'T') { // Read the question ret = read_string(rp, (unsigned char *) buf, sizeof(buf), "?", 1, 0, 1); if (ret < 0) { return ret; } // Read extra space ret = read_block(rp, (unsigned char *) buf, 1); if (ret < 0) { return ret; } // Send confirmation ret = write_block(rp, (unsigned char *) "Y", 1); if (ret < 0) { return ret; } } prm80_wait_for_prompt(rp); } else { // assume here chan->vfo == RIG_VFO_CURR // that is the "RAM" VFO not backed by memory tx_freq = (chan->split == RIG_SPLIT_ON) ? chan->tx_freq : chan->freq; ret = prm80_set_rx_tx_freq(rig, chan->freq, tx_freq); if (ret != RIG_OK) { return ret; } priv->split = chan->split; priv->rx_freq = chan->freq; priv->tx_freq = tx_freq; ret = prm80_set_level(rig, vfo, RIG_LEVEL_SQL, chan->levels[LVL_SQL]); if (ret != RIG_OK) { return ret; } ret = prm80_set_level(rig, vfo, RIG_LEVEL_AF, chan->levels[LVL_AF]); if (ret != RIG_OK) { return ret; } #if 0 // Not implemented yet.. ret = prm80_set_level(rig, vfo, RIG_LEVEL_RFPOWER, chan->levels[LVL_RFPOWER]); if (ret != RIG_OK) { return ret; } #endif ret = prm80_set_func(rig, vfo, RIG_FUNC_LOCK, !!(chan->funcs & RIG_FUNC_LOCK)); if (ret != RIG_OK) { return ret; } } prm80_force_cache_timeout(rig); return RIG_OK; } // TODO FUNC_REV through Channel state byte ? // TODO "Read-Modify-Write" (or shadowing in priv area) of the lock bits int prm80_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; if (func & RIG_FUNC_LOCK) { /* Lock keys(b0)/Vol(b2) */ ret = prm80_transaction(rig, "K", (status != 0) ? "05" : "00", 1); } else if (func & RIG_FUNC_MUTE) { /* Lock RX(b3) */ ret = prm80_transaction(rig, "K", (status != 0) ? "08" : "00", 1); } else { ret = -RIG_EINVAL; } prm80_force_cache_timeout(rig); return ret; } int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *status = !!(chan.funcs & func); return RIG_OK; } /* * prm80_set_level * Assumes rig!=NULL */ int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[BUFSZ]; int ret, mode_byte; // do some clamping, all levels are float values. if (val.f < 0.0) { val.f = 0.0; } else if (val.f > 1.0) { val.f = 1.0; } switch (level) { case RIG_LEVEL_AF: // Unlike system state, volume decimal SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)(val.f * 16)); return prm80_transaction(rig, "O", buf, 1); case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)(val.f * 15)); return prm80_transaction(rig, "F", buf, 1); case RIG_LEVEL_RFPOWER: /* Current mode: ; b0: Squelch b1: power ; b2: Squelch open b3: TX ; b4: PLL locked b5: Long press memorize ; b6: Debouncing in effect b7: LCD refresh */ // Perform a "Read-Modify-Write" of the mode_byte ret = prm80_read_system_state(rig, buf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(buf); mode_byte &= ~0x02; mode_byte |= (val.f == 0.) ? 0 : 0x02; SNPRINTF(buf, sizeof(buf), "%02X", (unsigned)mode_byte); return prm80_transaction(rig, "D", buf, 1); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } prm80_force_cache_timeout(rig); return RIG_OK; } #ifdef V4_ONLY /* * get_level RIG_LEVEL_RAWSTR */ // cppcheck-suppress unusedFunction static int prm80_get_rawstr_RAM(RIG *rig, value_t *val) { char buf[BUFSZ]; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); int ret, i; /* [U] = Print 80c552 internal RAM. */ // Send cmd, Wait for colon prompt, but then send nothing ret = prm80_transaction(rig, "U", "", 0); if (ret < 0) { return ret; } // Read CRLF ret = read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); if (ret < 0) { return ret; } // (16 lines of 16 bytes each) // According to prm.a51, the rssi_hold variable is in RAM at RAM+35. // The RAM base is at 030h. #define RSSI_HOLD_ADDR (0x30 + 35) // = 0x53 for (i = 0; i < (RSSI_HOLD_ADDR / 16) + 1; i++) { ret = read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); if (ret < 0) { return ret; } } // A line looks like this // "$50 : 00 01 02 53 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\r\n" val->i = hhtoi(buf + 6 + 3 * (RSSI_HOLD_ADDR % 16)); // discard the remaining content of RAM print for (i = 0; i < (16 - RSSI_HOLD_ADDR / 16) - 1; i++) { read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); } prm80_wait_for_prompt(rp); return RIG_OK; } #endif /* * prm80_get_level * Assumes rig!=NULL */ int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = chan.levels[LVL_RAWSTR].i; break; case RIG_LEVEL_AF: val->f = chan.levels[LVL_AF].f; break; case RIG_LEVEL_SQL: val->f = chan.levels[LVL_SQL].f; break; case RIG_LEVEL_RFPOWER: val->f = chan.levels[LVL_RFPOWER].f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char statebuf[BUFSZ]; int ret, mode_byte; ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(statebuf); // TX mode on? *ptt = (mode_byte & 0x08) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char statebuf[BUFSZ]; int ret, mode_byte; ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(statebuf); // Squelch open? *dcd = (mode_byte & 0x04) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } // TODO vfo_op : MCL FROM_VFO .. /* * prm80_get_info * Assumes rig!=NULL */ const char *prm80_get_info(RIG *rig) { static char s_buf[BUFSZ]; hamlib_port_t *rp = RIGPORT(rig); char *p; int ret; // Get rid of possible prompt sent by the rig rig_flush(rp); /* [V] = Print firmware version. */ ret = write_block(rp, (unsigned char *) "V", 1); if (ret < 0) { return NULL; } ret = read_string(rp, (unsigned char *) s_buf, BUFSZ, ">", 1, 0, 1); if (ret < 0) { return NULL; } p = strchr(s_buf, '\r'); if (p) { // chomp *p = '\0'; } return s_buf; } /* * initrigs_prm80 is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(prm80) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&prm8060_caps); return RIG_OK; } hamlib-4.6.5/rigs/prm80/Makefile.am0000664000175000017500000000022015056640443012414 PRM80SRC = prm8060.c prm80.c prm80.h noinst_LTLIBRARIES = libhamlib-prm80.la libhamlib_prm80_la_SOURCES = $(PRM80SRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/motorola/0000775000175000017500000000000015056640501011327 5hamlib-4.6.5/rigs/motorola/motorola.c0000664000175000017500000000205015056640443013251 /* * Hamlib Motorola backend - main file * Copyright (c) 2024 Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "motorola.h" #include DECLARE_INITRIG_BACKEND(motorola) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&micom_caps); return RIG_OK; } hamlib-4.6.5/rigs/motorola/motorola.h0000664000175000017500000000020315056640443013254 #ifndef _MOTOROLA_H #define _MOTOROLADUMMY_H 1 #include "hamlib/rig.h" extern struct rig_caps micom_caps; #endif // _MOTOROLA_H hamlib-4.6.5/rigs/motorola/micom.c0000664000175000017500000001617315056640443012534 /* * Hamlib Motorola Micom backend - main file * Copyright (c) 2024 Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include // char* to start of checksum for len bytes unsigned int checksum(unsigned char *buf, int len) { int checksum = 0; int i; // simple 1-byte checksum for (i = 0; i < len; ++i) { checksum += buf[i]; } return checksum & 0xff; } static int micom_open(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } // returns bytes read // format has length in byte[1] plus 5 bytes 0x24/len/cmd at start and checksum+0x03 at end // So a data "length" of 5 is 10 bytes for example static int micom_read_frame(RIG *rig, unsigned char *buf, int maxlen) { hamlib_port_t *rp = RIGPORT(rig); int bytes; //const char stopset[1] = {0x03}; ENTERFUNC; bytes = read_block(rp, buf, 3); if (bytes + buf[1] + 2 > maxlen) { rig_debug(RIG_DEBUG_ERR, "%s: buffer overrun...expected max of %d, got %d\n", __func__, maxlen, bytes + buf[1] + 2); dump_hex(buf, bytes); RETURNFUNC(-RIG_EPROTO); } bytes += read_block(rp, &buf[3], buf[1] + 2); dump_hex(buf, bytes); RETURNFUNC(bytes); } /* Example of set of commands that works 24 06 18 05 01 00 38 ea 50 ba 03 15 24 05 18 36 fe 7b ef 01 e0 03 15 24 05 18 36 ff 7b ef 01 e1 03 15 24 05 18 36 df 7b ef 01 c1 03 15 24 05 18 36 ff 7b ef 01 e1 03 */ static int micom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { hamlib_port_t *rp = RIGPORT(rig); unsigned char rxcmd[12] = { 0x24, 0x06, 0x18, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x15 }; unsigned char cmd2[11] = { 0x24, 0x05, 0x18, 0x36, 0xfe, 0x7b, 0xef, 0x01, 0xe0, 0x03, 0x15 }; unsigned char cmd3[11] = { 0x24, 0x05, 0x18, 0x36, 0xfe, 0x7b, 0xef, 0x01, 0xe1, 0x03, 0x15 }; unsigned char cmd4[11] = { 0x24, 0x05, 0x18, 0x36, 0xdf, 0x7b, 0xef, 0x01, 0xc1, 0x03, 0x15 }; unsigned char cmd5[10] = { 0x24, 0x05, 0x18, 0x36, 0xff, 0x7b, 0xef, 0x01, 0xe1, 0x03 }; //unsigned char txcmd[11] = { 0x24, 0x05, 0x81, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }; unsigned int ifreq = freq; unsigned char reply[11]; int retval; rxcmd[5] = (ifreq >> 24) & 0xff; rxcmd[6] = (ifreq >> 16) & 0xff; rxcmd[7] = (ifreq >> 8) & 0xff; rxcmd[8] = ifreq & 0xff; rxcmd[9] = checksum(rxcmd, 9); set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, rxcmd, sizeof(rxcmd)); micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd2, sizeof(cmd2)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd3, sizeof(cmd3)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd4, sizeof(cmd4)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd5, sizeof(cmd5)); } micom_read_frame(rig, reply, sizeof(reply)); micom_read_frame(rig, reply, sizeof(reply)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } micom_read_frame(rig, reply, sizeof(reply)); #if 0 // this method doesn't work txcmd[5] = (ifreq >> 16) & 0xff; txcmd[6] = (ifreq >> 8) & 0xff; txcmd[7] = ifreq & 0xff; txcmd[8] = checksum(txcmd, 8); txcmd[5] = (ifreq >> 24) & 0xff; txcmd[6] = (ifreq >> 16) & 0xff; txcmd[7] = (ifreq >> 8) & 0xff; txcmd[8] = ifreq & 0xff; txcmd[9] = checksum(rxcmd, 9); retval = write_block(rp, txcmd, sizeof(txcmd)); micom_read_frame(rig, reply, sizeof(reply)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } #endif set_transaction_inactive(rig); return retval; } static int micom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd[6] = { 0x24, 0x01, 0x18, 0x06, 0x06, 0x03 }; unsigned char ack[6] = { 0x24, 0x01, 0x18, 0xf3, 0xff, 0x03 }; unsigned char reply[11]; int retval; cmd[4] = checksum(cmd, 4); set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, cmd, sizeof(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } // expecting 24 01 80 fe 98 03 -- an ack packet? micom_read_frame(rig, reply, sizeof(reply)); if (reply[3] != 0xfe) { rig_debug(RIG_DEBUG_ERR, "%s: unknown packet...expected byte 4 = 0xfe\n", __func__); } micom_read_frame(rig, reply, sizeof(reply)); write_block(rp, ack, sizeof(ack)); set_transaction_inactive(rig); *freq = (reply[4] << 24) | (reply[5] << 16) | (reply[6] << 8) | reply[7]; RETURNFUNC2(RIG_OK); } static int micom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { hamlib_port_t *rp = RIGPORT(rig); unsigned char on[] = { 0x24, 0x02, 0x81, 0x13, 0x01, 0xBB, 0x03 }; unsigned char off[] = { 0x24, 0x02, 0x81, 0x14, 0x01, 0xBC, 0x03 }; int retval; set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, ptt ? on : off, sizeof(on)); set_transaction_inactive(rig); return retval; } struct rig_caps micom_caps = { RIG_MODEL(RIG_MODEL_MICOM2), .model_name = "Micom 2/3", .mfg_name = "Micom", .version = "20240504.0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .timeout = 500, .rig_open = micom_open, .set_freq = micom_set_freq, .get_freq = micom_get_freq, .set_ptt = micom_set_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/motorola/Android.mk0000664000175000017500000000040615056640443013165 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := motorola.c micom.c LOCAL_MODULE := motorola LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/motorola/Makefile.in0000664000175000017500000005275715056640452013341 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/motorola ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_motorola_la_LIBADD = am__objects_1 = motorola.lo micom.lo am_libhamlib_motorola_la_OBJECTS = $(am__objects_1) libhamlib_motorola_la_OBJECTS = $(am_libhamlib_motorola_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/micom.Plo ./$(DEPDIR)/motorola.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_motorola_la_SOURCES) DIST_SOURCES = $(libhamlib_motorola_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RSSRC = motorola.c micom.c motorola.h noinst_LTLIBRARIES = libhamlib-motorola.la libhamlib_motorola_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/motorola/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/motorola/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-motorola.la: $(libhamlib_motorola_la_OBJECTS) $(libhamlib_motorola_la_DEPENDENCIES) $(EXTRA_libhamlib_motorola_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_motorola_la_OBJECTS) $(libhamlib_motorola_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/micom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motorola.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/micom.Plo -rm -f ./$(DEPDIR)/motorola.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/micom.Plo -rm -f ./$(DEPDIR)/motorola.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/motorola/Makefile.am0000664000175000017500000000022415056640443013306 RSSRC = motorola.c micom.c motorola.h noinst_LTLIBRARIES = libhamlib-motorola.la libhamlib_motorola_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/gomspace/0000775000175000017500000000000015056640500011270 5hamlib-4.6.5/rigs/gomspace/Android.mk0000664000175000017500000000037315056640443013132 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := gs100.c LOCAL_MODULE := gomspace LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/gomspace/Makefile.in0000664000175000017500000005245015056640452013271 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/gomspace ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_gomspace_la_LIBADD = am__objects_1 = gs100.lo am_libhamlib_gomspace_la_OBJECTS = $(am__objects_1) libhamlib_gomspace_la_OBJECTS = $(am_libhamlib_gomspace_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gs100.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_gomspace_la_SOURCES) DIST_SOURCES = $(libhamlib_gomspace_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ GOMSPACESRC = gs100.c gs100.h noinst_LTLIBRARIES = libhamlib-gomspace.la libhamlib_gomspace_la_SOURCES = $(GOMSPACESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/gomspace/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/gomspace/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-gomspace.la: $(libhamlib_gomspace_la_OBJECTS) $(libhamlib_gomspace_la_DEPENDENCIES) $(EXTRA_libhamlib_gomspace_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_gomspace_la_OBJECTS) $(libhamlib_gomspace_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs100.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gs100.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gs100.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/gomspace/gs100.c0000664000175000017500000003647615056640443012234 /* * GomSpace backend and the GS100 radio control module * * Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com * and used during VZLUSAT-2 satellite mission. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Includes ------------------------------------------------------------------*/ #include #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "gs100.h" /* Private Defines -----------------------------------------------------------*/ // If defined, commands are software simulated only #undef _LOCAL_SIMULATION_ // If true, configuration table switching is minimized #define PARAM_MEM_MINIMAL 1 // Buffer size for serial transfers #define BUFSZ 256 // Last character on each line received from RIG #define GOM_STOPSET "\n" // Exact character sequence on the RIG's command prompt #define GOM_PROMPT "\x1B[1;32mnanocom-ax\x1B[1;30m # \x1B[0m\x1B[0m" // Maximum number of lines parsed from GS100 response #define GOM_MAXLINES 20 // RIG's parametric table number for receive #define GOM_CONFIG_TAB_RX 1 // RIG's parametric table number for transmit #define GOM_CONFIG_TAB_TX 5 /* Private Typedefs ----------------------------------------------------------*/ /** * GS100 rig private data structure */ struct gs100_priv_data { freq_t freq_rx; ///< currently just for backup and TRX emulation freq_t freq_tx; ///< currently just for backup and TRX emulation int param_mem; ///< last value of configuration table selection }; /* Imported Functions --------------------------------------------------------*/ struct ext_list *alloc_init_ext(const struct confparams *cfp); struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token); /* Private function prototypes -----------------------------------------------*/ /** * Set variable in the GS100 configuration table */ static int gomx_set(RIG *rig, int table, char *varname, char *varvalue); /** * Get variable from the GS100 configuration table */ static int gomx_get(RIG *rig, int table, char *varname, const char *varvalue, int varvalue_len); /** * Sends a message to the GS100 and parses response lines */ static int gomx_transaction(RIG *rig, char *message, char *response); /* Functions -----------------------------------------------------------------*/ /* GS100 transceiver control init */ static int gs100_init(RIG *rig) { __attribute__((unused)) struct gs100_priv_data *priv; ENTERFUNC; priv = (struct gs100_priv_data *)calloc(1, sizeof(struct gs100_priv_data)); if (!priv) { RETURNFUNC(-RIG_ENOMEM); } STATE(rig)->priv = (void *)priv; #ifdef _LOCAL_SIMULATION_ RIGPORT(rig)->type.rig = RIG_PORT_NONE; // just simulation priv->freq_rx = rig->caps->rx_range_list1->startf; priv->freq_tx = rig->caps->tx_range_list1->startf; #endif priv->param_mem = -1; // means undefined last selection RETURNFUNC(RIG_OK); } /* GS100 transceiver control deinit */ static int gs100_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* GS100 transceiver open */ static int gs100_open(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_GS100) { rig_debug(RIG_DEBUG_VERBOSE, "%s: OPENING'\n", __func__); } RETURNFUNC(RIG_OK); } /* GS100 transceiver close */ static int gs100_close(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_GS100) { rig_debug(RIG_DEBUG_VERBOSE, "%s: CLOSING'\n", __func__); } RETURNFUNC(RIG_OK); } /* GS100 transceiver set configuration */ static int gs100_set_conf(RIG *rig, hamlib_token_t token, const char *val) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; ENTERFUNC; priv = (struct gs100_priv_data *)STATE(rig)->priv; switch (token) { case 0: break; case 1: break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* GS100 transceiver get configuration */ static int gs100_get_conf(RIG *rig, hamlib_token_t token, char *val) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; ENTERFUNC; priv = (struct gs100_priv_data *)STATE(rig)->priv; switch (token) { case 0: break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* GS100 transceiver set receiver frequency */ static int gs100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char fstr[20], value[20]; int retval; ENTERFUNC; // reporting sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr); #ifdef _LOCAL_SIMULATION_ priv->freq_rx = freq; #endif // range check - GS100 don't do it! if (freq < rig->caps->rx_range_list1->startf || freq > rig->caps->rx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } // perform set command sprintf(value, "%1.0lf", freq); retval = gomx_set(rig, GOM_CONFIG_TAB_RX, "freq", value); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* GS100 transceiver get receiver frequency */ static int gs100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char resp[20]; int retval; freq_t f; ENTERFUNC; // perform the get command retval = gomx_get(rig, GOM_CONFIG_TAB_RX, "freq", resp, sizeof(resp)); if (retval != RIG_OK) { RETURNFUNC(retval); } #ifdef _LOCAL_SIMULATION_ *freq = priv->freq_rx; #else retval = sscanf(resp, "%lf", &f); #endif // relevance check if (retval != 1) { RETURNFUNC(-RIG_EPROTO); } if (f < rig->caps->rx_range_list1->startf || f > rig->caps->rx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } *freq = f; RETURNFUNC(RIG_OK); } /* GS100 transceiver set transmitter frequency */ static int gs100_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char fstr[20], value[20]; int retval; ENTERFUNC; // reporting sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr); #ifdef _LOCAL_SIMULATION_ priv->freq_tx = freq; #endif // range check - GS100 don't do it! if (freq < rig->caps->tx_range_list1->startf || freq > rig->caps->tx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } // perform set command sprintf(value, "%1.0lf", freq); retval = gomx_set(rig, GOM_CONFIG_TAB_TX, "freq", value); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* GS100 transceiver get transmitter frequency */ static int gs100_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char resp[20]; int retval; freq_t f; ENTERFUNC; // perform the get command retval = gomx_get(rig, GOM_CONFIG_TAB_TX, "freq", resp, sizeof(resp)); if (retval != RIG_OK) { RETURNFUNC(retval); } #ifdef _LOCAL_SIMULATION_ *freq = priv->freq_tx; #else retval = sscanf(resp, "%lf", &f); #endif // relevance check if (retval != 1) { RETURNFUNC(-RIG_EPROTO); } if (f < rig->caps->tx_range_list1->startf || f > rig->caps->tx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } *freq = f; RETURNFUNC(RIG_OK); } /* GS100 transceiver get info */ static const char *gs100_get_info(RIG *rig) { return ("Gomspace Ground Station Transceiver GS100"); } /* The HAMLIB RIG Capabilities Structure Definition --------------------------*/ #define GS100_FUNC (0) #define GS100_LEVEL (0) #define GS100_PARM (0) #define GS100_VFO_OPS RIG_OP_TUNE #define GS100_VFOS (RIG_VFO_A) #define GS100_MODES (RIG_MODE_PKTFM) struct rig_caps GS100_caps = { RIG_MODEL(RIG_MODEL_GS100), .model_name = "GS100", .mfg_name = "GOMSPACE", .version = "20211117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 500000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 1, .post_write_delay = 1, .timeout = 250, .retry = 0, .has_get_func = GS100_FUNC, .has_set_func = GS100_FUNC, .has_get_level = GS100_LEVEL, .has_set_level = GS100_LEVEL, .has_get_parm = GS100_PARM, .has_set_parm = GS100_PARM, .vfo_ops = GS100_VFO_OPS, .rx_range_list1 = { { .startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES, .low_power = 0, .high_power = 0, GS100_VFOS, .label = "GS100#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES, .low_power = 0, .high_power = 0, GS100_VFOS, .label = "GS100#1" }, RIG_FRNG_END, }, .tuning_steps = { {GS100_MODES, Hz(10)}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = gs100_init, .rig_cleanup = gs100_cleanup, .rig_open = gs100_open, .rig_close = gs100_close, .set_conf = gs100_set_conf, .get_conf = gs100_get_conf, .set_freq = gs100_set_freq, .get_freq = gs100_get_freq, .set_split_freq = gs100_set_tx_freq, .get_split_freq = gs100_get_tx_freq, .get_info = gs100_get_info, }; /* Private functions ---------------------------------------------------------*/ /* Set variable in the GS100 configuration table */ static int gomx_set(RIG *rig, int table, char *varname, char *varvalue) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; int retval; char msg[BUFSZ], resp[BUFSZ]; assert(rig != NULL); assert(varname != NULL); assert(varvalue != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s' = '%s'\n", __func__, table, varname, varvalue); if (!PARAM_MEM_MINIMAL || table != priv->param_mem) { // select the configuration table priv->param_mem = table; sprintf(msg, "param mem %d\n", table); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } } // set the variable sprintf(msg, "param set %s %s\n", varname, varvalue); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } // check response if (strlen(resp) > 0) { return (-RIG_EPROTO); } return (RIG_OK); } /* Get variable from the GS100 configuration table */ static int gomx_get(RIG *rig, int table, char *varname, const char *varvalue, int varvalue_len) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; int retval; char msg[BUFSZ], resp[BUFSZ], *c; char fmt[32]; assert(rig != NULL); assert(varname != NULL); assert(varvalue != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s'\n", __func__, table, varname); if (!PARAM_MEM_MINIMAL || table != priv->param_mem) { // select the configuration table priv->param_mem = table; sprintf(msg, "param mem %d\n", table); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } } // get the variable sprintf(msg, "param get %19s\n", varname); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } // check response and extract the value if ((c = strchr(resp, '=')) == NULL) { return (-RIG_EPROTO); } snprintf(fmt, sizeof(fmt), "%%%ds", varvalue_len); if (sscanf(c + 1, fmt, varvalue_len) != 1) { return (-RIG_EPROTO); } return (RIG_OK); } /* Sends a message to the GS100 and parses response lines */ static int gomx_transaction(RIG *rig, char *message, char *response) { hamlib_port_t *rp; int retval, n = 0; char buf[BUFSZ]; assert(rig != NULL); assert(message != NULL); assert(response != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: msg='%s'\n", __func__, message == NULL ? "NULL" : message); rp = RIGPORT(rig); // send message to the transceiver rig_flush(rp); retval = write_block(rp, (uint8_t *)message, strlen(message)); if (retval != RIG_OK) { return (retval); } while (1) { // read the response line retval = read_string(rp, (unsigned char *)buf, BUFSZ, (const char *)GOM_STOPSET, 0, strlen(GOM_STOPSET), 0); if (retval < 0) { return (retval); } if (retval == 0) { return (-RIG_ETIMEOUT); } n++; // prompt is always the last line if (strcmp(buf, GOM_PROMPT) == 0) { break; } // before last line would be the response if (n > 1) { strcpy(response, buf); } else { *response = '\0'; } // don't return command echo if (n > GOM_MAXLINES) { return (-RIG_EPROTO); } } // report the response rig_debug(RIG_DEBUG_VERBOSE, "%s: returning response='%s'\n", __func__, response == NULL ? "NULL" : response); return (RIG_OK); } /* System Integration Functions ----------------------------------------------*/ /* Init RIG backend function */ DECLARE_INITRIG_BACKEND(gomspace) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&GS100_caps); return (RIG_OK); } /* Probe RIG backend function */ DECLARE_PROBERIG_BACKEND(gomspace) { return (RIG_MODEL_GS100); } /*----------------------------------------------------------------------------*/ hamlib-4.6.5/rigs/gomspace/gs100.h0000664000175000017500000000371215056640443012224 /* * GomSpace backend and the GS100 radio control module * * Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com * and used during VZLUSAT-2 satellite mission. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _GS100_H #define _GS100_H 1 /* Includes ------------------------------------------------------------------*/ #include "hamlib/rig.h" #include "token.h" /* Definitions ---------------------------------------------------------------*/ /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_MAGICEXTFUNC TOKEN_BACKEND(6) /* Public variables ----------------------------------------------------------*/ /* RIG capabilities descriptions */ extern struct rig_caps gs100_caps; extern struct rig_caps netrigctl_caps; extern struct rig_caps flrig_caps; extern struct rig_caps trxmanager_caps; /*----------------------------------------------------------------------------*/ #endif /* _GS100_H */ hamlib-4.6.5/rigs/gomspace/Makefile.am0000664000175000017500000000022215056640443013246 GOMSPACESRC = gs100.c gs100.h noinst_LTLIBRARIES = libhamlib-gomspace.la libhamlib_gomspace_la_SOURCES = $(GOMSPACESRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/jrc/0000775000175000017500000000000015056640477010265 5hamlib-4.6.5/rigs/jrc/jst145.c0000664000175000017500000003673015056640443011405 /* * Hamlib JRC backend - JST-145 description * Copyright (c) 2001-2009 by Stephane Fillod * Copyright (c) 2021 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "iofunc.h" #include "jrc.h" static int jst145_init(RIG *rig); static int jst145_open(RIG *rig); static int jst145_close(RIG *rig); static int jst145_set_vfo(RIG *rig, vfo_t vfo); static int jst145_get_vfo(RIG *rig, vfo_t *vfo); static int jst145_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int jst145_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int jst145_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int jst145_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int jst145_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int jst145_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int jst145_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int jst145_set_mem(RIG *rig, vfo_t vfo, int ch); static int jst145_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int jst145_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); #define MAX_LEN 24 #define JST145_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_FAX) #define JST145_LEVEL (RIG_LEVEL_AGC) // Rig has VFOB but for now we won't do much with it except set freq #define JST145_VFO (RIG_VFO_VFO) #define JST145_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_AGC, \ } struct jst145_priv_data { ptt_t ptt; freq_t freqA, freqB; mode_t mode; }; /* * JST-145 rig capabilities. * */ struct rig_caps jst145_caps = { RIG_MODEL(RIG_MODEL_JST145), .model_name = "JST-145", .mfg_name = "JRC", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 1, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = JST145_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, JST145_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(30), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {JST145_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_open = jst145_open, .rig_close = jst145_close, .set_vfo = jst145_set_vfo, .get_vfo = jst145_get_vfo, .set_freq = jst145_set_freq, .get_freq = jst145_get_freq, .set_mode = jst145_set_mode, .get_mode = jst145_get_mode, .set_func = jst145_set_func, .set_level = jst145_set_level, .set_mem = jst145_set_mem, .vfo_op = jst145_vfo_op, .set_ptt = jst145_set_ptt, .get_ptt = jst145_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * JST-245 rig capabilities. * */ struct rig_caps jst245_caps = { RIG_MODEL(RIG_MODEL_JST245), .model_name = "JST-245", .mfg_name = "JRC", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = JST145_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, JST145_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(54), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(54), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {JST145_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_init = jst145_init, .rig_open = jst145_open, .rig_close = jst145_close, .set_vfo = jst145_set_vfo, .get_vfo = jst145_get_vfo, .set_freq = jst145_set_freq, .get_freq = jst145_get_freq, .set_mode = jst145_set_mode, .get_mode = jst145_get_mode, .set_func = jst145_set_func, .set_level = jst145_set_level, .set_mem = jst145_set_mem, .vfo_op = jst145_vfo_op, .set_ptt = jst145_set_ptt, .get_ptt = jst145_get_ptt }; /* * Function definitions below */ static int jst145_init(RIG *rig) { struct jst145_priv_data *priv; priv = (struct jst145_priv_data *)calloc(1, sizeof(struct jst145_priv_data)); if (!priv) { return -RIG_ENOMEM; } STATE(rig)->priv = (void *)priv; return RIG_OK; } static int jst145_open(RIG *rig) { int retval; freq_t freq; rmode_t mode; pbwidth_t width; struct jst145_priv_data *priv = STATE(rig)->priv; retval = write_block(RIGPORT(rig), (unsigned char *) "H1\r", 3); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: H1 failed: %s\n", __func__, rigerror(retval)); return retval; } rig_get_freq(rig, RIG_VFO_A, &freq); priv->freqA = freq; rig_get_freq(rig, RIG_VFO_B, &freq); priv->freqB = freq; rig_get_mode(rig, RIG_VFO_A, &mode, &width); priv->mode = mode; return retval; } static int jst145_close(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H0\r", 3); } static int jst145_set_vfo(RIG *rig, vfo_t vfo) { char cmd[MAX_LEN]; SNPRINTF(cmd, sizeof(cmd), "F%c\r", vfo == RIG_VFO_A ? 'A' : 'B'); return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } static int jst145_get_vfo(RIG *rig, vfo_t *vfo) { char cmd[MAX_LEN]; char channel[MAX_LEN]; int channel_size = sizeof(channel); int retval; ptt_t ptt; int retry = 1; jst145_get_ptt(rig, RIG_VFO_A, &ptt); // set priv->ptt to current transmit status CACHE(rig)->ptt = ptt; ptt_retry: if (ptt) // can't get vfo while transmitting { *vfo = STATE(rig)->current_vfo; return RIG_OK; } SNPRINTF(cmd, sizeof(cmd), "L\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), channel, &channel_size); if (retval != RIG_OK) { if (retry-- > 0) { goto ptt_retry; } rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } *vfo = channel[1] == 'A' ? RIG_VFO_A : RIG_VFO_B; return RIG_OK; } static int jst145_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[MAX_LEN]; int retval; struct jst145_priv_data *priv = STATE(rig)->priv; vfo_t save_vfo = STATE(rig)->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = save_vfo; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%08u%c\r", (unsigned)(freq), vfo == RIG_VFO_A ? 'A' : 'B'); if (vfo == RIG_VFO_B) { priv->freqB = freq; } else { priv->freqA = freq; } retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block: %s\n", __func__, rigerror(retval)); return retval; } if (vfo != save_vfo) { retval = rig_set_vfo(rig, save_vfo); } return retval; } static int jst145_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[MAX_LEN]; char cmd[MAX_LEN]; int freqbuf_size = sizeof(freqbuf); int retval; int n; vfo_t save_vfo = STATE(rig)->current_vfo; //struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(save_vfo)); if (vfo == RIG_VFO_CURR) { vfo = save_vfo; } if (save_vfo != vfo) { rig_set_vfo(rig, vfo); } SNPRINTF(cmd, sizeof(cmd), "I\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), freqbuf, &freqbuf_size); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } n = sscanf(freqbuf, "I%*c%*c%*c%8lf", freq); if (n != 1) { retval = -RIG_EPROTO; } if (save_vfo != vfo) { rig_set_vfo(rig, save_vfo); } return retval; } static int jst145_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *modestr; struct jst145_priv_data *priv = STATE(rig)->priv; switch (mode) { case RIG_MODE_RTTY: modestr = "D0\r"; break; case RIG_MODE_CW: modestr = "D1\r"; break; case RIG_MODE_USB: modestr = "D2\r"; break; case RIG_MODE_LSB: modestr = "D3\r"; break; case RIG_MODE_AM: modestr = "D4\r"; break; case RIG_MODE_FM: modestr = "D5\r"; break; default: return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) modestr, strlen(modestr)); if (retval != RIG_OK) { return retval; } priv->mode = mode; if (RIG_PASSBAND_NOCHANGE == width) { return retval; } // TODO: width -- could use B command but let user handle it for now return retval; } static int jst145_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char cmd[MAX_LEN]; char modebuf[MAX_LEN]; int modebuf_len = sizeof(modebuf); int retval; SNPRINTF(cmd, sizeof(cmd), "I\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), modebuf, &modebuf_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction failed: %s\n", __func__, rigerror(retval)); } switch (modebuf[3]) { case '0': *mode = RIG_MODE_RTTY; break; case '1': *mode = RIG_MODE_CW; break; case '2': *mode = RIG_MODE_USB; break; case '3': *mode = RIG_MODE_LSB; break; case '4': *mode = RIG_MODE_AM; break; case '5': *mode = RIG_MODE_FM; break; } return retval; } static int jst145_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } static int jst145_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { switch (level) { case RIG_LEVEL_AGC: { char *cmd = val.i == RIG_AGC_SLOW ? "G0\r" : (val.i == RIG_AGC_FAST ? "G1\r" : "G2\r"); return write_block(RIGPORT(rig), (unsigned char *) cmd, 3); } default: return -RIG_EINVAL; } return -RIG_EINVAL; } static int jst145_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[MAX_LEN]; SNPRINTF(membuf, sizeof(membuf), "C%03d\r", ch); return write_block(RIGPORT(rig), (unsigned char *) membuf, strlen(membuf)); } static int jst145_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_FROM_VFO: return write_block(RIGPORT(rig), (unsigned char *) "E1\r", 3); default: return -RIG_EINVAL; } return -RIG_EINVAL; } static int jst145_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmd[MAX_LEN]; struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: entered\n", __func__); SNPRINTF(cmd, sizeof(cmd), "X%c\r", ptt ? '1' : '0'); priv->ptt = ptt; return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } static int jst145_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char cmd[MAX_LEN]; char pttstatus[MAX_LEN]; int pttstatus_size = sizeof(pttstatus); int retval; struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: entered\n", __func__); SNPRINTF(cmd, sizeof(cmd), "X\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), pttstatus, &pttstatus_size); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } if (pttstatus[1] == '1') { *ptt = RIG_PTT_ON; } else { *ptt = RIG_PTT_OFF; } priv->ptt = CACHE(rig)->ptt = *ptt; return RIG_OK; } hamlib-4.6.5/rigs/jrc/nrd525.c0000664000175000017500000001530415056640443011364 /* * Hamlib JRC backend - NRD-525 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "iofunc.h" #include "jrc.h" static int nrd525_open(RIG *rig); static int nrd525_close(RIG *rig); static int nrd525_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int nrd525_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int nrd525_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int nrd525_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int nrd525_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int nrd525_set_mem(RIG *rig, vfo_t vfo, int ch); #define NRD525_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_FAX) #define NRD525_FUNC (RIG_FUNC_LOCK) #define NRD525_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC) #define NRD525_VFO (RIG_VFO_VFO) #define NRD525_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } /* * NRD-525 rig capabilities. * */ struct rig_caps nrd525_caps = { RIG_MODEL(RIG_MODEL_NRD525), .model_name = "NRD-525", .mfg_name = "JRC", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = NRD525_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = NRD525_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, NRD525_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(10), MHz(30), NRD525_MODES, -1, -1, NRD525_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), NRD525_MODES, -1, -1, NRD525_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD525_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_open = nrd525_open, .rig_close = nrd525_close, .set_freq = nrd525_set_freq, .set_mode = nrd525_set_mode, .set_func = nrd525_set_func, .set_level = nrd525_set_level, .set_mem = nrd525_set_mem, .vfo_op = nrd525_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ static int nrd525_open(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H1", 2); } static int nrd525_close(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H0", 2); } static int nrd525_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[12]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%08u", (unsigned)(freq / 10)); return write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); } static int nrd525_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *modestr; switch (mode) { case RIG_MODE_RTTY: modestr = "D0"; break; case RIG_MODE_CW: modestr = "D1"; break; case RIG_MODE_USB: modestr = "D2"; break; case RIG_MODE_LSB: modestr = "D3"; break; case RIG_MODE_AM: modestr = "D4"; break; case RIG_MODE_FM: modestr = "D5"; break; case RIG_MODE_FAX: modestr = "D6"; break; default: return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) modestr, strlen(modestr)); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } // TODO: width return retval; } static int nrd525_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } static int nrd525_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { switch (level) { case RIG_LEVEL_ATT: return write_block(RIGPORT(rig), (unsigned char *)(val.i != 0 ? "A1" : "A0"), 2); case RIG_LEVEL_AGC: return write_block(RIGPORT(rig), (unsigned char *)(val.i == RIG_AGC_SLOW ? "G0" : (val.i == RIG_AGC_FAST ? "G1" : "G2")), 2); default: return -RIG_EINVAL; } } static int nrd525_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[12]; SNPRINTF(membuf, sizeof(membuf), "C%03d", ch); return write_block(RIGPORT(rig), (unsigned char *) membuf, strlen(membuf)); } static int nrd525_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_FROM_VFO: return write_block(RIGPORT(rig), (unsigned char *) "E1", 2); default: return -RIG_EINVAL; } } hamlib-4.6.5/rigs/jrc/nrd535.c0000664000175000017500000001364415056640443011372 /* * Hamlib JRC backend - NRD-535 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "jrc.h" #define NRD535_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_ECSS|RIG_MODE_FAX) /* + FAX */ #define NRD535_FUNC (RIG_FUNC_NB|RIG_FUNC_NB2) #define NRD535_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_IF|RIG_LEVEL_AGC|RIG_LEVEL_CWPITCH) /*RIG_LEVEL_BWC*/ /* FIXME: add more from "U" command */ #define NRD535_PARM (RIG_PARM_TIME|RIG_PARM_BEEP) #define NRD535_VFO (RIG_VFO_VFO|RIG_VFO_MEM) /* * NRD-535, specs from http://mods.dk * * FIXME: measure S-meter levels */ #define NRD535_STR_CAL { 16, { \ { 0, 60 }, \ { 71, 50 }, \ { 75, 40 }, \ { 81, 30 }, \ { 87, 20 }, \ { 93, 10 }, \ { 100, 0 }, \ { 103, -6 }, \ { 107, -12 }, \ { 112, -18 }, \ { 118, -24 }, \ { 124, -30 }, \ { 133, -36 }, \ { 143, -42 }, \ { 152, -48 }, \ { 255, -60 }, \ } } /* * channel caps. */ #define NRD535_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } static const struct jrc_priv_caps nrd535_priv_caps = { .max_freq_len = 8, .info_len = 14, .mem_len = 17, .pbs_info_len = 7, .pbs_len = 4, .beep = 90, .beep_len = 2, .cw_pitch = "U2" }; /* * NRD-535 rig capabilities. * */ struct rig_caps nrd535_caps = { RIG_MODEL(RIG_MODEL_NRD535), .model_name = "NRD-535D", .mfg_name = "JRC", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 21, .timeout = 250, .retry = 3, .has_get_func = NRD535_FUNC, .has_set_func = NRD535_FUNC, .has_get_level = NRD535_LEVEL, .has_set_level = RIG_LEVEL_SET(NRD535_LEVEL), .has_get_parm = RIG_PARM_TIME, .has_set_parm = RIG_PARM_SET(NRD535_PARM), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 20 } }, [LVL_IF] = { .min = { .i = -2000 }, .max = { .i = 2000 } }, [LVL_CWPITCH] = { .min = { .i = -5000 }, .max = { .i = 5000 } }, /*[LVL_BWC] = { .min = { .i = 500 }, .max = { .i = 5500 }, .step = { .i = 10} },*/ }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_SLCT, .bank_qty = 0, .chan_desc_sz = 0, .priv = (void *)& nrd535_priv_caps, .chan_list = { { 0, 199, RIG_MTYPE_MEM, NRD535_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(30), NRD535_MODES, -1, -1, NRD535_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), NRD535_MODES, -1, -1, NRD535_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD535_MODES, 1}, {NRD535_MODES, 10}, {NRD535_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(2)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .str_cal = NRD535_STR_CAL, .rig_open = jrc_open, .rig_close = jrc_close, .set_freq = jrc_set_freq, .get_freq = jrc_get_freq, .set_mode = jrc_set_mode, .get_mode = jrc_get_mode, .set_vfo = jrc_set_vfo, .set_func = jrc_set_func, .get_func = jrc_get_func, .set_level = jrc_set_level, .get_level = jrc_get_level, .set_parm = jrc_set_parm, .get_parm = jrc_get_parm, .get_dcd = jrc_get_dcd, .set_trn = jrc_set_trn, .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, .set_channel = jrc_set_chan, .get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat, .get_powerstat = jrc_get_powerstat, .decode_event = jrc_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/jrc/jrc.c0000664000175000017500000011654215056640443011131 /* * Hamlib JRC backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "cal.h" #include "register.h" #include "jrc.h" /* * Carriage return */ #define EOM "\r" #define BUFSZ 32 /* * modes in use by the "2G" command */ #define MD_RTTY '0' #define MD_CW '1' #define MD_USB '2' #define MD_LSB '3' #define MD_AM '4' #define MD_FM '5' #define MD_AMS '6' #define MD_FAX '6' #define MD_ECSS_USB '7' #define MD_ECSS_LSB '8' #define MD_WFM '9' /* * jrc_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int jrc_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); set_transaction_active(rig); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { set_transaction_inactive(rig); return retval; } if (!data || !data_len) { set_transaction_inactive(rig); return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); set_transaction_inactive(rig); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } static int jrc2rig_mode(RIG *rig, char jmode, char jwidth, rmode_t *mode, pbwidth_t *width) { switch (jmode) { case MD_RTTY: *mode = RIG_MODE_RTTY; break; case MD_CW: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AMS: if (rig->caps->rig_model == RIG_MODEL_NRD535) { *mode = RIG_MODE_FAX; } else { *mode = RIG_MODE_AMS; } break; case MD_ECSS_USB: *mode = RIG_MODE_ECSSUSB; break; case MD_ECSS_LSB: *mode = RIG_MODE_ECSSLSB; break; case MD_WFM: *mode = RIG_MODE_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %c\n", __func__, jmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } /* * determine passband */ switch (jwidth) { case '0': *width = s_Hz(6000); //wide break; case '1': *width = s_Hz(2000); //inter break; case '2': *width = s_Hz(1000); //narr break; case '3': *width = s_Hz(12000); //aux - nrd535 only break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %c\n", __func__, jwidth); *width = RIG_PASSBAND_NORMAL; return -RIG_EINVAL; } return RIG_OK; } static int rig2jrc_mode(RIG *rig, rmode_t mode, pbwidth_t width, char *jmode, char *jwidth) { switch (mode) { case RIG_MODE_RTTY: *jmode = MD_RTTY; break; case RIG_MODE_CW: *jmode = MD_CW; break; case RIG_MODE_USB: *jmode = MD_USB; break; case RIG_MODE_LSB: *jmode = MD_LSB; break; case RIG_MODE_AM: *jmode = MD_AM; break; case RIG_MODE_FM: *jmode = MD_FM; break; case RIG_MODE_AMS: *jmode = MD_AMS; break; case RIG_MODE_FAX: *jmode = MD_FAX; break; case RIG_MODE_ECSSUSB: *jmode = MD_ECSS_USB; break; case RIG_MODE_ECSSLSB: *jmode = MD_ECSS_LSB; break; case RIG_MODE_WFM: *jmode = MD_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (RIG_PASSBAND_NOCHANGE == width) { *jwidth = '1'; return RIG_OK; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= s_Hz(1500)) { *jwidth = '2'; /*narr*/ } else if (width <= s_Hz(4000)) { *jwidth = '1'; /*inter*/ } else if (width <= s_Hz(9000)) { *jwidth = '0'; /*wide*/ } else if (rig->caps->rig_model == RIG_MODEL_NRD535) { *jwidth = '3'; /*aux - nrd535 only*/ } else { *jwidth = '1'; /*inter*/ } return RIG_OK; } int jrc_open(RIG *rig) { int retval; /* * Turning computer control ON, * Turn continuous mode on (for "I" query) */ if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "H1" EOM, 3, NULL, NULL); } else { retval = jrc_transaction(rig, "H1" EOM "I1"EOM, 6, NULL, NULL); } return retval; } int jrc_close(RIG *rig) { int retval; /* Turning computer control OFF */ retval = jrc_transaction(rig, "H0" EOM, 3, NULL, NULL); return retval; } /* * jrc_set_freq * Assumes rig!=NULL */ int jrc_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char freqbuf[BUFSZ]; if (freq >= (freq_t)pow(10, priv->max_freq_len)) { return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%0*"PRIll EOM, priv->max_freq_len, (int64_t)freq); return jrc_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } static int get_current_istate(RIG *rig, char *buf, int *buf_len) { int retval; /* * JRCs use "I" to get information, */ if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "I1" EOM "I0" EOM, 6, buf, buf_len); } else { retval = jrc_transaction(rig, "I" EOM, 2, buf, buf_len); } return retval; } /* * jrc_get_freq * Assumes rig!=NULL, freq!=NULL */ int jrc_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval; char freqbuf[BUFSZ]; int freq_len; //note: JRCs use "I" to get information retval = get_current_istate(rig, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } //I command returns Iabdffffffffg if (freqbuf[0] != 'I' || freq_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_freq: wrong answer %s, " "len=%d\n", freqbuf, freq_len); return -RIG_ERJCTED; } freqbuf[4 + priv->max_freq_len] = '\0'; /* extract freq */ sscanf(freqbuf + 4, "%"SCNfreq, freq); return RIG_OK; } /* * jrc_set_vfo * Assumes rig!=NULL */ int jrc_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmdbuf[16]; int retval; char vfo_function; switch (vfo) { case RIG_VFO_VFO: vfo_function = 'F'; break; case RIG_VFO_MEM: vfo_function = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "jrc_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "%c" EOM, vfo_function); retval = jrc_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); return retval; } /* * jrc_set_mode * Assumes rig!=NULL */ int jrc_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int retval; char amode, awidth; retval = rig2jrc_mode(rig, mode, width, &amode, &awidth); if (retval != RIG_OK) { return retval; } SNPRINTF(mdbuf, sizeof(mdbuf), "D" "%c" EOM, amode); retval = jrc_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "B" "%c" EOM, awidth); retval = jrc_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * jrc_get_mode * Assumes rig!=NULL, mode!=NULL, width!=NULL */ int jrc_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int md_len, retval; char mdbuf[BUFSZ]; char cmode; char cwidth; //note: JRCs use "I" to get information retval = get_current_istate(rig, mdbuf, &md_len); if (retval != RIG_OK) { return retval; } //I command returns Iabdffffffffg if (mdbuf[0] != 'I' || md_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mode: wrong answer %s, " "len=%d\n", mdbuf, md_len); return -RIG_ERJCTED; } /* extract width and mode */ cwidth = mdbuf[2]; cmode = mdbuf[3]; retval = jrc2rig_mode(rig, cmode, cwidth, mode, width); return retval; } /* * jrc_set_func * Assumes rig!=NULL */ int jrc_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; int blanker = 0; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_FAGC: /* FIXME: FAGC levels */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d" EOM, status ? 1 : 2); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_NB: case RIG_FUNC_NB2: if (!status) blanker = 0; else if (func == RIG_FUNC_NB) blanker = 1; else //if (func == RIG_FUNC_NB2) blanker = 2; SNPRINTF(cmdbuf, sizeof(cmdbuf), "N%d" EOM, blanker); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); /* * FIXME: which BB mode for NR and BC at same time ? */ case RIG_FUNC_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "BB%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_BC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "BB%d" EOM, status ? 2 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "DD%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_MN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "EE%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s\n", rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_func * Assumes rig!=NULL, status!=NULL */ int jrc_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, func_len; char funcbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_FAGC: /* FIXME: FAGC levels */ //retval = jrc_transaction (rig, "G" EOM, 2, funcbuf, &func_len); retval = get_current_istate(rig, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } //if (func_len != 3 || func_len != 6) { if (funcbuf[0] != 'I' || func_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } //*status = funcbuf[1] != '2'; *status = funcbuf[4 + priv->max_freq_len] != '2'; return RIG_OK; case RIG_FUNC_NB: case RIG_FUNC_NB2: retval = jrc_transaction(rig, "N" EOM, 2, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = (((func == RIG_FUNC_NB) && (funcbuf[1] == '1')) || ((func == RIG_FUNC_NB2) && (funcbuf[1] == '2'))); return RIG_OK; /* * FIXME: which BB mode for NR and BC at same time ? */ case RIG_FUNC_NR: retval = jrc_transaction(rig, "BB" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[2] == '1'; return RIG_OK; case RIG_FUNC_BC: retval = jrc_transaction(rig, "BB" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[2] == '2'; return RIG_OK; case RIG_FUNC_LOCK: retval = jrc_transaction(rig, "DD" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[1] == '1'; return RIG_OK; case RIG_FUNC_MN: retval = jrc_transaction(rig, "EE" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[1] == '1'; return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int jrc_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d" EOM, val.i ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "HH%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "JJ%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LL%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "FF%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #if 0 case RIG_LEVEL_TONE: SNPRINTF(cmdbuf, sizeof(cmdbuf), "KK%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #endif case RIG_LEVEL_NOTCHF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "GG%+04d" EOM, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #if 0 case RIG_LEVEL_BWC: if (priv->pbs_len == 3) { val.i /= 10; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "W%0*d" EOM, priv->pbs_len, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #endif case RIG_LEVEL_AGC: if (val.i < 10) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d" EOM, val.i == RIG_AGC_SLOW ? 0 : val.i == RIG_AGC_FAST ? 1 : 2); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "G3%03d" EOM, val.i / 20); } return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_CWPITCH: SNPRINTF(cmdbuf, sizeof(cmdbuf), "%s%+05d" EOM, priv->cw_pitch, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_IF: if (priv->pbs_len == 3) { val.i /= 10; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%+0*d" EOM, priv->pbs_len + 1, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_level * Assumes rig!=NULL, val!=NULL */ int jrc_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, lvl_len, lvl; char lvlbuf[BUFSZ]; char cwbuf[BUFSZ]; int cw_len; switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ retval = jrc_transaction(rig, "M" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[4] = '\0'; val->i = atoi(lvlbuf + 1); break; case RIG_LEVEL_STRENGTH: /* read calibrated A/D converted value */ retval = jrc_transaction(rig, "M" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[4] = '\0'; val->i = (int)rig_raw2val(atoi(lvlbuf + 1), &rig->caps->str_cal); break; case RIG_LEVEL_ATT: retval = get_current_istate(rig, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[1] == '1' ? 20 : 0; break; case RIG_LEVEL_AGC: retval = get_current_istate(rig, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[priv->info_len - 1] = '\0'; if (priv->info_len == 14) { switch (lvlbuf[priv->info_len - 2]) { case '0' : val->i = RIG_AGC_SLOW; break; case '1' : val->i = RIG_AGC_FAST; break; case '2' : val->i = RIG_AGC_OFF; break; default : val->i = RIG_AGC_FAST; } } else { val->i = atoi(lvlbuf + priv->info_len - 4); } break; case RIG_LEVEL_RF: retval = jrc_transaction(rig, "HH" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_AF: retval = jrc_transaction(rig, "JJ" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_SQL: retval = jrc_transaction(rig, "LL" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_NR: retval = jrc_transaction(rig, "FF" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; #if 0 case RIG_LEVEL_TONE: retval = jrc_transaction(rig, "KK" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%u", &lvl); val->f = (float)lvl / 255.0; break; #endif case RIG_LEVEL_NOTCHF: retval = jrc_transaction(rig, "GG" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; #if 0 case RIG_LEVEL_BWC: retval = jrc_transaction(rig, "W" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'W' || lvl_len != priv->pbs_len + 2) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 1, "%d", &lvl); if (priv->pbs_len == 3) { lvl *= 10; } val->i = lvl; break; #endif case RIG_LEVEL_CWPITCH: SNPRINTF(cwbuf, sizeof(cwbuf), "%s" EOM, priv->cw_pitch); cw_len = strlen(cwbuf); retval = jrc_transaction(rig, cwbuf, strlen(cwbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != cw_len + 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + (cw_len - 1), "%05d", &lvl); val->i = lvl; break; case RIG_LEVEL_IF: retval = jrc_transaction(rig, "P" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'P' || lvl_len != priv->pbs_info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 1, "%d", &lvl); if (priv->pbs_len == 3) { lvl *= 10; } val->i = lvl; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_set_parm * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int jrc_set_parm(RIG *rig, setting_t parm, value_t val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; int minutes; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_BACKLIGHT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AA%d" EOM, val.f > 0.5 ? 0 : 1); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_BEEP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "U%0*d" EOM, priv->beep_len, (priv->beep + val.i) ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_TIME: minutes = val.i / 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "R1%02d%02d" EOM, minutes / 60, minutes % 60); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_parm * Assumes rig!=NULL, val!=NULL */ int jrc_get_parm(RIG *rig, setting_t parm, value_t *val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, lvl_len, i; char lvlbuf[BUFSZ]; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_TIME: retval = jrc_transaction(rig, "R0" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* "Rhhmmss"CR */ if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "jrc_get_parm: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* convert ASCII to numeric 0..9 */ for (i = 1; i < 7; i++) { lvlbuf[i] -= '0'; } val->i = ((10 * lvlbuf[1] + lvlbuf[2]) * 60 + /* hours */ 10 * lvlbuf[3] + lvlbuf[4]) * 60 + /* minutes */ 10 * lvlbuf[5] + lvlbuf[6]; /* seconds */ break; case RIG_PARM_BEEP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "U%d" EOM, priv->beep / 10); retval = jrc_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != priv->beep_len + 2) { rig_debug(RIG_DEBUG_ERR, "jrc_get_parm: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[priv->beep_len] == 0 ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_dcd * Assumes rig!=NULL, dcd!=NULL */ int jrc_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int dcd_len, retval; retval = jrc_transaction(rig, "Q" EOM, 2, dcdbuf, &dcd_len); if (retval != RIG_OK) { return retval; } if (dcd_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_dcd: wrong answer %s, " "len=%d\n", dcdbuf, dcd_len); return -RIG_ERJCTED; } *dcd = dcdbuf[1] == '0' ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* * jrc_set_trn * Assumes rig!=NULL */ int jrc_set_trn(RIG *rig, int trn) { char *trncmd; /* transceive(continuous) mode not available in remote mode * so switch back and forth upon entering/leaving */ trncmd = trn == RIG_TRN_RIG ? "H0"EOM"I1"EOM : "H1"EOM"I1"EOM; return jrc_transaction(rig, trncmd, 6, NULL, NULL); } /* * jrc_set_powerstat * Assumes rig!=NULL */ int jrc_set_powerstat(RIG *rig, powerstat_t status) { char pwrbuf[BUFSZ]; SNPRINTF(pwrbuf, sizeof(pwrbuf), "T%d" EOM, status == RIG_POWER_ON ? 1 : 0); return jrc_transaction(rig, pwrbuf, strlen(pwrbuf), NULL, NULL); } /* * jrc_get_powerstat * Assumes rig!=NULL */ int jrc_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[BUFSZ]; int pwr_len, retval; if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "T" EOM, 2, pwrbuf, &pwr_len); if (retval != RIG_OK) { return retval; } if (pwr_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_powerstat: wrong answer %s, " "len=%d\n", pwrbuf, pwr_len); return -RIG_ERJCTED; } *status = pwrbuf[1] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } else { retval = jrc_transaction(rig, "I" EOM, 2, pwrbuf, &pwr_len); *status = retval != RIG_OK ? RIG_POWER_OFF : RIG_POWER_ON; return retval; } } /* * jrc_reset * Assumes rig!=NULL */ int jrc_reset(RIG *rig, reset_t reset) { char rstbuf[BUFSZ]; char rst; switch (reset) { case RIG_RESET_MCALL: rst = '1'; break; /* mem clear */ case RIG_RESET_VFO: rst = '2'; break; /* user setup default */ case RIG_RESET_MASTER: rst = '3'; break; /* 1 + 2 */ default: rig_debug(RIG_DEBUG_ERR, "jrc_reset: unsupported reset %d\n", reset); return -RIG_EINVAL; } SNPRINTF(rstbuf, sizeof(rstbuf), "Z%c" EOM, rst); return jrc_transaction(rig, rstbuf, strlen(rstbuf), NULL, NULL); } /* * jrc_set_mem * Assumes rig!=NULL */ int jrc_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; char membuf[BUFSZ]; int mem_len; if (ch < 0 || ch > rig->caps->chan_list[0].endc) { return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "C%03d" EOM, ch); /* don't care about the Automatic response from receiver */ return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), membuf, &mem_len); } /* * jrc_get_mem * Assumes rig!=NULL */ int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int mem_len, retval; char membuf[BUFSZ]; int chan; retval = jrc_transaction(rig, "L" EOM, 2, membuf, &mem_len); if (retval != RIG_OK) { return retval; } /* need to handle vacant memories LmmmV, len = 6 */ if ((mem_len != priv->mem_len) && (mem_len != 6)) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mem: wrong answer %s, " "len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } membuf[4] = '\0'; /*extract current channel*/ sscanf(membuf + 1, "%d", &chan); *ch = chan; return RIG_OK; } /* * jrc_set_chan * Assumes rig!=NULL */ int jrc_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; int retval; rmode_t mode; pbwidth_t width; channel_t current; /* read first to get current values */ current.channel_num = chan->channel_num; if ((retval = jrc_get_chan(rig, vfo, ¤t, 1)) != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%03d000", chan->channel_num); if (chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i == 20) { cmdbuf[4] = '1'; } mode = chan->mode; width = chan->width; if (RIG_MODE_NONE == mode) { mode = current.mode; } if (RIG_PASSBAND_NOCHANGE == width) { width = current.width; } retval = rig2jrc_mode(rig, mode, width, &cmdbuf[6], &cmdbuf[5]); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf + 7, sizeof(cmdbuf) - 7, "%0*"PRIll, priv->max_freq_len, (int64_t)chan->freq); if (priv->mem_len == 17) { switch (chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i) { case RIG_AGC_SLOW : cmdbuf[priv->mem_len - 2] = '0'; break; case RIG_AGC_FAST : cmdbuf[priv->mem_len - 2] = '1'; break; case RIG_AGC_OFF : cmdbuf[priv->mem_len - 2] = '2'; break; default : cmdbuf[priv->mem_len - 2] = '1'; } } else { SNPRINTF(cmdbuf + priv->mem_len - 4, sizeof(cmdbuf) - (priv->mem_len - 4), "%03d", chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i); } cmdbuf[priv->mem_len - 1] = 0x0d; return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * jrc_get_chan * Assumes rig!=NULL */ int jrc_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char membuf[BUFSZ], cmdbuf[BUFSZ]; int mem_len, retval; chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, ""); SNPRINTF(cmdbuf, sizeof(cmdbuf), "L%03d%03d" EOM, chan->channel_num, chan->channel_num); retval = jrc_transaction(rig, cmdbuf, strlen(cmdbuf), membuf, &mem_len); if (retval != RIG_OK) { return retval; } /* need to handle vacant memories LmmmV, len = 6 */ if ((mem_len != priv->mem_len) && (mem_len != 6)) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mem: wrong answer %s, " "len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } if (mem_len != 6) { char freqbuf[BUFSZ]; if (membuf[4] == '1') { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 20; } jrc2rig_mode(rig, membuf[6], membuf[5], &chan->mode, &chan->width); strncpy(freqbuf, membuf + 7, priv->max_freq_len); freqbuf[priv->max_freq_len] = 0x00; chan->freq = strtol(freqbuf, NULL, 10); if (priv->mem_len == 17) { switch (membuf[priv->mem_len - 2]) { case '0' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; case '1' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; case '2' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; } } else { strncpy(freqbuf, membuf + priv->mem_len - 4, 3); chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = strtol(freqbuf, NULL, 10); } } return RIG_OK; } /* * jrc_vfo_op * Assumes rig!=NULL */ int jrc_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const char *cmd; switch (op) { case RIG_OP_FROM_VFO: cmd = "E1" EOM; break; case RIG_OP_UP: cmd = "MM25" EOM; break; case RIG_OP_DOWN: cmd = "MM24" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "jrc_vfo_op: unsupported op %#x\n", op); return -RIG_EINVAL; } return jrc_transaction(rig, cmd, strlen(cmd), NULL, NULL); } /* * jrc_scan, scan operation * Assumes rig!=NULL * * Not really a scan operation so speaking. * You just make the rig increment frequency of decrement continuously, * depending on the sign of ch. * However, using DCD sensing, followed by a stop, you get it. */ int jrc_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { const char *scan_cmd = ""; switch (scan) { case RIG_SCAN_STOP: scan_cmd = "Y0" EOM; break; case RIG_SCAN_SLCT: scan_cmd = ch > 0 ? "Y+" EOM : "Y-" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported scan %#x", scan); return -RIG_EINVAL; } return jrc_transaction(rig, scan_cmd, 3, NULL, NULL); } /* * jrc_decode is called by sa_sigio, when some asynchronous * data has been received from the rig */ int jrc_decode_event(RIG *rig) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; freq_t freq; rmode_t mode; pbwidth_t width; int count; char buf[BUFSZ]; rig_debug(RIG_DEBUG_VERBOSE, "%s: jrc_decode called\n", __func__); /* "Iabdfg"CR */ //#define SETUP_STATUS_LEN 17 //count = read_string(RIGPORT(rig), buf, SETUP_STATUS_LEN, "", 0); count = read_string(RIGPORT(rig), (unsigned char *) buf, priv->info_len, "", 0, 0, 1); if (count < 0) { return count; } buf[31] = '\0'; /* stop run away.. */ if (buf[0] != 'I') { rig_debug(RIG_DEBUG_WARN, "jrc: unexpected data: %s\n", buf); return -RIG_EPROTO; } /* * TODO: Attenuator and AGC change notification. */ if (rig->callbacks.freq_event) { //buf[14] = '\0'; /* side-effect: destroy AGC first digit! */ buf[4 + priv->max_freq_len] = '\0'; /* side-effect: destroy AGC first digit! */ sscanf(buf + 4, "%"SCNfreq, &freq); return rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { jrc2rig_mode(rig, buf[3], buf[2], &mode, &width); return rig->callbacks.mode_event(rig, RIG_VFO_CURR, mode, width, rig->callbacks.freq_arg); } return RIG_OK; } /* * initrigs_jrc is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(jrc) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&nrd535_caps); rig_register(&nrd545_caps); rig_register(&nrd525_caps); rig_register(&jst145_caps); rig_register(&jst245_caps); return RIG_OK; } hamlib-4.6.5/rigs/jrc/nrd545.c0000664000175000017500000001456615056640443011377 /* * Hamlib JRC backend - NRD-545 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "jrc.h" #define NRD545_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_AMS|RIG_MODE_ECSS) #define NRD545_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_LOCK|RIG_FUNC_BC|RIG_FUNC_NR|RIG_FUNC_MN) #define NRD545_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_IF|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH) /*RIG_LEVEL_BWC*/ /* FIXME: add more from "U" command */ #define NRD545_PARM (RIG_PARM_TIME|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define NRD545_VFO (RIG_VFO_VFO|RIG_VFO_MEM) /* * FIXME: measure S-meter levels */ #define NRD545_STR_CAL { 16, { \ { 0, -60 }, \ { 36, -48 }, \ { 42, -42 }, \ { 48, -36 }, \ { 55, -30 }, \ { 60, -24 }, \ { 67, -18 }, \ { 72, -12 }, \ { 78, -6 }, \ { 87, 0 }, \ { 107, 10 }, \ { 126, 20 }, \ { 146, 30 }, \ { 164, 40 }, \ { 186, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define NRD545_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } static const struct jrc_priv_caps nrd545_priv_caps = { .max_freq_len = 10, .info_len = 18, .mem_len = 21, .pbs_info_len = 6, .pbs_len = 3, .beep = 100, .beep_len = 3, .cw_pitch = "U14" }; /* * NRD-545 rig capabilities. * */ struct rig_caps nrd545_caps = { RIG_MODEL(RIG_MODEL_NRD545), .model_name = "NRD-545 DSP", .mfg_name = "JRC", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = NRD545_FUNC, .has_set_func = NRD545_FUNC, .has_get_level = NRD545_LEVEL, .has_set_level = RIG_LEVEL_SET(NRD545_LEVEL), .has_get_parm = RIG_PARM_TIME, .has_set_parm = RIG_PARM_SET(NRD545_PARM), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 20 } }, [LVL_IF] = { .min = { .i = -2550 }, .max = { .i = 2550 }, .step = { .i = 10} }, [LVL_NOTCHF] = { .min = { .i = -1023 }, .max = { .i = 1023 } }, [LVL_CWPITCH] = { .min = { .i = -2550 }, .max = { .i = 2550 } }, /*[LVL_BWC] = { .min = { .i = 10 }, .max = { .i = 9990 }, .step = { .i = 10} },*/ }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* To be confirmed */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2.3), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .vfo_ops = RIG_OP_FROM_VFO | RIG_OP_UP | RIG_OP_DOWN, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_SLCT, .bank_qty = 0, .chan_desc_sz = 0, .priv = (void *)& nrd545_priv_caps, .chan_list = { { 0, 999, RIG_MTYPE_MEM, NRD545_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), NRD545_MODES, -1, -1, NRD545_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD545_MODES, 1}, {NRD545_MODES, 10}, {NRD545_MODES, 100}, {NRD545_MODES, kHz(1)}, {NRD545_MODES, kHz(5)}, {NRD545_MODES, kHz(6.25)}, {NRD545_MODES, kHz(9)}, {NRD545_MODES, kHz(10)}, {NRD545_MODES, kHz(12.5)}, {NRD545_MODES, kHz(20)}, {NRD545_MODES, kHz(25)}, {NRD545_MODES, kHz(30)}, {NRD545_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_AMS | RIG_MODE_ECSS | RIG_MODE_FM, kHz(10)}, {RIG_MODE_AM | RIG_MODE_AMS | RIG_MODE_ECSS | RIG_MODE_FM, kHz(4.5)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4.5)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2.4)}, RIG_FLT_END, }, .str_cal = NRD545_STR_CAL, .rig_open = jrc_open, .rig_close = jrc_close, .set_freq = jrc_set_freq, .get_freq = jrc_get_freq, .set_mode = jrc_set_mode, .get_mode = jrc_get_mode, .set_vfo = jrc_set_vfo, .set_func = jrc_set_func, .get_func = jrc_get_func, .set_level = jrc_set_level, .get_level = jrc_get_level, .set_parm = jrc_set_parm, .get_parm = jrc_get_parm, .get_dcd = jrc_get_dcd, .set_trn = jrc_set_trn, .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, .set_channel = jrc_set_chan, .get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat, .get_powerstat = jrc_get_powerstat, .decode_event = jrc_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/jrc/Android.mk0000664000175000017500000000041715056640443012111 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := nrd535.c nrd545.c nrd525.c jrc.c LOCAL_MODULE := jrc LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/jrc/jrc.h0000664000175000017500000000524615056640443011134 /* * Hamlib JRC backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _JRC_H #define _JRC_H 1 #include #define BACKEND_VER "20200320" struct jrc_priv_caps { int max_freq_len; int info_len; int mem_len; int pbs_info_len; int pbs_len; int beep; int beep_len; const char * cw_pitch; }; int jrc_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int jrc_open(RIG *rig); int jrc_close(RIG *rig); int jrc_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int jrc_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int jrc_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int jrc_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int jrc_set_vfo(RIG *rig, vfo_t vfo); int jrc_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int jrc_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int jrc_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int jrc_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int jrc_set_parm(RIG *rig, setting_t parm, value_t val); int jrc_get_parm(RIG *rig, setting_t parm, value_t *val); int jrc_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int jrc_set_trn(RIG *rig, int trn); int jrc_set_mem(RIG *rig, vfo_t vfo, int ch); int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch); int jrc_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan); int jrc_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int jrc_set_powerstat(RIG *rig, powerstat_t status); int jrc_get_powerstat(RIG *rig, powerstat_t *status); int jrc_reset(RIG *rig, reset_t reset); int jrc_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int jrc_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int jrc_decode_event(RIG *rig); extern struct rig_caps nrd535_caps; extern struct rig_caps nrd545_caps; extern struct rig_caps nrd525_caps; extern struct rig_caps jst145_caps; extern struct rig_caps jst245_caps; #endif /* _JRC_H */ hamlib-4.6.5/rigs/jrc/Makefile.in0000664000175000017500000005372115056640452012253 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/jrc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_jrc_la_LIBADD = am__objects_1 = nrd535.lo nrd545.lo nrd525.lo jrc.lo jst145.lo am_libhamlib_jrc_la_OBJECTS = $(am__objects_1) libhamlib_jrc_la_OBJECTS = $(am_libhamlib_jrc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/jrc.Plo ./$(DEPDIR)/jst145.Plo \ ./$(DEPDIR)/nrd525.Plo ./$(DEPDIR)/nrd535.Plo \ ./$(DEPDIR)/nrd545.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_jrc_la_SOURCES) DIST_SOURCES = $(libhamlib_jrc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ JRCSRC = nrd535.c nrd545.c nrd525.c jrc.c jrc.h jst145.c noinst_LTLIBRARIES = libhamlib-jrc.la libhamlib_jrc_la_SOURCES = $(JRCSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/jrc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/jrc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-jrc.la: $(libhamlib_jrc_la_OBJECTS) $(libhamlib_jrc_la_DEPENDENCIES) $(EXTRA_libhamlib_jrc_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_jrc_la_OBJECTS) $(libhamlib_jrc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jst145.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd525.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd535.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd545.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/jrc.Plo -rm -f ./$(DEPDIR)/jst145.Plo -rm -f ./$(DEPDIR)/nrd525.Plo -rm -f ./$(DEPDIR)/nrd535.Plo -rm -f ./$(DEPDIR)/nrd545.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/jrc.Plo -rm -f ./$(DEPDIR)/jst145.Plo -rm -f ./$(DEPDIR)/nrd525.Plo -rm -f ./$(DEPDIR)/nrd535.Plo -rm -f ./$(DEPDIR)/nrd545.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/jrc/Makefile.am0000664000175000017500000000023615056640443012233 JRCSRC = nrd535.c nrd545.c nrd525.c jrc.c jrc.h jst145.c noinst_LTLIBRARIES = libhamlib-jrc.la libhamlib_jrc_la_SOURCES = $(JRCSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/icmarine/0000775000175000017500000000000015056640477011276 5hamlib-4.6.5/rigs/icmarine/icmarine.c0000664000175000017500000004347315056640443013155 /* * Hamlib ICOM Marine backend - main file * Copyright (c) 2014-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include "icmarine.h" /* * NMEA 0183 protocol * * Total message is maximum 82 characters, including '$' and CR+LF. * * Serial setup is 8N1, msb always 0, -> ASCII protocol * * Proprietary Extension Message format: * Byte pos Length Value Description * 0 1 0x24 '$' Start character * 1 1 0x50 'P' Type: Proprietary * 2 3 'ICO' Manufacturer ID * 5 Message Data */ /* CR LF */ #define EOM "\x0d\x0a" #define LF "\x0a" #define BUFSZ 96 #define OFFSET_CMD 13 /* * Protocol stuff */ #define CONTROLLER_ID 90 #if 0 #define MD_LSB "J3E" #define MD_USB "J3E" #define MD_CW "A1A" #define MD_AM "A3E" #else #define MD_LSB "LSB" #define MD_USB "USB" #define MD_CW "CW" #define MD_AM "AM" #endif #define MD_FSK "J2B" #define CMD_TXFREQ "TXF" /* Transmit frequency */ #define CMD_RXFREQ "RXF" /* Receive frequency */ #define CMD_MODE "MODE" /* Mode */ #define CMD_REMOTE "REMOTE" /* Remote */ #define CMD_PTT "TRX" /* PTT */ #define CMD_AFGAIN "AFG" #define CMD_RFGAIN "RFG" #define CMD_RFPWR "TXP" #define CMD_NB "NB" #define CMD_AGC "AGC" #define CMD_TUNER "TUNER" /* Data Output Commands */ #define CMD_SMETER "SIGM" /* S-meter read */ #define CMD_SQLS "SQLS" /* Squelch status */ /* Tokens */ #define TOK_REMOTEID TOKEN_BACKEND(1) int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response); const struct confparams icmarine_cfg_params[] = { { TOK_REMOTEID, "remoteid", "Remote ID", "Transceiver's remote ID", "1", RIG_CONF_NUMERIC, { .n = { 1, 99, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Basically, set up *priv */ int icmarine_init(RIG *rig) { struct icmarine_priv_data *priv; const struct icmarine_priv_caps *priv_caps; struct rig_caps *caps; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; if (!caps->priv) { return -RIG_ECONF; } priv_caps = (const struct icmarine_priv_caps *) caps->priv; STATE(rig)->priv = (struct icmarine_priv_data *)calloc(1, sizeof( struct icmarine_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->remote_id = priv_caps->default_remote_id; priv->split = RIG_SPLIT_OFF; return RIG_OK; } int icmarine_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } #ifdef XXREMOVEDXX // This function not referenced -- doesn't do anything really int icmarine_open(RIG *rig) { char respbuf[BUFSZ + 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); int retval = icmarine_transaction(rig, "REMOTE", "ON", respbuf); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } #endif int icmarine_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icmarine_priv_data *priv; priv = (struct icmarine_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: priv->remote_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int icmarine_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icmarine_priv_data *priv; priv = (struct icmarine_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: SNPRINTF(val, val_len, "%u", priv->remote_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int icmarine_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icmarine_get_conf2(rig, token, val, 128); } /* * icmarine_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * * cmd: mandatory * param: only 1 optional NMEA parameter, NULL for none (=query) * response: optional (holding BUFSZ bytes) */ int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response) { struct icmarine_priv_data *priv; int i, retval; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ + 1]; char respbuf[BUFSZ + 1]; char *p; char *strip; int cmd_len; unsigned csum = 0; rig_debug(RIG_DEBUG_TRACE, "%s: cmd='%s', param=%s\n", __func__, cmd, param == NULL ? "NULL" : param); rs = STATE(rig); priv = (struct icmarine_priv_data *)rs->priv; rig_flush(rp); /* command formatting */ SNPRINTF(cmdbuf, BUFSZ, "$PICOA,%02d,%02u,%s", CONTROLLER_ID, priv->remote_id, cmd); cmd_len = strlen(cmdbuf); if (param) { cmd_len += snprintf(cmdbuf + cmd_len, BUFSZ - cmd_len, ",%s", param); } /* NMEA checksum, between '$' and '*' */ for (i = 1; i < cmd_len; i++) { csum = csum ^ (unsigned)cmdbuf[i]; } cmd_len += snprintf(cmdbuf + cmd_len, BUFSZ - cmd_len, "*%02X" EOM, csum); /* I/O */ retval = write_block(rp, (unsigned char *) cmdbuf, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF */ retval = read_string(rp, (unsigned char *) respbuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } /* Minimal length */ if (retval < OFFSET_CMD + 5) { return -RIG_EPROTO; } /* check response */ if (memcmp(respbuf, "$PICOA,", strlen("$PICOA,")) != 0) { return -RIG_EPROTO; } /* TODO: check ID's */ /* if not a query, check for correct as acknowledge */ if (param) { if (memcmp(cmdbuf + OFFSET_CMD, respbuf + OFFSET_CMD, cmd_len - OFFSET_CMD - 5) == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } /* strip from *checksum and after */ strip = strrchr(respbuf, '*'); if (strip) { *strip = 0; } else { rig_debug(RIG_DEBUG_ERR, "%s: checksum not in response? response='%s'\n", __func__, respbuf); return -RIG_EPROTO; } p = strrchr(respbuf, ','); if (p) { strncpy(response, p + 1, BUFSZ); } else { return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning response='%s'\n", __func__, response == NULL ? "NULL" : response); return RIG_OK; } int icmarine_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); /* no error reporting upon TXFREQ failure */ if (RIG_SPLIT_OFF == priv->split) { icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); } return icmarine_transaction(rig, CMD_RXFREQ, freqbuf, NULL); } /* * icmarine_get_freq * Assumes rig!=NULL, freq!=NULL */ int icmarine_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ] = ""; double d; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_RXFREQ, NULL, freqbuf); if (retval != RIG_OK) { return retval; } if (freqbuf[0] == '\0') { *freq = 0; } else { if (sscanf(freqbuf, "%lf", &d) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: sscanf('%s') failed\n", __func__, freqbuf); return -RIG_EPROTO; } *freq = (freq_t)(d * MHz(1)); } return RIG_OK; } int icmarine_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); return icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); } int icmarine_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ] = ""; double d; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_TXFREQ, NULL, freqbuf); if (retval != RIG_OK) { return retval; } if (freqbuf[0] == '\0') { *freq = 0; } else { if (sscanf(freqbuf, "%lf", &d) != 1) { return -RIG_EPROTO; } *freq = (freq_t)(d * MHz(1)); } return RIG_OK; } int icmarine_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; /* when disabling split mode */ if (RIG_SPLIT_ON == priv->split && RIG_SPLIT_OFF == split) { freq_t freq; if (RIG_OK == icmarine_get_freq(rig, rx_vfo, &freq)) { icmarine_set_tx_freq(rig, rx_vfo, freq); } } priv->split = split; return RIG_OK; } int icmarine_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = rx_vfo; return RIG_OK; } /* REM: no way to change passband width ? */ int icmarine_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *pmode; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (mode) { case RIG_MODE_CW: pmode = MD_CW; break; case RIG_MODE_USB: pmode = MD_USB; break; case RIG_MODE_LSB: pmode = MD_LSB; break; case RIG_MODE_AM: pmode = MD_AM; break; case RIG_MODE_RTTY: pmode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_MODE, pmode, NULL); } int icmarine_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char modebuf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_MODE, NULL, modebuf); if (retval != RIG_OK) { return retval; } if (!memcmp(modebuf, MD_LSB, strlen(MD_LSB))) { *mode = RIG_MODE_LSB; } else if (!memcmp(modebuf, MD_USB, strlen(MD_USB))) { *mode = RIG_MODE_USB; } else if (!memcmp(modebuf, MD_CW, strlen(MD_CW))) { *mode = RIG_MODE_CW; } else if (!memcmp(modebuf, MD_AM, strlen(MD_AM))) { *mode = RIG_MODE_AM; } else if (!memcmp(modebuf, MD_FSK, strlen(MD_FSK))) { *mode = RIG_MODE_RTTY; } else { retval = -RIG_EPROTO; } if (retval == RIG_OK) { *width = rig_passband_normal(rig, *mode); } return retval; } /* * Rem: The "TX" command will fail on invalid frequencies. */ int icmarine_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_PTT, ptt == RIG_PTT_ON ? "TX" : "RX", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed\n", __func__); return retval; } return RIG_OK; } int icmarine_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_PTT, NULL, pttbuf); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed\n", __func__); return retval; } if (strncmp(pttbuf, "TX", 2) == 0) { *ptt = RIG_PTT_ON; } else if (strncmp(pttbuf, "RX", 2) == 0) { *ptt = RIG_PTT_OFF; } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid pttbuf='%s'\n", __func__, pttbuf); retval = -RIG_EPROTO; } return retval; } int icmarine_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_SQLS, NULL, dcdbuf); if (retval != RIG_OK) { return retval; } if (!strcmp(dcdbuf, "OPEN")) { *dcd = RIG_DCD_ON; } else if (!strcmp(dcdbuf, "CLOSE")) { *dcd = RIG_DCD_OFF; } else { retval = -RIG_EPROTO; } return retval; } int icmarine_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); if (RIG_OP_TUNE != op && RIG_OP_NONE != op) { return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_TUNER, RIG_OP_TUNE == op ? "ON" : "OFF", NULL); } int icmarine_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, status ? "ON" : "OFF", NULL); break; default: return -RIG_EINVAL; } return retval; } int icmarine_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char funcbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, NULL, funcbuf); break; default: return -RIG_EINVAL; } *status = !strcmp(funcbuf, "ON"); return retval; } int icmarine_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char lvlbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (level) { case RIG_LEVEL_AF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", (unsigned)(val.f * 255)); retval = icmarine_transaction(rig, CMD_AFGAIN, lvlbuf, NULL); break; case RIG_LEVEL_RF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", (unsigned)(val.f * 9)); retval = icmarine_transaction(rig, CMD_RFGAIN, lvlbuf, NULL); break; case RIG_LEVEL_RFPOWER: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", 1 + (unsigned)(val.f * 2)); retval = icmarine_transaction(rig, CMD_RFPWR, lvlbuf, NULL); break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, RIG_AGC_OFF == val.i ? "OFF" : "ON", NULL); break; default: return -RIG_EINVAL; } return retval; } int icmarine_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (level) { case RIG_LEVEL_RAWSTR: retval = icmarine_transaction(rig, CMD_SMETER, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '0' || lvlbuf[0] > '9') { return -RIG_EPROTO; } val->i = lvlbuf[0] - '0'; break; case RIG_LEVEL_AF: retval = icmarine_transaction(rig, CMD_AFGAIN, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } val->f = atof(lvlbuf) / 255.; break; case RIG_LEVEL_RF: retval = icmarine_transaction(rig, CMD_RFGAIN, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '0' || lvlbuf[0] > '9') { return -RIG_EPROTO; } val->f = (float)(lvlbuf[0] - '0') / 9.; break; case RIG_LEVEL_RFPOWER: retval = icmarine_transaction(rig, CMD_RFPWR, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '1' || lvlbuf[0] > '3') { return -RIG_EPROTO; } val->f = (float)(lvlbuf[0] - '1') / 3.; break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } val->i = !strcmp(lvlbuf, "ON") ? RIG_AGC_SLOW : RIG_AGC_OFF; break; default: return -RIG_EINVAL; } return retval; } /* * initrigs_icmarine is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icmarine) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&icm700pro_caps); rig_register(&icm710_caps); rig_register(&icm802_caps); rig_register(&icm803_caps); return RIG_OK; } hamlib-4.6.5/rigs/icmarine/icmarine.h0000664000175000017500000000614215056640443013152 /* * Hamlib ICOM Marine backend - main header * Copyright (c) 2014-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICMARINE_H #define _ICMARINE_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20181007" struct icmarine_priv_caps { unsigned char default_remote_id; /* the remote default equipment's ID */ }; struct icmarine_priv_data { unsigned char remote_id; /* the remote equipment's ID */ split_t split; /* current split mode */ }; extern const struct confparams icmarine_cfg_params[]; int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response); int icmarine_init(RIG *rig); int icmarine_cleanup(RIG *rig); int icmarine_open(RIG *rig); int icmarine_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icmarine_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icmarine_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq); int icmarine_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icmarine_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icmarine_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icmarine_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icmarine_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icmarine_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icmarine_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icmarine_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icmarine_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icmarine_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int icmarine_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int icmarine_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icmarine_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icmarine_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icmarine_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icmarine_set_parm(RIG *rig, setting_t parm, value_t val); int icmarine_get_parm(RIG *rig, setting_t parm, value_t *val); int icmarine_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icmarine_get_conf(RIG *rig, hamlib_token_t token, char *val); int icmarine_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); extern struct rig_caps icm700pro_caps; extern struct rig_caps icm710_caps; extern struct rig_caps icm802_caps; extern struct rig_caps icm803_caps; #endif /* _ICMARINE_H */ hamlib-4.6.5/rigs/icmarine/icm710.h0000664000175000017500000000636715056640443012374 /* * Hamlib ICOM M710 backend - main header * Copyright (c) 2014-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICM710_H #define _ICM710_H 1 #include #include "hamlib/rig.h" struct icm710_priv_caps { unsigned char default_remote_id; /* the remote default equipment's ID */ }; /* The M710 does not support queries */ /* So we keep a copy of settings in priv to support get functions */ /* The priv settings only reflect what has been previously set */ /* So get's will return 0 until the value has been set */ struct icm710_priv_data { unsigned char remote_id; /* the remote equipment's ID */ split_t split; /* current split mode */ freq_t rxfreq, txfreq; mode_t mode; ptt_t ptt; unsigned afgain; unsigned rfgain; unsigned rfpwr; unsigned agc; }; extern const struct confparams icm710_cfg_params[]; int icm710_init(RIG *rig); int icm710_cleanup(RIG *rig); int icm710_open(RIG *rig); int icm710_close(RIG *rig); int icm710_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icm710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icm710_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq); int icm710_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icm710_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icm710_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icm710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icm710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icm710_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icm710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icm710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icm710_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icm710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int icm710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icm710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icm710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icm710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icm710_set_parm(RIG *rig, setting_t parm, value_t val); int icm710_get_parm(RIG *rig, setting_t parm, value_t *val); int icm710_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icm710_get_conf(RIG *rig, hamlib_token_t token, char *val); int icm710_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); extern struct rig_caps icm700pro_caps; extern struct rig_caps icm710_caps; extern struct rig_caps icm802_caps; #endif /* _ICM710_H */ hamlib-4.6.5/rigs/icmarine/icm710.c0000664000175000017500000004136115056640443012360 /* * Hamlib ICOM Marine backend - description of IC-M710 caps * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2017 by Michael Black W9MDB * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "idx_builtin.h" #include "icm710.h" #include "icmarine.h" #define ICM710_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM710_RX_MODES (ICM710_MODES|RIG_MODE_AM) #define ICM710_FUNC_ALL (RIG_FUNC_NB) #define ICM710_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM710_VFO_ALL (RIG_VFO_A) #define ICM710_VFO_OPS (RIG_OP_TUNE) #define ICM710_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM710_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icm710_priv_caps icm710_priv_caps = { .default_remote_id = 0x01, /* default address */ }; struct rig_caps icm710_caps = { RIG_MODEL(RIG_MODEL_IC_M710), .model_name = "IC-M710", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM710_FUNC_ALL, .has_set_func = ICM710_FUNC_ALL, .has_get_level = ICM710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM710_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM710_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM710_VFO_OPS, //.scan_ops = ICM710_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM710_RX_MODES, -1, -1, ICM710_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM710_MODES, W(60), W(60), ICM710_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM710_RX_MODES, -1, -1, ICM710_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM710_MODES, W(20), W(60), ICM710_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM710_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icm710_cfg_params, .set_conf = icm710_set_conf, .get_conf = icm710_get_conf, .get_conf2 = icm710_get_conf2, .priv = (void *)& icm710_priv_caps, .rig_init = icm710_init, .rig_cleanup = icm710_cleanup, .rig_open = icm710_open, .rig_close = icm710_close, .set_freq = icm710_set_freq, .get_freq = icm710_get_freq, .set_split_freq = icm710_set_tx_freq, .get_split_freq = icm710_get_tx_freq, .set_split_vfo = icm710_set_split_vfo, .get_split_vfo = icm710_get_split_vfo, .set_mode = icm710_set_mode, .get_mode = icm710_get_mode, .set_ptt = icm710_set_ptt, .get_ptt = icm710_get_ptt, .vfo_op = icm710_vfo_op, .set_level = icm710_set_level, .get_level = icm710_get_level, .set_func = icm710_set_func, .get_func = icm710_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * NMEA 0183 protocol * * Total message is maximum 82 characters, including '$' and CR+LF. * * Serial setup is 8N1, msb always 0, -> ASCII protocol * * Proprietary Extension Message format: * Byte pos Length Value Description * 0 1 0x24 '$' Start character * 1 1 0x50 'P' Type: Proprietary * 2 3 'ICO' Manufacturer ID * 5 Message Data */ /* CR LF */ #define EOM "\x0d\x0a" #define BUFSZ 96 /* * Protocol stuff */ #define CONTROLLER_ID 90 #define MD_LSB "LSB" #define MD_USB "USB" #define MD_CW "CW" #define MD_AM "AM" #define MD_FSK "AFS" #define CMD_TXFREQ "TXF" /* Transmit frequency */ #define CMD_RXFREQ "RXF" /* Receive frequency */ #define CMD_MODE "MODE" /* Mode */ #define CMD_REMOTE "REMOTE" /* Remote */ #define CMD_PTT "TRX" /* PTT */ #define CMD_AFGAIN "AFG" #define CMD_RFGAIN "RFG" #define CMD_RFPWR "TXP" #define CMD_NB "NB" #define CMD_AGC "AGC" #define CMD_TUNER "TUNER" /* Data Output Commands */ #define CMD_SMETER "SIGM" /* S-meter read */ #define CMD_SQLS "SQLS" /* Squelch status */ /* Tokens */ #define TOK_REMOTEID TOKEN_BACKEND(1) const struct confparams icm710_cfg_params[] = { { TOK_REMOTEID, "remoteid", "Remote ID", "Transceiver's remote ID", "1", RIG_CONF_NUMERIC, { .n = { 1, 99, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Basically, set up *priv */ int icm710_init(RIG *rig) { struct icm710_priv_data *priv; const struct icm710_priv_caps *priv_caps; struct rig_caps *caps; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; if (!caps->priv) { return -RIG_ECONF; } priv_caps = (const struct icm710_priv_caps *) caps->priv; STATE(rig)->priv = (struct icm710_priv_data *)calloc(1, sizeof(struct icm710_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->remote_id = priv_caps->default_remote_id; priv->split = RIG_SPLIT_OFF; return RIG_OK; } int icm710_open(RIG *rig) { int retval = icmarine_transaction(rig, "REMOTE", "ON", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } int icm710_close(RIG *rig) { int retval = icmarine_transaction(rig, "REMOTE", "OFF", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } int icm710_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int icm710_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: priv->remote_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int icm710_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: SNPRINTF(val, val_len, "%u", priv->remote_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int icm710_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icm710_get_conf2(rig, token, val, 128); } int icm710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; struct icm710_priv_data *priv; int retval; priv = (struct icm710_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); /* no error reporting upon TXFREQ failure */ if (RIG_SPLIT_OFF == priv->split) { retval = icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->txfreq = freq; } retval = icmarine_transaction(rig, CMD_RXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->rxfreq = freq; return RIG_OK; } /* * icm710_get_freq * Assumes rig!=NULL, freq!=NULL * The M710 does not respond to queries so we keep our own copy of things as a virtual rig response */ int icm710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { *freq = ((struct icm710_priv_data *)STATE(rig)->priv)->rxfreq; return RIG_OK; } int icm710_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int retval; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); retval = icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->txfreq = freq; return RIG_OK; } int icm710_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; *freq = priv->txfreq; return RIG_OK; } int icm710_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; /* when disabling split mode */ if (RIG_SPLIT_ON == priv->split && RIG_SPLIT_OFF == split) { int retval = icm710_set_tx_freq(rig, rx_vfo, priv->rxfreq); if (retval != RIG_OK) { return retval; } } priv->split = split; return RIG_OK; } int icm710_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = rx_vfo; return RIG_OK; } /* REM: no way to change passband width ? */ int icm710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *pmode; switch (mode) { case RIG_MODE_CW: pmode = MD_CW; break; case RIG_MODE_USB: pmode = MD_USB; break; case RIG_MODE_LSB: pmode = MD_LSB; break; case RIG_MODE_AM: pmode = MD_AM; break; case RIG_MODE_RTTY: pmode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_MODE, pmode, NULL); } int icm710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = ((struct icm710_priv_data *)STATE(rig)->priv)->mode; *width = 2200; return RIG_OK; } /* * Rem: The "TX" command will fail on invalid frequencies. */ int icm710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; retval = icmarine_transaction(rig, CMD_PTT, ptt == RIG_PTT_ON ? "TX" : "RX", NULL); if (retval != RIG_OK) { return retval; } priv->ptt = ptt; return RIG_OK; } int icm710_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { *ptt = ((struct icm710_priv_data *)STATE(rig)->priv)->ptt; return RIG_OK; } int icm710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { if (RIG_OP_TUNE != op && RIG_OP_NONE != op) { return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_TUNER, RIG_OP_TUNE == op ? "ON" : "OFF", NULL); } int icm710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, status ? "ON" : "OFF", NULL); break; default: return -RIG_EINVAL; } return retval; } int icm710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char funcbuf[BUFSZ]; int retval; switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, NULL, funcbuf); break; default: return -RIG_EINVAL; } *status = !strcmp(funcbuf, "ON"); return retval; } int icm710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char lvlbuf[BUFSZ]; int retval; unsigned value; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_AF: value = (unsigned)(val.f * 255); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_AFGAIN, lvlbuf, NULL); if (retval == RIG_OK) { priv->afgain = value; } break; case RIG_LEVEL_RF: value = (unsigned)(val.f * 9); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_RFGAIN, lvlbuf, NULL); if (retval == RIG_OK) { priv->rfgain = value; } break; case RIG_LEVEL_RFPOWER: value = (unsigned)(val.f * 2); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_RFPWR, lvlbuf, NULL); if (retval == RIG_OK) { priv->rfpwr = value; } break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, RIG_AGC_OFF == val.i ? "OFF" : "ON", NULL); if (retval == RIG_OK) { priv->afgain = val.i; } break; default: return -RIG_EINVAL; } return retval; } int icm710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_AF: val->f = priv->afgain / 255.; break; case RIG_LEVEL_RF: val->f = priv->rfgain / 9.; break; case RIG_LEVEL_RFPOWER: val->f = priv->rfpwr / 3.; break; case RIG_LEVEL_AGC: val->i = priv->agc; break; default: return -RIG_EINVAL; } return -RIG_OK; } /* * initrigs_icm710 is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icm710) { rig_debug(RIG_DEBUG_VERBOSE, "%s: icm710_init called\n", __func__); rig_register(&icm700pro_caps); rig_register(&icm710_caps); rig_register(&icm802_caps); return RIG_OK; } hamlib-4.6.5/rigs/icmarine/icm803.c0000664000175000017500000001410015056640443012352 /* * Hamlib ICOM Marine backend - model IC-M803 (derived from IC-M802) * Modifications by Blaine Kubesh (k5kub) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM803_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM803_RX_MODES (ICM803_MODES|RIG_MODE_AM) #define ICM803_FUNC_ALL (RIG_FUNC_NB) #define ICM803_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM803_VFO_ALL (RIG_VFO_A) #define ICM803_VFO_OPS (RIG_OP_TUNE) #define ICM803_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM803_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm803_priv_caps = { .default_remote_id = 20, /* default address */ }; struct rig_caps icm803_caps = { RIG_MODEL(RIG_MODEL_IC_M803), .model_name = "IC-M803", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM803_FUNC_ALL, .has_set_func = ICM803_FUNC_ALL, .has_get_level = ICM803_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM803_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM803_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM803_VFO_OPS, .scan_ops = ICM803_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM803_RX_MODES, -1, -1, ICM803_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM803_RX_MODES, -1, -1, ICM803_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM803_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm803_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icmarine/Android.mk0000664000175000017500000000045215056640443013121 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := icm700pro.c icm710.c icm802.c icm803.c \ icmarine.c LOCAL_MODULE := icmarine LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/icmarine/Makefile.in0000664000175000017500000005417515056640452013270 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/icmarine ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_icmarine_la_LIBADD = am__objects_1 = icm700pro.lo icm710.lo icm802.lo icm803.lo icmarine.lo am_libhamlib_icmarine_la_OBJECTS = $(am__objects_1) libhamlib_icmarine_la_OBJECTS = $(am_libhamlib_icmarine_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/icm700pro.Plo ./$(DEPDIR)/icm710.Plo \ ./$(DEPDIR)/icm802.Plo ./$(DEPDIR)/icm803.Plo \ ./$(DEPDIR)/icmarine.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_icmarine_la_SOURCES) DIST_SOURCES = $(libhamlib_icmarine_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #icm802.c ICMARINESRC = icm700pro.c icm710.c icm710.h icm802.c icm803.c \ icmarine.c icmarine.h noinst_LTLIBRARIES = libhamlib-icmarine.la libhamlib_icmarine_la_SOURCES = $(ICMARINESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/icmarine/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/icmarine/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-icmarine.la: $(libhamlib_icmarine_la_OBJECTS) $(libhamlib_icmarine_la_DEPENDENCIES) $(EXTRA_libhamlib_icmarine_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_icmarine_la_OBJECTS) $(libhamlib_icmarine_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm700pro.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm802.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm803.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icmarine.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/icm700pro.Plo -rm -f ./$(DEPDIR)/icm710.Plo -rm -f ./$(DEPDIR)/icm802.Plo -rm -f ./$(DEPDIR)/icm803.Plo -rm -f ./$(DEPDIR)/icmarine.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/icm700pro.Plo -rm -f ./$(DEPDIR)/icm710.Plo -rm -f ./$(DEPDIR)/icm802.Plo -rm -f ./$(DEPDIR)/icm803.Plo -rm -f ./$(DEPDIR)/icmarine.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/icmarine/icm802.c0000664000175000017500000001407415056640443012363 /* * Hamlib ICOM Marine backend - description of IC-M802 caps * Copyright (c) 2014-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM802_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM802_RX_MODES (ICM802_MODES|RIG_MODE_AM) #define ICM802_FUNC_ALL (RIG_FUNC_NB) #define ICM802_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM802_VFO_ALL (RIG_VFO_A) #define ICM802_VFO_OPS (RIG_OP_TUNE) #define ICM802_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM802_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm802_priv_caps = { .default_remote_id = 0x08, /* default address */ }; struct rig_caps icm802_caps = { RIG_MODEL(RIG_MODEL_IC_M802), .model_name = "IC-M802", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM802_FUNC_ALL, .has_set_func = ICM802_FUNC_ALL, .has_get_level = ICM802_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM802_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM802_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM802_VFO_OPS, .scan_ops = ICM802_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM802_RX_MODES, -1, -1, ICM802_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM802_RX_MODES, -1, -1, ICM802_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM802_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm802_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icmarine/icm700pro.c0000664000175000017500000001436015056640443013077 /* * Hamlib ICOM Marine backend - description of IC-M700PRO caps * Copyright (c) 2014-2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM700PRO_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM700PRO_RX_MODES (ICM700PRO_MODES|RIG_MODE_AM) #define ICM700PRO_FUNC_ALL (RIG_FUNC_NB) #define ICM700PRO_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM700PRO_VFO_ALL (RIG_VFO_A) #define ICM700PRO_VFO_OPS (RIG_OP_TUNE) #define ICM700PRO_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM700PRO_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm700pro_priv_caps = { .default_remote_id = 2, }; struct rig_caps icm700pro_caps = { RIG_MODEL(RIG_MODEL_IC_M700PRO), .model_name = "IC-M700PRO", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM700PRO_FUNC_ALL, .has_set_func = ICM700PRO_FUNC_ALL, .has_get_level = ICM700PRO_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM700PRO_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM700PRO_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(150), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM700PRO_VFO_OPS, .scan_ops = ICM700PRO_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 3, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM700PRO_RX_MODES, -1, -1, ICM700PRO_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM700PRO_MODES, W(60), W(60), ICM700PRO_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM700PRO_RX_MODES, -1, -1, ICM700PRO_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM700PRO_MODES, W(60), W(60), ICM700PRO_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM700PRO_RX_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm700pro_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icmarine/Makefile.am0000664000175000017500000000032515056640443013243 #icm802.c ICMARINESRC = icm700pro.c icm710.c icm710.h icm802.c icm803.c \ icmarine.c icmarine.h noinst_LTLIBRARIES = libhamlib-icmarine.la libhamlib_icmarine_la_SOURCES = $(ICMARINESRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/rs/0000775000175000017500000000000015056640477010133 5hamlib-4.6.5/rigs/rs/rs.c0000664000175000017500000001772315056640443010646 /* * Hamlib R&S backend - main file * Copyright (c) 2009-2010 by Stéphane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "num_stdio.h" #include "rs.h" #include "gp2000.h" #include "ek89x.h" #include "xk852.h" #define BUFSZ 64 #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM CR #define EOM CR /* * R&S GB2 protocol ? */ /* * rs_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int rs_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * rs_set_freq * Assumes rig!=NULL */ int rs_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; SNPRINTF(freqbuf, sizeof(freqbuf), BOM "FREQ %"PRIll EOM, (int64_t)freq); retval = rs_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * rs_get_freq * Assumes rig!=NULL */ int rs_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; #define FREQ_QUERY BOM "FREQ?" EOM retval = rs_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%"SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * rs_set_mode * Assumes rig!=NULL */ int rs_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; switch (mode) { case RIG_MODE_AM: smode = "AM"; break; case RIG_MODE_WFM: case RIG_MODE_FM: smode = "FM"; break; case RIG_MODE_CW: smode = "CW"; break; case RIG_MODE_USB: smode = "USB"; break; case RIG_MODE_LSB: smode = "LSB"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "DEM %s" EOM, smode); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { SNPRINTF(buf, sizeof(buf), BOM "BAND %d" EOM, (int) width); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * rs_get_mode * Assumes rig!=NULL */ int rs_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; #define DEM_QUERY BOM "DEM?" EOM retval = rs_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *mode = rig_parse_mode(buf); #define BAND_QUERY BOM "BAND?" EOM retval = rs_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *width = atoi(buf); return retval; } int rs_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int retval; switch (func) { case RIG_FUNC_AFC: sfunc = "FREQ:AFC"; break; case RIG_FUNC_SQL: sfunc = "OUTP:SQU"; break; case RIG_FUNC_LOCK: sfunc = "DISP:ENAB"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "ON" : "OFF"); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int rs_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; switch (func) { case RIG_FUNC_AFC: sfunc = BOM "FREQ:AFC?" EOM; break; case RIG_FUNC_SQL: sfunc = BOM "OUTP:SQU?" EOM; break; case RIG_FUNC_LOCK: sfunc = BOM "DISP:ENAB?" EOM; break; default: return -RIG_EINVAL; } retval = rs_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } *status = (!memcmp(buf, "ON", 2) || !memcmp(buf, "1", 1)) ? 1 : 0; return retval; } int rs_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[32]; int retval; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(buf, sizeof(buf), BOM "INP:ATT:STAT %s" EOM, val.i ? "ON" : "OFF"); break; case RIG_LEVEL_SQL: /* dBuV */ SNPRINTF(buf, sizeof(buf), BOM "OUTP:SQU:THR %d" EOM, (int)(20 + val.f * 20)); break; case RIG_LEVEL_AF: num_snprintf(buf, sizeof(buf), BOM "SYST:AUD:VOL %.1f" EOM, val.f); break; case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int rs_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval; switch (level) { case RIG_LEVEL_STRENGTH: slevel = BOM "SENS:DATA? \"VOLT:AC\"" EOM; break; case RIG_LEVEL_ATT: slevel = BOM "INP:ATT:STAT?" EOM; break; case RIG_LEVEL_AF: slevel = BOM "SYST:AUD:VOL?" EOM; break; case RIG_LEVEL_SQL: case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = rs_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_STRENGTH: /* assumes FORMAat:DATA ASCii * result in dBuV, keep only integer part */ sscanf(buf, "%d", &val->i); val->i -= 34; break; case RIG_LEVEL_ATT: val->i = (!memcmp(buf, "ON", 2) || !memcmp(buf, "1", 1)) ? STATE(rig)->attenuator[0] : 0; break; case RIG_LEVEL_AF: if (num_sscanf(buf, "%f", &val->f) != 1) { return -RIG_EPROTO; } break; default: return -RIG_EINVAL; } return retval; } const char *rs_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; #define ID_QUERY BOM "*IDN?" EOM retval = rs_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } return infobuf; } int rs_reset(RIG *rig, reset_t reset) { int retval; #define RST_CMD BOM "*RST" EOM retval = rs_transaction(rig, RST_CMD, strlen(RST_CMD), NULL, NULL); return retval; } /* * initrigs_rs is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(rs) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&esmc_caps); rig_register(&eb200_caps); rig_register(&xk2100_caps); rig_register(&xk852_caps); rig_register(&ek89x_caps); return RIG_OK; } hamlib-4.6.5/rigs/rs/gp2000.c0000664000175000017500000002472715056640443011134 /* * Hamlib R&S GP2000 backend - main file * Reused from rs.c * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stéphane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Looks like the GP2000 could be reused in other rigs so * we implement that and then the XK2100 uses this interface */ #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "gp2000.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR /* * R&S GB2 protocol ? */ /* * gp2000 * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int gp2000_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "gp2000_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * gp2000_set_freq * Assumes rig!=NULL */ int gp2000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; // cppcheck-suppress * char *fmt = BOM "F%" PRIll ",%" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t) freq, (int64_t) freq); retval = gp2000_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * gp2000_get_freq * Assumes rig!=NULL */ int gp2000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define FREQ_QUERY BOM "F?" EOM retval = gp2000_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cF%" SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * gp2000_set_mode * Assumes rig!=NULL */ int gp2000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_AM: smode = "1"; break; case RIG_MODE_USB: smode = "2"; break; case RIG_MODE_LSB: smode = "3"; break; case RIG_MODE_CW: smode = "5"; break; case RIG_MODE_FM: smode = "9"; break; case RIG_MODE_PKTUSB: smode = "13"; // use the 2700 bandwidth for packet break; case RIG_MODE_PKTLSB: smode = "14"; // use the 2700 bandwidth for packet break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "I%s" EOM, smode); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { SNPRINTF(buf, sizeof(buf), BOM "W%d" EOM, (int) width); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * gp2000_get_mode * Assumes rig!=NULL */ int gp2000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; int nmode; char *pmode = "UNKNOWN"; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define DEM_QUERY BOM "I?" EOM retval = gp2000_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } n = sscanf(buf, "%*cI%d", &nmode); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, buf); return -RIG_EPROTO; } switch (nmode) { case 1: pmode = "AM"; break; case 2: pmode = "USB"; break; case 3: pmode = "LSB"; break; case 5: pmode = "CW"; break; case 9: pmode = "FM"; break; case 13: pmode = "PKTUSB"; break; case 14: pmode = "PKTLSB"; break; } *mode = rig_parse_mode(pmode); #define BAND_QUERY BOM "W?" EOM retval = gp2000_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *width = atoi(&buf[2]); return retval; } #ifdef XXREMOVEDXX // Not referenced anywhere int gp2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = "SQ00"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "1" : "0"); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } #endif #ifdef XXREMOVEDXX // Not referenced anywhere int gp2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = BOM "SQ00?" EOM; break; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } // we expected LF+"X" where X is the status *status = buf[2] == 1 ? 1 : 0; return retval; } #endif int gp2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: SNPRINTF(buf, sizeof(buf), BOM "SR%02d" EOM, (int)val.f); break; case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), BOM "SQ%1d" EOM, (int)val.f); break; case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int gp2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval, ival; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: slevel = BOM "SL?" EOM; break; case RIG_LEVEL_SQL: slevel = BOM "SQ?" EOM; break; case RIG_LEVEL_STRENGTH: case RIG_LEVEL_ATT: case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_AF: if (num_sscanf(buf, "%*cSL%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; case RIG_LEVEL_SQL: if (num_sscanf(buf, "%*cSQ%1d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; default: return -RIG_EINVAL; } return retval; } const char * gp2000_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; int addr = -1; char type[32] = "unk type"; char rigid[32] = "unk rigid"; char sernum[32] = "unk sernum"; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); #define ID_QUERY BOM "IDENT?" EOM retval = gp2000_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } p = strtok(infobuf, ","); while (p) { switch (p[0]) { case 0x0a: sscanf(p, "%*cIDENT%31s", type); break; case 'i': sscanf(p, "id%31s", rigid); break; case 's': sscanf(p, "sn%31s", sernum); break; default: printf("Unknown response: %s\n", p); } p = strtok(NULL, ","); } SNPRINTF(infobuf, sizeof(infobuf), "ADDR=%02d\nTYPE=%s\nSER#=%s\nID =%s\n", addr, type, sernum, rigid); return infobuf; } int gp2000_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = 0; char cmd[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "X%1d", ptt); retval = gp2000_transaction(rig, cmd, strlen(cmd), NULL, NULL); return retval; } int gp2000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval = 0; int len; char buf[RESPSZ]; char *cmd = BOM "X?" EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = gp2000_transaction(rig, cmd, strlen(cmd), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cX%1u", ptt) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } hamlib-4.6.5/rigs/rs/ek89x.c0000664000175000017500000003326215056640443011166 /* * Hamlib R&S EK895/896 backend - main file * Reused from p2000.c * Copyright (c) 2022 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stéphane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Looks like the GP2000 could be reused in other rigs so * we implement that and then the EK89X uses this interface */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "ek89x.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR /* * ek89x * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int ek89x_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "ek89x_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * ek89x_set_freq * Assumes rig!=NULL */ int ek89x_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; // cppcheck-suppress * char *fmt = BOM "F%" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t) freq, (int64_t) freq); retval = ek89x_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * ek89x_get_freq * Assumes rig!=NULL */ int ek89x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define FREQ_QUERY BOM "F?" EOM retval = ek89x_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cF%" SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * ek89x_set_mode * Assumes rig!=NULL */ int ek89x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_USB: smode = "15"; break; case RIG_MODE_LSB: smode = "16"; break; case RIG_MODE_ISBUSB: smode = "17"; break; case RIG_MODE_ISBLSB: smode = "18"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "I%s" EOM, smode); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { if (width <= 150) { width = 1; } else if (width <= 300) { width = 3; } else if (width <= 600) { width = 6; } else if (width <= 1000) { width = 10; } else if (width <= 1500) { width = 15; } else if (width <= 2100) { width = 21; } else if (width <= 2400) { width = 24; } else if (width <= 2700) { width = 27; } else if (width <= 3100) { width = 31; } else if (width <= 4000) { width = 40; } else if (width <= 4800) { width = 48; } else if (width <= 6000) { width = 60; } else if (width <= 8000) { width = 80; } SNPRINTF(buf, sizeof(buf), BOM "W%d" EOM, (int) width); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * ek89x_get_mode * Assumes rig!=NULL */ int ek89x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; int nmode; char *pmode = "UNKNOWN"; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define DEM_QUERY BOM "I?" EOM retval = ek89x_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } n = sscanf(buf, "%*cI%d", &nmode); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, buf); return -RIG_EPROTO; } switch (nmode) { case 15: pmode = "USB"; break; case 16: pmode = "LSB"; break; } *mode = rig_parse_mode(pmode); #define BAND_QUERY BOM "FIB?" EOM retval = ek89x_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } int twidth; sscanf(buf, "%*cFIB%d", &twidth); if (twidth == 1) { *width = 150; } else { *width = twidth * 100; } return retval; } #ifdef XXREMOVEDXX // Not referenced anywhere int ek89x_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = "SQ00"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "1" : "0"); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } #endif #ifdef XXREMOVEDXX // Not referenced anywhere int ek89x_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = BOM "SQ00?" EOM; break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } // we expected LF+"X" where X is the status *status = buf[2] == 1 ? 1 : 0; return retval; } #endif int ek89x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(buf, sizeof(buf), BOM "PA%d" EOM, (int)val.f); break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int ek89x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval, ival; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_PREAMP: slevel = BOM "PA?" EOM; break; case RIG_LEVEL_STRENGTH: slevel = BOM "L?" EOM; break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_PREAMP: if (num_sscanf(buf, "%*cPA%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; case RIG_LEVEL_STRENGTH: if (num_sscanf(buf, "%*cL%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival - 34; // approximately break; default: return -RIG_EINVAL; } return retval; } const char * ek89x_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; int addr = -1; char type[32] = "unk type"; char rigid[32] = "unk rigid"; char sernum[32] = "unk sernum"; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); #define ID_QUERY BOM "IDENT?" EOM retval = ek89x_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } p = strtok(infobuf, ","); while (p) { switch (p[0]) { case 0x0a: sscanf(p, "%*cIDENT%31s", type); break; case 'i': sscanf(p, "id%31s", rigid); break; case 's': sscanf(p, "sn%31s", sernum); break; default: printf("Unknown response: %s\n", p); } p = strtok(NULL, ","); } SNPRINTF(infobuf, sizeof(infobuf), "ADDR=%02d\nTYPE=%s\nSER#=%s\nID =%s\n", addr, type, sernum, rigid); return infobuf; } #define EK89X_MODES (RIG_MODE_USB|RIG_MODE_LSB) #define EK89X_FUNC (RIG_FUNC_SQL) #define EK89X_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH) #define EK89X_PARM_ALL (RIG_PARM_NONE) #define EK89X_VFO (RIG_VFO_A) #define EK89X_VFO_OPS (RIG_OP_NONE) #define EK89X_ANTS (RIG_ANT_1) #define EK89X_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = EK89X_FUNC, \ .levels = RIG_LEVEL_SET(EK89X_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * EK89X rig capabilities. * * Had to use NONE for flow control and set RTS high * We are not using address mode since we're on RS232 for now * If using RS485 should add address capability * * TODO * - set/get_channels */ struct rig_caps ek89x_caps = { RIG_MODEL(RIG_MODEL_EK89X), .model_name = "EK895/6", .mfg_name = "Rohde&Schwarz", .version = "20220813.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 38400, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = EK89X_FUNC, .has_set_func = EK89X_FUNC, .has_get_level = EK89X_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EK89X_LEVEL_ALL), .has_get_parm = EK89X_PARM_ALL, .has_set_parm = RIG_PARM_SET(EK89X_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {32, RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ //.vfo_ops = XK2100_VFO_OPS, .chan_list = { {0, 999, RIG_MTYPE_MEM, EK89X_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(0), MHz(30), EK89X_MODES, -1, -1, EK89X_VFO, EK89X_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(0), MHz(30), EK89X_MODES, -1, -1, EK89X_VFO, EK89X_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* .tuning_steps = { {EK89X_MODES,1}, {EK89X_MODES,10}, {EK89X_MODES,100}, {EK89X_MODES,1000}, RIG_TS_END, }, */ /* mode/filter list, remember: order matters! */ .filters = { {EK89X_MODES, kHz(8.0)}, {EK89X_MODES, kHz(6.0)}, {EK89X_MODES, Hz(4.8)}, {EK89X_MODES, Hz(4.0)}, {EK89X_MODES, Hz(3.1)}, {EK89X_MODES, kHz(2.7)}, {EK89X_MODES, kHz(2.4)}, {EK89X_MODES, kHz(1.5)}, {EK89X_MODES, kHz(1.0)}, {EK89X_MODES, Hz(600)}, {EK89X_MODES, Hz(300)}, {EK89X_MODES, Hz(150)}, RIG_FLT_END, }, .priv = NULL, // .set_ptt = ek89x_set_ptt, receiver only // .get_ptt = ek89x_get_ptt, receiver only .set_freq = ek89x_set_freq, .get_freq = ek89x_get_freq, .set_mode = ek89x_set_mode, .get_mode = ek89x_get_mode, .set_level = ek89x_set_level, .get_level = ek89x_get_level, //.set_func = ek89x_set_func, //.get_func = ek89x_get_func, .get_info = ek89x_get_info, #if 0 /* TODO */ .rig_open = ek89x_rig_open, .set_channel = ek89x_set_channel, .get_channel = ek89x_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/rs/xk2100.c0000664000175000017500000001235215056640443011140 /* * Hamlib R&S backend - XK2100 description * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "gp2000.h" #define XK2100_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM) #define XK2100_FUNC (RIG_FUNC_SQL) /* #define XK2100_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC| \ * RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_STRENGTH) */ #define XK2100_LEVEL_ALL (RIG_LEVEL_SQL|\ RIG_LEVEL_AF) #define XK2100_PARM_ALL (RIG_PARM_NONE) #define XK2100_VFO (RIG_VFO_A) #define XK2100_VFO_OPS (RIG_OP_NONE) #define XK2100_ANTS (RIG_ANT_1) #define XK2100_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = XK2100_FUNC, \ .levels = RIG_LEVEL_SET(XK2100_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * XK2100 rig capabilities. * * Had to use NONE for flow control and set RTS high * We are not using address mode since we're on RS232 for now * If using RS485 should add address capability * * TODO * - set/get_channels */ struct rig_caps xk2100_caps = { RIG_MODEL(RIG_MODEL_XK2100), .model_name = "XK2100", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 38400, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = XK2100_FUNC, .has_set_func = XK2100_FUNC, .has_get_level = XK2100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XK2100_LEVEL_ALL), .has_get_parm = XK2100_PARM_ALL, .has_set_parm = RIG_PARM_SET(XK2100_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {32, RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = XK2100_VFO_OPS, .chan_list = { {0, 99, RIG_MTYPE_MEM, XK2100_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(1500), MHz(30), XK2100_MODES, -1, -1, XK2100_VFO, XK2100_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(1500), MHz(30), XK2100_MODES, -1, -1, XK2100_VFO, XK2100_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* .tuning_steps = { {XK2100_MODES,1}, {XK2100_MODES,10}, {XK2100_MODES,100}, {XK2100_MODES,1000}, RIG_TS_END, }, */ /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {XK2100_MODES, kHz(2.4)}, {XK2100_MODES, kHz(1.5)}, {XK2100_MODES, Hz(150)}, {XK2100_MODES, Hz(300)}, {XK2100_MODES, Hz(600)}, {XK2100_MODES, kHz(6)}, {XK2100_MODES, kHz(9)}, {XK2100_MODES, kHz(15)}, {XK2100_MODES, kHz(30)}, {XK2100_MODES, kHz(50)}, {XK2100_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_ptt = gp2000_set_ptt, .get_ptt = gp2000_get_ptt, .set_freq = gp2000_set_freq, .get_freq = gp2000_get_freq, .set_mode = gp2000_set_mode, .get_mode = gp2000_get_mode, .set_level = gp2000_set_level, .get_level = gp2000_get_level, //.set_func = gp2000_set_func, //.get_func = gp2000_get_func, .get_info = gp2000_get_info, #if 0 /* TODO */ .rig_open = gp2000_rig_open, .set_channel = gp2000_set_channel, .get_channel = gp2000_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/rs/xk852.c0000664000175000017500000002656315056640443011105 #include #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "xk852.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR #define XK852_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_CW|RIG_MODE_AM) #define XK852_FUNC (RIG_FUNC_NONE) #define XK852_LEVEL_ALL (RIG_LEVEL_SQL | RIG_LEVEL_RFPOWER) #define XK852_PARM_ALL (RIG_PARM_NONE) #define XK852_VFO (RIG_VFO_A) #define XK852_VFO_OPS (RIG_OP_NONE) #define XK852_ANTS (RIG_ANT_1) #define XK852_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = XK852_FUNC, \ .levels = RIG_LEVEL_SET(XK852_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } int xk852_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "xk852_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } // Send command discard return int xk852_send_command(RIG *rig, const char *cmd, int cmd_len) { char buf[RESPSZ]; int len; int retval = 0; retval = xk852_transaction(rig, cmd, cmd_len, buf, &len); return retval; } int xk852_parse_state(const char *msg, xk852_state *state) { int ret; ret = sscanf(msg, BOM "*F%7u" SCNfreq, &state -> freq); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse frequency from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*13cI%1u", &state -> mode); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*23cN%1u", &state -> noise_blank); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse noise blanker state from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*31cS%1u", &state -> op_mode); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse op mode state from '%s'\n", __func__, msg); return -RIG_EPROTO; }; return RIG_OK; }; int xk852_query_state(RIG *rig, xk852_state *state) { char buf[RESPSZ]; int buf_len, ret; #define STATE_QUERY BOM "*O1" EOM ret = xk852_transaction(rig, STATE_QUERY, strlen(STATE_QUERY), buf, &buf_len); if (ret < 0) { return ret; } ret = xk852_parse_state(buf, state); return ret; }; /* * xk852_set_freq * Assumes rig!=NULL */ int xk852_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; char *fmt = BOM "*F%.7" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t)((freq + 5) / 10)); retval = xk852_send_command(rig, freqbuf, strlen(freqbuf)); return retval; } /* * xk852_get_freq * Assumes rig!=NULL */ int xk852_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { xk852_state state; int ret; ret = xk852_query_state(rig, &state); *freq = (freq_t)(state.freq * 10); return ret; } /* * xk852_set_mode * Assumes rig!=NULL */ int xk852_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32]; xk852_mode smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_AM: smode = XK852_MODE_AME; break; case RIG_MODE_USB: smode = XK852_MODE_USB; break; case RIG_MODE_LSB: smode = XK852_MODE_LSB; break; case RIG_MODE_CW: smode = XK852_MODE_CW; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "*I%1u" EOM, smode); retval = xk852_send_command(rig, buf, strlen(buf)); return retval; } /* * xk852_get_mode * Assumes rig!=NULL */ int xk852_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { xk852_state state; int ret; ret = xk852_query_state(rig, &state); if (ret != RIG_OK) { return ret; } switch (state.mode) { case XK852_MODE_AME: *mode = RIG_MODE_AM; break; case XK852_MODE_USB: *mode = RIG_MODE_USB; break; case XK852_MODE_LSB: *mode = RIG_MODE_LSB; break; case XK852_MODE_CW: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; } return RIG_OK; } int xk852_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f >= 0.5) SNPRINTF(buf, sizeof(buf), BOM "*S4" EOM) else if (val.f >= 0.1) SNPRINTF(buf, sizeof(buf), BOM "*S3" EOM) else if (val.f >= 0.001) SNPRINTF(buf, sizeof(buf), BOM "*S2" EOM) else { SNPRINTF(buf, sizeof(buf), BOM "*S1" EOM); } break; case RIG_LEVEL_SQL: if (val.f <= 0.5) SNPRINTF(buf, sizeof(buf), BOM "*N0" EOM) else { SNPRINTF(buf, sizeof(buf), BOM "*N1" EOM); } break; case RIG_LEVEL_AGC: case RIG_LEVEL_AF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = xk852_send_command(rig, buf, strlen(buf)); return retval; } int xk852_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; xk852_state state; ret = xk852_query_state(rig, &state); if (ret != RIG_OK) { return ret; } switch (level) { case RIG_LEVEL_SQL: switch (state.noise_blank) { case XK852_NOISE_BLANK_OFF: val->f = 1; return RIG_OK; break; case XK852_NOISE_BLANK_ON: val->f = 0; return RIG_OK; break; } case RIG_LEVEL_RFPOWER: switch (state.op_mode) { case XK852_OP_MODE_OFF: val->f = 0; return RIG_OK; break; case XK852_OP_MODE_RX: val->f = 0; return RIG_OK; break; case XK852_OP_MODE_TX_LOW: val->f = 0.099; return RIG_OK; break; case XK852_OP_MODE_TX_MID: val->f = 0.499; return RIG_OK; break; case XK852_OP_MODE_TX_FULL: val->f = 1; return RIG_OK; break; } default: return -RIG_ENIMPL; break; } return -RIG_EINVAL; } int xk852_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = 0; char cmd[32]; int ptt_code = 2; switch (ptt) { case RIG_PTT_OFF: ptt_code = 2; break; case RIG_PTT_ON: ptt_code = 1; break; case RIG_PTT_ON_MIC: ptt_code = 1; break; case RIG_PTT_ON_DATA: ptt_code = 1; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), BOM "*X%1d" EOM, ptt_code); retval = xk852_transaction(rig, cmd, strlen(cmd), NULL, NULL); return retval; } int xk852_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { // int retval = 0; // int len; // char buf[RESPSZ]; // char *cmd = BOM "X?" EOM; // rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); // retval = xk852_transaction(rig, cmd, strlen(cmd), buf, &len); // if (retval < 0) // { // return retval; // } // retval = (sscanf(buf, "%*cX%1u", ptt) == 1) ? RIG_OK : -RIG_EPROTO; *ptt = RIG_PTT_OFF; return RIG_OK; } /* * XK852 rig capabilities. */ struct rig_caps xk852_caps = { RIG_MODEL(RIG_MODEL_XK852), .model_name = "XK852", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 200, //nach senden warten // also see post_ptt_delay (in manpage) .timeout = 200, .retry = 3, .has_get_func = XK852_FUNC, .has_set_func = XK852_FUNC, .has_get_level = XK852_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XK852_LEVEL_ALL), .has_get_parm = XK852_PARM_ALL, .has_set_parm = RIG_PARM_SET(XK852_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = XK852_VFO_OPS, .chan_list = { {0, 99, RIG_MTYPE_MEM, XK852_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(1500), MHz(30), XK852_MODES, -1, -1, XK852_VFO, XK852_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1500), MHz(30), XK852_MODES, 0, 150000, XK852_VFO, XK852_ANTS }, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {XK852_MODES, kHz(2.4)}, {XK852_MODES, kHz(1.5)}, {XK852_MODES, Hz(150)}, {XK852_MODES, Hz(300)}, {XK852_MODES, Hz(600)}, {XK852_MODES, kHz(6)}, {XK852_MODES, kHz(9)}, {XK852_MODES, kHz(15)}, {XK852_MODES, kHz(30)}, {XK852_MODES, kHz(50)}, {XK852_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_ptt = xk852_set_ptt, .get_ptt = xk852_get_ptt, .set_freq = xk852_set_freq, .get_freq = xk852_get_freq, .set_mode = xk852_set_mode, .get_mode = xk852_get_mode, .set_level = xk852_set_level, .get_level = xk852_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/rs/ek89x.h0000664000175000017500000000346015056640443011170 /* * Hamlib R&S backend for EK895/896 - main header * Reused from gp2000.c * Copyright (c) 2022 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _EK89X_H #define _EK89X_H 1 #include int ek89x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int ek89x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int ek89x_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ek89x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ek89x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ek89x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ek89x_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ek89x_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ek89x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ek89x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int ek89x_reset(RIG *rig, reset_t reset); const char * gek89x_get_info(RIG *rig); extern struct rig_caps ek89x_caps; #endif /* EK89X_H */ hamlib-4.6.5/rigs/rs/Android.mk0000664000175000017500000000042315056640443011754 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := esmc.c eb200.c rs.c xk2100.c gp2000.c LOCAL_MODULE := rs LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/rs/gp2000.h0000664000175000017500000000347515056640443011136 /* * Hamlib R&S backend for XK2000 - main header * Reused from rs.c * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _XK2000_H #define _XK2000_H 1 #undef BACKEND_VER #define BACKEND_VER "20210901" #include int gp2000_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int gp2000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int gp2000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int gp2000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int gp2000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int gp2000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int gp2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int gp2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int gp2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int gp2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int gp2000_reset(RIG *rig, reset_t reset); const char * gp2000_get_info(RIG *rig); extern struct rig_caps xk2100_caps; #endif /* XK2000_H */ hamlib-4.6.5/rigs/rs/Makefile.in0000664000175000017500000005447515056640453012131 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/rs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_rs_la_LIBADD = am__objects_1 = esmc.lo eb200.lo rs.lo gp2000.lo xk2100.lo ek89x.lo \ xk852.lo am_libhamlib_rs_la_OBJECTS = $(am__objects_1) libhamlib_rs_la_OBJECTS = $(am_libhamlib_rs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/eb200.Plo ./$(DEPDIR)/ek89x.Plo \ ./$(DEPDIR)/esmc.Plo ./$(DEPDIR)/gp2000.Plo ./$(DEPDIR)/rs.Plo \ ./$(DEPDIR)/xk2100.Plo ./$(DEPDIR)/xk852.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_rs_la_SOURCES) DIST_SOURCES = $(libhamlib_rs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RSSRC = esmc.c eb200.c rs.c rs.h gp2000.c gp2000.h xk2100.c ek89x.c ek89x.h xk852.h xk852.c noinst_LTLIBRARIES = libhamlib-rs.la libhamlib_rs_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/rs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/rs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-rs.la: $(libhamlib_rs_la_OBJECTS) $(libhamlib_rs_la_DEPENDENCIES) $(EXTRA_libhamlib_rs_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_rs_la_OBJECTS) $(libhamlib_rs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eb200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ek89x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esmc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gp2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xk2100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xk852.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/eb200.Plo -rm -f ./$(DEPDIR)/ek89x.Plo -rm -f ./$(DEPDIR)/esmc.Plo -rm -f ./$(DEPDIR)/gp2000.Plo -rm -f ./$(DEPDIR)/rs.Plo -rm -f ./$(DEPDIR)/xk2100.Plo -rm -f ./$(DEPDIR)/xk852.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/eb200.Plo -rm -f ./$(DEPDIR)/ek89x.Plo -rm -f ./$(DEPDIR)/esmc.Plo -rm -f ./$(DEPDIR)/gp2000.Plo -rm -f ./$(DEPDIR)/rs.Plo -rm -f ./$(DEPDIR)/xk2100.Plo -rm -f ./$(DEPDIR)/xk852.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/rs/rs.h0000664000175000017500000000314015056640443010637 /* * Hamlib R&S backend - main header * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RS_H #define _RS_H 1 #include #define BACKEND_VER "20090803" int rs_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int rs_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int rs_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int rs_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int rs_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int rs_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int rs_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int rs_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int rs_reset(RIG *rig, reset_t reset); const char * rs_get_info(RIG *rig); extern struct rig_caps esmc_caps; extern struct rig_caps eb200_caps; #endif /* _RS_H */ hamlib-4.6.5/rigs/rs/esmc.c0000664000175000017500000001135015056640443011137 /* * Hamlib R&S backend - ESMC description * Copyright (c) 2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rs.h" /* TODO: LOG and PULSE ? */ #define ESMC_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ESMC_FUNC (RIG_FUNC_SQL|RIG_FUNC_AFC) #define ESMC_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_STRENGTH) #define ESMC_PARM_ALL (RIG_PARM_NONE) #define ESMC_VFO (RIG_VFO_A) #define ESMC_VFO_OPS (RIG_OP_NONE) #define ESMC_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = ESMC_FUNC, \ .levels = RIG_LEVEL_SET(ESMC_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * ESMC rig capabilities. * * Needs option ESMC-R2 for computer operation RS232C/RS422/RS485 * * http://www2.rohde-schwarz.com/file/ESMC_25.pdf */ struct rig_caps esmc_caps = { RIG_MODEL(RIG_MODEL_ESMC), .model_name = "ESMC", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, /* 7E2 */ .serial_rate_max = 115200, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = ESMC_FUNC, .has_set_func = ESMC_FUNC, .has_get_level = ESMC_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ESMC_LEVEL_ALL), .has_get_parm = ESMC_PARM_ALL, .has_set_parm = RIG_PARM_SET(ESMC_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = ESMC_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, ESMC_MEM_CAP }, RIG_CHAN_END, }, /* * With following options: * ESMC-T2 20 MHz to 1.3 GHz * ESMC-T0 0.5 MHz to 30 MHz * ESMC-FE 20 MHz to 3 GHz */ .rx_range_list1 = { {kHz(20), MHz(650), ESMC_MODES, -1, -1, ESMC_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(20), MHz(650), ESMC_MODES, -1, -1, ESMC_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ESMC_MODES, 1}, {ESMC_MODES, 10}, {ESMC_MODES, 100}, {ESMC_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(200)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {ESMC_MODES, kHz(2.5)}, {ESMC_MODES, kHz(0.5)}, {ESMC_MODES, kHz(8)}, {ESMC_MODES, kHz(15)}, {ESMC_MODES, kHz(30)}, {ESMC_MODES, kHz(50)}, {ESMC_MODES, kHz(100)}, {ESMC_MODES, kHz(200)}, {ESMC_MODES, kHz(500)}, {ESMC_MODES, MHz(1)}, {ESMC_MODES, MHz(2)}, {ESMC_MODES, MHz(4)}, {ESMC_MODES, MHz(8)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rs_set_freq, .get_freq = rs_get_freq, .set_mode = rs_set_mode, .get_mode = rs_get_mode, .set_level = rs_set_level, .get_level = rs_get_level, .set_func = rs_set_func, .get_func = rs_get_func, .get_info = rs_get_info, #if 0 /* TODO */ .rig_open = rs_rig_open, .set_channel = rs_set_channel, .get_channel = rs_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/rs/eb200.c0000664000175000017500000001131115056640443011015 /* * Hamlib R&S backend - EB200 description * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rs.h" /* TODO: PULSE and IQ ? */ #define EB200_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define EB200_FUNC (RIG_FUNC_SQL|RIG_FUNC_AFC|RIG_FUNC_LOCK) #define EB200_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|\ RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_STRENGTH) #define EB200_PARM_ALL (RIG_PARM_NONE) #define EB200_VFO (RIG_VFO_A) #define EB200_VFO_OPS (RIG_OP_NONE) #define EB200_ANTS (RIG_ANT_1) #define EB200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = EB200_FUNC, \ .levels = RIG_LEVEL_SET(EB200_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * EB200 rig capabilities. * * Needs option ESMBR2 for computer operation RS-232C * * TODO * - set/get_channels * - get_dcd * - set_ant */ struct rig_caps eb200_caps = { RIG_MODEL(RIG_MODEL_EB200), .model_name = "EB200", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, /* 7E2 */ .serial_rate_max = 115200, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = EB200_FUNC, .has_set_func = EB200_FUNC, .has_get_level = EB200_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EB200_LEVEL_ALL), .has_get_parm = EB200_PARM_ALL, .has_set_parm = RIG_PARM_SET(EB200_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 32, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = EB200_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, EB200_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), GHz(3), EB200_MODES, -1, -1, EB200_VFO, EB200_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), GHz(3), EB200_MODES, -1, -1, EB200_VFO, EB200_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {EB200_MODES, 1}, {EB200_MODES, 10}, {EB200_MODES, 100}, {EB200_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {EB200_MODES, kHz(2.4)}, {EB200_MODES, kHz(1.5)}, {EB200_MODES, Hz(150)}, {EB200_MODES, Hz(300)}, {EB200_MODES, Hz(600)}, {EB200_MODES, kHz(6)}, {EB200_MODES, kHz(9)}, {EB200_MODES, kHz(15)}, {EB200_MODES, kHz(30)}, {EB200_MODES, kHz(50)}, {EB200_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rs_set_freq, .get_freq = rs_get_freq, .set_mode = rs_set_mode, .get_mode = rs_get_mode, .set_level = rs_set_level, .get_level = rs_get_level, .set_func = rs_set_func, .get_func = rs_get_func, .get_info = rs_get_info, .reset = rs_reset, #if 0 /* TODO */ .rig_open = rs_rig_open, .set_channel = rs_set_channel, .get_channel = rs_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/rs/xk852.h0000664000175000017500000000607315056640443011104 /* * Hamlib R&S backend for XK852 - main header * Reused from rs.c * Based on xk2000.h * Copyright (c) 2024 by Marc Fontaine DM1MF * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _XK852_H #define _XK852_H 1 #undef BACKEND_VER #define BACKEND_VER "20240921" #include typedef enum { XK852_CMD_ADDRESS = 'A', XK852_CMD_BFO = 'B', XK852_CMD_FREQUENCY = 'F', XK852_CMD_LINE = 'G', XK852_CMD_FSK_STOP = 'H', XK852_CMD_MODE = 'I', XK852_CMD_EXTERN = 'J', XK852_CMD_CHANNEL = 'K', XK852_CMD_NOISE_BLANK = 'N', XK852_CMD_STATUS = 'O', XK852_CMD_OP_MODE = 'S', XK852_CMD_SELFTEST = 'T', XK852_CMD_VOICE = 'V', XK852_CMD_PTT = 'X', XK852_CMD_TUNE = 'Y', XK852_CMD_FSK_POLARITY = 'Z' } xk852_cmd; typedef enum { XK852_LINE_OFF = 1, XK852_LINE_ON = 1 } xk852_line; typedef enum { XK852_FSK_STOP_OFF = 0, XK852_FSK_STOP_ON = 1 } xk852_fsk_stop; typedef enum { XK852_MODE_AME = 1, XK852_MODE_USB = 2, XK852_MODE_LSB = 3, XK852_MODE_CW = 5, XK852_MODE_ISB = 6, XK852_MODE_FSK_LP = 7, XK852_MODE_FSK_NP = 8, XK852_MODE_FSK_HP = 9 } xk852_mode; typedef enum { XK852_OP_MODE_OFF = 0, XK852_OP_MODE_RX = 1, XK852_OP_MODE_TX_LOW = 2, XK852_OP_MODE_TX_MID = 3, XK852_OP_MODE_TX_FULL = 4, } xk852_op_mode; // TODO: check Noiseblank command does not work ! typedef enum { XK852_NOISE_BLANK_OFF = 0, XK852_NOISE_BLANK_ON = 1, } xk852_noise_blank; typedef struct { int freq; xk852_mode mode; xk852_noise_blank noise_blank; xk852_op_mode op_mode; } xk852_state; int xk852_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int xk852_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int xk852_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int xk852_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int xk852_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int xk852_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int xk852_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int xk852_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int xk852_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int xk852_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int xk852_reset(RIG *rig, reset_t reset); //const char * xk852_get_info(RIG *rig); extern struct rig_caps xk852_caps; #endif /* XK852_H */ hamlib-4.6.5/rigs/rs/Makefile.am0000664000175000017500000000027615056640443012105 RSSRC = esmc.c eb200.c rs.c rs.h gp2000.c gp2000.h xk2100.c ek89x.c ek89x.h xk852.h xk852.c noinst_LTLIBRARIES = libhamlib-rs.la libhamlib_rs_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/winradio/0000775000175000017500000000000015056640500011306 5hamlib-4.6.5/rigs/winradio/NOTES0000664000175000017500000000253315056640443012052 Mail from , 02/06/01 Stephane mentioned the hamlib project to the linradio.sourceforge.net developers a few weeks ago. I believe my reply was routed to /dev/null@shell1.sourceforge.net. Anyway I have put some notes and early untested code at: http://linradio.sourceforge.net/hamlib.html Here are some winradio-specific issues: - Winradios are simple (henceforth cheap) receivers. The software driver does a lot of work that you would normally expect to see in an embedded controller. The driver is about 100KB of C. - Receivers come with ISA, PCMCIA and RS232 interfaces. - The protocol varies a lot across the model range. - Most models barely have an internal state. They can't even tell which frequency they are tuned to. - With most models, frequency sweeping must be done in software. This requires real-time tricks with RS232 (currently suboptimal). - High-end models have a DSP (not supported with Linux). We are currently providing two abstractions for all of this: - A kernel module which provides /dev/winradioX devices and ioctl API (radio_ioctl.h). - A user-mode driver which has problems with security (being root to use ISA receivers) and RS232 performance. The best approach is to create a hamlib-X.Y.Z/winradio/winradio.c file that wraps our ioctl API (toolkit/driver/radio_ioctl.h) into a "struct rig_caps". hamlib-4.6.5/rigs/winradio/wr3150.c0000664000175000017500000001003115056640443012334 /* * Hamlib WiNRADiO backend - WR3150 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3150_FUNC RIG_FUNC_NONE #define WR3150_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR3150_LEVEL (WR3150_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3150_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3150_caps = { RIG_MODEL(RIG_MODEL_WR3150), .model_name = "WR-3150", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3150_FUNC, .has_set_func = WR3150_FUNC, .has_get_level = WR3150_LEVEL, .has_set_level = WR3150_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR3150_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3150_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3150_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR3150_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/g303.c0000664000175000017500000002730715056640443012065 /* * Hamlib WiNRADiO backend - WR-G303 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * * TODO: rig_probe, rig_scan */ #define WRG3DLL "wrg3api.dll" #define G303_FUNC RIG_FUNC_NONE #define G303_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G303_MODES (RIG_MODE_USB) /* FIXME? */ static int g3_init(RIG *rig); static int g3_cleanup(RIG *rig); static int g3_open(RIG *rig); static int g3_close(RIG *rig); static int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g3_set_powerstat(RIG *rig, powerstat_t status); static int g3_get_powerstat(RIG *rig, powerstat_t *status); static int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g3_get_info(RIG *rig); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); struct g3_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; }; struct rig_caps g303_caps = { RIG_MODEL(RIG_MODEL_G303), .model_name = "WR-G303", .mfg_name = "Winradio", .version = "0.2.1", .copyright = "LGPL", /* This wrapper, not the G3 DLL */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G303_FUNC, .has_set_func = G303_FUNC, .has_get_level = G303_LEVEL, .has_set_level = RIG_LEVEL_SET(G303_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G303_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G303_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G303_MODES, 1}, RIG_TS_END, }, .filters = { {G303_MODES, kHz(12)}, RIG_FLT_END, }, .rig_init = g3_init, .rig_cleanup = g3_cleanup, .rig_open = g3_open, .rig_close = g3_close, .set_freq = g3_set_freq, .get_freq = g3_get_freq, .set_powerstat = g3_set_powerstat, .get_powerstat = g3_get_powerstat, .set_level = g3_set_level, .get_level = g3_get_level, .get_info = g3_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g3_init(RIG *rig) { struct g3_priv_data *priv; STATE(rig)->priv = (struct g3_priv_data *)calloc(1, sizeof(struct g3_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(WRG3DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG3DLL); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); return RIG_OK; } int g3_open(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int device_num; device_num = atoi(RIGPORT(rig)->pathname); /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); return RIG_OK; } int g3_close(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g3_cleanup(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g3_set_powerstat(RIG *rig, powerstat_t status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_powerstat(RIG *rig, powerstat_t *status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g3_get_info(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } #endif /* _WIN32 */ hamlib-4.6.5/rigs/winradio/wr3500.c0000664000175000017500000001020115056640443012332 /* * Hamlib WiNRADiO backend - WR3500 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3500_FUNC RIG_FUNC_FAGC #define WR3500_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_IF | RIG_LEVEL_RF) #define WR3500_LEVEL (WR3500_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3500_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3500_caps = { RIG_MODEL(RIG_MODEL_WR3500), .model_name = "WR-3500", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3500_FUNC, .has_set_func = WR3500_FUNC, .has_get_level = WR3500_LEVEL, .has_set_level = WR3500_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = GHz(2.6), .modes = WR3500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = GHz(2.6), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = GHz(2.6), .modes = WR3500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = wr_set_func, .get_func = wr_get_func, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/wr3700.c0000664000175000017500000001017315056640443012344 /* * Hamlib WiNRADiO backend - WR3700 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3700_FUNC RIG_FUNC_FAGC #define WR3700_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_IF | RIG_LEVEL_RF) #define WR3700_LEVEL (WR3700_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3700_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3700_caps = { RIG_MODEL(RIG_MODEL_WR3700), .model_name = "WR-3700", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3700_FUNC, .has_set_func = WR3700_FUNC, .has_get_level = WR3700_LEVEL, .has_set_level = WR3700_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = GHz(4), .modes = WR3700_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = GHz(4), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3700_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3700_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = GHz(4), .modes = WR3700_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = wr_set_func, .get_func = wr_get_func, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/winradio.c0000664000175000017500000001743615056640443013227 /* * Hamlib WiNRADiO backend - main file for interface through /dev/winradio API * Copyright (C) 2001 pab@users.sourceforge.net * Derived from hamlib code (C) 2000-2009 Stephane Fillod. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "winradio.h" /* config.h */ #include /* String function definitions */ #ifdef HAVE_SYS_IOCTL_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "register.h" #ifdef WINRADIO_IOCTL #include #include #define DEFAULT_WINRADIO_PATH "/dev/winradio0" #define WINRADIO_MODES RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_LSB | RIG_MODE_USB | RIG_MODE_WFM | RIG_MODE_FM int wr_rig_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); rp->type.rig = RIG_PORT_DEVICE; strncpy(rp->pathname, DEFAULT_WINRADIO_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int wr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long f; if (freq > GHz(4.2)) { return -RIG_EINVAL; } f = (unsigned long)freq; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_FREQ, &f)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { unsigned long f; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_FREQ, &f) < 0) { return -RIG_EINVAL; } *freq = (freq_t)f; return RIG_OK; } int wr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned long m; switch (mode) { case RIG_MODE_AM: m = RMD_AM; break; case RIG_MODE_CW: m = RMD_CW; break; case RIG_MODE_LSB: m = RMD_LSB; break; case RIG_MODE_USB: m = RMD_USB; break; case RIG_MODE_WFM: m = RMD_FMW; break; case RIG_MODE_FM: switch (width) { case RIG_PASSBAND_NORMAL: case (int)kHz(17): case (int)kHz(15): m = RMD_FMN; break; case (int)kHz(6): m = RMD_FM6; break; case (int)kHz(50): m = RMD_FMM; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (ioctl(RIGPORT(rig)->fd, RADIO_SET_MODE, &m)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { unsigned long m; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_MODE, &m)) { return -RIG_EINVAL; } *width = RIG_PASSBAND_NORMAL; switch (m) { case RMD_CW: *mode = RIG_MODE_CW; break; case RMD_AM: *mode = RIG_MODE_AM; break; case RMD_FMN: *mode = RIG_MODE_FM; break; /* 15kHz or 17kHz on WR-3100 */ case RMD_FM6: *mode = RIG_MODE_FM; break; /* 6kHz */ case RMD_FMM: *mode = RIG_MODE_FM; break; /* 50kHz */ case RMD_FMW: *mode = RIG_MODE_WFM; break; case RMD_LSB: *mode = RIG_MODE_LSB; break; case RMD_USB: *mode = RIG_MODE_USB; break; default: return -RIG_EINVAL; } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } int wr_set_powerstat(RIG *rig, powerstat_t status) { unsigned long p = 1; p = status == RIG_POWER_ON ? 1 : 0; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_POWER, &p)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_powerstat(RIG *rig, powerstat_t *status) { unsigned long p; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_POWER, &p)) { return -RIG_EINVAL; } *status = p ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int wr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_FAGC: { unsigned long v = status ? 1 : 0; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_AGC, &v)) { return -RIG_EINVAL; } return RIG_OK; } default: return -RIG_EINVAL; } } int wr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { case RIG_FUNC_FAGC: { unsigned long v; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_AGC, &v)) { return -RIG_EINVAL; } *status = v; return RIG_OK; } default: return -RIG_EINVAL; } } int wr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { hamlib_port_t *rp = RIGPORT(rig); switch (level) { case RIG_LEVEL_AF: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_MAXVOL, &v)) { return -RIG_EINVAL; } v *= val.f; if (ioctl(rp->fd, RADIO_SET_VOL, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_ATT: { unsigned long v = val.i ? 1 : 0; if (ioctl(rp->fd, RADIO_SET_ATTN, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_IF: { long v = val.i; if (ioctl(rp->fd, RADIO_SET_IFS, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_RF: { long v = val.f * 100; /* iMaxIFGain on wHWVer > RHV_3150 */ if (ioctl(rp->fd, RADIO_SET_IFG, &v)) { return -RIG_EINVAL; } return RIG_OK; } default: return -RIG_EINVAL; } } int wr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { hamlib_port_t *rp = RIGPORT(rig); switch (level) { case RIG_LEVEL_AF: { unsigned long v, mv; if (ioctl(rp->fd, RADIO_GET_MAXVOL, &mv)) { return -RIG_EINVAL; } if (ioctl(rp->fd, RADIO_GET_VOL, &v)) { return -RIG_EINVAL; } val->f = (float)v / mv; return RIG_OK; } case RIG_LEVEL_ATT: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_VOL, &v)) { return -RIG_EINVAL; } val->i = v ? STATE(rig)->attenuator[0] : 0; return RIG_OK; } case RIG_LEVEL_STRENGTH: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_SS, &v)) { return -RIG_EINVAL; } val->i = v - 60; /* 0..120, Hamlib assumes S9 = 0dB */ return RIG_OK; } case RIG_LEVEL_IF: { long v; if (ioctl(rp->fd, RADIO_GET_IFS, &v)) { return -RIG_EINVAL; } val->i = v; return RIG_OK; } case RIG_LEVEL_RF: { long v; if (ioctl(rp->fd, RADIO_GET_IFG, &v)) { return -RIG_EINVAL; } val->f = (float)v / 100; /* iMaxIFGain on wHWVer > RHV_3150 */ return RIG_OK; } default: return -RIG_EINVAL; } } /* * FIXME: static buf does not allow reentrancy! */ const char *wr_get_info(RIG *rig) { static char buf[100]; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_DESCR, buf) < 0) { return "?"; } return buf; } #endif /* WINRADIO_IOCTL */ DECLARE_INITRIG_BACKEND(winradio) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); #ifdef WINRADIO_IOCTL rig_register(&wr1000_caps); rig_register(&wr1500_caps); rig_register(&wr1550_caps); rig_register(&wr3100_caps); rig_register(&wr3150_caps); rig_register(&wr3500_caps); rig_register(&wr3700_caps); #endif /* WINRADIO_IOCTL */ /* Receivers with DLL only available under Windows */ #ifdef _WIN32 #ifdef __CYGWIN__ rig_register(&g303_caps); rig_register(&g305_caps); #endif #endif /* Available on Linux and MS Windows */ #ifndef OTHER_POSIX rig_register(&g313_caps); #endif return RIG_OK; } hamlib-4.6.5/rigs/winradio/Android.mk0000664000175000017500000000055315056640443013150 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g313.c g305.c winradio.c linradio/wrg313api.c LOCAL_MODULE := winradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/winradio/wr1550.c0000664000175000017500000001003115056640443012336 /* * Hamlib WiNRADiO backend - WR1550 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1550_FUNC RIG_FUNC_NONE #define WR1550_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1550_LEVEL (WR1550_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1550_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1550_caps = { RIG_MODEL(RIG_MODEL_WR1550), .model_name = "WR-1550", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1550_FUNC, .has_set_func = WR1550_FUNC, .has_get_level = WR1550_LEVEL, .has_set_level = WR1550_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR1550_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR1550_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1550_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR1550_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/g305.c0000664000175000017500000002730615056640443012066 /* * Hamlib WiNRADiO backend - WR-G305 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * Cloned from G303 * * TODO: rig_probe, rig_scan */ #define WRG3DLL "wrg3api.dll" #define G305_FUNC RIG_FUNC_NONE #define G305_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G305_MODES (RIG_MODE_USB) /* FIXME? */ static int g3_init(RIG *rig); static int g3_cleanup(RIG *rig); static int g3_open(RIG *rig); static int g3_close(RIG *rig); static int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g3_set_powerstat(RIG *rig, powerstat_t status); static int g3_get_powerstat(RIG *rig, powerstat_t *status); static int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g3_get_info(RIG *rig); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); struct g3_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; }; struct rig_caps g305_caps = { RIG_MODEL(RIG_MODEL_G305), .model_name = "WR-G305", .mfg_name = "Winradio", .version = "0.2.1", .copyright = "LGPL", /* This wrapper, not the G3 DLL */ .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G305_FUNC, .has_set_func = G305_FUNC, .has_get_level = G305_LEVEL, .has_set_level = RIG_LEVEL_SET(G305_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G305_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G305_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G305_MODES, 1}, RIG_TS_END, }, .filters = { {G305_MODES, kHz(12)}, RIG_FLT_END, }, .rig_init = g3_init, .rig_cleanup = g3_cleanup, .rig_open = g3_open, .rig_close = g3_close, .set_freq = g3_set_freq, .get_freq = g3_get_freq, .set_powerstat = g3_set_powerstat, .get_powerstat = g3_get_powerstat, .set_level = g3_set_level, .get_level = g3_get_level, .get_info = g3_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g3_init(RIG *rig) { struct g3_priv_data *priv; STATE(rig)->priv = (struct g3_priv_data *)calloc(1, sizeof(struct g3_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(WRG3DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG3DLL); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); return RIG_OK; } int g3_open(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int device_num; device_num = atoi(RIGPORT(rig)->pathname); /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); return RIG_OK; } int g3_close(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g3_cleanup(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; if (priv) { /* Clean up the dll access */ FreeLibrary(priv->dll); free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g3_set_powerstat(RIG *rig, powerstat_t status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_powerstat(RIG *rig, powerstat_t *status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g3_get_info(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } #endif /* _WIN32 */ hamlib-4.6.5/rigs/winradio/Makefile.in0000664000175000017500000006161515056640453013313 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @G313_LINUX_GNU_TRUE@am__append_1 = g313-posix.c linradio/wrg313api.c linradio/wrg313api.h @G313_WINDOWS_TRUE@am__append_2 = g313-win.c subdir = rigs/winradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @G313_LINUX_GNU_TRUE@libhamlib_winradio_la_DEPENDENCIES = \ @G313_LINUX_GNU_TRUE@ $(am__DEPENDENCIES_1) am__libhamlib_winradio_la_SOURCES_DIST = wr1000.c wr1500.c wr1550.c \ wr3100.c wr3150.c wr3500.c wr3700.c g303.c g305.c winradio.c \ winradio.h linradio/radio_ioctl.h linradio/wrapi.h \ g313-posix.c linradio/wrg313api.c linradio/wrg313api.h \ g313-win.c am__dirstamp = $(am__leading_dot)dirstamp @G313_LINUX_GNU_TRUE@am__objects_1 = g313-posix.lo \ @G313_LINUX_GNU_TRUE@ linradio/wrg313api.lo @G313_WINDOWS_TRUE@am__objects_2 = g313-win.lo am__objects_3 = wr1000.lo wr1500.lo wr1550.lo wr3100.lo wr3150.lo \ wr3500.lo wr3700.lo g303.lo g305.lo winradio.lo \ $(am__objects_1) $(am__objects_2) am_libhamlib_winradio_la_OBJECTS = $(am__objects_3) libhamlib_winradio_la_OBJECTS = $(am_libhamlib_winradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/g303.Plo ./$(DEPDIR)/g305.Plo \ ./$(DEPDIR)/g313-posix.Plo ./$(DEPDIR)/g313-win.Plo \ ./$(DEPDIR)/winradio.Plo ./$(DEPDIR)/wr1000.Plo \ ./$(DEPDIR)/wr1500.Plo ./$(DEPDIR)/wr1550.Plo \ ./$(DEPDIR)/wr3100.Plo ./$(DEPDIR)/wr3150.Plo \ ./$(DEPDIR)/wr3500.Plo ./$(DEPDIR)/wr3700.Plo \ linradio/$(DEPDIR)/wrg313api.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_winradio_la_SOURCES) DIST_SOURCES = $(am__libhamlib_winradio_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ WRSRC = wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g305.c winradio.c winradio.h linradio/radio_ioctl.h \ linradio/wrapi.h $(am__append_1) $(am__append_2) @G313_LINUX_GNU_TRUE@libhamlib_winradio_la_LIBADD = $(DL_LIBS) noinst_LTLIBRARIES = libhamlib-winradio.la libhamlib_winradio_la_SOURCES = $(WRSRC) EXTRA_DIST = NOTES Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/winradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/winradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} linradio/$(am__dirstamp): @$(MKDIR_P) linradio @: >>linradio/$(am__dirstamp) linradio/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) linradio/$(DEPDIR) @: >>linradio/$(DEPDIR)/$(am__dirstamp) linradio/wrg313api.lo: linradio/$(am__dirstamp) \ linradio/$(DEPDIR)/$(am__dirstamp) libhamlib-winradio.la: $(libhamlib_winradio_la_OBJECTS) $(libhamlib_winradio_la_DEPENDENCIES) $(EXTRA_libhamlib_winradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_winradio_la_OBJECTS) $(libhamlib_winradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f linradio/*.$(OBJEXT) -rm -f linradio/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g303.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g305.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g313-posix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g313-win.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1550.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3150.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@linradio/$(DEPDIR)/wrg313api.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf linradio/.libs linradio/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) linradio/$(DEPDIR)/$(am__dirstamp) -$(am__rm_f) linradio/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/g303.Plo -rm -f ./$(DEPDIR)/g305.Plo -rm -f ./$(DEPDIR)/g313-posix.Plo -rm -f ./$(DEPDIR)/g313-win.Plo -rm -f ./$(DEPDIR)/winradio.Plo -rm -f ./$(DEPDIR)/wr1000.Plo -rm -f ./$(DEPDIR)/wr1500.Plo -rm -f ./$(DEPDIR)/wr1550.Plo -rm -f ./$(DEPDIR)/wr3100.Plo -rm -f ./$(DEPDIR)/wr3150.Plo -rm -f ./$(DEPDIR)/wr3500.Plo -rm -f ./$(DEPDIR)/wr3700.Plo -rm -f linradio/$(DEPDIR)/wrg313api.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/g303.Plo -rm -f ./$(DEPDIR)/g305.Plo -rm -f ./$(DEPDIR)/g313-posix.Plo -rm -f ./$(DEPDIR)/g313-win.Plo -rm -f ./$(DEPDIR)/winradio.Plo -rm -f ./$(DEPDIR)/wr1000.Plo -rm -f ./$(DEPDIR)/wr1500.Plo -rm -f ./$(DEPDIR)/wr1550.Plo -rm -f ./$(DEPDIR)/wr3100.Plo -rm -f ./$(DEPDIR)/wr3150.Plo -rm -f ./$(DEPDIR)/wr3500.Plo -rm -f ./$(DEPDIR)/wr3700.Plo -rm -f linradio/$(DEPDIR)/wrg313api.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/winradio/wr3100.c0000664000175000017500000001003115056640443012327 /* * Hamlib WiNRADiO backend - WR3100 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3100_FUNC RIG_FUNC_NONE #define WR3100_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR3100_LEVEL (WR3100_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3100_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3100_caps = { RIG_MODEL(RIG_MODEL_WR3100), .model_name = "WR-3100", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3100_FUNC, .has_set_func = WR3100_FUNC, .has_get_level = WR3100_LEVEL, .has_set_level = WR3100_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR3100_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3100_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3100_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR3100_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/wr1000.c0000664000175000017500000000762315056640443012341 /* * Hamlib WiNRADiO backend - WR1000 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1000_FUNC 0 #define WR1000_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1000_LEVEL (WR1000_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1000_MODES (RIG_MODE_AM | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1000_caps = { RIG_MODEL(RIG_MODEL_WR1000), .model_name = "WR-1000", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1000_FUNC, .has_set_func = WR1000_FUNC, .has_get_level = WR1000_LEVEL, .has_set_level = WR1000_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(500), .endf = MHz(1300), .modes = WR1000_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1300), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(500), .endf = MHz(824), .modes = WR1000_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1000_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1300), .modes = WR1000_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {WR1000_MODES | RIG_MODE_WFM, 100}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/linradio/0000775000175000017500000000000015056640500013107 5hamlib-4.6.5/rigs/winradio/linradio/wrg313api.c0000664000175000017500000001342015056640443014721 #if (!defined(_WIN32) || !defined(__CYGWIN__)) #include #include "config.h" #ifdef HAVE_DLFCN_H # include #endif #include "wrg313api.h" OPEN_DEVICE OpenDevice = 0; CLOSE_DEVICE CloseDevice = 0; SET_POWER SetPower = 0; GET_POWER GetPower = 0; SET_FREQUENCY SetFrequency = 0; GET_FREQUENCY GetFrequency = 0; GET_RADIO_INFO GetRadioInfo = 0; GET_RSSI GetRSSI = 0; GET_AGC GetAGC = 0; SET_AGC SetAGC = 0; SET_IF_GAIN SetIFGain = 0; GET_IF_GAIN GetIFGain = 0; SET_SOFT_AGC SetSoftAGC = 0; GET_SOFT_AGC GetSoftAGC = 0; SET_VOLUME SetVolume = 0; GET_VOLUME GetVolume = 0; SET_MODE SetMode = 0; GET_MODE GetMode = 0; GET_DEVICE_LIST GetDeviceList = 0; DESTROY_DEVICE_LIST DestroyDeviceList = 0; SET_ATTENUATOR SetAttenuator = 0; GET_ATTENUATOR GetAttenuator = 0; SET_IF_SHIFT SetIFShift = 0; GET_IF_SHIFT GetIFShift = 0; SET_IF_BANDWIDTH SetIFBandwidth = 0; GET_IF_BANDWIDTH GetIFBandwidth = 0; START_STREAMING StartStreaming = 0; STOP_STREAMING StopStreaming = 0; GET_RAW_SIGNAL_STRENGTH GetRawSignalStrength = 0; GET_SIGNAL_STRENGTH GetSignalStrength = 0; IS_DEVICE_CONNECTED IsDeviceConnected = 0; GET_INTERFACE GetInterface = 0; SET_CW_TONE SetCWTone = 0; GET_CW_TONE GetCWTone = 0; SET_FM_AF_SQUELCH_LEVEL SetFMAFSquelchLevel = 0; GET_FM_AF_SQUELCH_LEVEL GetFMAFSquelchLevel = 0; SET_NOTCH_FILTER SetNotchFilter = 0; GET_NOTCH_FILTER GetNotchFilter = 0; SET_NOISE_BLANKER SetNoiseBlanker = 0; GET_NOISE_BLANKER GetNoiseBlanker = 0; SET_ISB_AUDIO_CHANNEL SetISBAudioChannel = 0; GET_ISB_AUDIO_CHANNEL GetISBAudioChannel = 0; LOAD_CALIBRATION_FILE LoadCalibrationFile = 0; RESET_CALIBRATION ResetCalibration = 0; GET_API_VERSION GetAPIVersion = 0; int InitAPI(void *hWRAPI) { if (hWRAPI == NULL) { return 0; } GetAPIVersion = (GET_API_VERSION)dlsym(hWRAPI, "GetAPIVersion"); OpenDevice = (OPEN_DEVICE)dlsym(hWRAPI, "OpenDevice"); CloseDevice = (CLOSE_DEVICE)dlsym(hWRAPI, "CloseDevice"); SetPower = (SET_POWER)dlsym(hWRAPI, "SetPower"); GetPower = (GET_POWER)dlsym(hWRAPI, "GetPower"); SetFrequency = (SET_FREQUENCY)dlsym(hWRAPI, "SetFrequency"); GetFrequency = (GET_FREQUENCY)dlsym(hWRAPI, "GetFrequency"); GetRadioInfo = (GET_RADIO_INFO)dlsym(hWRAPI, "GetRadioInfo"); GetRSSI = (GET_RSSI)dlsym(hWRAPI, "GetRSSI"); GetAGC = (GET_AGC)dlsym(hWRAPI, "GetAGC"); SetAGC = (SET_AGC)dlsym(hWRAPI, "SetAGC"); SetIFGain = (SET_IF_GAIN)dlsym(hWRAPI, "SetIFGain"); GetIFGain = (GET_IF_GAIN)dlsym(hWRAPI, "GetIFGain"); GetDeviceList = (GET_DEVICE_LIST)dlsym(hWRAPI, "GetDeviceList"); DestroyDeviceList = (DESTROY_DEVICE_LIST)dlsym(hWRAPI, "DestroyDeviceList"); SetSoftAGC = (SET_SOFT_AGC)dlsym(hWRAPI, "SetSoftAGC"); GetSoftAGC = (GET_SOFT_AGC)dlsym(hWRAPI, "GetSoftAGC"); GetVolume = (GET_VOLUME)dlsym(hWRAPI, "GetVolume"); SetVolume = (SET_VOLUME)dlsym(hWRAPI, "SetVolume"); SetMode = (SET_MODE)dlsym(hWRAPI, "SetMode"); GetMode = (GET_MODE)dlsym(hWRAPI, "GetMode"); SetIFShift = (SET_IF_SHIFT)dlsym(hWRAPI, "SetIFShift"); GetIFShift = (GET_IF_SHIFT)dlsym(hWRAPI, "GetIFShift"); SetIFBandwidth = (SET_IF_BANDWIDTH)dlsym(hWRAPI, "SetIFBandwidth"); GetIFBandwidth = (GET_IF_BANDWIDTH)dlsym(hWRAPI, "GetIFBandwidth"); StartStreaming = (START_STREAMING)dlsym(hWRAPI, "StartStreaming"); StopStreaming = (STOP_STREAMING)dlsym(hWRAPI, "StopStreaming"); SetAttenuator = (SET_ATTENUATOR)dlsym(hWRAPI, "SetAttenuator"); GetAttenuator = (GET_ATTENUATOR)dlsym(hWRAPI, "GetAttenuator"); IsDeviceConnected = (IS_DEVICE_CONNECTED)dlsym(hWRAPI, "IsDeviceConnected"); GetInterface = (GET_INTERFACE)dlsym(hWRAPI, "GetInterface"); GetRawSignalStrength = (GET_RAW_SIGNAL_STRENGTH)dlsym(hWRAPI, "GetRawSignalStrength"); GetSignalStrength = (GET_SIGNAL_STRENGTH)dlsym(hWRAPI, "GetSignalStrength"); SetCWTone = (SET_CW_TONE)dlsym(hWRAPI, "SetCWTone"); GetCWTone = (GET_CW_TONE)dlsym(hWRAPI, "GetCWTone"); SetFMAFSquelchLevel = (SET_FM_AF_SQUELCH_LEVEL)dlsym(hWRAPI, "SetFMAFSquelchLevel"); GetFMAFSquelchLevel = (GET_FM_AF_SQUELCH_LEVEL)dlsym(hWRAPI, "GetFMAFSquelchLevel"); SetNotchFilter = (SET_NOTCH_FILTER)dlsym(hWRAPI, "SetNotchFilter"); GetNotchFilter = (GET_NOTCH_FILTER)dlsym(hWRAPI, "GetNotchFilter"); SetNoiseBlanker = (SET_NOISE_BLANKER)dlsym(hWRAPI, "SetNoiseBlanker"); GetNoiseBlanker = (GET_NOISE_BLANKER)dlsym(hWRAPI, "GetNoiseBlanker"); SetISBAudioChannel = (SET_ISB_AUDIO_CHANNEL)dlsym(hWRAPI, "SetISBAudioChannel"); GetISBAudioChannel = (GET_ISB_AUDIO_CHANNEL)dlsym(hWRAPI, "GetISBAudioChannel"); LoadCalibrationFile = (LOAD_CALIBRATION_FILE)dlsym(hWRAPI, "LoadCalibrationFile"); ResetCalibration = (RESET_CALIBRATION)dlsym(hWRAPI, "ResetCalibration"); if (!GetAPIVersion || !OpenDevice || !CloseDevice || !SetPower || !GetPower || !GetFrequency || !SetFrequency || !GetRadioInfo || !GetRSSI || !GetAGC || !SetAGC || !GetIFGain || !SetIFGain || !SetSoftAGC || !GetSoftAGC || !SetVolume || !GetVolume || !GetMode || !SetMode || !GetDeviceList || !DestroyDeviceList || !ResetCalibration || !StartStreaming || !StopStreaming || !LoadCalibrationFile || !SetAttenuator || !GetAttenuator || !GetSignalStrength || !SetIFShift || !SetIFBandwidth || !GetIFBandwidth || !GetIFShift || !GetRawSignalStrength || !IsDeviceConnected || !GetInterface || !SetCWTone || !GetCWTone || !SetFMAFSquelchLevel || !GetFMAFSquelchLevel || !SetNotchFilter || !GetNotchFilter || !SetNoiseBlanker || !GetNoiseBlanker || !SetISBAudioChannel || !GetISBAudioChannel) { return 0; } return 1; } #endif /* not _WIN32 or __CYGWIN__ */ hamlib-4.6.5/rigs/winradio/linradio/radio_ioctl.h0000664000175000017500000000375615056640443015511 /* ioctl API for radio devices. * (C) 1997 Michael McCormack * * Adapted for wrkit and newer winradio receivers. * (C) 1999-2000 */ #ifndef RADIO_H #define RADIO_H #include /* define ioctl() numbers for the radio */ #define RADIO_ID 0x8C /* See linux/Documentation/ioctl-number.txt */ #define RADIO_GET_POWER _IOR(RADIO_ID,0x00,long) #define RADIO_SET_POWER _IOW(RADIO_ID,0x01,long) #define RADIO_GET_MODE _IOR(RADIO_ID,0x02,long) #define RADIO_SET_MODE _IOW(RADIO_ID,0x03,long) #define RADIO_GET_MUTE _IOR(RADIO_ID,0x04,long) #define RADIO_SET_MUTE _IOW(RADIO_ID,0x05,long) #define RADIO_GET_ATTN _IOR(RADIO_ID,0x06,long) #define RADIO_SET_ATTN _IOW(RADIO_ID,0x07,long) #define RADIO_GET_VOL _IOR(RADIO_ID,0x08,long) #define RADIO_SET_VOL _IOW(RADIO_ID,0x09,long) #define RADIO_GET_FREQ _IOR(RADIO_ID,0x0a,long) /* Hz */ #define RADIO_SET_FREQ _IOW(RADIO_ID,0x0b,long) #define RADIO_GET_BFO _IOR(RADIO_ID,0x0c,long) /* Hz */ #define RADIO_SET_BFO _IOW(RADIO_ID,0x0d,long) /* #define RADIO_GET_SSAM _IOR(RADIO_ID,0x0e,long) #define RADIO_GET_SSFMN _IOR(RADIO_ID,0x0f,long) #define RADIO_GET_SSFMW1 _IOR(RADIO_ID,0x10,long) #define RADIO_GET_SSFMW2 _IOR(RADIO_ID,0x11,long) */ #define RADIO_GET_SS _IOR(RADIO_ID,0x12,long) /* 0..120 */ #define RADIO_GET_IFS _IOR(RADIO_ID,0x13,long) /* Hz */ #define RADIO_SET_IFS _IOW(RADIO_ID,0x14,long) #define RADIO_GET_DESCR _IOR(RADIO_ID,0x15,char[256]) #define RADIO_GET_AGC _IOR(RADIO_ID,0x16,long) #define RADIO_SET_AGC _IOW(RADIO_ID,0x17,long) #define RADIO_GET_IFG _IOR(RADIO_ID,0x18,long) #define RADIO_SET_IFG _IOW(RADIO_ID,0x19,long) /* Someone forgot 0x1A-0x1F ? */ #define RADIO_GET_MAXVOL _IOR(RADIO_ID,0x20,long) #define RADIO_GET_MAXIFG _IOR(RADIO_ID,0x21,long) /* radio modes */ typedef enum { RADIO_CW = 0, RADIO_AM = 1, RADIO_FMN = 2, RADIO_FMW = 3, RADIO_LSB = 4, RADIO_USB = 5, RADIO_FMM = 6, RADIO_FM6 = 7, } radio_mode; #endif /* RADIO_H */ hamlib-4.6.5/rigs/winradio/linradio/wrg313api.h0000664000175000017500000001341615056640443014733 #ifndef __WRG313_API_H__ #define __WRG313_API_H__ #include #define WRG3APINAME "wrg313api" #define RADIOMODE_AM 0 #define RADIOMODE_SAM 1 #define RADIOMODE_LSB 2 #define RADIOMODE_USB 3 #define RADIOMODE_DSB 4 #define RADIOMODE_ISB 5 #define RADIOMODE_CW 6 #define RADIOMODE_FMN 7 #define AGC_NONE 0 #define AGC_SLOW 1 #define AGC_MEDIUM 2 #define AGC_FAST 3 #define INTERFACE_PCI 0 #define INTERFACE_USB 1 #pragma pack(push,1) typedef struct { __u32 Size; char SerNum[9]; char Model[9]; __u32 MinFreq; __u32 MaxFreq; __u8 NumBands; __u32 BandFreq[16]; __u32 LOFreq; __u8 NumVcos; __u32 VcoFreq[8]; __u16 VcoDiv[8]; __u8 VcoBits[8]; __u32 RefClk1; __u32 RefClk2; __u8 IF1DAC[8]; __s32 AGCstart; __s32 AGCmid; __s32 AGCend; __s32 DropLevel; __s32 RSSItop; __s32 RSSIref; __s32 RxGain; } RADIO_INFO; typedef struct { char Path[64]; __u8 Interface; RADIO_INFO Info; } RADIO_DESC; #pragma pack(pop) #ifdef __cplusplus extern "C" { #endif typedef void (*IF_CALLBACK)(__s16 *Buffer,int Count,void *Context); typedef void (*SPECTRUM_CALLBACK)(float *Spectrum,int Count,void *Context); typedef void (*AUDIO_CALLBACK)(__s16 *AudioBuffer,int Count,void *UserData); typedef int (*OPEN_DEVICE)(const char *DeviceName); typedef void (*CLOSE_DEVICE)(int hRadio); typedef int (*SET_POWER)(int hRadio,int Power); typedef int (*GET_POWER)(int hRadio,int *Power); typedef int (*GET_FREQUENCY)(int hRadio,unsigned int *Frequency); typedef int (*SET_FREQUENCY)(int hRadio,unsigned int Frequency); typedef int (*GET_RADIO_INFO)(int hRadio,RADIO_INFO *Info); typedef int (*GET_RSSI)(int hRadio,int *RSSI); typedef int (*GET_AGC)(int hRadio,int *AGC); typedef int (*SET_AGC)(int hRadio,int AGC); typedef int (*SET_IF_GAIN)(int hRadio,unsigned int Gain); typedef int (*GET_IF_GAIN)(int hRadio,unsigned int *Gain); typedef int (*SET_SOFT_AGC)(int hRadio,int AGC); typedef int (*GET_SOFT_AGC)(int hRadio,int *AGC); typedef int (*SET_VOLUME)(int hRadio,unsigned int Volume); typedef int (*GET_VOLUME)(int hRadio,unsigned int *Volume); typedef int (*SET_MODE)(int hRadio,int Mode); typedef int (*GET_MODE)(int hRadio,int *Mode); typedef int (*SET_IF_SHIFT)(int hRadio,int IFShift); typedef int (*GET_IF_SHIFT)(int hRadio,int *IFShift); typedef int (*SET_IF_BANDWIDTH)(int hRadio,unsigned int IFBandwidth); typedef int (*GET_IF_BANDWIDTH)(int hRadio,unsigned int *IFBandwidth); typedef int (*GET_DEVICE_LIST)(RADIO_DESC **List,int *Count); typedef void (*DESTROY_DEVICE_LIST)(RADIO_DESC *List); typedef int (*SET_ATTENUATOR)(int hRadio,int Attennutator); typedef int (*GET_ATTENUATOR)(int hRadio,int *Attenuator); typedef int (*START_STREAMING)(int hRadio,AUDIO_CALLBACK AudioCallback,IF_CALLBACK IFCallback,SPECTRUM_CALLBACK SpectrumCallback,void *Context); typedef int (*STOP_STREAMING)(int hRadio); typedef int (*GET_RAW_SIGNAL_STRENGTH)(int hRadio,unsigned char *Raw); typedef int (*GET_SIGNAL_STRENGTH)(int hRadio,double *SignalStrength); typedef int (*IS_DEVICE_CONNECTED)(int hRadio); typedef int (*GET_INTERFACE)(int hRadio,int *Interface); typedef int (*SET_CW_TONE)(int hRadio,unsigned int Frequency); typedef int (*GET_CW_TONE)(int hRadio,unsigned int *Frequency); typedef int (*SET_FM_AF_SQUELCH_LEVEL)(int hRadio,unsigned int Level); typedef int (*GET_FM_AF_SQUELCH_LEVEL)(int hRadio,unsigned int *Level); typedef int (*SET_NOTCH_FILTER)(int hRadio,int Active,int Frequency,unsigned int Bandwidth); typedef int (*GET_NOTCH_FILTER)(int hRadio,int *Active,int *Frequency,unsigned int *Bandwidth); typedef int (*SET_NOISE_BLANKER)(int hRadio,int Active,unsigned int Threshold); typedef int (*GET_NOISE_BLANKER)(int hRadio,int *Active,unsigned int *Threshold); typedef int (*SET_ISB_AUDIO_CHANNEL)(int hRadio,unsigned int Channel); typedef int (*GET_ISB_AUDIO_CHANNEL)(int hRadio,unsigned int *Channel); typedef int (*LOAD_CALIBRATION_FILE)(int hRadio,const char *Path); typedef int (*RESET_CALIBRATION)(int hRadio); typedef unsigned int (*GET_API_VERSION)(void); #ifdef __cplusplus }; #endif extern OPEN_DEVICE OpenDevice; extern CLOSE_DEVICE CloseDevice; extern SET_POWER SetPower; extern GET_POWER GetPower; extern SET_FREQUENCY SetFrequency; extern GET_FREQUENCY GetFrequency; extern GET_RADIO_INFO GetRadioInfo; extern GET_RSSI GetRSSI; extern GET_AGC GetAGC; extern SET_AGC SetAGC; extern SET_IF_GAIN SetIFGain; extern GET_IF_GAIN GetIFGain; extern SET_SOFT_AGC SetSoftAGC; extern GET_SOFT_AGC GetSoftAGC; extern SET_VOLUME SetVolume; extern GET_VOLUME GetVolume; extern SET_MODE SetMode; extern GET_MODE GetMode; extern SET_IF_SHIFT SetIFShift; extern GET_IF_SHIFT GetIFShift; extern SET_IF_BANDWIDTH SetIFBandwidth; extern GET_IF_BANDWIDTH GetIFBandwidth; extern GET_DEVICE_LIST GetDeviceList; extern DESTROY_DEVICE_LIST DestroyDeviceList; extern SET_ATTENUATOR SetAttenuator; extern GET_ATTENUATOR GetAttenuator; extern START_STREAMING StartStreaming; extern STOP_STREAMING StopStreaming; extern GET_RAW_SIGNAL_STRENGTH GetRawSignalStrength; extern GET_SIGNAL_STRENGTH GetSignalStrength; extern IS_DEVICE_CONNECTED IsDeviceConnected; extern GET_INTERFACE GetInterface; extern SET_CW_TONE SetCWTone; extern GET_CW_TONE GetCWTone; extern SET_FM_AF_SQUELCH_LEVEL SetFMAFSquelchLevel; extern GET_FM_AF_SQUELCH_LEVEL GetFMAFSquelchLevel; extern SET_NOTCH_FILTER SetNotchFilter; extern GET_NOTCH_FILTER GetNotchFilter; extern SET_NOISE_BLANKER SetNoiseBlanker; extern GET_NOISE_BLANKER GetNoiseBlanker; extern SET_ISB_AUDIO_CHANNEL SetISBAudioChannel; extern GET_ISB_AUDIO_CHANNEL GetISBAudioChannel; extern LOAD_CALIBRATION_FILE LoadCalibrationFile; extern RESET_CALIBRATION ResetCalibration; extern GET_API_VERSION GetAPIVersion; int InitAPI(void *hWRAPI); void UninitAPI(void); #endif hamlib-4.6.5/rigs/winradio/linradio/wrapi.h0000664000175000017500000001374415056640443014341 /****************************************************************************/ /* Low-level receiver interface code. */ /* Copyright (C) 2000 WiNRADiO Communications. */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; Version 2, June 1991. */ /* */ /* 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 */ /* General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, */ /* USA. */ /****************************************************************************/ #ifndef _WRAPI_H_ #define _WRAPI_H_ #ifdef __cplusplus extern "C" { #endif /* WiNRADiO Information Features (capabilities) */ #define RIF_USVERSION 0x00000001 /* set if hardware is US version */ #define RIF_DSP 0x00000002 /* set if DSP is present */ #define RIF_LSBUSB 0x00000004 /* set if receiver as CW/LSB/USB instead of SSB */ #define RIF_CWIFSHIFT 0x00000008 /* set if receiver uses IFShift in CW (not BFOOffset) */ #define RIF_AGC 0x00000100 /* set if receiver supports AGC on/off */ #define RIF_IFGAIN 0x00000200 /* set if receiver has manual IF gain control */ /* WiNRADiO Modes */ #define RMD_CW 0 #define RMD_AM 1 #define RMD_FMN 2 #define RMD_FMW 3 #define RMD_LSB 4 #define RMD_USB 5 #define RMD_FMM 6 /* 50kHz FM */ #define RMD_FM6 7 /* 6kHz FMN */ /* WiNRADiO Hardware Versions */ #define RHV_1000a 0x0100 /* older WR-1000 series */ #define RHV_1000b 0x010a /* current WR-1000 series */ #define RHV_1500 0x0132 #define RHV_1550 0x0137 /* new WR-1550 receiver */ #define RHV_3000 0x0200 /* Spectrum Monitor series */ #define RHV_3100 0x020a #define RHV_3150 0x020f /* new WR-3150 receiver */ #define RHV_3200 0x0214 #define RHV_3500 0x0232 #define RHV_3700 0x0246 #define RHV_2000 0x0300 /* frequency x10 multiplier (ie. 2-20 GHz maximum support) */ #define RFQ_X10 0x80000000L /* WiNRADiO Hardware Interfaces */ #define RHI_ISA 0 #define RHI_SERIAL 1 #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif typedef unsigned long DWORD; typedef int BOOL; typedef unsigned int UINT; typedef unsigned char BYTE; typedef unsigned short WORD; typedef float FLOAT; typedef FLOAT *PFLOAT; typedef BOOL *PBOOL; typedef BOOL *LPBOOL; typedef BYTE *PBYTE; typedef BYTE *LPBYTE; typedef int *PINT; typedef int *LPINT; typedef UINT *PUINT; typedef UINT *LPUINT; typedef WORD *PWORD; typedef WORD *LPWORD; typedef long *LPLONG; typedef DWORD *PDWORD; typedef DWORD *LPDWORD; typedef void *LPVOID; typedef int *MODELIST; typedef MODELIST *LPMODELIST; typedef struct _RADIOINFO { DWORD dwSize; /* size of structure (must be set before calling GetRadioDeviceInfo) */ DWORD dwFeatures; /* bit flags for extra features (RIF_XXX) */ WORD wAPIVer; /* driver version */ WORD wHWVer; /* hardware version (RHV_XXX) */ DWORD dwMinFreq; /* minimum frequency receiver can tune to */ DWORD dwMaxFreq; /* maximum frequency receiver can tune to */ int iFreqRes; /* resolution of receiver in Hz */ int iNumModes; /* number of modes that can be set */ int iMaxVolume; /* maximum volume level */ int iMaxBFO; /* maximum BFO offset range (+/- in Hz) */ int iMaxFMScanRate; /* maximum scan rate for FM scanning/sweeping */ int iMaxAMScanRate; /* maximum scan rate for AM scanning/sweeping */ int iHWInterface; /* physical interface radio is connected to (RHI_XXX) */ int iDeviceNum; /* logical radio device number */ int iNumSources; /* number of selectable audio sources */ int iMaxIFShift; /* maximum IF shift */ DWORD dwWaveFormats; /* bit array of supported rec/play formats (RWF_XXX) */ int iDSPSources; /* number of selectable DSP input sources */ LPMODELIST lpSupportedModes; /* list of available modes (length specified by iNumModes) */ DWORD dwMaxFreqkHz; /* same as dwMaxFreq, but in kHz */ char szDeviceName[64]; /* not used in DOSRADIO */ int iMaxIFGain; /* the maximum manual IF gain level */ char descr[80]; /* Description (PB) */ } RADIOINFO, *PRADIOINFO, *LPRADIOINFO; int OpenRadioDevice(WORD); BOOL CloseRadioDevice(int); int GetRadioDeviceInfo(int, LPRADIOINFO); int GetSignalStrength(int); BOOL SetFrequency(int, DWORD); BOOL SetMode(int, int); BOOL SetVolume(int, int); BOOL SetAtten(int, BOOL); BOOL SetMute(int, BOOL); BOOL SetPower(int, BOOL); BOOL SetBFOOffset(int, int); BOOL SetIFShift(int, int); BOOL SetAGC(int, BOOL); BOOL SetIFGain(int, int); DWORD GetFrequency(int); int GetMode(int); int GetMaxVolume(int); int GetVolume(int); BOOL GetAtten(int); BOOL GetMute(int); BOOL GetPower(int); int GetBFOOffset(int); int GetIFShift(int); BOOL GetAGC(int); int GetMaxIFGain(int); int GetIFGain(int); char *GetDescr(int); #ifdef __cplusplus } #endif #ifdef __KERNEL__ /* Hooks called when rescheduling */ extern void (*yield_hook)(); extern void (*reenter_hook)(); #endif #endif hamlib-4.6.5/rigs/winradio/wr1500.c0000664000175000017500000001003115056640443012331 /* * Hamlib WiNRADiO backend - WR1500 description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1500_FUNC RIG_FUNC_NONE #define WR1500_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1500_LEVEL (WR1500_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1500_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1500_caps = { RIG_MODEL(RIG_MODEL_WR1500), .model_name = "WR-1500", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1500_FUNC, .has_set_func = WR1500_FUNC, .has_get_level = WR1500_LEVEL, .has_set_level = WR1500_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR1500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR1500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR1500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.5/rigs/winradio/g313-win.c0000664000175000017500000004372315056640443012661 /* * Hamlib WiNRADiO backend - WR-G313 * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G313_MODES (RIG_MODE_USB) #if defined (_WIN32) || !defined(OTHER_POSIX) #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * * TODO: rig_probe, rig_scan */ #define WAVEOUT_SOUNDCARDID 0x150901 const struct confparams g313_cfg_params[] = { { WAVEOUT_SOUNDCARDID, "wodeviceid", "WaveOut Device ID", "Sound card device ID for playing IF signal from receiver", "-1", RIG_CONF_NUMERIC, { .n = { -3, 32, 1 } } }, { RIG_CONF_END, NULL, } }; #define WRG313DLL "wrg3130api.dll" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) static int g313_init(RIG *rig); static int g313_cleanup(RIG *rig); static int g313_open(RIG *rig); static int g313_close(RIG *rig); static int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g313_set_powerstat(RIG *rig, powerstat_t status); static int g313_get_powerstat(RIG *rig, powerstat_t *status); static int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g313_get_info(RIG *rig); int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val); int g313_get_conf(RIG *rig, hamlib_token_t token, char *val); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); typedef MMRESULT(__stdcall *TwaveOutGetDevCaps)(UINT_PTR uDeviceID, LPWAVEOUTCAPS pwoc, UINT cbwoc); typedef UINT(__stdcall *TwaveOutGetNumDevs)(void); typedef HANDLE(__stdcall *TStartWaveOut)(LONG hRadio, LONG WaveOutDeviceIndex); typedef void (__stdcall *TStopWaveOut)(HANDLE hWaveOut); struct g313_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; HMODULE WinMM; TwaveOutGetDevCaps waveOutGetDevCaps; TwaveOutGetNumDevs waveOutGetNumDevs; HMODULE hWRG313WO; int WaveOutDeviceID; HANDLE hWaveOut; TStartWaveOut StartWaveOut; TStopWaveOut StopWaveOut; int Opened; }; struct rig_caps g313_caps = { RIG_MODEL(RIG_MODEL_G313), .model_name = "WR-G313", .mfg_name = "Winradio", .version = "20191204.0", .copyright = "LGPL", /* This wrapper, not the G313 DLL */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G313_FUNC, .has_set_func = G313_FUNC, .has_get_level = G313_LEVEL, .has_set_level = RIG_LEVEL_SET(G313_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G313_MODES, 1}, RIG_TS_END, }, .filters = { {G313_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = g313_cfg_params, .set_conf = g313_set_conf, .get_conf = g313_get_conf, .rig_init = g313_init, .rig_cleanup = g313_cleanup, .rig_open = g313_open, .rig_close = g313_close, .set_freq = g313_set_freq, .get_freq = g313_get_freq, .set_powerstat = g313_set_powerstat, .get_powerstat = g313_get_powerstat, .set_level = g313_set_level, .get_level = g313_get_level, .get_info = g313_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g313_init(RIG *rig) { struct g313_priv_data *priv; STATE(rig)->priv = (struct g313_priv_data *)calloc(1, sizeof( struct g313_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->WaveOutDeviceID = -1; priv->Opened = 0; priv->hWaveOut = NULL; priv->WinMM = LoadLibrary("WinMM.dll"); if (priv->WinMM == NULL) { free(priv); return -RIG_EIO; } priv->hWRG313WO = LoadLibrary("WRG313WO.dll"); if (priv->hWRG313WO == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary WRG313WO.dll\n", __func__); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } priv->StartWaveOut = (TStartWaveOut)GetProcAddress(priv->hWRG313WO, "StartWaveOut"); priv->StopWaveOut = (TStopWaveOut)GetProcAddress(priv->hWRG313WO, "StopWaveOut"); if (!priv->StartWaveOut || !priv->StopWaveOut) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load valid WRG313WO.dll library\n", __func__); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } /* Try to load required dll */ priv->dll = LoadLibrary(WRG313DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG313DLL); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); if (!priv->OpenRadioDevice || !priv->CloseRadioDevice || !priv->G3SetFrequency || !priv->G3GetFrequency || !priv->SetPower || !priv->GetPower || !priv->SetAtten || !priv->GetAtten || !priv->SetAGC || !priv->GetAGC || !priv->SetIFGain || !priv->GetIFGain || !priv->GetSignalStrengthdBm || !priv->GetRawSignalStrength) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load valid %s library\n", __func__, WRG313DLL); FreeLibrary(priv->dll); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } priv->waveOutGetDevCaps = (TwaveOutGetDevCaps)GetProcAddress(priv->WinMM, "waveOutGetDevCapsA"); priv->waveOutGetNumDevs = (TwaveOutGetNumDevs)GetProcAddress(priv->WinMM, "waveOutGetNumDevs"); return RIG_OK; } int g313_findVSC(struct g313_priv_data *priv) { int OutIndex; WAVEOUTCAPS Caps; int Count; int i; OutIndex = -1; Count = priv->waveOutGetNumDevs(); for (i = 0; i < Count; i++) { if (priv->waveOutGetDevCaps(i, &Caps, sizeof(Caps)) == MMSYSERR_NOERROR) { if (strncmp(Caps.szPname, "WiNRADiO Virtual Sound Card", 27) == 0) { OutIndex = i; break; } } } return OutIndex; } int g313_open(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int device_num; int Count; int id; device_num = atoi(RIGPORT(rig)->pathname); Count = priv->waveOutGetNumDevs(); if (Count == 0) { return -RIG_EIO; } if (priv->WaveOutDeviceID == -2) { id = g313_findVSC(priv); } else { id = priv->WaveOutDeviceID; } /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); if (id > -3) { priv->hWaveOut = priv->StartWaveOut(priv->hRadio, id); if (priv->hWaveOut == NULL) { priv->CloseRadioDevice(priv->hRadio); return -RIG_EIO; } } else { priv->hWaveOut = NULL; } priv->Opened = 1; return RIG_OK; } int g313_close(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; if (!priv->Opened) { return RIG_OK; } priv->Opened = 0; if (priv->hWaveOut) { priv->StopWaveOut(priv->hWaveOut); } priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g313_cleanup(RIG *rig) { struct g313_priv_data *priv; if (!rig) { return -RIG_EINVAL; } priv = (struct g313_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ FreeLibrary(priv->dll); FreeLibrary(priv->WinMM); FreeLibrary(priv->hWRG313WO); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g313_set_powerstat(RIG *rig, powerstat_t status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_powerstat(RIG *rig, powerstat_t *status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g313_get_info(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int id; switch (token) { case WAVEOUT_SOUNDCARDID: if (val[0] == '0' && val[1] == 'x') { id = strtol(val, (char **)NULL, 16); } else { id = atoi(val); } if (id < -3 || id > 32) { return -RIG_EINVAL; } priv->WaveOutDeviceID = id; if (priv->Opened) { if (id == -2) { id = g313_findVSC(priv); } if (priv->hWaveOut) { priv->StopWaveOut(priv->hWaveOut); } if (id > -3) { priv->hWaveOut = priv->StartWaveOut(priv->hRadio, id); } else { priv->hWaveOut = NULL; } } break; default: return -RIG_EINVAL; } return RIG_OK; } int g313_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; switch (token) { case WAVEOUT_SOUNDCARDID: SNPRINTF(val, val_len, "%d", priv->WaveOutDeviceID); break; default: return -RIG_EINVAL; } return RIG_OK; } int g313_get_conf(RIG *rig, hamlib_token_t token, char *val) { return g313_get_conf2(rig, token, val, 128); } #endif /* _WIN32 */ hamlib-4.6.5/rigs/winradio/Makefile.am0000664000175000017500000000067315056640443013276 WRSRC = wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g305.c \ winradio.c winradio.h linradio/radio_ioctl.h linradio/wrapi.h if G313_LINUX_GNU WRSRC += g313-posix.c linradio/wrg313api.c linradio/wrg313api.h libhamlib_winradio_la_LIBADD = $(DL_LIBS) endif if G313_WINDOWS WRSRC += g313-win.c endif noinst_LTLIBRARIES = libhamlib-winradio.la libhamlib_winradio_la_SOURCES = $(WRSRC) EXTRA_DIST = NOTES Android.mk hamlib-4.6.5/rigs/winradio/winradio.h0000664000175000017500000000434715056640443013231 /* * Hamlib WiNRADiO backend - main header * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _WINRADIO_H #define _WINRADIO_H 1 #include "hamlib/config.h" #define BACKEND_VER "20110822" /* * So far, only Linux has Linradio support through ioctl, * until someone port it to some other OS... */ #ifdef HAVE_LINUX_IOCTL_H #define WINRADIO_IOCTL #endif #include int wr_rig_init(RIG *rig); int wr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int wr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int wr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int wr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int wr_set_powerstat(RIG *rig, powerstat_t status); int wr_get_powerstat(RIG *rig, powerstat_t *status); int wr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int wr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int wr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int wr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char *wr_get_info(RIG *rig); extern struct rig_caps wr1000_caps; extern struct rig_caps wr1500_caps; extern struct rig_caps wr1550_caps; extern struct rig_caps wr3100_caps; extern struct rig_caps wr3150_caps; extern struct rig_caps wr3500_caps; extern struct rig_caps wr3700_caps; extern struct rig_caps g303_caps; extern struct rig_caps g305_caps; #if defined( _WIN32) || !defined(OTHER_POSIX) extern struct rig_caps g313_caps; #endif #endif /* _WINRADIO_H */ hamlib-4.6.5/rigs/winradio/g313-posix.c0000664000175000017500000004255215056640443013225 /* * Hamlib WiNRADiO backend - WR-G313 * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "config.h" #ifdef HAVE_DLFCN_H # include #endif #include #include "winradio.h" #include "linradio/wrg313api.h" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G313_MODES (RIG_MODE_USB) #define TOK_SHM_AUDIO 0x150901 #define TOK_SHM_IF 0x150902 #define TOK_SHM_SPECTRUM 0x150903 #define FIFO_PATHNAME_SIZE 64 const struct confparams g313_cfg_params[] = { { TOK_SHM_AUDIO, "audio_path", "audio path name", "POSIX shared memory path name to the audio ringbuffer", "", RIG_CONF_STRING, }, { TOK_SHM_IF, "if_path", "I/F path name", "POSIX shared memory path name to the I/F ringbuffer", "", RIG_CONF_STRING, }, { TOK_SHM_SPECTRUM, "spectrum_path", "spectrum path name", "POSIX shared memory path name to the spectrum ringbuffer", "", RIG_CONF_STRING, }, { RIG_CONF_END, NULL, } }; struct g313_fifo_data { int fd; char path[FIFO_PATHNAME_SIZE]; }; struct g313_priv_data { void *hWRAPI; int hRadio; int Opened; struct g313_fifo_data if_buf; struct g313_fifo_data audio_buf; struct g313_fifo_data spectrum_buf; }; static void g313_audio_callback(short *buffer, int count, void *arg); static void g313_if_callback(short *buffer, int count, void *arg); static void g313_spectrum_callback(float *buffer, int count, void *arg); void *g313_init_api(void) { void *hWRAPI = dlopen("wrg313api.so", RTLD_LAZY); if (hWRAPI == 0) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load G313 shared library wrg313api.so\n", __func__); return 0; } if (InitAPI(hWRAPI) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to initialise G313 api\n", __func__); return 0; } return hWRAPI; } int g313_init(RIG *rig) { struct g313_priv_data *priv; priv = (struct g313_priv_data *)calloc(1, sizeof(struct g313_priv_data)); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } memset(priv, 0, sizeof(struct g313_priv_data)); priv->hWRAPI = g313_init_api(); if (priv->hWRAPI) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Initialised G313 API\n", __func__); } /* otherwise try again when open rig */ STATE(rig)->priv = (void *)priv; return RIG_OK; } int g313_open(RIG *rig) { int ret; struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; RADIO_DESC *List; int Count; void *audio_callback = g313_audio_callback; void *if_callback = g313_if_callback; void *spectrum_callback = g313_spectrum_callback; if (priv->hWRAPI == 0) /* might not be done yet, must be done now! */ { priv->hWRAPI = g313_init_api(); if (priv->hWRAPI) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Initialised G313 API\n", __func__); } else { return -RIG_EIO; /* can't go any further */ } } if (priv->Opened) { return RIG_OK; } ret = GetDeviceList(&List, &Count); if (ret < 0 || Count == 0) { return -RIG_EIO; } /* Open Winradio receiver handle (default to first device?) */ rig_debug(RIG_DEBUG_VERBOSE, "%s: found %d rigs 0 is %s\n", __func__, Count, List[0].Path); if (RIGPORT(rig)->pathname[0]) { priv->hRadio = OpenDevice(RIGPORT(rig)->pathname); } else { priv->hRadio = OpenDevice(List[0].Path); } DestroyDeviceList(List); if (priv->hRadio < 0) { return -RIG_EIO; /* huh! */ } rig_debug(RIG_DEBUG_VERBOSE, "%s: Opened G313\n", __func__); /* Make sure the receiver is switched on */ SetPower(priv->hRadio, 1); priv->audio_buf.fd = open(priv->audio_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: audio path %s fifo: %d\n", __func__, priv->audio_buf.path, priv->audio_buf.fd); if (priv->audio_buf.fd == -1) { audio_callback = NULL; } priv->if_buf.fd = open(priv->if_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: if path %s fifo: %d\n", __func__, priv->if_buf.path, priv->if_buf.fd); if (priv->if_buf.fd == -1) { if_callback = NULL; } priv->spectrum_buf.fd = open(priv->spectrum_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: spectrum path %s fifo: %d\n", __func__, priv->spectrum_buf.path, priv->spectrum_buf.fd); if (priv->spectrum_buf.fd == -1) { spectrum_callback = NULL; } ret = StartStreaming(priv->hRadio, audio_callback, if_callback, spectrum_callback, priv); if (ret) { return -RIG_EIO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: told G313 to start streaming audio: %d, if: %d, spec: %d\n", __func__, audio_callback ? 1 : 0, if_callback ? 1 : 0, spectrum_callback ? 1 : 0); priv->Opened = 1; return RIG_OK; } int g313_close(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; if (!priv->Opened) { return RIG_OK; } priv->Opened = 0; /* rig_debug(RIG_DEBUG_VERBOSE, "%s: stop streaming\n", __func__); StopStreaming(priv->hRadio); req.tv_sec=0; req.tv_nsec=500000000L; nanosleep(&req, NULL); */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Closing G313\n", __func__); CloseDevice(priv->hRadio); return RIG_OK; } int g313_cleanup(RIG *rig) { struct g313_priv_data *priv; if (!rig) { return -RIG_EINVAL; } priv = (struct g313_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: close fifos\n", __func__); if (priv->audio_buf.fd >= 0) { close(priv->audio_buf.fd); } if (priv->if_buf.fd >= 0) { close(priv->if_buf.fd); } if (priv->spectrum_buf.fd) { close(priv->spectrum_buf.fd); } rig_debug(RIG_DEBUG_VERBOSE, "%s: Uninitialising G313 API\n", __func__); if (priv->hWRAPI) { dlclose(priv->hWRAPI); } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: %u\n", __func__, (unsigned int)freq); ret = SetFrequency(priv->hRadio, (unsigned int)(freq)); ret = ret == 0 ? RIG_OK : -RIG_EIO; return ret; } int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; unsigned int f; int ret = GetFrequency(priv->hRadio, &f); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d f: %u\n", __func__, ret, f); if (ret) { return -RIG_EIO; } *freq = (freq_t)f; return RIG_OK; } int g313_set_powerstat(RIG *rig, powerstat_t status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int p = status == RIG_POWER_ON ? 1 : 0; int ret = SetPower(priv->hRadio, p); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d state: %d\n", __func__, ret, p); return ret == 0 ? RIG_OK : -RIG_EIO; } int g313_get_powerstat(RIG *rig, powerstat_t *status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int p; int ret = GetPower(priv->hRadio, &p); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d state: %d\n", __func__, ret, p); if (ret) { return -RIG_EIO; } *status = p ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = SetAttenuator(priv->hRadio, val.i != 0 ? 1 : 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Attenuator: %d\n", __func__, ret, val.i); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = SetAGC(priv->hRadio, agc); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d AGC: %d\n", __func__, ret, val.i); break; case RIG_LEVEL_RF: ret = SetIFGain(priv->hRadio, (int)(val.f * 100)); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Gain: %f\n", __func__, ret, val.f); break; default: return -RIG_EINVAL; } return ret == 0 ? RIG_OK : -RIG_EIO; } int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; int value; unsigned int uvalue; double dbl; unsigned char ch; switch (level) { case RIG_LEVEL_ATT: ret = GetAttenuator(priv->hRadio, &value); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Attenuator: %d\n", __func__, ret, value); if (ret) { return -RIG_EIO; } val->i = value ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: ret = GetAGC(priv->hRadio, &value); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d AGC: %d\n", __func__, ret, value); if (ret) { return -RIG_EIO; } switch (value) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_RF: ret = GetIFGain(priv->hRadio, &uvalue); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Gain: %u\n", __func__, ret, uvalue); if (ret) { return -RIG_EIO; } val->f = ((float)uvalue) / 100.0; break; case RIG_LEVEL_STRENGTH: ret = GetSignalStrength(priv->hRadio, &dbl); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d sigstr: %f\n", __func__, ret, dbl); if (ret) { return -RIG_EIO; } val->i = ((int)dbl / 1.0) + 73; break; case RIG_LEVEL_RAWSTR: ret = GetRawSignalStrength(priv->hRadio, &ch); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Raw Sigstr: %u\n", __func__, ret, (unsigned int)ch); if (ret) { return -RIG_EIO; } val->i = ch; break; default: return -RIG_EINVAL; } return RIG_OK; } static const char *g313_get_info(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; static RADIO_INFO info; int ret; info.Size = sizeof(RADIO_INFO); ret = GetRadioInfo(priv->hRadio, &info); if (ret) { return NULL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d sernum: %s\n", __func__, ret, info.SerNum); return info.SerNum; } int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; size_t len = strlen(val); switch (token) { case TOK_SHM_AUDIO: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set audio_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->audio_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->audio_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set audio_path %s\n", __func__, priv->audio_buf.path); break; case TOK_SHM_IF: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set if_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->if_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->if_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set if_path %s\n", __func__, priv->if_buf.path); break; case TOK_SHM_SPECTRUM: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set spectrum_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->spectrum_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->spectrum_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set spectrum_path %s\n", __func__, priv->spectrum_buf.path); } return RIG_OK; } int g313_get_conf(RIG *rig, hamlib_token_t token, char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; switch (token) { case TOK_SHM_AUDIO: strcpy(val, priv->audio_buf.path); break; case TOK_SHM_IF: strcpy(val, priv->if_buf.path); break; case TOK_SHM_SPECTRUM: strcpy(val, priv->spectrum_buf.path); } return RIG_OK; } /* no need to check return from write - if not all can be written, accept overruns */ static void g313_audio_callback(short *buffer, int count, void *arg) { struct g313_priv_data *priv = (struct g313_priv_data *)arg; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(priv->audio_buf.fd, buffer, count * sizeof(short)); #pragma GCC diagnostic pop } static void g313_if_callback(short *buffer, int count, void *arg) { struct g313_priv_data *priv = (struct g313_priv_data *)arg; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(priv->if_buf.fd, buffer, count * sizeof(short)); #pragma GCC diagnostic pop } static void g313_spectrum_callback(float *buffer, int count, void *arg) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" struct g313_priv_data *priv = (struct g313_priv_data *)arg; write(priv->spectrum_buf.fd, buffer, count * sizeof(float)); #pragma GCC diagnostic pop } struct rig_caps g313_caps = { RIG_MODEL(RIG_MODEL_G313), .model_name = "WR-G313", .mfg_name = "Winradio", .version = "20191224.0", .copyright = "LGPL", /* This wrapper, not the G313 shared library or driver */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G313_FUNC, .has_set_func = G313_FUNC, .has_get_level = G313_LEVEL, .has_set_level = RIG_LEVEL_SET(G313_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G313_MODES, 1}, RIG_TS_END, }, .filters = { {G313_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = g313_cfg_params, .set_conf = g313_set_conf, .get_conf = g313_get_conf, .rig_init = g313_init, .rig_cleanup = g313_cleanup, .rig_open = g313_open, .rig_close = g313_close, .set_freq = g313_set_freq, .get_freq = g313_get_freq, .set_powerstat = g313_set_powerstat, .get_powerstat = g313_get_powerstat, .set_level = g313_set_level, .get_level = g313_get_level, .get_info = g313_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/anytone/0000775000175000017500000000000015056640500011147 5hamlib-4.6.5/rigs/anytone/d578.c0000664000175000017500000000652315056640443011736 // --------------------------------------------------------------------------- // Anytone D578UVIII // --------------------------------------------------------------------------- // // d578.c // // Created by Michael Black W9MDB // Copyright © 2023, Michael Black W9MDB. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "anytone.h" #define D578_VFO (RIG_VFO_A|RIG_VFO_B) #define D578_MODES (RIG_MODE_USB|RIG_MODE_AM) struct rig_caps anytone_d578_caps = { RIG_MODEL(RIG_MODEL_ATD578UVIII), .model_name = "D578A", .mfg_name = "AnyTone", .version = BACKEND_VER ".0", .copyright = "Michael Black W9MDB: GNU LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = 0, .rx_range_list1 = { { MHz(108), MHz(174), D578_MODES, -1, -1, D578_VFO }, { MHz(144), MHz(148), D578_MODES, -1, -1, D578_VFO }, { MHz(222), MHz(225), D578_MODES, -1, -1, D578_VFO }, { MHz(420), MHz(450), D578_MODES, -1, -1, D578_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(144), MHz(148), D578_MODES, W(1), W(55), D578_VFO }, { MHz(222), MHz(225), D578_MODES, W(1), W(40), D578_VFO }, { MHz(420), MHz(450), D578_MODES, W(1), W(25), D578_VFO }, RIG_FRNG_END, }, .rig_init = anytone_init, .rig_cleanup = anytone_cleanup, .rig_open = anytone_open, .rig_close = anytone_close, .get_vfo = anytone_get_vfo, .set_vfo = anytone_set_vfo, .get_ptt = anytone_get_ptt, .set_ptt = anytone_set_ptt, .set_freq = anytone_set_freq, .get_freq = anytone_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.5/rigs/anytone/anytone.c0000664000175000017500000003175215056640443012726 // --------------------------------------------------------------------------- // AnyTone D578 Hamlib Backend // --------------------------------------------------------------------------- // // d578.c // // Created by Michael Black W9MDB // Copyright © 2023 Michael Black W9MDB. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include #include #include #include #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "serial.h" #include "misc.h" #include "register.h" #include "riglist.h" // --------------------------------------------------------------------------- // ANYTONE INCLUDES // --------------------------------------------------------------------------- #include "anytone.h" int anytone_transaction(RIG *rig, unsigned char *cmd, int cmd_len, unsigned char *reply, int reply_len, int expected_len); DECLARE_INITRIG_BACKEND(anytone) { int retval = RIG_OK; rig_register(&anytone_d578_caps); return retval; } // --------------------------------------------------------------------------- // proberig_anytone // --------------------------------------------------------------------------- DECLARE_PROBERIG_BACKEND(anytone) { int retval = RIG_OK; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 1; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { retval = -RIG_EIO; } return retval; } // AnyTone needs a keep-alive to emulate the MIC // Apparently to keep the rig from getting stuck in PTT if mic disconnects void *anytone_thread(void *vrig) { RIG *rig = (RIG *)vrig; hamlib_port_t *rp = RIGPORT(rig); anytone_priv_data_t *p = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: anytone_thread started\n", __func__); p->runflag = 1; while (p->runflag) { char c[64]; SNPRINTF(c, sizeof(c), "+ADATA:00,001\r\na\r\n"); MUTEX_LOCK(p->priv.mutex); // if we don't have CACHE debug enabled then we only show WARN and higher for this rig enum rig_debug_level_e debug_level_save; rig_get_debug(&debug_level_save); if (rig_need_debug(RIG_DEBUG_CACHE) == 0) { rig_set_debug(RIG_DEBUG_WARN); // only show WARN debug otherwise too verbose } write_block(rp, (unsigned char *)c, strlen(c)); char buf[32]; read_block(rp, (unsigned char *)buf, 22); if (rig_need_debug(RIG_DEBUG_CACHE) == 0) { rig_set_debug(debug_level_save); } MUTEX_UNLOCK(p->priv.mutex); hl_usleep(1000 * 1000); // 1-second loop } return NULL; } // --------------------------------------------------------------------------- // anytone_send // --------------------------------------------------------------------------- int anytone_send(RIG *rig, unsigned char *cmd, int cmd_len) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_receive // --------------------------------------------------------------------------- int anytone_receive(RIG *rig, unsigned char *buf, int buf_len, int expected) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // retval = read_string(rp, (unsigned char *) buf, buf_len, // NULL, 0, 0, expected); retval = read_block(rp, buf, expected); if (retval > 0) { retval = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: read %d byte=0x%02x\n", __func__, retval, buf[0]); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_transaction // --------------------------------------------------------------------------- int anytone_transaction(RIG *rig, unsigned char *cmd, int cmd_len, unsigned char *reply, int reply_len, int expected_len) { int retval = RIG_OK; //anytone_priv_data_t *p = STATE(rig)->priv; ENTERFUNC; retval = anytone_send(rig, cmd, cmd_len); if (retval == RIG_OK && expected_len != 0) { int len = anytone_receive(rig, reply, reply_len, expected_len); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): rx len=%d\n", __func__, __LINE__, len); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_init // --------------------------------------------------------------------------- int anytone_init(RIG *rig) { int retval = RIG_OK; ENTERFUNC; if (rig != NULL) { anytone_priv_data_ptr p = NULL; // Get new Priv Data p = calloc(1, sizeof(anytone_priv_data_t)); if (p == NULL) { retval = -RIG_ENOMEM; RETURNFUNC(retval); } else { STATE(rig)->priv = p; p->vfo_curr = RIG_VFO_NONE; #ifdef HAVE_PTHREAD pthread_mutex_init(&p->mutex, NULL); #endif } } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_cleanup // --------------------------------------------------------------------------- int anytone_cleanup(RIG *rig) { int retval = RIG_OK; if (rig == NULL) { return -RIG_EARG; } ENTERFUNC; free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_open // --------------------------------------------------------------------------- int anytone_open(RIG *rig) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; unsigned char cmd[] = { 0x2B, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3A, 0x30, 0x30, 0x2C, 0x30, 0x30, 0x31, 0x0d, 0x0a, 'a', 0x0d, 0x0a }; write_block(rp, cmd, sizeof(cmd)); hl_usleep(500 * 1000); char cmd2[64]; SNPRINTF(cmd2, sizeof(cmd2), "+ADATA:00,016\r\n%cD578UV COM MODE\r\n", 0x01); write_block(rp, (unsigned char *)cmd2, strlen(cmd2)); SNPRINTF(cmd2, sizeof(cmd2), "+ADATA:00,000\r\n"); unsigned char reply[512]; anytone_transaction(rig, (unsigned char *)cmd2, strlen(cmd2), reply, sizeof(reply), strlen(cmd2)); pthread_t id; // will start the keep alive int err = pthread_create(&id, NULL, anytone_thread, (void *)rig); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_close // --------------------------------------------------------------------------- int anytone_close(RIG *rig) { int retval = RIG_OK; ENTERFUNC; char *cmd = "+ADATA:00,000\r\n"; anytone_transaction(rig, (unsigned char *)cmd, strlen(cmd), NULL, 0, 0); RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_get_vfo // --------------------------------------------------------------------------- int anytone_get_vfo(RIG *rig, vfo_t *vfo) { int retval = RIG_OK; //char cmd[] = { 0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; //char cmd[] = { "+ADATA06:00,001",0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; ENTERFUNC; const anytone_priv_data_ptr p = (anytone_priv_data_ptr) STATE(rig)->priv; unsigned char reply[512]; unsigned char cmd[] = { 0x2b, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3a, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x36, 0x0d, 0x0a, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a }; anytone_transaction(rig, cmd, sizeof(cmd), reply, sizeof(reply), 114); if (reply[113] == 0x9b) { *vfo = RIG_VFO_A; } else if (reply[113] == 0x9c) { *vfo = RIG_VFO_B; } else { *vfo = RIG_VFO_A; // default to VFOA rig_debug(RIG_DEBUG_ERR, "%s: unknown vfo=0x%02x\n", __func__, reply[113]); } p->vfo_curr = *vfo; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_set_vfo // --------------------------------------------------------------------------- int anytone_set_vfo(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(RIG_OK); } // --------------------------------------------------------------------------- // Function anytone_get_ptt // --------------------------------------------------------------------------- int anytone_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval = RIG_OK; ENTERFUNC; anytone_priv_data_t *p = STATE(rig)->priv; *ptt = p->ptt; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_set_ptt // --------------------------------------------------------------------------- int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = RIG_OK; ENTERFUNC; //char buf[8] = { 0x41, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x06 }; unsigned char ptton[] = { 0x2B, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3A, 0x30, 0x30, 0x2C, 0x30, 0x30, 0x31, 0x0d, 0x0a, 0x61, 0x0d, 0x0a }; unsigned char pttoff[] = { 0x2B, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3A, 0x30, 0x30, 0x2C, 0x30, 0x32, 0x33, 0x0d, 0x0a, 0x56, 0x0d, 0x0a }; void *pttcmd = ptton; if (!ptt) { pttcmd = pttoff; } //if (!ptt) { cmd = " (unsigned char*)+ADATA:00,023\r\nV\r\n"; } MUTEX_LOCK(p->mutex); anytone_transaction(rig, pttcmd, sizeof(ptton), NULL, 0, 0); anytone_priv_data_t *p = STATE(rig)->priv; p->ptt = ptt; MUTEX_UNLOCK(p->mutex); RETURNFUNC(retval); } int anytone_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char cmd[32]; int retval; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(cmd, sizeof(cmd), "+ADATA:00,006\r\n"); cmd[15] = 0x04; cmd[16] = 0x2c; cmd[17] = 0x07; cmd[18] = 0x00; cmd[19] = 0x00; cmd[21] = 0x00; cmd[22] = 0x00; cmd[23] = 0x0d; cmd[24] = 0x0a; if (vfo == RIG_VFO_B) { cmd[16] = 0x2d; } int retry = 2; MUTEX_LOCK(p->priv.mutex); rig_flush(rp); do { write_block(rp, (unsigned char *)cmd, 25); unsigned char buf[512]; retval = read_block(rp, buf, 138); if (retval == 138) { *freq = from_bcd_be(&buf[17], 8) * 10; rig_debug(RIG_DEBUG_VERBOSE, "%s: VFOA freq=%g\n", __func__, *freq); retval = RIG_OK; } } while (retval != 138 && --retry > 0); MUTEX_UNLOCK(p->priv.mutex); return RIG_OK; } int anytone_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd[64]; hamlib_port_t *rp = RIGPORT(rig); if (vfo == RIG_VFO_A) { snprintf(cmd, sizeof(cmd), "ADATA:00,005\r\n%c%c%c%c\r\n", 2, 0, 0, 0); } else { snprintf(cmd, sizeof(cmd), "ADATA:00,005\r\n%c%c%c%c\r\n", 1, 0, 0, 0); } MUTEX_LOCK(p->priv.mutex); rig_flush(rp); write_block(rp, (unsigned char *) cmd, 20); unsigned char backend[] = { 0x2f, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0x15, 0x50, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x09, 0x00, 0x00, 0x0d, 0x0a}; snprintf(cmd, sizeof(cmd), "ADATA:00,023\r\n"); int bytes = strlen(cmd) + sizeof(backend); memcpy(&cmd[15], backend, sizeof(backend)); hl_usleep(10 * 1000); write_block(rp, (unsigned char *)cmd, bytes); MUTEX_UNLOCK(p->priv.mutex); return -RIG_ENIMPL; } // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.5/rigs/anytone/Android.mk0000664000175000017500000000042415056640443013006 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := anytone.c d578.c LOCAL_MODULE := anytone LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := $(LOCAL_SHARED_LIBRARIES) -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/anytone/Makefile.in0000664000175000017500000005273415056640452013155 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/anytone ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_anytone_la_LIBADD = am__objects_1 = anytone.lo d578.lo am_libhamlib_anytone_la_OBJECTS = $(am__objects_1) libhamlib_anytone_la_OBJECTS = $(am_libhamlib_anytone_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/anytone.Plo ./$(DEPDIR)/d578.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_anytone_la_SOURCES) DIST_SOURCES = $(libhamlib_anytone_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ANYTONESRC = anytone.c d578.c anytone.h noinst_LTLIBRARIES = libhamlib-anytone.la libhamlib_anytone_la_SOURCES = $(ANYTONESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/anytone/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/anytone/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-anytone.la: $(libhamlib_anytone_la_OBJECTS) $(libhamlib_anytone_la_DEPENDENCIES) $(EXTRA_libhamlib_anytone_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_anytone_la_OBJECTS) $(libhamlib_anytone_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anytone.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d578.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/anytone.Plo -rm -f ./$(DEPDIR)/d578.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/anytone.Plo -rm -f ./$(DEPDIR)/d578.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/anytone/anytone.h0000664000175000017500000000230015056640443012716 #ifndef _ANYTONE_H #define _ANYTONE_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20231001" #define ANYTONE_RESPSZ 64 extern struct rig_caps anytone_d578_caps; #ifdef PTHREAD #include #define MUTEX(var) static pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #define MUTEX_LOCK(var) pthread_mutex_lock(var) #define MUTEX_UNLOCK(var) pthread_mutex_unlock(var) #else #define MUTEX(var) #define MUTEX_LOCK(var) #define MUTEX_UNLOCK(var) #endif typedef struct _anytone_priv_data { ptt_t ptt; vfo_t vfo_curr; int runflag; // thread control char buf[64]; pthread_mutex_t mutex; } anytone_priv_data_t, * anytone_priv_data_ptr; extern int anytone_init(RIG *rig); extern int anytone_cleanup(RIG *rig); extern int anytone_open(RIG *rig); extern int anytone_close(RIG *rig); extern int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); extern int anytone_get_ptt(RIG *rig, vfo_t vfo,ptt_t *ptt); extern int anytone_set_vfo(RIG *rig, vfo_t vfo); extern int anytone_get_vfo(RIG *rig, vfo_t *vfo); extern int anytone_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int anytone_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); #endif /* _ANYTONE_H */ hamlib-4.6.5/rigs/anytone/Makefile.am0000664000175000017500000000023215056640443013126 ANYTONESRC = anytone.c d578.c anytone.h noinst_LTLIBRARIES = libhamlib-anytone.la libhamlib_anytone_la_SOURCES = $(ANYTONESRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/codan/0000775000175000017500000000000015056640476010572 5hamlib-4.6.5/rigs/codan/codan.c0000664000175000017500000004625115056640443011744 /* * Hamlib CODAN backend - main file * Copyright (c) 2021 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "codan.h" #define MAXCMDLEN 64 #define CODAN_VFOS (RIG_VFO_A|RIG_VFO_B) #define CODAN_MODES (RIG_MODE_USB) int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int codan_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int codan_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; hamlib_port_t *rp = RIGPORT(rig); struct codan_priv_data *priv = STATE(rig)->priv; int retry = 3; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); // Seems the 2110 wants CR instead of LF if (rig->caps->rig_model == RIG_MODEL_CODAN_2110 || rig->caps->rig_model == RIG_MODEL_CODAN_NGT) { SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%c%c", cmd, 0x0d, 0x0a); } else { SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%c", cmd, 0x0a); } repeat: retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); hl_usleep(rig->caps->post_write_delay); if (retval < 0) { return retval; } if (expected == 0) { again1: // response format is response...0x0d0x0a retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s, resultlen=%d\n", __func__, priv->ret_data, (int)strlen(priv->ret_data)); if (strncmp(cmd, priv->ret_data, strlen(cmd)) == 0) { goto again1; } if (strstr(priv->ret_data, "ERROR") && --retry > 0) { goto repeat; } if (strstr(priv->ret_data, "CHAN") && --retry > 0) { goto again1; } if (retval < 0) { return retval; } } else { again2: retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); if (strncmp(cmd, priv->ret_data, strlen(cmd)) == 0) { goto again2; } if (strstr(priv->ret_data, "ERROR") && --retry > 0) { goto repeat; } if (strstr(priv->ret_data, "CHAN")) { goto again2; } if (retval < 0) { return retval; } if (strncmp(priv->ret_data, "LEVELS:", 7) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); } } #if 0 int hr, min, sec; while (--retry >= 0 && strncmp(priv->ret_data, "OK", 2) != 0 && sscanf(priv->ret_data, "%d:%d:%d", &hr, &min, &sec) != 3) { char tmpbuf[256]; retval = read_string(rp, (unsigned char *) tmpbuf, sizeof(priv->ret_data), "\x0a", 1, 0, 1); dump_hex((unsigned char *)priv->ret_data, strlen(priv->ret_data)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); } #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: retval=%d\n", __func__, retval); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); if (result != NULL) { *result = &(priv->ret_data[0]); rig_debug(RIG_DEBUG_VERBOSE, "%s: returning result=%s\n", __func__, *result); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int codan_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct codan_priv_data *)calloc(1, sizeof(struct codan_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } RETURNFUNC2(RIG_OK); } int codan_set_freq_ngt(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); // Purportedly can't do split so we just set VFOB=VFOA SNPRINTF(cmd_buf, sizeof(cmd_buf), "\rfreq %.3f", freq / 1000); char *response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } return retval; } int codan_open(RIG *rig) { char *results = NULL; codan_transaction(rig, "\recho off", 1, &results); codan_transaction(rig, "ver", 1, &results); //codan_transaction(rig, "prompt time", 1, &results); codan_transaction(rig, "login", 1, &results); if (!strstr(results, "admin")) { codan_transaction(rig, "login admin ''", 0, NULL); } codan_transaction(rig, "login", 1, &results); if (rig->caps->rig_model == RIG_MODEL_CODAN_NGT) { codan_set_freq_ngt(rig, RIG_VFO_A, 14074000.0); } else { codan_set_freq(rig, RIG_VFO_A, 14074000.0); } RETURNFUNC2(RIG_OK); } int codan_close(RIG *rig) { char *results = NULL; codan_transaction(rig, "logout admin\rfreq", 1, &results); RETURNFUNC2(RIG_OK); } int codan_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * codan_get_mode * Assumes rig!=NULL */ int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; char modeA[8], modeB[8]; int widthA, center; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = codan_transaction(rig, "mode", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s", __func__, result); int n = sscanf(result, "MODE: %7[A-Z], %7[A-Z], %d, %d", modeA, modeB, ¢er, &widthA); if (n != 4) { rig_debug(RIG_DEBUG_ERR, "%s: sscanf expected 4, got %d, %s\n", __func__, n, result); return -RIG_EPROTO; } if (strncmp(modeA, "USB", 3) == 0) { *mode = RIG_MODE_USB; } else if (strncmp(modeA, "LSB", 3) == 0) { *mode = RIG_MODE_LSB; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode=%s'\n", __func__, modeA); return -RIG_EPROTO; } *width = widthA; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } /* * codan_set_mode * Assumes rig!=NULL */ int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], *ttmode; char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_USB: ttmode = "USBW"; break; case RIG_MODE_LSB: ttmode = "LSBW"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "mode %s", ttmode); retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } return RIG_OK; } /* * codan_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int codan_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); // Purportedly can't do split so we just set VFOB=VFOA SNPRINTF(cmd_buf, sizeof(cmd_buf), "connect tcvr rf %.0f %.0f\rfreq", freq, freq); char *response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } return retval; } /* * codan_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int codan_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; retval = codan_transaction(rig, "freq", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "FREQ: %lg", freq); if (retval == 0) retval = sscanf(response, "CHAN: %lg", freq); *freq *= 1000; // returned freq is in kHz if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } /* * codan_get_ptt * Assumes rig!=NULL */ int codan_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = codan_transaction(rig, "connect tcvr rf ptt", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } const char *p = strstr(response, "Ptt"); if (p) { if (strcmp(p, "Ptt=Off") == 0) { *ptt = 0; } else { *ptt = 1; } } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to find Ptt in %s\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } int codan_get_ptt_2110(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = codan_transaction(rig, "ptt", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } const char *p = strstr(response, "PTT"); if (p) { if (strstr(p, "OFF")) { *ptt = 0; } else { *ptt = 1; } } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to find Ptt in %s\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * codan_set_ptt * Assumes rig!=NULL * * VK5MCA * Changing PTT activation from 'connect tcvr rf ptt %s' to CICS command 'ptt %s voice'. * This sets fast ALC and allows audio to pass to the transmitter via the GPIO port. */ int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); SNPRINTF(cmd_buf, sizeof(cmd_buf), "ptt %s voice\rptt", ptt == 0 ? "off" : "on"); response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd result=%s\n", __func__, response); return RIG_OK; } int codan_set_ptt_ngs(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); SNPRINTF(cmd_buf, sizeof(cmd_buf), "ptt %s", ptt == 0 ? "off" : "on"); response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd result=%s\n", __func__, response); return RIG_OK; } struct rig_caps codan_envoy_caps = { RIG_MODEL(RIG_MODEL_CODAN_ENVOY), .model_name = "Envoy", .mfg_name = "CODAN", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = CODAN_MODES, .low_power = -1, .high_power = -1, CODAN_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {CODAN_MODES, 1}, {CODAN_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.0)}, RIG_FLT_END, }, .priv = NULL, .rig_init = codan_init, .rig_open = codan_open, .rig_close = codan_close, .rig_cleanup = codan_cleanup, .set_freq = codan_set_freq, .get_freq = codan_get_freq, .set_mode = codan_set_mode, .get_mode = codan_get_mode, .set_ptt = codan_set_ptt, .get_ptt = codan_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps codan_ngt_caps = { RIG_MODEL(RIG_MODEL_CODAN_NGT), .model_name = "NGT", .mfg_name = "CODAN", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = CODAN_MODES, .low_power = -1, .high_power = -1, CODAN_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {CODAN_MODES, 1}, {CODAN_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.0)}, RIG_FLT_END, }, .priv = NULL, .rig_init = codan_init, .rig_cleanup = codan_cleanup, .rig_open = codan_open, .set_freq = codan_set_freq_ngt, .get_freq = codan_get_freq, .set_mode = codan_set_mode, .get_mode = codan_get_mode, //.set_ptt = codan_set_ptt, // does not have it //.get_ptt = codan_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps codan_2110_caps = { RIG_MODEL(RIG_MODEL_CODAN_2110), .model_name = "2110", .mfg_name = "CODAN", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = CODAN_MODES, .low_power = -1, .high_power = -1, CODAN_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {CODAN_MODES, 1}, {CODAN_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.0)}, RIG_FLT_END, }, .priv = NULL, .rig_init = codan_init, .rig_open = codan_open, .rig_cleanup = codan_cleanup, .set_freq = codan_set_freq, .get_freq = codan_get_freq, .set_mode = codan_set_mode, .get_mode = codan_get_mode, .set_ptt = codan_set_ptt, .get_ptt = codan_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; DECLARE_INITRIG_BACKEND(codan) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&codan_envoy_caps); rig_register(&codan_ngt_caps); rig_register(&codan_2110_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } hamlib-4.6.5/rigs/codan/Android.mk0000664000175000017500000000040015056640443012407 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := codan.c codan.h LOCAL_MODULE := codan LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/codan/Makefile.in0000664000175000017500000005237415056640452012564 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/codan ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_codan_la_LIBADD = am__objects_1 = codan.lo am_libhamlib_codan_la_OBJECTS = $(am__objects_1) libhamlib_codan_la_OBJECTS = $(am_libhamlib_codan_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/codan.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_codan_la_SOURCES) DIST_SOURCES = $(libhamlib_codan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CODANSRC = codan.c codan.h noinst_LTLIBRARIES = libhamlib-codan.la libhamlib_codan_la_SOURCES = $(CODANSRC) EXTRA_DIST = README.codan Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/codan/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/codan/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-codan.la: $(libhamlib_codan_la_OBJECTS) $(libhamlib_codan_la_DEPENDENCIES) $(EXTRA_libhamlib_codan_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_codan_la_OBJECTS) $(libhamlib_codan_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codan.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/codan.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/codan.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/codan/codan.h0000664000175000017500000000407015056640443011742 /* * Hamlib Barrett backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _CODAN_H #define _CODAN_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20250216" #define EOM "\x0d" #define TRUE 1 #define FALSE 0 // For the current implemented command set 64 is long enough // This will need a lot more room for some channel commands like IDFA which return all channels // But that would 9999*41 or 406KB so didn't do that right now #define CODAN_DATA_LEN 64 extern struct rig_caps codan_envoy_caps; extern struct rig_caps codan_ngt_caps; extern struct rig_caps codan_2021_caps; struct codan_priv_data { char cmd_str[CODAN_DATA_LEN]; /* command string buffer */ char ret_data[CODAN_DATA_LEN]; /* returned data--max value, most are less */ }; extern int codan_transaction(RIG *rig, char *cmd, int expected, char **result); extern int codan_init(RIG *rig); extern int codan_cleanup(RIG *rig); extern int codan_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int codan_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); extern int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); #endif /* _CODAN_H */ hamlib-4.6.5/rigs/codan/Makefile.am0000664000175000017500000000022315056640443012535 CODANSRC = codan.c codan.h noinst_LTLIBRARIES = libhamlib-codan.la libhamlib_codan_la_SOURCES = $(CODANSRC) EXTRA_DIST = README.codan Android.mk hamlib-4.6.5/rigs/codan/README.codan0000664000175000017500000000127515056640443012454 CODAN NGT and Envoy Radio Control Process. User Programming Responsibilities 1. Set Admin password to '' (empty, or NO password) 2. Enable Free TX mode by the sales option available from CODAN USA 3. Must know the serial port connected to "CICS" in the radio programming. This is most often the GP (general purpose) port which is a 15-pin D-Sub connector on a flying lead on the back of the radio. (NGT and Envoy models). Programming must be set to select "CICS" as the device which is addressed via the GP port. As of SDR firmware V3.51 for Envoy and Sentry radios, the Amateur option allows for Freetune Tx on ham bands only. Freetune Tx is no longer required for this rig file to work. VK5MCA hamlib-4.6.5/rigs/tapr/0000775000175000017500000000000015056640500010440 5hamlib-4.6.5/rigs/tapr/tapr.h0000664000175000017500000000211715056640443011506 /* * Hamlib TAPR backend - main header * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TAPR_H #define _TAPR_H 1 #include int tapr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tapr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern struct rig_caps dsp10_caps; #endif /* _TAPR_H */ hamlib-4.6.5/rigs/tapr/Android.mk0000664000175000017500000000037615056640443012305 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dsp10.c tapr.c LOCAL_MODULE := tapr LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/tapr/Makefile.in0000664000175000017500000005262315056640453012444 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tapr ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tapr_la_LIBADD = am__objects_1 = dsp10.lo tapr.lo am_libhamlib_tapr_la_OBJECTS = $(am__objects_1) libhamlib_tapr_la_OBJECTS = $(am_libhamlib_tapr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dsp10.Plo ./$(DEPDIR)/tapr.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tapr_la_SOURCES) DIST_SOURCES = $(libhamlib_tapr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TAPRSRC = dsp10.c tapr.c tapr.h noinst_LTLIBRARIES = libhamlib-tapr.la libhamlib_tapr_la_SOURCES = $(TAPRSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tapr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tapr/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-tapr.la: $(libhamlib_tapr_la_OBJECTS) $(libhamlib_tapr_la_DEPENDENCIES) $(EXTRA_libhamlib_tapr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tapr_la_OBJECTS) $(libhamlib_tapr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsp10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tapr.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dsp10.Plo -rm -f ./$(DEPDIR)/tapr.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dsp10.Plo -rm -f ./$(DEPDIR)/tapr.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/tapr/tapr.c0000664000175000017500000000476215056640443011511 /* * Hamlib TAPR backend - main file * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "register.h" #include "serial.h" #include "tapr.h" #define ESC '$' #define CMD_LEN 6 #define CMD7 7 #define NU1 1 #define NU2 2 #define NU3 3 #define NU4 4 /* * tapr_cmd * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int tapr_cmd(RIG *rig, unsigned char cmd, unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4) { int retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char cmdbuf[CMD_LEN]; rig_flush(rp); cmdbuf[0] = ESC; cmdbuf[1] = cmd; cmdbuf[2] = c1; cmdbuf[3] = c2; cmdbuf[4] = c3; cmdbuf[5] = c4; retval = write_block(rp, cmdbuf, 6); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tapr_set_freq * Assumes rig!=NULL */ int tapr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned int dsp_dph, dsp_deltap_lo, dsp_deltap_hi; int retval; return -RIG_ENIMPL; /* FIXME! */ dsp_dph = (unsigned int)(1.365333333 * (double)(freq - MHz(144) + 15000UL)); dsp_deltap_lo = 0xff & dsp_dph; dsp_deltap_hi = 0xff & (dsp_dph >> 8); retval = tapr_cmd(rig, CMD7, 0, NU1, dsp_deltap_lo, dsp_deltap_hi); return retval; } /* * tapr_set_mode * Assumes rig!=NULL */ int tapr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return -RIG_ENIMPL; } /* * initrigs_tapr is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(tapr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dsp10_caps); return RIG_OK; } hamlib-4.6.5/rigs/tapr/dsp10.c0000664000175000017500000000707215056640443011467 /* * Hamlib TAPR backend - DSP-10 description * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "tapr.h" #define DSP10_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DSP10_FUNC (RIG_FUNC_NONE) #define DSP10_LEVEL_ALL (RIG_LEVEL_NONE) #define DSP10_PARM_ALL (RIG_PARM_NONE) #define DSP10_VFO (RIG_VFO_A) /* * DSP-10 rig capabilities. * * This backend is not working, and is just a call for someone motivated. * Note: The DSP has to be loaded beforehand! * * protocol is documented at (version 2) * http://www.proaxis.com/~boblark/pc_dsp2.txt * * See also: * http://home.teleport.com/~oldaker/dsp10_repository.htm * http://www.proaxis.com/~boblark/dsp10.htm * http://www.tapr.org/tapr/html/Fdsp10.html * * */ struct rig_caps dsp10_caps = { RIG_MODEL(RIG_MODEL_DSP10), .model_name = "DSP-10", .mfg_name = "TAPR", .version = "20061007.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .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 = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DSP10_FUNC, .has_set_func = DSP10_FUNC, .has_get_level = DSP10_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DSP10_LEVEL_ALL), .has_get_parm = DSP10_PARM_ALL, .has_set_parm = RIG_PARM_SET(DSP10_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148), DSP10_MODES, -1, -1, DSP10_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), DSP10_MODES, mW(20), mW(20), DSP10_VFO}, RIG_FRNG_END, }, .tuning_steps = { {DSP10_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .priv = (void *)NULL, .set_freq = tapr_set_freq, .set_mode = tapr_set_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/tapr/Makefile.am0000664000175000017500000000021015056640443012413 TAPRSRC = dsp10.c tapr.c tapr.h noinst_LTLIBRARIES = libhamlib-tapr.la libhamlib_tapr_la_SOURCES = $(TAPRSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/kit/0000775000175000017500000000000015056640477010276 5hamlib-4.6.5/rigs/kit/kit.c0000664000175000017500000000430115056640443011140 /* * Hamlib KIT backend - main file * Copyright (c) 2004-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "register.h" #include "kit.h" /* * initrigs_kit is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kit) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&elektor304_caps); rig_register(&drt1_caps); rig_register(&dds60_caps); rig_register(&miniVNA_caps); rig_register(&hiqsdr_caps); rig_register(&rshfiq_caps); #if (defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H))) rig_register(&si570avrusb_caps); rig_register(&si570picusb_caps); rig_register(&si570peaberry1_caps); rig_register(&si570peaberry2_caps); rig_register(&funcube_caps); rig_register(&fifisdr_caps); rig_register(&fasdr_caps); rig_register(&funcubeplus_caps); #endif #if (defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H))) || defined(_WIN32) /* rigs with alternate DLL support on Win32 */ rig_register(&dwt_caps); rig_register(&elektor507_caps); #endif #ifdef HAVE_USRP //rig_register(&usrp0_caps); rig_register(&usrp_caps); #endif return RIG_OK; } /* * initrots_kit is called by rot_backend_load */ DECLARE_INITROT_BACKEND(kit) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&pcrotor_caps); return RIG_OK; } hamlib-4.6.5/rigs/kit/funcube.c0000664000175000017500000006422315056640443012011 /* * Hamlib KIT backend - FUNcube Dongle USB tuner description * Copyright (c) 2009-2011 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * Author: Stefano Speretta, Innovative Solutions In Space BV * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "misc.h" #define BACKEND_VER "20210830" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "funcube.h" static int funcube_hid_cmd(RIG *rig, unsigned char *au8BufOut, unsigned char *au8BufIn, int inputSize); static int funcube_init(RIG *rig); static int funcubeplus_init(RIG *rig); static int funcube_cleanup(RIG *rig); static int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int funcubepro_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int funcubepro_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *funcube_get_info(RIG *rig); static int funcube_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static const struct confparams funcube_cfg_params[] = { { RIG_CONF_END, NULL, } }; // functions used set / read frequency, working on FUNcube version 0 and 1 int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout); int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout); /* * Common data struct */ struct funcube_priv_data { freq_t freq; /* Hz */ }; /* * FUNcube Dongle description * * Based on Jan Axelson HID examples * http://www.lvr.com/ * */ struct rig_caps funcube_caps = { RIG_MODEL(RIG_MODEL_FUNCUBEDONGLE), .model_name = "FUNcube Dongle", .mfg_name = "AMSAT-UK", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_ATT | RIG_LEVEL_STRENGTH | RIG_LEVEL_PREAMP, .has_set_level = RIG_LEVEL_ATT | RIG_LEVEL_PREAMP, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 5, 10, 15, 20, 25, 30, RIG_DBLST_END, }, .attenuator = { 2, 5, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(50), MHz(2500), RIG_MODE_USB, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_USB, kHz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_USB, kHz(192)}, RIG_FLT_END, }, .cfgparams = funcube_cfg_params, .rig_init = funcube_init, .rig_cleanup = funcube_cleanup, .set_freq = funcube_set_freq, .get_freq = funcube_get_freq, .get_level = funcube_get_level, .set_level = funcube_set_level, .get_info = funcube_get_info, .get_mode = funcube_get_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps funcubeplus_caps = { RIG_MODEL(RIG_MODEL_FUNCUBEDONGLEPLUS), .model_name = "FUNcube Dongle Pro+", .mfg_name = "AMSAT-UK", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_PREAMP | RIG_LEVEL_RF, // RIG_LEVEL_PREAMP: 10dB=LNAon MixGainOff. 20dB=LNAoff, MixGainOn. 30dB=LNAOn, MixGainOn // RIG_LEVEL_RF 0..1 : IF gain 0 .. 59 dB .has_set_level = RIG_LEVEL_PREAMP | RIG_LEVEL_RF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(1900), RIG_MODE_IQ, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_IQ, kHz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_IQ, kHz(192)}, RIG_FLT_END, }, .cfgparams = funcube_cfg_params, .rig_init = funcubeplus_init, .rig_cleanup = funcube_cleanup, .set_freq = funcube_set_freq, .get_freq = funcube_get_freq, .get_level = funcubepro_get_level, .set_level = funcubepro_set_level, .get_info = funcube_get_info, .get_mode = funcube_get_mode, }; int funcube_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct funcube_priv_data *priv; STATE(rig)->priv = (struct funcube_priv_data *)calloc(sizeof( struct funcube_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->freq = 0; rp->parm.usb.vid = VID; rp->parm.usb.pid = PID; rp->parm.usb.conf = FUNCUBE_CONFIGURATION; rp->parm.usb.iface = FUNCUBE_INTERFACE; rp->parm.usb.alt = FUNCUBE_ALTERNATIVE_SETTING; rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PRODUCT_NAME; return RIG_OK; } int funcubeplus_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct funcube_priv_data *priv; STATE(rig)->priv = (struct funcube_priv_data *)calloc(sizeof( struct funcube_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->freq = 0; rp->parm.usb.vid = VID; rp->parm.usb.pid = PIDPLUS; rp->parm.usb.conf = FUNCUBE_CONFIGURATION; rp->parm.usb.iface = FUNCUBE_INTERFACE; rp->parm.usb.alt = FUNCUBE_ALTERNATIVE_SETTING; rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PRODUCT_NAMEPLUS; return RIG_OK; } int funcube_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* Rem: not reentrant */ const char *funcube_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "Dev %04d", desc.bcdDevice); return buf; } int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; int actual_length; unsigned char au8BufOut[64]; // endpoint size unsigned char au8BufIn[64]; // endpoint size // frequency is in Hz, while the dongle expects it in kHz f = f / 1000; au8BufOut[0] = REQUEST_SET_FREQ; // Command to Set Frequency on dongle au8BufOut[1] = (unsigned char)f; au8BufOut[2] = (unsigned char)(f >> 8); au8BufOut[3] = (unsigned char)(f >> 16); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; int actual_length; unsigned char au8BufOut[64]; // endpoint size unsigned char au8BufIn[64]; // endpoint size au8BufOut[0] = REQUEST_SET_FREQ_HZ; // Command to Set Frequency in Hz on dongle au8BufOut[1] = (unsigned char)f; au8BufOut[2] = (unsigned char)(f >> 8); au8BufOut[3] = (unsigned char)(f >> 16); au8BufOut[4] = (unsigned char)(f >> 24); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF, au8BufOut[4] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ_HZ not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct funcube_priv_data *priv = (struct funcube_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; if ((ret = set_freq_v1(udh, freq, rp->timeout)) != RIG_OK) { if ((ret = set_freq_v0(udh, freq, rp->timeout)) == RIG_OK) { priv->freq = freq; } } else { priv->freq = freq; } return ret; } int get_freq_v0(RIG *rig, vfo_t vfo, freq_t *freq) { const struct funcube_priv_data *priv = (struct funcube_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: frequency is not read from the device, the value shown is the last successfully set.\n", __func__); *freq = priv->freq; return RIG_OK; } int get_freq_v1(RIG *rig, vfo_t vfo, freq_t *freq) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; unsigned int f; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size au8BufOut[0] = REQUEST_GET_FREQ_HZ; // Command to Set Frequency on dongle rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_GET_FREQ_HZ not supported\n", __func__); return -RIG_EIO; } f = (au8BufIn[2] & 0xFF) | ((au8BufIn[3] & 0xFF) << 8) | ((au8BufIn[4] & 0xFF) << 16) | ((au8BufIn[5] & 0xFF) << 24), *freq = f; return RIG_OK; } int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; if ((ret = get_freq_v1(rig, vfo, freq)) != RIG_OK) { ret = get_freq_v0(rig, vfo, freq); } return ret; } int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to Set LNA gain switch (val.i) { case 5: au8BufOut[1] = 6; break; case 10: au8BufOut[1] = 8; break; case 15: au8BufOut[1] = 10; break; case 20: au8BufOut[1] = 12; break; case 25: au8BufOut[1] = 13; break; case 30: au8BufOut[1] = 14; break; default: au8BufOut[1] = 4; } break; case RIG_LEVEL_ATT: au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to Set LNA gain switch (val.i) { case 2: au8BufOut[1] = 1; break; case 5: au8BufOut[1] = 0; break; default: au8BufOut[1] = 4; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_LEVEL not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size switch (level) { case RIG_LEVEL_ATT: case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_GET_LNA_GAIN; // Command to Get LNA / ATT gain break; case RIG_LEVEL_STRENGTH: au8BufOut[0] = REQUEST_GET_RSSI; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_GET_LEVEL_x not supported\n", __func__); return -RIG_EIO; } switch (level) { case RIG_LEVEL_PREAMP: switch (au8BufIn[2]) { case 6: val->i = 5; break; case 8: val->i = 10; break; case 10: val->i = 15; break; case 12: val->i = 20; break; case 13: val->i = 25; break; case 14: val->i = 30; break; default: val->i = 0; } break; case RIG_LEVEL_ATT: switch (au8BufIn[2]) { case 0: val->i = 5; break; case 1: val->i = 2; break; default: val->i = 0; } break; case RIG_LEVEL_STRENGTH: val->i = (int)((float)au8BufIn[2] * 2.8 - 35); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int funcube_hid_cmd(RIG *rig, unsigned char *au8BufOut, unsigned char *au8BufIn, int inputSize) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, inputSize, &actual_length, rp->timeout); if (ret < 0 || actual_length != inputSize) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: failed to perform FUNCube HID command %d.\n", __func__, au8BufOut[0]); return -RIG_EIO; } return RIG_OK; } int funcubepro_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; unsigned char au8BufOut[64] = { 0 }; // endpoint size unsigned char au8BufIn[64] = { 0 }; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: rig_debug(RIG_DEBUG_TRACE, "%s: Setting PREAMP state to %d.\n", __func__, val.i); au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to set LNA gain if (val.i == 10 || val.i == 30) { au8BufOut[1] = 1; } else { au8BufOut[1] = 0; } ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } au8BufOut[0] = REQUEST_SET_MIXER_GAIN; // Set mixer gain if (val.i == 20 || val.i == 30) { au8BufOut[1] = 1; } else { au8BufOut[1] = 0; } return funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); case RIG_LEVEL_RF: au8BufOut[0] = REQUEST_SET_IF_GAIN; // Command to set IF gain au8BufOut[1] = (int)(val.f * 100) ; if (au8BufOut[1] > 59) { au8BufOut[1] = 59; } return funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } } int funcubepro_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; int gain_state; unsigned char au8BufOut[64] = { 0 }; // endpoint size unsigned char au8BufIn[64] = { 0 }; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_GET_MIXER_GAIN; // Command to get mixer gain enabled ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s: Mixer gain state returned %d.\n", __func__, au8BufIn[2] & 0xFF); gain_state = au8BufIn[2] & 0x1; au8BufOut[0] = REQUEST_GET_LNA_GAIN; // Command to get LNA gain enabled ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s: LNA gain state returned %d.\n", __func__, au8BufIn[2] & 0xFF); //Mixer gain is 20dB 0x2 gain_state *= 2; //Add the LNA gain if present (10dB) 0x1 gain_state += (au8BufIn[2] & 0x1); //Scale it to tens 1->10dB 2->20dB 3->30dB gain_state *= 10; rig_debug(RIG_DEBUG_TRACE, "%s: Calculated gain state is %d.\n", __func__, gain_state); if (gain_state > 30 || gain_state < 0 || gain_state % 10 != 0) { rig_debug(RIG_DEBUG_ERR, "%s: unrecognized composite gain: %d\n", __func__, gain_state); return -RIG_EINVAL; } val->i = gain_state; return RIG_OK; case RIG_LEVEL_RF: au8BufOut[0] = REQUEST_GET_IF_GAIN; ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); val->f = ((float)au8BufIn[2]) / 100.; return ret; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int funcube_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { if (rig->caps->rig_model == RIG_MODEL_FUNCUBEDONGLE) { *mode = RIG_MODE_USB; } else { *mode = RIG_MODE_IQ; } *width = 192000; return RIG_OK; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.5/rigs/kit/si570avrusb.h0000664000175000017500000000401215056640443012447 /*** * SoftRock USB I2C host control program * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Based on powerSwitch.c by Christian Starkjohann, * and usbtemp.c by Mathias Dalheimer * of Objective Development Software GmbH (2005) * (see http://www.obdev.at/avrusb) * */ #ifndef _SI570AVRUSB_H #define _SI570AVRUSB_H 1 /* DG8SAQ specific values */ #define SI570_I2C_ADDR 0x55 #define SI570_DCO_HIGH 5670.0 #define SI570_DCO_LOW 4850.0 #define SI570_NOMINAL_XTALL_FREQ 114.285 #define SI570_XTALL_DEVIATION_PPM 2000 #define SI570_DEFAULT_STARTUP_FREQ 56.32 #define REQUEST_READ_VERSION 0x00 #define REQUEST_SET_DDRB 0x01 #define REQUEST_SET_PORTB 0x04 #define REQUEST_READ_EEPROM 0x11 #define REQUEST_FILTERS 0x17 #define REQUEST_SET_FREQ 0x30 #define REQUEST_SET_FREQ_BY_VALUE 0x32 #define REQUEST_SET_XTALL_FREQ 0x33 #define REQUEST_SET_STARTUP_FREQ 0x34 #define REQUEST_READ_MULTIPLY_LO 0x39 #define REQUEST_READ_FREQUENCY 0x3A #define REQUEST_READ_SMOOTH_TUNE_PPM 0x3B #define REQUEST_READ_STARTUP 0x3C #define REQUEST_READ_XTALL 0x3D #define REQUEST_READ_REGISTERS 0x3F //#define REQUEST_SET_STARTUP_FREQ 0x41 #define REQUEST_SET_PTT 0x50 #define REQUEST_READ_KEYS 0x51 struct solution { int HS_DIV; int N1; double f0; double RFREQ; }; #endif /* _SI570AVRUSB_H */ hamlib-4.6.5/rigs/kit/miniVNA.c0000664000175000017500000000544615056640443011665 /* * Hamlib miniVNA backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #define DDS_RATIO 10.73741824 static int miniVNA_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char fstr[20]; char cmdstr[40]; int retval; hamlib_port_t *rp = RIGPORT(rig); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "0\r%lu\r1\r0\r", (unsigned long int)(freq * DDS_RATIO)); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } return RIG_OK; } struct rig_caps miniVNA_caps = { RIG_MODEL(RIG_MODEL_MINIVNA), .model_name = "miniVNA", .mfg_name = "mRS", .version = "20190817.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .rx_range_list1 = { {.startf = kHz(100), .endf = MHz(180), .modes = RIG_MODE_CW, .low_power = -1, .high_power = -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { {.startf = kHz(100), .endf = MHz(180), .modes = RIG_MODE_CW, .low_power = W(0), .high_power = W(.004), RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .set_freq = miniVNA_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kit/usrp_impl.h0000664000175000017500000000275615056640443012404 /* * Hamlib KIT backend - Universal Software Radio Peripheral * Copyright (c) 2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _USRP_IMPL_H #define _USRP_IMPL_H 1 #include #include __BEGIN_DECLS #define TOK_IFMIXFREQ TOKEN_BACKEND(2) int usrp_init(RIG *rig); int usrp_cleanup(RIG *rig); int usrp_open(RIG *rig); int usrp_close(RIG *rig); int usrp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int usrp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int usrp_set_conf(RIG *rig, hamlib_token_t token, const char *val); int usrp_get_conf(RIG *rig, hamlib_token_t token, char *val); const char * usrp_get_info(RIG *rig); extern struct rig_caps usrp0_caps; extern struct rig_caps usrp_caps; __END_DECLS #endif /* _USRP_IMPL_H */ hamlib-4.6.5/rigs/kit/kit.h0000664000175000017500000000323015056640443011145 /* * Hamlib KIT backend - main header * Copyright (c) 2004-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KIT_H #define _KIT_H 1 #include "hamlib/rig.h" #include "rotator.h" extern struct rig_caps elektor304_caps; extern struct rig_caps elektor507_caps; extern struct rig_caps si570avrusb_caps; extern struct rig_caps si570picusb_caps; extern struct rig_caps si570peaberry1_caps; extern struct rig_caps si570peaberry2_caps; extern struct rig_caps drt1_caps; extern struct rig_caps dwt_caps; extern struct rig_caps usrp0_caps; extern struct rig_caps usrp_caps; extern struct rig_caps dds60_caps; extern struct rig_caps miniVNA_caps; extern struct rig_caps funcube_caps; extern struct rig_caps funcubeplus_caps; extern struct rig_caps fifisdr_caps; extern struct rig_caps hiqsdr_caps; extern struct rig_caps fasdr_caps; extern struct rig_caps rshfiq_caps; extern const struct rot_caps pcrotor_caps; #endif /* _KIT_H */ hamlib-4.6.5/rigs/kit/drt1.c0000664000175000017500000002472315056640443011235 /* * Hamlib KIT backend - Sat-Schneider DRT1/SAD1 DRM receiver description * Copyright (c) 2004-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "token.h" #define DRT1_MODES (RIG_MODE_AM) #define DRT1_FUNC (RIG_FUNC_NONE) #define DRT1_LEVEL_ALL (RIG_LEVEL_NONE) #define DRT1_PARM_ALL (RIG_PARM_NONE) #define DRT1_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(45.012) #define IFMIXFREQ MHz(45) #define REFMULT 8 #define CHARGE_PUMP_CURRENT 150 struct drt1_priv_data { freq_t osc_freq; freq_t if_mix_freq; unsigned ref_mult; unsigned pump_crrnt; }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) #define TOK_REFMULT TOKEN_BACKEND(3) #define TOK_PUMPCRNT TOKEN_BACKEND(4) static const struct confparams drt1_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillatorfreq", "Oscillator frequency in Hz", "45012000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "45000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { TOK_REFMULT, "ref_mult", "REFCLK Multiplier", "REFCLK Multiplier", "8", RIG_CONF_NUMERIC, { .n = { 4, 20, 1 } } }, { TOK_PUMPCRNT, "pump_current", "Charge pump current", "Charge pump current in uA", "150", RIG_CONF_NUMERIC, { .n = { 75, 150, 25 } } }, { RIG_CONF_END, NULL, } }; static int drt1_init(RIG *rig); static int drt1_cleanup(RIG *rig); static int drt1_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int drt1_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int drt1_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * SAT-Service Schneider DRM tuner. * * The receiver is controlled via the TX, RTS and DTR pins of the serial port. */ struct rig_caps drt1_caps = { RIG_MODEL(RIG_MODEL_DRT1), .model_name = "DRT1", .mfg_name = "SAT-Schneider", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, /* bit banging */ .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DRT1_FUNC, .has_set_func = DRT1_FUNC, .has_get_level = DRT1_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DRT1_LEVEL_ALL), .has_get_parm = DRT1_PARM_ALL, .has_set_parm = RIG_PARM_SET(DRT1_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), MHz(30), DRT1_MODES, -1, -1, DRT1_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), MHz(30), DRT1_MODES, -1, -1, DRT1_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DRT1_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {DRT1_MODES, kHz(10)}, /* opt. 20 kHz */ RIG_FLT_END, }, .cfgparams = drt1_cfg_params, .rig_init = drt1_init, .rig_cleanup = drt1_cleanup, .set_conf = drt1_set_conf, .get_conf = drt1_get_conf, .set_freq = drt1_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int drt1_init(RIG *rig) { struct drt1_priv_data *priv; STATE(rig)->priv = (struct drt1_priv_data *)calloc(1, sizeof( struct drt1_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->ref_mult = REFMULT; priv->if_mix_freq = IFMIXFREQ; priv->pump_crrnt = CHARGE_PUMP_CURRENT; return RIG_OK; } int drt1_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int drt1_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct drt1_priv_data *priv; priv = (struct drt1_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_REFMULT: sscanf(val, "%u", &priv->ref_mult); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; case TOK_PUMPCRNT: sscanf(val, "%u", &priv->pump_crrnt); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int drt1_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct drt1_priv_data *priv; priv = (struct drt1_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_REFMULT: SNPRINTF(val, val_len, "%u", priv->ref_mult); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; case TOK_PUMPCRNT: SNPRINTF(val, val_len, "%u", priv->pump_crrnt); break; default: return -RIG_EINVAL; } return RIG_OK; } int drt1_get_conf(RIG *rig, hamlib_token_t token, char *val) { return drt1_get_conf2(rig, token, val, 128); } /* DDS is AD9951. The clock input is 45,012 MHz (also 2nd LO frequency at the same time). The clock multiplier should be set to 8x at start value (possible, that this will change to lower clock multiplier). The charge pump current to 75 A at start value (possible will change). The VCO gain bit has to be set. The IF offset for LO to the receiving frequency is + 45,000 MHz (fLO = frec + 45,000 MHz) Don't make the data clock too high, there are 1 KOhms decoupling resistors at the input pins of the DDS. Inputs (SDI(O)); SCLK und I/O UPDATE haves 5V TTL level, so that a level converter from RS232 is needed. I will use the attached motorola IC MC1489 as converter for amateur application. This IC inverts the signals ! */ #define AD_DELAY 4000 /* * Introduce delay after changing the bit state * FIXME: This implementation may not work for very fast computers, * or smart compilers. However, nanosleep can have * granularity > 10ms! */ static int ad_delay(int m) { long j; for (j = 0; j <= m; j++) {} return j; } static int ad_sdio(hamlib_port_t *port, int i) { int ret; ret = ser_set_rts(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_sclk(const hamlib_port_t *port, int i) { int ret; ret = ser_set_brk(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_ioupd(hamlib_port_t *port, int i) { int ret; ret = ser_set_dtr(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_write_reg(hamlib_port_t *port, unsigned addr, unsigned nb_bytes, unsigned data) { int i; ad_sclk(port, 0); /* TXD 0 */ ad_ioupd(port, 1); /* DTR 1, CE */ /* Instruction byte, MSB Logic 0 = write */ addr &= 0x1f; for (i = 7; i >= 0; i--) { ad_sdio(port, (addr & (1U << i)) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ } /* Data transfer */ for (i = nb_bytes * 8 - 1; i >= 0; i--) { ad_sdio(port, (data & (1U << i)) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ } ad_ioupd(port, 0); /* DTR 0 */ return RIG_OK; } /* Register serial addresses */ #define CFR1 0x0 #define CFR2 0x1 #define ASF 0x2 #define ARR 0x3 #define FTW0 0x4 #define POW0 0x5 int drt1_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned cfr2; struct drt1_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); priv = (struct drt1_priv_data *)STATE(rig)->priv; rig_flush(port); /* Initialization */ ad_ioupd(port, 0); ad_sdio(port, 0); ad_sclk(port, 0); /* * CFR2: * clock multiplier set to 8x, charge pump current to 75 A * VCO gain bit has to be set */ cfr2 = ((priv->ref_mult << 3) & 0xf8) | 0x4 | (((priv->pump_crrnt - 75) / 25) & 0x3); ad_write_reg(port, CFR2, 3, cfr2); /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / (priv->osc_freq * priv->ref_mult) * 4294967296.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: [%#lx]\n", __func__, frg); ad_write_reg(port, FTW0, 4, frg); return RIG_OK; } hamlib-4.6.5/rigs/kit/hiqsdr.c0000664000175000017500000003411415056640443011650 /* * Hamlib HiQSDR backend * Copyright (c) 20012 by Stephane Fillod * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include "hamlib/rig.h" #include "iofunc.h" #include "token.h" /* * http://www.hiqsdr.org */ /* HiQSDR constants */ #define REFCLOCK 122880000 #define DEFAULT_SAMPLE_RATE 48000 /* V1.1 */ #define CTRL_FRAME_LEN 22 struct hiqsdr_priv_data { split_t split; int sample_rate; double ref_clock; unsigned char control_frame[CTRL_FRAME_LEN]; }; static int hiqsdr_init(RIG *rig); static int hiqsdr_cleanup(RIG *rig); static int hiqsdr_open(RIG *rig); static int hiqsdr_close(RIG *rig); static int hiqsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int hiqsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int hiqsdr_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int hiqsdr_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int hiqsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int hiqsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int hiqsdr_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int hiqsdr_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int hiqsdr_get_conf(RIG *rig, hamlib_token_t token, char *val); static int hiqsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int hiqsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_SAMPLE_RATE TOKEN_BACKEND(2) const struct confparams hiqsdr_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency of reference clock in Hz", "122880000", RIG_CONF_NUMERIC, { .n = { 0, MHz(256), 1 } } }, { TOK_SAMPLE_RATE, "sample_rate", "Sample rate", "Sample rate", "48000", RIG_CONF_NUMERIC, { /* .n = */ { 48000, 1920000, 1 } } }, { RIG_CONF_END, NULL, } }; /* * HiQSDR rig capabilities. */ #define HIQSDR_FUNC RIG_FUNC_NONE #define HIQSDR_LEVEL (RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT) #define HIQSDR_PARM RIG_PARM_NONE #define HIQSDR_VFO_OP RIG_OP_NONE #define HIQSDR_SCAN RIG_SCAN_NONE #define HIQSDR_VFO (RIG_VFO_A) #define HIQSDR_ANT (RIG_ANT_1|RIG_ANT_2) #define HIQSDR_MODES (RIG_MODE_CW|RIG_MODE_DSB) struct rig_caps hiqsdr_caps = { RIG_MODEL(RIG_MODEL_HIQSDR), .model_name = "HiQSDR", .mfg_name = "N2ADR", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .targetable_vfo = RIG_TARGETABLE_NONE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 500, .has_get_func = HIQSDR_FUNC, .has_set_func = HIQSDR_FUNC, .has_get_level = HIQSDR_LEVEL, .has_set_level = RIG_LEVEL_SET(HIQSDR_LEVEL), .has_get_parm = HIQSDR_PARM, .has_set_parm = RIG_PARM_SET(HIQSDR_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = HIQSDR_SCAN, .vfo_ops = HIQSDR_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { 2, 4, 6, 10, 20, 30, 44, RIG_DBLST_END }, // -2dB steps in fact .preamp = { 10, RIG_DBLST_END, }, // TODO .rx_range_list1 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = -1, .high_power = -1, HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = mW(1), .high_power = mW(50), HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = -1, .high_power = -1, HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tx_range_list2 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = mW(1), .high_power = mW(50), HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tuning_steps = { {HIQSDR_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_CW, kHz(2.4)}, {HIQSDR_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .priv = NULL, .rig_init = hiqsdr_init, .rig_cleanup = hiqsdr_cleanup, .rig_open = hiqsdr_open, .rig_close = hiqsdr_close, .cfgparams = hiqsdr_cfg_params, .set_conf = hiqsdr_set_conf, .get_conf = hiqsdr_get_conf, .set_freq = hiqsdr_set_freq, .get_freq = hiqsdr_get_freq, .set_split_freq = hiqsdr_set_split_freq, .set_split_vfo = hiqsdr_set_split_vfo, .set_mode = hiqsdr_set_mode, .set_ptt = hiqsdr_set_ptt, .set_ant = hiqsdr_set_ant, .set_level = hiqsdr_set_level, .get_level = hiqsdr_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int send_command(RIG *rig) { const struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *) STATE(rig)->priv; int ret; ret = write_block(RIGPORT(rig), (unsigned char *) priv->control_frame, CTRL_FRAME_LEN); #if 0 ret = read_block(RIGPORT(rig), (unsigned char *) priv->control_frame, CTRL_FRAME_LEN); if (ret != CTRL_FRAME_LEN) { ret = ret < 0 ? ret : -RIG_EPROTO; } #endif return ret; } static unsigned compute_sample_rate(const struct hiqsdr_priv_data *priv) { unsigned rx_control; rx_control = (unsigned)(priv->ref_clock / (8. * 8. * priv->sample_rate)) - 1; if (rx_control > 39) { rx_control = 39; } return rx_control; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int hiqsdr_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct hiqsdr_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct hiqsdr_priv_data *)rs->priv; switch (token) { case TOK_OSCFREQ: priv->ref_clock = atof(val); priv->control_frame[12] = compute_sample_rate(priv); break; case TOK_SAMPLE_RATE: priv->sample_rate = atoi(val); priv->control_frame[12] = compute_sample_rate(priv); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int hiqsdr_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct hiqsdr_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct hiqsdr_priv_data *)rs->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%f", priv->ref_clock); break; case TOK_SAMPLE_RATE: SNPRINTF(val, val_len, "%d", priv->sample_rate); break; default: return -RIG_EINVAL; } return RIG_OK; } int hiqsdr_get_conf(RIG *rig, hamlib_token_t token, char *val) { return hiqsdr_get_conf2(rig, token, val, 128); } int hiqsdr_init(RIG *rig) { struct hiqsdr_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct hiqsdr_priv_data *)calloc(1, sizeof( struct hiqsdr_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->split = RIG_SPLIT_OFF; priv->ref_clock = REFCLOCK; priv->sample_rate = DEFAULT_SAMPLE_RATE; strncpy(RIGPORT(rig)->pathname, "192.168.2.196:48248", HAMLIB_FILPATHLEN - 1); return RIG_OK; } int hiqsdr_open(RIG *rig) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; #if 0 const char buf_send_to_me[] = { 0x72, 0x72 }; int ret; #endif rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* magic value */ priv->control_frame[0] = 'S'; priv->control_frame[1] = 't'; /* zero tune phase */ memset(priv->control_frame + 2, 0, 8); /* TX output level */ priv->control_frame[10] = 120; /* Tx control: non-CW */ priv->control_frame[11] = 0x02; /* decimation: 48 kSpls */ priv->control_frame[12] = compute_sample_rate(priv); /* firmware version */ priv->control_frame[13] = 0x00; /* X1 connector */ priv->control_frame[14] = 0x00; /* Attenuator */ priv->control_frame[15] = 0x00; /* AntSwitch */ priv->control_frame[16] = 0x00; /* RFU */ memset(priv->control_frame + 17, 0, 5); #if 0 /* Send the samples to me. FIXME: send to port 48247 */ ret = write_block(RIGPORT(rig), buf_send_to_me, sizeof(buf_send_to_me)); if (ret != RIG_OK) { return RIG_OK; } #endif return RIG_OK; } int hiqsdr_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } int hiqsdr_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* */ int hiqsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret; double rxphase; uint32_t rxphase32; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rxphase = (freq / priv->ref_clock) * (1ULL << 32) + 0.5; rxphase32 = (uint32_t)rxphase; priv->control_frame[2] = rxphase32 & 0xff; priv->control_frame[3] = (rxphase32 >> 8) & 0xff; priv->control_frame[4] = (rxphase32 >> 16) & 0xff; priv->control_frame[5] = (rxphase32 >> 24) & 0xff; if (priv->split == RIG_SPLIT_OFF) { priv->control_frame[6] = priv->control_frame[2]; priv->control_frame[7] = priv->control_frame[3]; priv->control_frame[8] = priv->control_frame[4]; priv->control_frame[9] = priv->control_frame[5]; } ret = send_command(rig); return ret; } static int hiqsdr_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } int hiqsdr_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret; double rxphase; uint32_t rxphase32; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rxphase = (tx_freq / priv->ref_clock) * (1ULL << 32) + 0.5; rxphase32 = (uint32_t)rxphase; priv->control_frame[6] = rxphase32 & 0xff; priv->control_frame[7] = (rxphase32 >> 8) & 0xff; priv->control_frame[8] = (rxphase32 >> 16) & 0xff; priv->control_frame[9] = (rxphase32 >> 24) & 0xff; ret = send_command(rig); return ret; } int hiqsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { return -RIG_ENIMPL; } int hiqsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strrmode(mode)); if (mode == RIG_MODE_CW) { priv->control_frame[11] = 0x01; } else { priv->control_frame[11] = 0x02; } ret = send_command(rig); return ret; } int hiqsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %d\n", __func__, ptt); /* not allowed in CW mode */ if (priv->control_frame[11] & 0x01) { return -RIG_ERJCTED; } if (ptt == RIG_PTT_ON) { priv->control_frame[11] |= 0x08; } else { priv->control_frame[11] &= ~0x08; } ret = send_command(rig); return ret; } int hiqsdr_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %u\n", __func__, ant); if (ant == RIG_ANT_2) { priv->control_frame[16] |= 0x01; } else { priv->control_frame[16] &= ~0x01; } ret = send_command(rig); return ret; } int hiqsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; switch (level) { case RIG_LEVEL_PREAMP: if (val.i) { priv->control_frame[14] |= 0x02; } else { priv->control_frame[14] &= ~0x02; } break; case RIG_LEVEL_ATT: /* FIXME: val->i should be looked up from the att list */ priv->control_frame[14] = val.i & 0x1f; break; case RIG_LEVEL_RFPOWER: /* TX output level */ priv->control_frame[10] = 0xff & (unsigned)(255 * val.f); break; default: return -RIG_EINVAL; } ret = send_command(rig); return ret; } static int hiqsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return -RIG_ENIMPL; } hamlib-4.6.5/rigs/kit/pcrotor.c0000664000175000017500000000644315056640443012052 /* * Hamlib Rotator backend - PcRotor/WA6UFQ parallel port * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rotator.h" #include "parallel.h" /* ************************************************************************* */ //pcrotor_set_position(ROT *rot, azimuth_t az, elevation_t el) #define PCROTOR_POWER 0x20 #define PCROTOR_CW 0x40 #define PCROTOR_CCW 0x80 #define PCROTOR_MASK (PCROTOR_CCW|PCROTOR_CW|PCROTOR_POWER) static int setDirection(hamlib_port_t *port, unsigned char outputvalue) { int ret; par_lock(port); /* set the data bits. * Should we read before write to not trample the lower significant bits? */ ret = par_write_data(port, outputvalue); par_unlock(port); return ret; } static int pcrotor_stop(ROT *rot) { /* CW=0, CCW=0, Power-up=0 */ return setDirection(ROTPORT(rot), 0); } static int pcrotor_move(ROT *rot, int direction, int speed) { unsigned char outputvalue; rig_debug(RIG_DEBUG_TRACE, "%s called: %d %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_CCW: outputvalue = PCROTOR_POWER | PCROTOR_CCW; break; case ROT_MOVE_CW: outputvalue = PCROTOR_POWER | PCROTOR_CCW; break; case 0: /* Stop */ outputvalue = 0; break; default: return -RIG_EINVAL; } return setDirection(ROTPORT(rot), outputvalue); } /* ************************************************************************* */ /* * PcRotor rotator capabilities. * * Control Interface schematics from, courtesy of Bob Hillard WA6UFQ: * http://www.dxzone.com/cgi-bin/dir/jump2.cgi?ID=11173 * * DB25-7=Data-5= Power up/Sleep * DB25-8=Data-6= CW * DB25-9=Data-7= CCW * * There's no feedback. */ /** Fodtrack implement essentially only the set position function. * */ const struct rot_caps pcrotor_caps = { ROT_MODEL(ROT_MODEL_PCROTOR), .model_name = "PcRotor", .mfg_name = "WA6UFQ", .version = "20081013.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .move = pcrotor_move, .stop = pcrotor_stop, //.set_position = pcrotor_set_position, //.get_position = pcrotor_get_position, }; /* end of file */ hamlib-4.6.5/rigs/kit/rs_hfiq.c0000664000175000017500000002573615056640443012023 /* * Hamlib rs-hfiq backend - main file * Copyright (c) 2017 by Volker Schroer * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * * For information about the controls see * https://sites.google.com/site/rshfiqtransceiver/home/technical-data/interface-commands * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #define RSHFIQ_INIT_RETRY 5 #define RSHFIQ_LEVEL_ALL (RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_TEMP_METER) int rshfiq_version_major, rshfiq_version_minor; static int rshfiq_open(RIG *rig) { int retval; int flag; char versionstr[20]; char stopset[2]; hamlib_port_t *rp = RIGPORT(rig); stopset[0] = '\r'; stopset[1] = '\n'; rig_debug(RIG_DEBUG_TRACE, "%s: Port = %s\n", __func__, rp->pathname); rp->timeout = 2000; rp->retry = 1; retval = serial_open(rp); if (retval != RIG_OK) { return retval; } retval = ser_get_dtr(rp, &flag); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: DTR: %d\n", __func__, flag); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Could not get DTR\n", __func__); } if (flag == 0) { flag = 1; // Set DTR retval = ser_set_dtr(rp, flag); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: set DTR\n", __func__); } } //There is a delay between when the port is open and the RS-HFIQ can receive and respond. //Make a few attempts at getting the version string just in case the RS-HFIQ has to catch up first. retval = -RIG_ETIMEOUT; for (int init_retry_count = 0; (init_retry_count < RSHFIQ_INIT_RETRY) && (retval == -RIG_ETIMEOUT); init_retry_count++) { rig_flush(rp); SNPRINTF(versionstr, sizeof(versionstr), "*w\r"); rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, versionstr); retval = write_block(rp, (unsigned char *) versionstr, strlen(versionstr)); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) versionstr, 20, stopset, 2, 0, 1); } if (retval <= 0) { return retval; } rig_flush(rp); versionstr[retval] = 0; rig_debug(RIG_DEBUG_TRACE, "%s: Rigversion = %s\n", __func__, versionstr); if (!strstr(versionstr, "RS-HFIQ")) { rig_debug(RIG_DEBUG_WARN, "%s: Invalid Rigversion: %s\n", __func__, versionstr); return -RIG_ECONF; } retval = sscanf(versionstr, "RS-HFIQ FW %d.%d", &rshfiq_version_major, &rshfiq_version_minor); if (retval <= 0) { rig_debug(RIG_DEBUG_WARN, "%s: Failed to parse RS-HFIQ firmware version string. Defaulting to 2.0.\n", __func__); rshfiq_version_major = 2; rshfiq_version_minor = 0; } rig_debug(RIG_DEBUG_VERBOSE, "RS-HFIQ returned firmware version major=%d minor=%d\n", rshfiq_version_major, rshfiq_version_minor); if (rshfiq_version_major < 4) { rig_debug(RIG_DEBUG_WARN, "%s: RS-HFIQ firmware major version is less than 4. RFPOWER_METER support will be unavailable.\n", __func__); } return RIG_OK; } static int rshfiq_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char fstr[9]; char cmdstr[15]; int retval; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(fstr, sizeof(fstr), "%lu", (unsigned long int)(freq)); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*f%lu\r", (unsigned long int)(freq)); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int rshfiq_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char cmdstr[15]; char stopset[2]; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); stopset[0] = '\r'; stopset[1] = '\n'; SNPRINTF(cmdstr, sizeof(cmdstr), "*f?\r"); rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); if (retval <= 0) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: reply = %s\n", __func__, cmdstr); cmdstr[retval] = 0; *freq = atoi(cmdstr); if (*freq == 0) // fldigi interprets zero frequency as error { *freq = 1; // so return 1 ( freq= 1Hz ) } return RIG_OK; } static int rshfiq_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdstr[5]; int retval; cmdstr[0] = '*'; cmdstr[1] = 'x'; cmdstr[3] = '\r'; cmdstr[4] = 0; if (ptt == RIG_PTT_ON) { cmdstr[2] = '1'; } else { cmdstr[2] = '0'; } rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); retval = write_block(RIGPORT(rig), (unsigned char *) cmdstr, strlen(cmdstr)); return retval; } static int rshfiq_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { // cppcheck-suppress syntaxError rig_debug(RIG_DEBUG_VERBOSE, "%s called. level type =%"PRIll"\n", __func__, level); char cmdstr[15]; char stopset[2]; int retval; hamlib_port_t *rp = RIGPORT(rig); if (!val) { return -RIG_EINVAL; } switch (level) { //Requires RS-HFIQ firmware version 4 or later case RIG_LEVEL_RFPOWER_METER: if (rshfiq_version_major <= 3) { return -RIG_ENAVAIL; } rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*L\r"); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER command=%s\n", cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } stopset[0] = '\r'; stopset[1] = '\n'; retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER reply=%s\n", cmdstr); if (retval <= 0) { return retval; } cmdstr[retval] = 0; //Range is 0-110. Unit is percent val->i = atoi(cmdstr); val->f = (float)(val->i) / 100; rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER val=%f\n", val->f); return RIG_OK; case RIG_LEVEL_TEMP_METER: rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*T\r"); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER command=%s\n", cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } stopset[0] = '\r'; stopset[1] = '\n'; retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER reply=%s\n", cmdstr); if (retval <= 0) { return retval; } cmdstr[retval] = 0; sscanf(cmdstr, "%d.", &val->i); val->f = val->i; rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER val=%g\n", val->f); return RIG_OK; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unrecognized RIG_LEVEL_* enum: %"PRIll"\n", __func__, level); return -RIG_EDOM; } } static int rshfiq_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = RIG_MODE_IQ; return RIG_OK; } struct rig_caps rshfiq_caps = { RIG_MODEL(RIG_MODEL_RSHFIQ), .model_name = "RS-HFIQ", .mfg_name = "HobbyPCB", .version = "20220430.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .dcd_type = RIG_DCD_NONE, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_level = RSHFIQ_LEVEL_ALL, .rx_range_list1 = { {.startf = kHz(3500), .endf = MHz(30), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .rx_range_list2 = { {.startf = kHz(3500), .endf = MHz(30), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { {.startf = kHz(3500), .endf = kHz(3800), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(7000), .endf = kHz(7200), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(10100), .endf = kHz(10150), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(14), .endf = kHz(14350), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(21), .endf = kHz(21450), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(24890), .endf = kHz(24990), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(28), .endf = kHz(29700), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_IQ, Hz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rig_open = rshfiq_open, .get_freq = rshfiq_get_freq, .set_freq = rshfiq_set_freq, .set_ptt = rshfiq_set_ptt, .get_level = rshfiq_get_level, .get_mode = rshfiq_get_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kit/si570avrusb.c0000664000175000017500000011655415056640443012461 /* * Hamlib KIT backend - SoftRock / Si570 AVR USB tuner description * Copyright (c) 2009-2010 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #define BACKEND_VER "20200112" #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "hamlib/rig.h" #include "token.h" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "si570avrusb.h" static int si570avrusb_init(RIG *rig); static int si570picusb_init(RIG *rig); static int si570peaberry1_init(RIG *rig); static int si570peaberry2_init(RIG *rig); static int fasdr_init(RIG *rig); static int si570xxxusb_cleanup(RIG *rig); static int si570xxxusb_open(RIG *rig); static int fasdr_open(RIG *rig); static int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq); static int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq); static int si570xxxusb_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int si570xxxusb_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int si570xxxusb_get_conf(RIG *rig, hamlib_token_t token, char *val); static const char *si570xxxusb_get_info(RIG *rig); #define USBDEV_SHARED_VID 0x16C0 /* VOTI */ #define USBDEV_SHARED_PID 0x05DC /* Obdev's free shared PID */ /* Use obdev's generic shared VID/PID pair and follow the rules outlined * in firmware/usbdrv/USBID-License.txt. */ #define VENDOR_NAME "www.obdev.at" #define PEABERRY_VENDOR_NAME "AE9RB" /* Only for V1, V2 uses the 'standard' obdev name */ #define AVR_PRODUCT_NAME "DG8SAQ-I2C" #define PIC_PRODUCT_NAME "KTH-SDR-KIT" #define PEABERRY_PRODUCT_NAME "Peaberry SDR" #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_MULTIPLIER TOKEN_BACKEND(3) #define TOK_I2C_ADDR TOKEN_BACKEND(4) #define TOK_BPF TOKEN_BACKEND(5) #define F_CAL_STATUS 1 //1 byte #define F_CRYST 2 //4 byte static const struct confparams si570xxxusb_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "114285000", RIG_CONF_NUMERIC, { .n = { 1, MHz(300), 1 } } }, { TOK_MULTIPLIER, "multiplier", "Freq Multiplier", "Frequency multiplier", "4", RIG_CONF_NUMERIC, { .n = { 0.000001, 100 } } }, { TOK_I2C_ADDR, "i2c_addr", "I2C Address", "Si570 I2C Address", "55", RIG_CONF_NUMERIC, { .n = { 0, 512 } } }, { TOK_BPF, "bpf", "BPF", "Enable Band Pass Filter", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /* * Common data struct */ struct si570xxxusb_priv_data { unsigned short version; /* >=0x0f00 is PE0FKO's */ double osc_freq; /* MHz */ double multiplier; /* default to 4 for QSD/QSE */ int i2c_addr; int bpf; /* enable BPF? */ }; #define SI570AVRUSB_MODES (RIG_MODE_USB) /* USB is for SDR */ #define SI570AVRUSB_FUNC (RIG_FUNC_NONE) #define SI570AVRUSB_LEVEL_ALL (RIG_LEVEL_NONE) /* TODO: BPF as a parm or ext_level? */ #define SI570AVRUSB_PARM_ALL (RIG_PARM_NONE) #define SI570AVRUSB_VFO (RIG_VFO_A) #define SI570AVRUSB_ANT (RIG_ANT_1) /* * SoftRock Si570 AVR-USB description * * Heavily based on SoftRock USB-I2C Utility usbsoftrock-0.5, * author Andrew Nilsson VK6JBL: * http://groups.yahoo.com/group/softrock40/files/VK6JBL/ * */ struct rig_caps si570avrusb_caps = { RIG_MODEL(RIG_MODEL_SI570AVRUSB), .model_name = "Si570 AVR-USB", .mfg_name = "SoftRock", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570avrusb_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Peaberry V1 * http://www.ae9rb.com */ struct rig_caps si570peaberry1_caps = { RIG_MODEL(RIG_MODEL_SI570PEABERRY1), .model_name = "Si570 Peaberry V1", .mfg_name = "AE9RB", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570peaberry1_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Peaberry V2 * http://www.ae9rb.com */ struct rig_caps si570peaberry2_caps = { RIG_MODEL(RIG_MODEL_SI570PEABERRY2), .model_name = "Si570 Peaberry V2", .mfg_name = "AE9RB", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570peaberry2_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * KTH-SDR-KIT Si570 PIC-USB description * * Same USB interface as AVR-USB, except different product string * and different multiplier. * * http://home.kpn.nl/rw.engberts/sdr_kth.htm */ struct rig_caps si570picusb_caps = { RIG_MODEL(RIG_MODEL_SI570PICUSB), .model_name = "Si570 PIC-USB", .mfg_name = "KTH-SDR kit", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, /* TODO */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(800), MHz(550), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(550), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570picusb_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Funkamateur Sdr with Si570 * * Same USB interface as AVR-USB, except different product string * and Oscillator correction may be stored on the device * * http://www.funkamateur.de * ( BX- 200 ) */ struct rig_caps fasdr_caps = { RIG_MODEL(RIG_MODEL_FASDR), .model_name = "FA-SDR", .mfg_name = "Funkamateur", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_FLAG_TUNER | RIG_FLAG_TRANSMITTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(1800), MHz(30), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(1800), MHz(30), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = fasdr_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = fasdr_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, }; // libusb control transfer request types #define REQUEST_TYPE_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN) #define REQUEST_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT) /* * some little endian (these devices are LE) to host endian converters */ static unsigned char *setLongWord(uint32_t value, unsigned char *bytes) { bytes[0] = value & 0xff; bytes[1] = ((value & 0xff00) >> 8) & 0xff; bytes[2] = ((value & 0xff0000) >> 16) & 0xff; bytes[3] = ((value & 0xff000000) >> 24) & 0xff; return bytes; } static uint32_t getLongWord(unsigned char const *bytes) { return bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24); } /* * AVR-USB model */ int si570avrusb_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = AVR_PRODUCT_NAME; return RIG_OK; } /* * Peaberry V1 model (AVR version with different vendor/product name) */ int si570peaberry1_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = PEABERRY_VENDOR_NAME; rp->parm.usb.product = PEABERRY_PRODUCT_NAME; return RIG_OK; } /* * Peaberry V2 model (AVR version with different product name) */ int si570peaberry2_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PEABERRY_PRODUCT_NAME; return RIG_OK; } /* * PIC-USB model */ int si570picusb_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 2; priv->i2c_addr = SI570_I2C_ADDR; /* enable BPF, because this is kit is receiver only */ priv->bpf = 1; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PIC_PRODUCT_NAME; return RIG_OK; } /* * FA-SDR */ int fasdr_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = AVR_PRODUCT_NAME; return RIG_OK; } int fasdr_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret, i; double f; unsigned char buffer[4]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, 2, RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } priv->version = buffer[0] + (buffer[1] << 8); // Unsure how to get firmware version ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_EEPROM, F_CAL_STATUS, 0, buffer, 1, RIGPORT(rig)->timeout); if (ret != 1) { return -RIG_EIO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: calibration byte %x", __func__, buffer[0]); // ret = libusb_control_transfer(udh, // REQUEST_TYPE_IN, // REQUEST_READ_XTALL, 0, 0, (unsigned char *) &iFreq, sizeof(iFreq), // RIGPORT(rig)->timeout); if (buffer[0] == 0xFF) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Device not calibrated", __func__); return RIG_OK; } for (i = 0; i < 4; i++) { ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_EEPROM, F_CRYST + i, 0, &buffer[i], 1, RIGPORT(rig)->timeout); if (ret != 1) { return -RIG_EIO; } } priv->osc_freq = buffer[0]; f = buffer[1]; priv->osc_freq += f / 256.; f = buffer[2]; priv->osc_freq += f / (256.*256.); f = buffer[3]; priv->osc_freq += f / (256.*256.*256.); rig_debug(RIG_DEBUG_VERBOSE, "%s: using Xtall at %.3f MHz\n", __func__, priv->osc_freq); return RIG_OK; } int si570xxxusb_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int si570xxxusb_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct si570xxxusb_priv_data *priv; freq_t freq; double multiplier; unsigned int i2c_addr; priv = (struct si570xxxusb_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: if (sscanf(val, "%"SCNfreq, &freq) != 1) { return -RIG_EINVAL; } priv->osc_freq = (double)freq / 1e6; break; case TOK_MULTIPLIER: if (sscanf(val, "%lf", &multiplier) != 1) { return -RIG_EINVAL; } if (multiplier == 0.) { return -RIG_EINVAL; } priv->multiplier = multiplier; break; case TOK_I2C_ADDR: if (sscanf(val, "%x", &i2c_addr) != 1) { return -RIG_EINVAL; } if (i2c_addr >= (1 << 9)) { return -RIG_EINVAL; } priv->i2c_addr = i2c_addr; break; case TOK_BPF: if (sscanf(val, "%d", &priv->bpf) != 1) { return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } return RIG_OK; } int si570xxxusb_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct si570xxxusb_priv_data *priv; priv = (struct si570xxxusb_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, (freq_t)(priv->osc_freq * 1e6)); break; case TOK_MULTIPLIER: SNPRINTF(val, val_len, "%f", priv->multiplier); break; case TOK_I2C_ADDR: SNPRINTF(val, val_len, "%x", priv->i2c_addr); break; case TOK_BPF: SNPRINTF(val, val_len, "%d", priv->bpf); break; default: return -RIG_EINVAL; } return RIG_OK; } int si570xxxusb_get_conf(RIG *rig, hamlib_token_t token, char *val) { return si570xxxusb_get_conf2(rig, token, val, 128); } static int setBPF(RIG *rig, int enable) { libusb_device_handle *udh = RIGPORT(rig)->handle; /* allocate enough space for up to 16 filters */ unsigned short FilterCrossOver[16]; int nBytes; // Does FilterCrossOver needs endianness ordering ? // first find out how may cross over points there are for the 1st bank, use 255 for index nBytes = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, 0, 255, (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), RIGPORT(rig)->timeout); if (nBytes < 0) { return -RIG_EIO; } if (nBytes > 2) { int i; int retval = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, enable, (nBytes / 2) - 1, (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), RIGPORT(rig)->timeout); if (retval < 2) { return -RIG_EIO; } nBytes = retval; rig_debug(RIG_DEBUG_TRACE, "%s: Filter Bank 1:\n", __func__); for (i = 0; i < (nBytes / 2) - 1; i++) { rig_debug(RIG_DEBUG_TRACE, " CrossOver[%d] = %f\n", i, (double) FilterCrossOver[i] / (1UL << 5)); } rig_debug(RIG_DEBUG_TRACE, " BPF Enabled: %d\n", FilterCrossOver[(nBytes / 2) - 1]); } return RIG_OK; } int si570xxxusb_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * Determine firmware */ ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, 2, RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } priv->version = buffer[0] + (buffer[1] << 8); if (priv->version >= 0x0F00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB) { unsigned int iFreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: detected PE0FKO-like firmware\n", __func__); ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_XTALL, 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 4) { return -RIG_EIO; } iFreq = getLongWord(buffer); priv->osc_freq = (double)iFreq / (1UL << 24); if (priv->bpf) { ret = setBPF(rig, 1); if (ret != RIG_OK) { return ret; } } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using Xtall at %.3f MHz\n", __func__, priv->osc_freq); return RIG_OK; } /* Rem: not reentrant */ const char *si570xxxusb_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; int ret; unsigned char buffer[2]; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return NULL; } /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "USB dev %04d, version: %d.%d", desc.bcdDevice, buffer[1], buffer[0]); return buf; } static const int HS_DIV_MAP[] = {4, 5, 6, 7, -1, 9, -1, 11}; static int calcDividers(RIG *rig, double f, struct solution *solution) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; struct solution sols[8]; int i; int imin; double fmin; double y; // Count down through the dividers for (i = 7; i >= 0; i--) { if (HS_DIV_MAP[i] > 0) { sols[i].HS_DIV = i; y = (SI570_DCO_HIGH + SI570_DCO_LOW) / (2 * f); y = y / HS_DIV_MAP[i]; if (y < 1.5) { y = 1.0; } else { y = 2 * round(y / 2.0); } if (y > 128) { y = 128; } sols[i].N1 = trunc(y) - 1; sols[i].f0 = f * y * HS_DIV_MAP[i]; } else { sols[i].f0 = 10000000000000000.0; } } imin = -1; fmin = 10000000000000000.0; for (i = 0; i < 8; i++) { if ((sols[i].f0 >= SI570_DCO_LOW) && (sols[i].f0 <= SI570_DCO_HIGH)) { if (sols[i].f0 < fmin) { fmin = sols[i].f0; imin = i; } } } if (imin >= 0) { solution->HS_DIV = sols[imin].HS_DIV; solution->N1 = sols[imin].N1; solution->f0 = sols[imin].f0; solution->RFREQ = sols[imin].f0 / priv->osc_freq; rig_debug(RIG_DEBUG_TRACE, "%s: solution: HS_DIV = %d, N1 = %d, f0 = %f, RFREQ = %f\n", __func__, solution->HS_DIV, solution->N1, solution->f0, solution->RFREQ); return 1; } else { solution->HS_DIV = 0; solution->N1 = 0; solution->f0 = 0; solution->RFREQ = 0; rig_debug(RIG_DEBUG_TRACE, "%s: No solution\n", __func__); return 0; } } int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[6]; int request = REQUEST_SET_FREQ; int value = 0x700 + priv->i2c_addr; int index = 0; double f; struct solution theSolution; int RFREQ_int; int RFREQ_frac; unsigned char fracBuffer[4]; unsigned char intBuffer[4]; if (priv->version >= 0x0f00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY1 || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY2) { return si570xxxusb_set_freq_by_value(rig, vfo, freq); } f = (freq * priv->multiplier) / 1e6; calcDividers(rig, f, &theSolution); RFREQ_int = trunc(theSolution.RFREQ); RFREQ_frac = round((theSolution.RFREQ - RFREQ_int) * 268435456); setLongWord(RFREQ_int, intBuffer); setLongWord(RFREQ_frac, fracBuffer); buffer[5] = fracBuffer[0]; buffer[4] = fracBuffer[1]; buffer[3] = fracBuffer[2]; buffer[2] = fracBuffer[3]; buffer[2] = buffer[2] | ((intBuffer[0] & 0xf) << 4); buffer[1] = RFREQ_int / 16; buffer[1] = buffer[1] + ((theSolution.N1 & 3) << 6); buffer[0] = theSolution.N1 / 4; buffer[0] = buffer[0] + (theSolution.HS_DIV << 5); ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, request, value, index, buffer, sizeof(buffer), RIGPORT(rig)->timeout); rig_debug(RIG_DEBUG_TRACE, "%s: Freq=%.6f MHz, Real=%.6f MHz, buf=%02x%02x%02x%02x%02x%02x\n", __func__, freq / 1e6, f, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); if (!ret) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Result buf=%02x%02x\n", __func__, buffer[0], buffer[1]); return RIG_OK; } int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; int request = REQUEST_SET_FREQ_BY_VALUE; int value = 0x700 + priv->i2c_addr; int index = 0; double f; f = (freq * priv->multiplier) / 1e6; setLongWord(round(f * 2097152.0), buffer); rig_debug(RIG_DEBUG_TRACE, "%s: Freq=%.6f MHz, Real=%.6f MHz, buf=%02x%02x%02x%02x\n", __func__, freq / 1e6, f, buffer[0], buffer[1], buffer[2], buffer[3]); ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, request, value, index, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (!ret) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Result buf=%02x%02x\n", __func__, buffer[0], buffer[1]); return RIG_OK; } static double calculateFrequency(RIG *rig, const unsigned char *buffer) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; int RFREQ_int = ((buffer[2] & 0xf0) >> 4) + ((buffer[1] & 0x3f) * 16); int RFREQ_frac = (256 * 256 * 256 * (buffer[2] & 0xf)) + (256 * 256 * buffer[3]) + (256 * buffer[4]) + (buffer[5]); double RFREQ = RFREQ_int + (RFREQ_frac / 268435456.0); int N1 = ((buffer[1] & 0xc0) >> 6) + ((buffer[0] & 0x1f) * 4); int HS_DIV = (buffer[0] & 0xE0) >> 5; double fout = priv->osc_freq * RFREQ / ((N1 + 1) * HS_DIV_MAP[HS_DIV]); rig_debug(RIG_DEBUG_VERBOSE, "%s: Registers 7..13: %02x%02x%02x%02x%02x%02x\n", __func__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); rig_debug(RIG_DEBUG_VERBOSE, "%s: RFREQ = %f, N1 = %d, HS_DIV = %d, nHS_DIV = %d, fout = %f\n", __func__, RFREQ, N1, HS_DIV, HS_DIV_MAP[HS_DIV], fout); return fout; } int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; unsigned char buffer[6]; int ret; if (priv->version >= 0x0f00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY1 || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY2) { return si570xxxusb_get_freq_by_value(rig, vfo, freq); } ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_REGISTERS, priv->i2c_addr, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } *freq = (calculateFrequency(rig, buffer) / priv->multiplier) * 1e6; return RIG_OK; } int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; uint32_t iFreq; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_FREQUENCY, 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 4) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } iFreq = getLongWord(buffer); rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq raw: %02x%02x%02x%02x endian converted: %u\n", __func__, buffer[0], buffer[1], buffer[2], buffer[3], iFreq); *freq = (((double)iFreq / (1UL << 21)) / priv->multiplier) * 1e6; return RIG_OK; } int si570xxxusb_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[3]; rig_debug(RIG_DEBUG_TRACE, "%s called: %d\n", __func__, ptt); buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_SET_PTT, (ptt == RIG_PTT_ON) ? 1 : 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.5/rigs/kit/README.funcubedongle0000664000175000017500000000444215056640443013712 +----------------------------------------+ | Hamlib FUNcube dongle Win32 readme | | Written by Wouter Weggelaar PA3WEG | |ISIS - Innovative Solutions In Space BV | +----------------------------------------+ Note: The following only applies for users running Win32 systems. First of all, congratulations on obtaining a FUNcube dongle, the SDR receiver ground segment for the FUNcube satellite! More info on this exciting AMSAT-UK project can be found on http://funcube.org.uk/ more about the dongle on http://www.funcubedongle.com/ The FUNcube dongle driver uses the USB kit backend in hamlib to interface to the dongle via the USB HID interface. For this to work in hamlib, we need LibUSB support (tested with 1.2.3.0 and 1.2.4.0) and LibUSB support compiled into hamlib. This should be the case for all official hamlib releases (hamlib-win32-1.2.13-2 tested). You will need to download and install libusb-win32 from http://sourceforge.net/projects/libusb-win32/ extract the zip archive to a convenient location, change into this directory and run inf-wizard.exe located in the bin directory. Select the proper device in this wizard (Vendor ID 0x04D8, Product ID 0xFB56, interface 2) Click NEXT and accept the defaults, or change the vendor name and product ID as you wish to see it appear in device manager. I've changed this ID to reflect the vendor (hanlincrest ltd) and product name (funcube dongle). You can now suggest a location to store the driver (I suggest creating a directory for this as the wizard creates more than one file). Finally, install the driver as suggested by the wizard. You should be all set up now. Running hamlib from the command line using rigctl -m 2513 -vvvv should provide something like below: ------------------------------------------ >rigctl.exe -m 2513 -v Opened rig model 2513, 'FUNcube Dongle' Rig command: ------------------------------------------ If you made it to here, you are all set up and ready to go. **** PLEASE NOTE: by installing the LibUSB INF driver, other tools accessing the dongle cannot find it anymore as they are looking for the windows HID driver. Just uninstall the hamlib driver if you want to use those tools again! HAMLIB or LibUSB DID NOT BREAK YOUR SYSTEM! **** You could use hardware profiles to easily switch drivers. Happy SDR-ing! Wouter PA3WEG hamlib-4.6.5/rigs/kit/funcube.h0000664000175000017500000000401115056640443012003 /* * Hamlib KIT backend - FUNcube Dongle USB tuner description * Copyright (c) 2009-2011 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * Author: Stefano Speretta, Innovative Solutions In Space BV * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FUNCUBE_H #define _FUNCUBE_H 1 #define VID 0x04D8 #define PID 0xFB56 #define PIDPLUS 0xFB31 #define VENDOR_NAME "Hanlincrest Ltd. " #define PRODUCT_NAME "FunCube Dongle" #define PRODUCT_NAMEPLUS "FunCube Dongle Pro+" #define FUNCUBE_INTERFACE 0x02 #define FUNCUBE_CONFIGURATION -1 /* no setup */ #define FUNCUBE_ALTERNATIVE_SETTING 0x00 #define INPUT_ENDPOINT 0x82 #define OUTPUT_ENDPOINT 0x02 // Commands #define REQUEST_SET_FREQ 0x64 #define REQUEST_SET_FREQ_HZ 0x65 #define REQUEST_GET_FREQ_HZ 0x66 #define REQUEST_SET_LNA_GAIN 0x6E #define REQUEST_SET_MIXER_GAIN 0x72 // Taken from qthid code #define REQUEST_SET_IF_GAIN 0x75 #define REQUEST_GET_LNA_GAIN 0x96 #define REQUEST_GET_MIXER_GAIN 0x9A // Taken from qthid code #define REQUEST_GET_IF_GAIN 0x9D // Taken from qthid code #define REQUEST_GET_RSSI 0x68 #define FUNCUBE_SUCCESS 0x01 #endif /* _FUNCUBE_H */ hamlib-4.6.5/rigs/kit/elektor507.c0000664000175000017500000010636015056640443012262 /* * Hamlib KIT backend - Elektor SDR USB (5/07) receiver description * Copyright (c) 2007-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "token.h" #ifdef _WIN32 #define USE_FTDI_DLL #elif defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #define USE_LIBUSB #endif /* * Compile this model only if libusb is available * or if .DLL is available under Windows */ #if defined(USE_FTDI_DLL) || defined(USE_LIBUSB) static int elektor507_init(RIG *rig); static int elektor507_cleanup(RIG *rig); static int elektor507_open(RIG *rig); static int elektor507_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int elektor507_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int elektor507_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int elektor507_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int elektor507_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int elektor507_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); static int elektor507_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int elektor507_get_conf(RIG *rig, hamlib_token_t token, char *val); static const char *elektor507_get_info(RIG *rig); /* * I2C addresses */ #define CY_I2C_RAM_ADR 210 #define CY_I2C_EEPROM_ADR 208 /* * I2C registers */ #define CLKOE_REG 0x09 #define DIV1_REG 0x0c #define DIV2_REG 0x47 #define XTALCTL_REG 0x12 #define CAPLOAD_REG 0x13 #define PUMPCOUNTERS_REG 0x40 #define CLKSRC_REG 0x44 static int cy_update_pll(RIG *rig, unsigned char IICadr); static int i2c_write_regs(RIG *rig, unsigned char IICadr, int reg_count, unsigned char reg_adr, unsigned char reg_val1, unsigned char reg_val2, unsigned char reg_val3); #define i2c_write_reg(rig, IICadr, reg_adr, reg_val) \ i2c_write_regs(rig, IICadr, 1, reg_adr, reg_val, 0, 0) #ifdef USE_FTDI_DLL #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif #include #define ELEKTOR507_DLL "FTD2XX.dll" /* Some type definitions needed for dll access */ typedef enum { FT_OK = 0, FT_INVALID_HANDLE = 1, FT_DEVICE_NOT_FOUND = 2, FT_DEVICE_NOT_OPENED = 3, FT_IO_ERROR = 4, FT_INSUFFICIENT_RESOURCES = 5, FT_INVALID_PARAMETER = 6, FT_SUCCESS = FT_OK, FT_INVALID_BAUD_RATE = 7, FT_DEVICE_NOT_OPENED_FOR_ERASE = 8, FT_DEVICE_NOT_OPENED_FOR_WRITE = 9, FT_FAILED_TO_WRITE_DEVICE = 10, FT_EEPROM_READ_FAILED = 11, FT_EEPROM_WRITE_FAILED = 12, FT_EEPROM_ERASE_FAILED = 13, FT_EEPROM_NOT_PRESENT = 14, FT_EEPROM_NOT_PROGRAMMED = 15, FT_INVALID_ARGS = 16, FT_OTHER_ERROR = 17, } FT_Result; typedef FT_Result(__stdcall *FNCFT_Open)(int Index, unsigned long *ftHandle); typedef FT_Result(__stdcall *FNCFT_Close)(unsigned long ftHandle); typedef FT_Result(__stdcall *FNCFT_SetBitMode)(unsigned long ftHandle, unsigned char Mask, unsigned char Enable); typedef FT_Result(__stdcall *FNCFT_SetBaudRate)(unsigned long ftHandle, unsigned long BaudRate); typedef FT_Result(__stdcall *FNCFT_Write)(unsigned long ftHandle, void *FTOutBuf, unsigned long BufferSize, int *ResultPtr); struct elektor507_extra_priv_data { HMODULE dll; FNCFT_Open FT_Open; FNCFT_Close FT_Close; FNCFT_SetBitMode FT_SetBitMode; FNCFT_SetBaudRate FT_SetBaudRate; FNCFT_Write FT_Write; unsigned long ftHandle; }; #elif defined(USE_LIBUSB) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #define USB_VID_FTDI 0x0403 /* Future Technology Devices International */ #define USB_PID_FTDI_FT232 0x6001 /* FT232R 8-bit FIFO */ #define FTDI_IN_EP 0x02 #define FTDI_USB_WRITE_TIMEOUT 5000 struct elektor507_extra_priv_data { /* empty with libusb */ }; #endif /* defaults */ #define OSCFREQ 10000 /* kHz unit -> MHz(10) */ #define XTAL_CAL 128 #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_XTALCAL TOKEN_BACKEND(2) static const struct confparams elektor507_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "10000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(30), 1 } } }, { TOK_XTALCAL, "xtal_cal", "Xtal Cal", "Crystal calibration", "132", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Common data struct */ struct elektor507_priv_data { struct elektor507_extra_priv_data extra_priv; unsigned xtal_cal; /* 0..255 (-150ppm..150ppm) */ unsigned osc_freq; /* kHz */ #define ANT_AUTO RIG_ANT_1 #define ANT_EXT RIG_ANT_2 #define ANT_TEST_CLK RIG_ANT_3 ant_t ant; /* current antenna */ /* CY PLL stuff. * This is Qtotal & Ptotal values here. */ int P, Q, Div1N; /* FTDI comm stuff */ unsigned char FT_port; int Buf_adr; #define FT_OUT_BUFFER_MAX 1024 unsigned char FT_Out_Buffer[FT_OUT_BUFFER_MAX]; }; #ifdef USE_FTDI_DLL int elektor507_init(RIG *rig) { struct elektor507_priv_data *priv; struct elektor507_extra_priv_data *extra_priv; priv = (struct elektor507_priv_data *)calloc(sizeof(struct elektor507_priv_data), 1); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv->xtal_cal = XTAL_CAL; priv->osc_freq = OSCFREQ; priv->ant = ANT_AUTO; /* DIV1N set to safe default */ priv->Div1N = 8; priv->P = 8; priv->Q = 2; extra_priv = &priv->extra_priv; /* Try to load required dll */ extra_priv->dll = LoadLibrary(ELEKTOR507_DLL); if (!extra_priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, ELEKTOR507_DLL); free(priv); return -RIG_EIO; /* huh! */ } /* * Get process addresses from dll for function access */ /* Open_USB_Device */ extra_priv->FT_Open = (FNCFT_Open) GetProcAddress(extra_priv->dll, "FT_Open"); /* Close_USB_Device */ extra_priv->FT_Close = (FNCFT_Close) GetProcAddress(extra_priv->dll, "FT_Close"); /* Set_USB_Device_BitMode */ extra_priv->FT_SetBitMode = (FNCFT_SetBitMode) GetProcAddress(extra_priv->dll, "FT_SetBitMode"); /* Set_USB_Device_BaudRate */ extra_priv->FT_SetBaudRate = (FNCFT_SetBaudRate) GetProcAddress(extra_priv->dll, "FT_SetBaudRate"); /* Write_USB_Device_Buffer */ extra_priv->FT_Write = (FNCFT_Write) GetProcAddress(extra_priv->dll, "FT_Write"); STATE(rig)->priv = (void *)priv; return RIG_OK; } int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSize) { struct elektor507_extra_priv_data *extra_priv = &((struct elektor507_priv_data *)STATE(rig)->priv)->extra_priv; FT_Result ret; int Result; rig_debug(RIG_DEBUG_TRACE, "%s called, %d bytes\n", __func__, (int)BufferSize); /* Open FTDI */ ret = extra_priv->FT_Open(0, &extra_priv->ftHandle); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_SetBitMode(extra_priv->ftHandle, 0xff, 1); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_SetBaudRate(extra_priv->ftHandle, 38400); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_Write(extra_priv->ftHandle, FTOutBuf, BufferSize, &Result); if (ret != FT_OK) { rig_debug(RIG_DEBUG_ERR, "FT_Write failed: %d, Result: %d\n", ret, Result); return -RIG_EIO; } ret = extra_priv->FT_Close(extra_priv->ftHandle); if (ret != FT_OK) { return -RIG_EIO; } return RIG_OK; } int elektor507_cleanup(RIG *rig) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->extra_priv.dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } const char *elektor507_get_info(RIG *rig) { static char buf[64]; SNPRINTF(buf, sizeof(buf), "Elektor SDR USB w/ FTDI DLL"); return buf; } #elif defined(USE_LIBUSB) /* * The libusb code is inspired by libftdi: * http://www.intra2net.com/de/produkte/opensource/ftdi/ */ int elektor507_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct elektor507_priv_data *priv; STATE(rig)->priv = (struct elektor507_priv_data *)calloc(sizeof(struct elektor507_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->xtal_cal = XTAL_CAL; priv->osc_freq = OSCFREQ; priv->ant = ANT_AUTO; /* DIV1N set to safe default */ priv->Div1N = 8; priv->P = 8; priv->Q = 2; rp->parm.usb.vid = USB_VID_FTDI; rp->parm.usb.pid = USB_PID_FTDI_FT232; rp->parm.usb.conf = 1; rp->parm.usb.iface = 0; rp->parm.usb.alt = 0; /* necessary ? */ return RIG_OK; } int elektor507_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* Rem: not reentrant */ const char *elektor507_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "USB dev %04d", desc.bcdDevice); return buf; } int elektor507_libusb_setup(RIG *rig) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned short index = 0, usb_val; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* Reset the ftdi device */ #if 1 ret = libusb_control_transfer(udh, 0x40, 0, 0, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer reset failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } #endif /* * Enable bitbang mode */ usb_val = 0xff; /* low byte: bitmask */ usb_val |= (0x01 << 8); /* Basic bitbang_mode: 0x01 */ ret = libusb_control_transfer(udh, 0x40, 0x0B, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer bitbangmode failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } /* * Set baudrate * 9600 x4 because of bitbang mode */ usb_val = 49230; /* magic value for 38400 bauds */ index = 0; ret = libusb_control_transfer(udh, 0x40, 3, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer baudrate failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSize) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret, actual_length; rig_debug(RIG_DEBUG_TRACE, "%s called, %lu bytes\n", __func__, BufferSize); ret = libusb_bulk_transfer(udh, FTDI_IN_EP, FTOutBuf, BufferSize, &actual_length, FTDI_USB_WRITE_TIMEOUT); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "usb_bulk_write failed: %s\n", libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } #endif /* USE_LIBUSB */ #define ELEKTOR507_MODES (RIG_MODE_USB) /* USB is for SDR */ #define ELEKTOR507_FUNC (RIG_FUNC_NONE) #define ELEKTOR507_LEVEL_ALL (RIG_LEVEL_ATT) #define ELEKTOR507_PARM_ALL (RIG_PARM_NONE) #define ELEKTOR507_VFO (RIG_VFO_A) /* * - Auto-filter antenna (K3) * - External antenna (PC1) * - Internal TEST_CLK (5 MHz) */ #define ELEKTOR507_ANT (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) /* * Elektor SDR USB (5/07) receiver description * * This kit is a QSD based on a CY27EE16ZE PLL. * The receiver is controlled via USB (through FTDI FT232R). * * Original article: * http://www.elektor.com/magazines/2007/may/software-defined-radio.91527.lynkx * * Author (Burkhard Kainka) page, in German: * http://www.b-kainka.de/sdrusb.html */ struct rig_caps elektor507_caps = { RIG_MODEL(RIG_MODEL_ELEKTOR507), .model_name = "Elektor SDR-USB", .mfg_name = "Elektor", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, #ifdef USE_LIBUSB .port_type = RIG_PORT_USB, #else .port_type = RIG_PORT_NONE, #endif .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 = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = ELEKTOR507_FUNC, .has_set_func = ELEKTOR507_FUNC, .has_get_level = ELEKTOR507_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ELEKTOR507_LEVEL_ALL), .has_get_parm = ELEKTOR507_PARM_ALL, .has_set_parm = RIG_PARM_SET(ELEKTOR507_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - kHz(1), ELEKTOR507_MODES, -1, -1, ELEKTOR507_VFO, ELEKTOR507_ANT}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - kHz(1), ELEKTOR507_MODES, -1, -1, ELEKTOR507_VFO, ELEKTOR507_ANT}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ELEKTOR507_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(24)}, /* bandpass may be more */ RIG_FLT_END, }, .cfgparams = elektor507_cfg_params, .rig_init = elektor507_init, .rig_cleanup = elektor507_cleanup, .rig_open = elektor507_open, .set_conf = elektor507_set_conf, .get_conf = elektor507_get_conf, .set_freq = elektor507_set_freq, .get_freq = elektor507_get_freq, .set_level = elektor507_set_level, .get_level = elektor507_get_level, .set_ant = elektor507_set_ant, .get_ant = elektor507_get_ant, .get_info = elektor507_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int elektor507_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct elektor507_priv_data *priv; freq_t freq; priv = (struct elektor507_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &freq); priv->osc_freq = freq / kHz(1); break; case TOK_XTALCAL: sscanf(val, "%u", &priv->xtal_cal); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor507_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct elektor507_priv_data *priv; priv = (struct elektor507_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq * kHz(1)); break; case TOK_XTALCAL: SNPRINTF(val, val_len, "%u", priv->xtal_cal); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor507_get_conf(RIG *rig, hamlib_token_t token, char *val) { return elektor507_get_conf2(rig, token, val, 128); } int elektor507_open(RIG *rig) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * Setup the FT232R. */ #ifdef USE_LIBUSB ret = elektor507_libusb_setup(rig); if (ret != RIG_OK) { return ret; } #endif /* Init the FT232R port to SCL/SDA high, Mux A0, Att 0 */ priv->FT_port = 0x03; /* * Setup the CY27EE16ZE PLL. */ /* Enable only CLOCK5. CLOCK3 will be on demand in set_ant() */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CLKOE_REG, 0x20); if (ret != 0) { return ret; } /* DIV1N set to safe default */ priv->Div1N = 8; ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, DIV1_REG, priv->Div1N); if (ret != 0) { return ret; } #if 0 /* Xtal gain setting */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, XTALCTL_REG, 0x32); if (ret != 0) { return ret; } /* CapLoad set to middle */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CAPLOAD_REG, priv->xtal_cal); if (ret != 0) { return ret; } #endif /* CLKSRC: CLOCK3=DIV2CLK/2, CLOCK5=DIV1CLK/DIV1N */ ret = i2c_write_regs(rig, CY_I2C_RAM_ADR, 3, CLKSRC_REG, 0x02, 0x8e, 0x47); if (ret != 0) { return ret; } /* DIV2SRC from REF */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, DIV2_REG, 0x88); if (ret != 0) { return ret; } return RIG_OK; } #define FREQ_ALGORITHM 3 /* use AC6SL version 3-Aug-2010 */ #if FREQ_ALGORITHM == 1 /* this used to be ORIG_ALGORITHM */ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) { int Freq; double Min, VCO; int p, q, q_max; Freq = freq / kHz(1); if (Freq > 19 && Freq < 60) { priv->Div1N = (2500 + Freq / 2) / Freq + 128; priv->P = 1000; priv->Q = 40; return; } else if (Freq > 59 && Freq < 801) { priv->Div1N = 125; priv->P = Freq * 2; priv->Q = 40; return; } else if (Freq > 800 && Freq < 2001) { priv->Div1N = 50; priv->P = Freq; priv->Q = 50; return; } else if (Freq > 2000 && Freq < 4001) { priv->Div1N = 25; } else if (Freq > 4000 && Freq < 10001) { priv->Div1N = 10; } else if (Freq > 10000 && Freq < 20001) { priv->Div1N = 5; } else if (Freq > 20000 && Freq < 30001) { priv->Div1N = 4; } Min = priv->osc_freq; freq /= kHz(1); /* * Q:2..129 * P:8..2055, best 16..1023 (because of Pump) For stable operation: + REF/Qtotal must not fall below 250kHz ( + P*(REF/Qtotal) must not be above 400 MHz or below 100 MHz */ #if 1 q_max = priv->osc_freq / 250; #else q_max = 100; #endif for (q = q_max; q >= 10; q--) { for (p = 500; p <= 2000; p++) { VCO = ((double)priv->osc_freq / q) * p; if (fabs(4 * freq - VCO / priv->Div1N) < Min) { Min = fabs(4 * freq - VCO / priv->Div1N); priv->Q = q; priv->P = p; } } } VCO = ((double)priv->osc_freq / priv->Q) * priv->P; if (VCO < 100e3 || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", __func__, VCO); } #endif /* ORIG_ALGORITHM */ #if FREQ_ALGORITHM == 2 /* this used to be default alternative to ORIG_ALGORITHM */ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) { double Min, VCO, freq4; int div1n_min, div1n_max; int p, q, div1n, q_max; Min = priv->osc_freq; freq4 = freq * 4 / kHz(1); #define vco_min 100e3 #define vco_max 500e3 /* * Q:2..129 * P:8..2055, best 16..1023 (because of Pump) For stable operation: + REF/Qtotal must not fall below 250kHz ( + P*(REF/Qtotal) must not be above 400 MHz or below 100 MHz */ #if 1 q_max = priv->osc_freq / 250; #else q_max = 100; #endif div1n_min = vco_min / freq4; if (div1n_min < 2) { div1n_min = 2; } else if (div1n_min > 127) { div1n_min = 127; } div1n_max = vco_max / freq4; if (div1n_max > 127) { div1n_max = 127; } else if (div1n_max < 2) { div1n_max = 2; } for (div1n = div1n_min; div1n <= div1n_max; div1n++) { // P/Qtotal = FREQ4*DIV1N/REF // (Q*int(r) + frac(r)*Q)/Q for (q = q_max; q >= 2; q--) { p = q * freq4 * div1n / priv->osc_freq; #if 1 if (p < 16 || p > 1023) { continue; } #endif VCO = ((double)priv->osc_freq / q) * p; #if 1 if (VCO < vco_min || VCO > vco_max) { continue; } #endif if (fabs(freq4 - VCO / div1n) < Min) { Min = fabs(freq4 - VCO / div1n); priv->Div1N = div1n; priv->Q = q; priv->P = p; } } } VCO = ((double)priv->osc_freq / priv->Q) * priv->P; if (VCO < vco_min || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", __func__, VCO); } #endif /* default alternative to ORIG_ALGORITHM */ #if FREQ_ALGORITHM == 3 /* AC6SL version 5-Aug-2010 */ /* search valid (P,Q,N) for closest match to requested frequency */ static void find_P_Q_DIV1N( struct elektor507_priv_data *priv, freq_t freq) { #define VCO_MIN 100000000 #define VCO_MAX 400000000 int Ptotal; int Qtotal, Qmax = 40; int Div1N; double PmulREFdivQ; double Ref = priv->osc_freq * 1000.0; double freq4 = freq * 4; double newdelta, delta = fabs((priv->P * (Ref / priv->Q) / priv->Div1N) - freq4); /* For stable operation: Ref/Qtotal must not fall below 250kHz */ /* Qmax = (int) ( Ref / 250000); */ for (Qtotal = 2; Qtotal <= Qmax; Qtotal++) { double REFdivQ = (Ref / Qtotal); /* For stable operation: Ptotal*(Ref/Qtotal) must be ... */ int Pmin = (int)(VCO_MIN / REFdivQ); /* ... >= 100mHz */ int Pmax = (int)(VCO_MAX / REFdivQ); /* ... <= 400mHz */ for (Ptotal = Pmin; Ptotal <= Pmax; Ptotal++) { PmulREFdivQ = Ptotal * REFdivQ; Div1N = (int)((PmulREFdivQ + freq4 / 2) / freq4); if (Div1N < 2) { Div1N = 2; } if (Div1N > 127) { Div1N = 127; } newdelta = fabs((PmulREFdivQ / Div1N) - freq4); if (newdelta < delta) { /* save best (P,Q,N) */ delta = newdelta; priv->P = Ptotal; priv->Q = Qtotal; priv->Div1N = Div1N; } } } } #endif /* AC6SL version 5-Aug-2010 */ int elektor507_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; freq_t final_freq; int ret = 0; if (priv->ant == ANT_AUTO) { int Mux; /* Automatically select appropriate filter */ if (freq <= kHz(1600)) { /* Select A1, low pass, fc=1.6MHz */ Mux = 1; } else { /* Select A2, high pass */ Mux = 2; } priv->FT_port &= 0x63; //0,1 = I2C, 2,3,4=MUX, 5,6=Attenuator priv->FT_port |= Mux << 2; } find_P_Q_DIV1N(priv, freq); /* Compute PLL parameters */ elektor507_get_freq(rig, vfo, &final_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq=%.0f kHz, delta=%d Hz, Div1N=%d, P=%d, Q=%d, FREQ_ALGORITHM=%d\n", __func__, freq / kHz(1), (int)(final_freq - freq), priv->Div1N, priv->P, priv->Q, FREQ_ALGORITHM); if ((double)priv->osc_freq / priv->Q < 250) rig_debug(RIG_DEBUG_WARN, "%s: Unstable parameters for REF/Qtotal=%.1f\n", __func__, (double)priv->osc_freq / priv->Q); ret = cy_update_pll(rig, CY_I2C_RAM_ADR); return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; double VCO; VCO = ((double)priv->osc_freq * kHz(1)) / priv->Q * priv->P; /* Div by 4 because of QSD */ *freq = (VCO / priv->Div1N) / 4; return RIG_OK; } int elektor507_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret = 0; int att = 0; switch (level) { case RIG_LEVEL_ATT: /* val.i */ /* FTDI: DSR, DCD */ switch (val.i) { case 0: att = 0; break; case 10: att = 1; break; case 20: att = 2; break; default: return -RIG_EINVAL; } priv->FT_port &= 0x1f; priv->FT_port |= (att & 0x3) << 5; ret = elektor507_ftdi_write_data(rig, &priv->FT_port, 1); break; default: return -RIG_EINVAL; } return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret = 0; switch (level) { case RIG_LEVEL_ATT: switch ((priv->FT_port >> 5) & 3) { case 0: val->i = 0; break; case 1: val->i = 10; break; case 2: val->i = 20; break; default: ret = -RIG_EINVAL; } break; default: return -RIG_EINVAL; } return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret, Mux; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * FTDI: RTS, CTS, DTR * * A4,A5,A6 are not connected * * ANT1->A1/A2, ANT2->A3, ANT3->A7 */ switch (ant) { case RIG_ANT_1: Mux = 0; break; /* Mux will be updated upon next set_freq */ case RIG_ANT_2: Mux = 3; break; /* ANT_EXT */ case RIG_ANT_3: Mux = 7; break; /* ANT_TEST_CLK */ default: return -RIG_EINVAL; } priv->ant = ant; priv->FT_port &= 0x63; //0,1 = I2C, 2,3,4=MUX, 5,6=Attenuator priv->FT_port |= Mux << 2; #if 0 ret = elektor507_ftdi_write_data(rig, &priv->FT_port, 1); #else /* Enable CLOCK3 on demand */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CLKOE_REG, 0x20 | (ant == RIG_ANT_3 ? 0x04 : 0)); #endif return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; *ant_curr = priv->ant; return RIG_OK; } /* * Update the PLL counters */ static int cy_update_pll(RIG *rig, unsigned char IICadr) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int P0, R40, R41, R42; unsigned char Div1N; unsigned char Clk3_src; int Pump; int ret; /* * PLL Pump setting according to table 9 */ if (priv->P < 45) { Pump = 0; } else if (priv->P < 480) { Pump = 1; } else if (priv->P < 640) { Pump = 2; } else if (priv->P < 800) { Pump = 3; } else { Pump = 4; } P0 = priv->P & 0x01; R40 = (((priv->P >> 1) - 4) >> 8) | (Pump << 2) | 0xc0; R41 = ((priv->P >> 1) - 4) & 0xff; R42 = (priv->Q - 2) | (P0 << 7); ret = i2c_write_regs(rig, IICadr, 3, PUMPCOUNTERS_REG, R40, R41, R42); if (ret != 0) { return ret; } switch (priv->Div1N) { case 2: /* Fixed /2 divider option */ Clk3_src = 0x80; Div1N = 8; break; case 3: /* Fixed /3 divider option */ Clk3_src = 0xc0; Div1N = 6; break; default: Div1N = priv->Div1N; Clk3_src = 0x40; } ret = i2c_write_reg(rig, IICadr, DIV1_REG, Div1N); if (ret != 0) { return ret; } /* Set 2 low bits of CLKSRC for CLOCK5. DIV1CLK is set already */ ret = i2c_write_reg(rig, IICadr, CLKSRC_REG + 2, Clk3_src | 0x07); if (ret != 0) { return ret; } return RIG_OK; } static void ftdi_SCL(RIG *rig, int d) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; if (priv->Buf_adr >= FT_OUT_BUFFER_MAX) { return; } /* * FTDI RXD->SCL */ if (d == 0) { priv->FT_port &= ~0x02; } else { priv->FT_port |= 0x02; } priv->FT_Out_Buffer[priv->Buf_adr++] = priv->FT_port; } static void ftdi_SDA(RIG *rig, int d) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; if (priv->Buf_adr >= FT_OUT_BUFFER_MAX) { return; } /* * FTDI TXD->SDA */ if (d == 0) { priv->FT_port &= ~0x01; } else { priv->FT_port |= 0x01; } priv->FT_Out_Buffer[priv->Buf_adr++] = priv->FT_port; } static void ftdi_I2C_Init(RIG *rig) { ftdi_SCL(rig, 1); ftdi_SDA(rig, 1); /* SCL=1, SDA=1 */ } static void ftdi_I2C_Start(RIG *rig) { ftdi_SDA(rig, 0); /* SDA=0 */ ftdi_SCL(rig, 0); /* SCL=0 */ } static void ftdi_I2C_Stop(RIG *rig) { ftdi_SCL(rig, 0); ftdi_SDA(rig, 0); /* SCL=0, SDA=0 */ ftdi_SCL(rig, 1); /* SCL=1 */ ftdi_SDA(rig, 1); /* SDA=1 */ } /* Acknowledge: SCL=0, SDA=0 SCL=1 SCL=0 No Acknowledge: SCL=0, SDA=1 SCL=1 SCL=0 */ static void ftdi_I2C_Write_Byte(RIG *rig, unsigned char c) { int i; for (i = 7; i >= 0; i--) { ftdi_SDA(rig, c & (1 << i)); /* SDA value */ ftdi_SCL(rig, 1); ftdi_SCL(rig, 0); } ftdi_SDA(rig, 1); ftdi_SCL(rig, 1); ftdi_SCL(rig, 0); } int i2c_write_regs(RIG *rig, unsigned char IICadr, int reg_count, unsigned char reg_adr, unsigned char reg_val1, unsigned char reg_val2, unsigned char reg_val3) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; /* Start with a new buffer */ priv->Buf_adr = 0; ftdi_I2C_Init(rig); ftdi_I2C_Start(rig); ftdi_I2C_Write_Byte(rig, IICadr); ftdi_I2C_Write_Byte(rig, reg_adr); if (reg_count >= 1) { ftdi_I2C_Write_Byte(rig, reg_val1); } if (reg_count >= 2) { ftdi_I2C_Write_Byte(rig, reg_val2); } if (reg_count >= 3) { ftdi_I2C_Write_Byte(rig, reg_val3); } ftdi_I2C_Stop(rig); //usleep(10000); ret = elektor507_ftdi_write_data(rig, priv->FT_Out_Buffer, priv->Buf_adr); if (ret != 0) { return -RIG_EIO; } return 0; } #if 0 static const unsigned char ftdi_code[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x34, 0x08, 0x5a, 0x24/*0x6f*/, 0x00, 0x14, 0x0a, 0x00, 0x08, 0x88, 0x50, 0x04, 0x32, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x2b, 0x17, 0x00, 0xfe, 0xfe, 0x7f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32 }; int load_ftdi_code(RIG *rig, unsigned char IICadr, const unsigned char code[]) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; int i, j; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0; i < 16; i++) { /* Start with a new buffer */ priv->Buf_adr = 0; ftdi_I2C_Init(rig); ftdi_I2C_Start(rig); ftdi_I2C_Write_Byte(rig, IICadr); ftdi_I2C_Write_Byte(rig, i * 16); for (j = 0; j < 16; j++) { ftdi_I2C_Write_Byte(rig, code[i * 16 + j]); } ftdi_I2C_Stop(rig); ret = elektor507_ftdi_write_data(rig, priv->FT_Out_Buffer, priv->Buf_adr); if (ret != 0) { return -RIG_EIO; } } return RIG_OK; } #endif #endif /* defined(USE_FTDI_DLL) || defined(USE_LIBUSB) */ hamlib-4.6.5/rigs/kit/dds60.c0000664000175000017500000002251015056640443011273 /* * Hamlib KIT backend - DDS-60 description * Copyright (c) 2007 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "parallel.h" #include "token.h" #define DDS60_MODES (RIG_MODE_AM) #define DDS60_FUNC (RIG_FUNC_NONE) #define DDS60_LEVEL_ALL (RIG_LEVEL_NONE) #define DDS60_PARM_ALL (RIG_PARM_NONE) #define DDS60_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(30) #define IFMIXFREQ kHz(0) #define PHASE_INCR 11.25 struct dds60_priv_data { freq_t osc_freq; freq_t if_mix_freq; int multiplier; unsigned phase_step; /* as 11.25 deg steps */ }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) #define TOK_MULTIPLIER TOKEN_BACKEND(3) #define TOK_PHASE_MOD TOKEN_BACKEND(4) static const struct confparams dds60_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "30000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(180), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "0", RIG_CONF_NUMERIC, { .n = { 0, MHz(180), 1 } } }, { TOK_MULTIPLIER, "multiplier", "Multiplier", "Optional X6 multiplier", "1", RIG_CONF_CHECKBUTTON }, { TOK_IFMIXFREQ, "phase_mod", "Phase Modulation", "Phase modulation in degrees", "0", RIG_CONF_NUMERIC, { .n = { 0, 360, PHASE_INCR } } }, { RIG_CONF_END, NULL, } }; static int dds60_init(RIG *rig); static int dds60_cleanup(RIG *rig); static int dds60_open(RIG *rig); static int dds60_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dds60_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int dds60_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * The DDS-60 kit exists with a AD9851 chip (60 MHz), * as well as with the AD9850 chip (30 MHz) (no multiplier). * There is an option to enable/disable the AD9851 X6 multiplier. * http://www.amqrp.org/kits/dds60/ * http://www.analog.com/en/prod/0,2877,AD9851,00.html * * The receiver is controlled via the parallel port (D0,D1,D2). */ struct rig_caps dds60_caps = { RIG_MODEL(RIG_MODEL_DDS60), .model_name = "DDS-60", .mfg_name = "AmQRP", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DDS60_FUNC, .has_set_func = DDS60_FUNC, .has_get_level = DDS60_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DDS60_LEVEL_ALL), .has_get_parm = DDS60_PARM_ALL, .has_set_parm = RIG_PARM_SET(DDS60_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {MHz(1), MHz(60), DDS60_MODES, -1, -1, DDS60_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(1), MHz(60), DDS60_MODES, -1, -1, DDS60_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DDS60_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {DDS60_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = dds60_cfg_params, .rig_init = dds60_init, .rig_cleanup = dds60_cleanup, .rig_open = dds60_open, .set_conf = dds60_set_conf, .get_conf = dds60_get_conf, .set_freq = dds60_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int dds60_init(RIG *rig) { struct dds60_priv_data *priv; STATE(rig)->priv = (struct dds60_priv_data *)calloc(1, sizeof( struct dds60_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->if_mix_freq = IFMIXFREQ; priv->multiplier = 1; priv->phase_step = 0; return RIG_OK; } int dds60_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int dds60_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dds60_priv_data *priv; float phase; priv = (struct dds60_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; case TOK_MULTIPLIER: sscanf(val, "%d", &priv->multiplier); break; case TOK_PHASE_MOD: sscanf(val, "%f", &phase); priv->phase_step = ((unsigned)((phase + PHASE_INCR / 2) / PHASE_INCR)) % 32; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int dds60_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct dds60_priv_data *priv; priv = (struct dds60_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; case TOK_MULTIPLIER: SNPRINTF(val, val_len, "%d", priv->multiplier); break; case TOK_PHASE_MOD: SNPRINTF(val, val_len, "%f", priv->phase_step * PHASE_INCR); break; default: return -RIG_EINVAL; } return RIG_OK; } int dds60_get_conf(RIG *rig, hamlib_token_t token, char *val) { return dds60_get_conf2(rig, token, val, 128); } #define DATA 0x01 /* d0 */ #define CLOCK 0x02 /* d1 */ #define LOAD 0x03 /* d2 */ static void ad_delay(int delay) { /* none needed, I/O bus should be slow enough */ } static void ad_bit(hamlib_port_t *port, unsigned char bit) { bit &= DATA; par_write_data(port, bit); ad_delay(1); par_write_data(port, bit | CLOCK); ad_delay(1); par_write_data(port, bit); ad_delay(1); } static void ad_write(hamlib_port_t *port, unsigned long word, unsigned char control) { int i; /* lock the parallel port */ par_lock(port); /* shift out the least significant 32 bits of the word */ for (i = 0; i < 32; i++) { ad_bit(port, word & DATA); word >>= 1; } /* write out the control byte */ for (i = 0; i < 8; i++) { ad_bit(port, control & DATA); control >>= 1; } /* load the register */ par_write_data(port, LOAD); ad_delay(1); par_write_data(port, 0); /* unlock the parallel port */ par_unlock(port); } int dds60_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned char control; struct dds60_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); freq_t osc_ref; priv = (struct dds60_priv_data *)STATE(rig)->priv; if (priv->multiplier) { osc_ref = priv->osc_freq * 6; } else { osc_ref = priv->osc_freq; } /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / osc_ref * 4294967296.0 + 0.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: word %lu, X6 multiplier %d, phase %.2f\n", __func__, frg, priv->multiplier, priv->phase_step * PHASE_INCR); control = priv->multiplier ? 0x01 : 0x00; control |= (priv->phase_step & 0x1f) << 3; ad_write(port, frg, control); return RIG_OK; } int dds60_open(RIG *rig) { hamlib_port_t *port = RIGPORT(rig); /* lock the parallel port */ par_lock(port); /* Serial load enable sequence W_CLK */ par_write_data(port, 0); ad_delay(1); par_write_data(port, CLOCK); ad_delay(1); par_write_data(port, 0); ad_delay(1); /* Serial load enable sequence FQ_UD */ par_write_data(port, LOAD); ad_delay(1); par_write_data(port, 0); /* unlock the parallel port */ par_unlock(port); return RIG_OK; } hamlib-4.6.5/rigs/kit/elektor304.c0000664000175000017500000002212415056640443012250 /* * Hamlib KIT backend - Elektor DRM receiver description * Copyright (c) 2004-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "token.h" #define ELEKTOR304_MODES (RIG_MODE_AM) #define ELEKTOR304_FUNC (RIG_FUNC_NONE) #define ELEKTOR304_LEVEL_ALL (RIG_LEVEL_NONE) #define ELEKTOR304_PARM_ALL (RIG_PARM_NONE) #define ELEKTOR304_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(50) #define IFMIXFREQ kHz(454.3) struct elektor304_priv_data { freq_t osc_freq; freq_t if_mix_freq; }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) static const struct confparams elektor304_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillatorfreq", "Oscillator frequency in Hz", "50000000", RIG_CONF_NUMERIC, { .n = { 0, GHz(2), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "454300", RIG_CONF_NUMERIC, { .n = { 0, MHz(100), 1 } } }, { RIG_CONF_END, NULL, } }; static int elektor304_init(RIG *rig); static int elektor304_cleanup(RIG *rig); static int elektor304_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int elektor304_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int elektor304_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * The Elektor DRM Receiver 3/04 COM interface is based on the Visual Basic * source code by Burkhard Kainka which can be downloaded from www.b-kainka.de * Linux support is based on a code written by Markus Mrz: * http://mitglied.lycos.de/markusmaerz/drm * Linux support is available from DRM Dream project. * * The DDS is a AD9835. * * The receiver is controlled via the TX, RTS and DTR pins of the serial port. */ struct rig_caps elektor304_caps = { RIG_MODEL(RIG_MODEL_ELEKTOR304), .model_name = "Elektor 3/04", .mfg_name = "Elektor", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, /* bit banging */ .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = ELEKTOR304_FUNC, .has_set_func = ELEKTOR304_FUNC, .has_get_level = ELEKTOR304_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ELEKTOR304_LEVEL_ALL), .has_get_parm = ELEKTOR304_PARM_ALL, .has_set_parm = RIG_PARM_SET(ELEKTOR304_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(22), ELEKTOR304_MODES, -1, -1, ELEKTOR304_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(22), ELEKTOR304_MODES, -1, -1, ELEKTOR304_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ELEKTOR304_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {ELEKTOR304_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = elektor304_cfg_params, .rig_init = elektor304_init, .rig_cleanup = elektor304_cleanup, .set_conf = elektor304_set_conf, .get_conf = elektor304_get_conf, .set_freq = elektor304_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int elektor304_init(RIG *rig) { struct elektor304_priv_data *priv; STATE(rig)->priv = (struct elektor304_priv_data *)calloc(1, sizeof(struct elektor304_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->if_mix_freq = IFMIXFREQ; return RIG_OK; } int elektor304_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int elektor304_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct elektor304_priv_data *priv; priv = (struct elektor304_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int elektor304_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct elektor304_priv_data *priv; priv = (struct elektor304_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor304_get_conf(RIG *rig, hamlib_token_t token, char *val) { return elektor304_get_conf2(rig, token, val, 128); } #define AD_DELAY 4000 /* * Introduce delay after changing the bit state * FIXME: This implementation may not work for very fast computers, * or smart compilers. However, nanosleep can have * granularity > 10ms! */ static int ad_delay(int m) { long j; for (j = 0; j <= m; j++) {} return j; } static int ad_sdata(hamlib_port_t *port, int i) { int ret; ret = ser_set_rts(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_sclk(const hamlib_port_t *port, int i) { int ret; ret = ser_set_brk(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_fsync(hamlib_port_t *port, int i) { int ret; ret = ser_set_dtr(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_write(hamlib_port_t *port, unsigned data) { unsigned mask = 0x8000; int i; ad_sclk(port, 0); /* TXD 0 */ ad_fsync(port, 1); /* DTR 1, CE */ for (i = 0; i < 16; i++) { ad_sdata(port, (data & mask) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ mask >>= 1; /* Next bit for masking */ } ad_fsync(port, 0); /* DTR 0 */ return RIG_OK; } int elektor304_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned fhl, fhh, fll, flh; struct elektor304_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); priv = (struct elektor304_priv_data *)STATE(rig)->priv; rig_flush(port); /* Initialization */ ad_fsync(port, 0); ad_sdata(port, 0); ad_sclk(port, 0); /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / priv->osc_freq * 4294967296.0 + 0.5); fll = frg & 0xff; flh = (frg >> 8) & 0xff; fhl = (frg >> 16) & 0xff; fhh = (frg >> 24) & 0xff; rig_debug(RIG_DEBUG_VERBOSE, "%s: %lu=[%02x.%02x.%02x.%02x]\n", __func__, frg, fll, flh, fhl, fhh); ad_write(port, 0xF800); /* Reset */ ad_write(port, 0x3000 | fll); /* 4 Bytes to FREQ0 */ ad_write(port, 0x2100 | flh); ad_write(port, 0x3200 | fhl); ad_write(port, 0x2300 | fhh); ad_write(port, 0x8000); /* Sync */ ad_write(port, 0xC000); /* Reset end */ return RIG_OK; } hamlib-4.6.5/rigs/kit/Android.mk0000664000175000017500000000057515056640443012127 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := elektor304.c drt1.c dwt.c usrp.c elektor507.c \ dds60.c miniVNA.c si570avrusb.c funcube.c fifisdr.c hiqsdr.c \ pcrotor.c kit.c rs_hfiq.c LOCAL_MODULE := kit LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/kit/usrp.c0000664000175000017500000000756015056640443011354 /* * Hamlib KIT backend - Universal Software Radio Peripheral description * Copyright (c) 2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* * Compile only this model if usrp is available */ #if defined(HAVE_USRP) #include #include #include #include "hamlib/rig.h" #include "usrp_impl.h" #include "token.h" #define USRP_MODES (RIG_MODE_NONE) #define USRP_FUNC (RIG_FUNC_NONE) #define USRP_LEVEL_ALL (RIG_LEVEL_NONE) #define USRP_PARM_ALL (RIG_PARM_NONE) #define USRP_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_C|RIG_VFO_N(3)) static const struct confparams usrp_cfg_params[] = { { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "45000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { RIG_CONF_END, NULL } }; /* * GNU Radio Universal Software Radio Peripheral * */ struct rig_caps usrp_caps = { RIG_MODEL(RIG_MODEL_USRP), .model_name = "USRP", .mfg_name = "GNU Radio", .version = "0.1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NONE, .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = USRP_FUNC, .has_set_func = USRP_FUNC, .has_get_level = USRP_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(USRP_LEVEL_ALL), .has_get_parm = USRP_PARM_ALL, .has_set_parm = RIG_PARM_SET(USRP_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), USRP_MODES, -1, -1, USRP_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, USRP_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30), USRP_MODES, -1, -1, USRP_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, USRP_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {USRP_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {USRP_MODES, kHz(40)}, /* FIXME */ RIG_FLT_END, }, .cfgparams = usrp_cfg_params, .rig_init = usrp_init, .rig_cleanup = usrp_cleanup, .rig_open = usrp_open, .rig_close = usrp_close, .set_conf = usrp_set_conf, .get_conf = usrp_get_conf, .set_freq = usrp_set_freq, .get_freq = usrp_get_freq, .get_info = usrp_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* HAVE_USRP */ hamlib-4.6.5/rigs/kit/usrp_impl.cc0000664000175000017500000000777515056640443012550 /* * Hamlib KIT backend - Universal Software Radio Peripheral * Copyright (c) 2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* * Compile only this model if usrp is available */ #if defined(HAVE_USRP) #include #include #include #include #include "usrp_impl.h" #include "token.h" struct usrp_priv_data { usrp_standard_rx *urx; usrp_standard_tx *utx; freq_t if_mix_freq; }; int usrp_init(RIG *rig) { // cppcheck-suppress leakReturnValNotUsed STATE(rig)->priv = static_cast(malloc(sizeof(struct usrp_priv_data))); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } return RIG_OK; } int usrp_cleanup(RIG *rig) { if (!rig) return -RIG_EINVAL; if (STATE(rig)->priv) free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int usrp_open(RIG *rig) { struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); int which_board = 0; int decim = 125; priv->urx = usrp_standard_rx::make (which_board, decim, 1, -1, usrp_standard_rx::FPGA_MODE_NORMAL).get(); if (priv->urx == 0) return -RIG_EIO; return RIG_OK; } int usrp_close(RIG *rig) { struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } delete priv->urx; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int usrp_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } switch(token) { case TOK_IFMIXFREQ: sscanf(val, "%" SCNfreq, &priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int usrp_get_conf(RIG *rig, hamlib_token_t token, char *val) { const struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } switch(token) { case TOK_IFMIXFREQ: sprintf(val, "%" PRIfreq, priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } int usrp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); int chan = 0; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } if (!priv->urx->set_rx_freq (chan, freq)) return -RIG_EPROTO; return RIG_OK; } int usrp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct usrp_priv_data *priv = static_cast(STATE(rig)->priv); int chan = 0; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } *freq = priv->urx->rx_freq (chan); return RIG_OK; } const char * usrp_get_info(RIG *rig) { return NULL; } #endif /* HAVE_USRP */ hamlib-4.6.5/rigs/kit/Makefile.in0000664000175000017500000006701515056640452012265 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_USRP_TRUE@am__append_1 = $(USRP_CFLAGS) @HAVE_USRP_TRUE@am__append_2 = usrp_impl.cc subdir = rigs/kit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libhamlib_kit_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__libhamlib_kit_la_SOURCES_DIST = elektor304.c drt1.c dwt.c usrp.c \ elektor507.c dds60.c miniVNA.c si570avrusb.c si570avrusb.h \ funcube.c funcube.h fifisdr.c hiqsdr.c kit.c kit.h usrp_impl.h \ rs_hfiq.c usrp_impl.cc pcrotor.c @HAVE_USRP_TRUE@am__objects_1 = usrp_impl.lo am__objects_2 = elektor304.lo drt1.lo dwt.lo usrp.lo elektor507.lo \ dds60.lo miniVNA.lo si570avrusb.lo funcube.lo fifisdr.lo \ hiqsdr.lo kit.lo rs_hfiq.lo $(am__objects_1) am__objects_3 = pcrotor.lo am_libhamlib_kit_la_OBJECTS = $(am__objects_2) $(am__objects_3) libhamlib_kit_la_OBJECTS = $(am_libhamlib_kit_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dds60.Plo ./$(DEPDIR)/drt1.Plo \ ./$(DEPDIR)/dwt.Plo ./$(DEPDIR)/elektor304.Plo \ ./$(DEPDIR)/elektor507.Plo ./$(DEPDIR)/fifisdr.Plo \ ./$(DEPDIR)/funcube.Plo ./$(DEPDIR)/hiqsdr.Plo \ ./$(DEPDIR)/kit.Plo ./$(DEPDIR)/miniVNA.Plo \ ./$(DEPDIR)/pcrotor.Plo ./$(DEPDIR)/rs_hfiq.Plo \ ./$(DEPDIR)/si570avrusb.Plo ./$(DEPDIR)/usrp.Plo \ ./$(DEPDIR)/usrp_impl.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libhamlib_kit_la_SOURCES) DIST_SOURCES = $(am__libhamlib_kit_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ $(LIBUSB_CFLAGS) AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ $(am__append_1) AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # FIXME: compile usrp only if CXX available KITSRC = elektor304.c drt1.c dwt.c usrp.c elektor507.c dds60.c \ miniVNA.c si570avrusb.c si570avrusb.h funcube.c funcube.h \ fifisdr.c hiqsdr.c kit.c kit.h usrp_impl.h rs_hfiq.c \ $(am__append_2) @HAVE_USRP_FALSE@libhamlib_kit_la_LINK = $(LINK) $(libhamlib_kit_la_LDFLAGS) @HAVE_USRP_TRUE@libhamlib_kit_la_LINK = $(CXXLINK) $(libhamlib_kit_la_LDFLAGS) KITROTSRC = pcrotor.c noinst_LTLIBRARIES = libhamlib-kit.la libhamlib_kit_la_SOURCES = $(KITSRC) $(KITROTSRC) libhamlib_kit_la_LIBADD = $(USRP_LIBS) $(LIBUSB_LIBS) $(MATH_LIBS) EXTRA_DIST = README.funcubedongle Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-kit.la: $(libhamlib_kit_la_OBJECTS) $(libhamlib_kit_la_DEPENDENCIES) $(EXTRA_libhamlib_kit_la_DEPENDENCIES) $(AM_V_GEN)$(libhamlib_kit_la_LINK) $(libhamlib_kit_la_OBJECTS) $(libhamlib_kit_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dds60.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drt1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elektor304.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elektor507.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifisdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funcube.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hiqsdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miniVNA.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrotor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rs_hfiq.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/si570avrusb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usrp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usrp_impl.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dds60.Plo -rm -f ./$(DEPDIR)/drt1.Plo -rm -f ./$(DEPDIR)/dwt.Plo -rm -f ./$(DEPDIR)/elektor304.Plo -rm -f ./$(DEPDIR)/elektor507.Plo -rm -f ./$(DEPDIR)/fifisdr.Plo -rm -f ./$(DEPDIR)/funcube.Plo -rm -f ./$(DEPDIR)/hiqsdr.Plo -rm -f ./$(DEPDIR)/kit.Plo -rm -f ./$(DEPDIR)/miniVNA.Plo -rm -f ./$(DEPDIR)/pcrotor.Plo -rm -f ./$(DEPDIR)/rs_hfiq.Plo -rm -f ./$(DEPDIR)/si570avrusb.Plo -rm -f ./$(DEPDIR)/usrp.Plo -rm -f ./$(DEPDIR)/usrp_impl.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dds60.Plo -rm -f ./$(DEPDIR)/drt1.Plo -rm -f ./$(DEPDIR)/dwt.Plo -rm -f ./$(DEPDIR)/elektor304.Plo -rm -f ./$(DEPDIR)/elektor507.Plo -rm -f ./$(DEPDIR)/fifisdr.Plo -rm -f ./$(DEPDIR)/funcube.Plo -rm -f ./$(DEPDIR)/hiqsdr.Plo -rm -f ./$(DEPDIR)/kit.Plo -rm -f ./$(DEPDIR)/miniVNA.Plo -rm -f ./$(DEPDIR)/pcrotor.Plo -rm -f ./$(DEPDIR)/rs_hfiq.Plo -rm -f ./$(DEPDIR)/si570avrusb.Plo -rm -f ./$(DEPDIR)/usrp.Plo -rm -f ./$(DEPDIR)/usrp_impl.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @HAVE_USRP_TRUE@ # Append to the already defined AM_CXXFLAGS that exists outside the conditional. @HAVE_USRP_FALSE@ # automake gets confused and invokes the C++ linker via libtool regardless @HAVE_USRP_FALSE@ # of whether or not HAVE_USRP enables the .cc source. This override forces @HAVE_USRP_FALSE@ # automake to invoke the C linker as no C++ is involved: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/kit/fifisdr.c0000664000175000017500000005143015056640443012004 /* * Hamlib KIT backend - FiFi-SDR Receiver(/Tuner) description * Copyright (c) 2010 by Rolf Meeser * * Derived from si570avrusb backend: * Copyright (C) 2004-2010 Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "hamlib/rig.h" #include "token.h" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif /* Selected request codes of the original AVR USB Si570 firmware */ #define REQUEST_SET_FREQ_BY_VALUE (0x32) #define REQUEST_SET_XTALL_FREQ (0x33) #define REQUEST_READ_MULTIPLY_LO (0x39) #define REQUEST_READ_FREQUENCY (0x3A) /* FiFi-SDR specific requests */ #define REQUEST_FIFISDR_READ (0xAB) #define REQUEST_FIFISDR_WRITE (0xAC) /* USB VID/PID, vendor name (idVendor), product name (idProduct). * Use obdev's generic shared VID/PID pair and follow the rules outlined * in firmware/usbdrv/USBID-License.txt. */ #define USBDEV_SHARED_VID 0x16C0 /* VOTI */ #define USBDEV_SHARED_PID 0x05DC /* Obdev's free shared PID */ #define FIFISDR_VENDOR_NAME "www.ov-lennestadt.de" #define FIFISDR_PRODUCT_NAME "FiFi-SDR" /* All level controls */ #define FIFISDR_LEVEL_ALL (0 \ | RIG_LEVEL_PREAMP \ | RIG_LEVEL_STRENGTH \ | RIG_LEVEL_AF \ | RIG_LEVEL_AGC \ | RIG_LEVEL_SQL \ ) static int fifisdr_init(RIG *rig); static int fifisdr_cleanup(RIG *rig); static int fifisdr_open(RIG *rig); static int fifisdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int fifisdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static const char *fifisdr_get_info(RIG *rig); static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int fifisdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); /* Private tokens. */ #define TOK_LVL_FMCENTER TOKEN_BACKEND(1) /* FM center frequency deviation */ /* Extra levels definitions */ static const struct confparams fifisdr_ext_levels[] = { { TOK_LVL_FMCENTER, "fmcenter", "FM center", "Center frequency deviation of FM signal", NULL, RIG_CONF_NUMERIC, { .n = { -kHz(5), kHz(5), Hz(1) } } }, { RIG_CONF_END, NULL, } }; /** Private instance data. */ struct fifisdr_priv_instance_data { double multiplier; }; /** FiFi-SDR receiver description. */ struct rig_caps fifisdr_caps = { RIG_MODEL(RIG_MODEL_FIFISDR), .model_name = "FiFi-SDR", .mfg_name = "FiFi", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = FIFISDR_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(FIFISDR_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(RIG_PARM_NONE), .level_gran = {}, .parm_gran = {}, .extparms = NULL, .extlevels = fifisdr_ext_levels, .preamp = { 6, RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_NONE, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(39.1), .endf = MHz(175.0), .modes = RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_FM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A, .ant = RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(39.1), .endf = MHz(175.0), .modes = RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_FM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A, .ant = RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB, Hz(1)}, {RIG_MODE_SSB, Hz(10)}, {RIG_MODE_SSB, Hz(50)}, {RIG_MODE_AM, Hz(10)}, {RIG_MODE_AM, Hz(50)}, {RIG_MODE_AM, Hz(100)}, {RIG_MODE_FM, kHz(0.1)}, {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(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, /* normal */ {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_AM, kHz(8.0)}, /* normal */ {RIG_MODE_AM, kHz(6.2)}, {RIG_MODE_AM, kHz(10.0)}, {RIG_MODE_FM, kHz(9.0)}, /* normal */ {RIG_MODE_FM, kHz(6.0)}, {RIG_MODE_FM, kHz(12.5)}, RIG_FLT_END, }, .cfgparams = NULL, .rig_init = fifisdr_init, .rig_cleanup = fifisdr_cleanup, .rig_open = fifisdr_open, .rig_close = NULL, .set_freq = fifisdr_set_freq, .get_freq = fifisdr_get_freq, .set_mode = fifisdr_set_mode, .get_mode = fifisdr_get_mode, .set_level = fifisdr_set_level, .get_level = fifisdr_get_level, .get_ext_level = fifisdr_get_ext_level, .get_info = fifisdr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /** Convert from host endianness to FiFi-SDR little endian. */ static uint32_t fifisdr_tole32(uint32_t x) { return (((((x) / 1ul) % 256ul) << 0) | ((((x) / 256ul) % 256ul) << 8) | ((((x) / 65536ul) % 256ul) << 16) | ((((x) / 16777216ul) % 256ul) << 24)); } /** Convert FiFi-SDR little endian to host endianness. */ static uint32_t fifisdr_fromle32(uint32_t x) { return (((((x) >> 24) & 0xFF) * 16777216ul) + ((((x) >> 16) & 0xFF) * 65536ul) + ((((x) >> 8) & 0xFF) * 256ul) + ((((x) >> 0) & 0xFF) * 1ul)); } /** USB OUT transfer via vendor device command. */ static int fifisdr_usb_write(RIG *rig, int request, int value, int index, unsigned char *bytes, int size) { int ret; libusb_device_handle *udh = RIGPORT(rig)->handle; ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, request, value, index, bytes, size, RIGPORT(rig)->timeout); if (ret != size) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } /** USB IN transfer via vendor device command. */ static int fifisdr_usb_read(RIG *rig, int request, int value, int index, unsigned char *bytes, int size) { int ret; libusb_device_handle *udh = RIGPORT(rig)->handle; ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, request, value, index, bytes, size, RIGPORT(rig)->timeout); if (ret != size) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } int fifisdr_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct fifisdr_priv_instance_data *priv; STATE(rig)->priv = (struct fifisdr_priv_instance_data *)calloc(sizeof( struct fifisdr_priv_instance_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->multiplier = 4; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; rp->parm.usb.vendor_name = FIFISDR_VENDOR_NAME; rp->parm.usb.product = FIFISDR_PRODUCT_NAME; return RIG_OK; } int fifisdr_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int fifisdr_open(RIG *rig) { int ret; uint32_t multiply; struct fifisdr_priv_instance_data *priv; priv = (struct fifisdr_priv_instance_data *)STATE(rig)->priv; /* The VCO is a multiple of the RX frequency. Typically 4 */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 11, /* Read virtual VCO factor */ (unsigned char *)&multiply, sizeof(multiply)); if (ret == RIG_OK) { priv->multiplier = fifisdr_fromle32(multiply); } return RIG_OK; } const char *fifisdr_get_info(RIG *rig) { static char buf[64]; int ret; uint32_t svn_version; ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 0, (unsigned char *)&svn_version, sizeof(svn_version)); if (ret != RIG_OK) { return NULL; } SNPRINTF(buf, sizeof(buf), "Firmware version: %u", svn_version); return buf; } int fifisdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct fifisdr_priv_instance_data *priv = (struct fifisdr_priv_instance_data *) STATE(rig)->priv; int ret; double mhz; uint32_t freq1121; /* Need frequency in 11.21 format */ mhz = (freq * priv->multiplier) / 1e6; freq1121 = fifisdr_tole32(round(mhz * 2097152.0)); ret = fifisdr_usb_write(rig, REQUEST_SET_FREQ_BY_VALUE, 0, 0, (unsigned char *)&freq1121, sizeof(freq1121)); if (ret != RIG_OK) { return -RIG_EIO; } return RIG_OK; } int fifisdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct fifisdr_priv_instance_data *priv = (struct fifisdr_priv_instance_data *) STATE(rig)->priv; int ret; uint32_t freq1121; ret = fifisdr_usb_read(rig, REQUEST_READ_FREQUENCY, 0, 0, (unsigned char *)&freq1121, sizeof(freq1121)); if (ret == RIG_OK) { freq1121 = fifisdr_fromle32(freq1121); *freq = MHz(((double)freq1121 / (1ul << 21)) / priv->multiplier); } return ret; } static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; uint8_t fifi_mode; uint32_t fifi_width; /* Translate mode into FiFi-SDR language */ fifi_mode = 0; switch (mode) { case RIG_MODE_AM: fifi_mode = 2; break; case RIG_MODE_LSB: fifi_mode = 0; break; case RIG_MODE_USB: fifi_mode = 1; break; case RIG_MODE_FM: fifi_mode = 3; break; default: return -RIG_EINVAL; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 15, /* Demodulator mode */ (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } /* Set filter width */ fifi_width = fifisdr_tole32(width); ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 16, /* Filter width */ (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } return RIG_OK; } static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; uint8_t fifi_mode; uint32_t fifi_width; /* Read current mode */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 15, /* Demodulator mode */ (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; } /* Translate mode coding */ *mode = RIG_MODE_NONE; switch (fifi_mode) { case 0: *mode = RIG_MODE_LSB; break; case 1: *mode = RIG_MODE_USB; break; case 2: *mode = RIG_MODE_AM; break; case 3: *mode = RIG_MODE_FM; break; } /* Read current filter width */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 16, /* Filter width */ (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } *width = s_Hz(fifisdr_fromle32(fifi_width)); return RIG_OK; } static int fifisdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret = RIG_OK; uint8_t fifi_preamp; int16_t fifi_volume; uint8_t fifi_squelch; uint8_t fifi_agc; switch (level) { /* Preamplifier (ADC 0/+6dB switch) */ case RIG_LEVEL_PREAMP: /* Value can be 0 (0 dB) or 1 (+6 dB) */ fifi_preamp = 0; if (val.i == 6) { fifi_preamp = 1; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 19, /* Preamp */ (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); break; /* RX volume control */ case RIG_LEVEL_AF: /* Transform Hamlib value (float: 0...1) to an integer range (0...100) */ fifi_volume = (int16_t)(val.f * 100.0f); if (fifi_volume < 0) { fifi_volume = 0; } if (fifi_volume > 100) { fifi_volume = 100; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 14, /* Demodulator volume */ (unsigned char *)&fifi_volume, sizeof(fifi_volume)); break; /* Squelch level */ case RIG_LEVEL_SQL: /* Transform Hamlib value (float: 0...1) to an integer range (0...100) */ fifi_squelch = (uint8_t)(val.f * 100.0f); if (fifi_squelch > 100) { fifi_squelch = 100; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 20, /* Squelch control */ (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); break; /* AGC */ case RIG_LEVEL_AGC: /* Transform Hamlib enum value to FiFi-SDR selector */ fifi_agc = 0; switch (val.i) { case RIG_AGC_OFF: fifi_agc = 0; break; case RIG_AGC_SUPERFAST: fifi_agc = 1; break; case RIG_AGC_FAST: fifi_agc = 2; break; case RIG_AGC_SLOW: fifi_agc = 3; break; case RIG_AGC_USER: fifi_agc = 4; break; case RIG_AGC_MEDIUM: fifi_agc = 5; break; case RIG_AGC_AUTO: fifi_agc = 6; break; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 21, /* AGC template */ (unsigned char *)&fifi_agc, sizeof(fifi_agc)); break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret = RIG_OK; uint32_t fifi_meter = 0; uint8_t fifi_preamp = 0; int16_t fifi_volume = 0; uint8_t fifi_squelch = 0; uint8_t fifi_agc = 0; switch (level) { /* Preamplifier (ADC 0/+6dB switch) */ case RIG_LEVEL_PREAMP: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 19, /* Preamp */ (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); if (ret == RIG_OK) { /* Value can be 0 (0 dB) or 1 (+6 dB) */ val->i = 0; if (fifi_preamp != 0) { val->i = 6; } } break; /* RX volume control */ case RIG_LEVEL_AF: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 14, /* Demodulator volume */ (unsigned char *)&fifi_volume, sizeof(fifi_volume)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; if ((fifi_volume >= 0) && (fifi_volume <= 100)) { val->f = (float)fifi_volume / 100.0f; } } break; /* Squelch level */ case RIG_LEVEL_SQL: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 20, /* Squelch control */ (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; if (fifi_squelch <= 100) { val->f = (float)fifi_squelch / 100.0f; } } break; /* AGC */ case RIG_LEVEL_AGC: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 21, /* AGC template */ (unsigned char *)&fifi_agc, sizeof(fifi_agc)); if (ret == RIG_OK) { val->i = 0; switch (fifi_agc) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SUPERFAST; break; case 2: val->i = RIG_AGC_FAST; break; case 3: val->i = RIG_AGC_SLOW; break; case 4: val->i = RIG_AGC_USER; break; case 5: val->i = RIG_AGC_MEDIUM; break; case 6: val->i = RIG_AGC_AUTO; break; } } break; /* Signal strength */ case RIG_LEVEL_STRENGTH: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 17, /* S-Meter */ (unsigned char *)&fifi_meter, sizeof(fifi_meter)); if (ret == RIG_OK) { val->i = fifisdr_fromle32(fifi_meter); } break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int ret = RIG_OK; uint32_t u32; switch (token) { /* FM center frequency deviation */ case TOK_LVL_FMCENTER: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 18, /* FM center frequency */ (unsigned char *)&u32, sizeof(u32)); if (ret == RIG_OK) { val->f = Hz((int32_t)fifisdr_fromle32(u32)); } break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.5/rigs/kit/dwt.c0000664000175000017500000004472615056640443011166 /* * Hamlib KIT backend - Digital World Traveller DRM receiver description * Copyright (c) 2005-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #define BACKEND_VER "20200112" /* * Compile only this model if libusb is available * or if .DLL is available under Windows */ #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif #include /* * Coding Technologies Digital World Traveller DRM tuner. * * TODO: rig_scan, set/get FM mode (mono/stereo), * get antenna mode (loop/wire), * get low intermediate frequency (LIF) which may vary up to +-667 Hz * and may be additionally increased of up to 2000 Hz */ #define DWTDLL "afgusbfe.dll" /* Some type definitions needed for dll access */ typedef enum _tFrontendMode { eFrontendModeUndefined = 0, eFrontendModeDrm = 1, eFrontendModeAm = 2, eFrontendModeFm = 6, } tFrontendMode; typedef short (__stdcall *FNCFrontendOpen)(void); typedef short (__stdcall *FNCFrontendClose)(void); typedef short (__stdcall *FNCFrontendGetId)(char *id); typedef short (__stdcall *FNCFrontendSetMode)(tFrontendMode mode); typedef tFrontendMode(__stdcall *FNCFrontendGetMode)(void); typedef short (__stdcall *FNCFrontendSetFrequency)(double freq); typedef double (__stdcall *FNCFrontendGetFrequency)(void); typedef short (__stdcall *FNCFrontendGetRfLevel)(void); typedef double (__stdcall *FNCFrontendGetLIF)(void); typedef short (__stdcall *FNCFrontendStartScan)(short ScanMode, double WindowStartFreq, double WindowEndFreq, double DeltaFreq, double StepSize); typedef short (__stdcall *FNCFrontendStopScan)(void); typedef short (__stdcall *FNCFrontendGetScanStatus)(void); typedef short (__stdcall *FNCFrontendSetRfAttenuator)(short n); typedef short (__stdcall *FNCFrontendGetRfAttenuator)(void); typedef short (__stdcall *FNCFrontendSetAntennaMode)(short n); typedef short (__stdcall *FNCFrontendGetAntennaMode)(void); typedef short (__stdcall *FNCFrontendSetFmMode)(short n); typedef short (__stdcall *FNCFrontendGetFmMode)(void); struct dwtdll_priv_data { HMODULE dll; FNCFrontendOpen FrontendOpen; FNCFrontendClose FrontendClose; FNCFrontendGetId FrontendGetId; FNCFrontendSetMode FrontendSetMode; FNCFrontendGetMode FrontendGetMode; FNCFrontendSetFrequency FrontendSetFrequency; FNCFrontendGetFrequency FrontendGetFrequency; FNCFrontendGetRfLevel FrontendGetRfLevel; FNCFrontendGetLIF FrontendGetLIF; FNCFrontendStartScan FrontendStartScan; FNCFrontendStopScan FrontendStopScan; FNCFrontendGetScanStatus FrontendGetScanStatus; FNCFrontendSetRfAttenuator FrontendSetRfAttenuator; FNCFrontendGetRfAttenuator FrontendGetRfAttenuator; FNCFrontendSetAntennaMode FrontendSetAntennaMode; FNCFrontendGetAntennaMode FrontendGetAntennaMode; FNCFrontendSetFmMode FrontendSetFmMode; FNCFrontendGetFmMode FrontendGetFmMode; }; #define DWT_MODES (RIG_MODE_AM|RIG_MODE_USB) /* USB is for DRM */ #define DWT_FUNC (RIG_FUNC_NONE) #define DWT_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_STRENGTH|RIG_LEVEL_RAWSTR) #define DWT_PARM_ALL (RIG_PARM_NONE) #define DWT_VFO (RIG_VFO_A) #define DWT_ANT (RIG_ANT_1) static int dwtdll_init(RIG *rig); static int dwtdll_cleanup(RIG *rig); static int dwtdll_open(RIG *rig); static int dwtdll_close(RIG *rig); static int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *dwtdll_get_info(RIG *rig); /* * Coding Technologies Digital World Traveller DRM tuner. * * The receiver is controlled via USB, through a Windows DLL. * * see Winradio G303 as an example */ struct rig_caps dwt_caps = { RIG_MODEL(RIG_MODEL_DWT), .model_name = "Digital World Traveller", .mfg_name = "Coding Technologies", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DWT_FUNC, .has_set_func = DWT_FUNC, .has_get_level = DWT_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DWT_LEVEL_ALL), .has_get_parm = DWT_PARM_ALL, .has_set_parm = RIG_PARM_SET(DWT_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO, DWT_ANT}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO, DWT_ANT}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO, DWT_ANT}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO, DWT_ANT}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DWT_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(22)}, /* FIXME */ {RIG_MODE_AM, kHz(9)}, /* FIXME */ {RIG_MODE_WFM, kHz(230)}, /* FIXME */ RIG_FLT_END, }, .rig_init = dwtdll_init, .rig_cleanup = dwtdll_cleanup, .rig_open = dwtdll_open, .rig_close = dwtdll_close, .set_freq = dwtdll_set_freq, .get_freq = dwtdll_get_freq, .set_mode = dwtdll_set_mode, .get_mode = dwtdll_get_mode, .set_level = dwtdll_set_level, .get_level = dwtdll_get_level, .get_info = dwtdll_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int dwtdll_init(RIG *rig) { struct dwtdll_priv_data *priv; STATE(rig)->priv = (struct dwtdll_priv_data *)calloc(1, sizeof( struct dwtdll_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(DWTDLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, DWTDLL); free(STATE(rig)->priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->FrontendOpen = (FNCFrontendOpen) GetProcAddress(priv->dll, "FrontendOpen"); priv->FrontendClose = (FNCFrontendClose) GetProcAddress(priv->dll, "FrontendClose"); priv->FrontendGetId = (FNCFrontendGetId) GetProcAddress(priv->dll, "FrontendGetId"); priv->FrontendSetMode = (FNCFrontendSetMode) GetProcAddress(priv->dll, "FrontendSetMode"); priv->FrontendGetMode = (FNCFrontendGetMode) GetProcAddress(priv->dll, "FrontendGetMode"); priv->FrontendSetFrequency = (FNCFrontendSetFrequency) GetProcAddress(priv->dll, "FrontendSetFrequency"); priv->FrontendGetFrequency = (FNCFrontendGetFrequency) GetProcAddress(priv->dll, "FrontendGetFrequency"); priv->FrontendGetRfLevel = (FNCFrontendGetRfLevel) GetProcAddress(priv->dll, "FrontendGetRfLevel"); priv->FrontendGetLIF = (FNCFrontendGetLIF) GetProcAddress(priv->dll, "FrontendGetLIF"); priv->FrontendStartScan = (FNCFrontendStartScan) GetProcAddress(priv->dll, "FrontendStartScan"); priv->FrontendStopScan = (FNCFrontendStopScan) GetProcAddress(priv->dll, "FrontendStopScan"); priv->FrontendGetScanStatus = (FNCFrontendGetScanStatus) GetProcAddress(priv->dll, "FrontendGetScanStatus"); priv->FrontendSetRfAttenuator = (FNCFrontendSetRfAttenuator) GetProcAddress(priv->dll, "FrontendSetRfAttenuator"); priv->FrontendGetRfAttenuator = (FNCFrontendGetRfAttenuator) GetProcAddress(priv->dll, "FrontendGetRfAttenuator"); priv->FrontendSetAntennaMode = (FNCFrontendSetAntennaMode) GetProcAddress(priv->dll, "FrontendSetAntennaMode"); priv->FrontendGetAntennaMode = (FNCFrontendGetAntennaMode) GetProcAddress(priv->dll, "FrontendGetAntennaMode"); priv->FrontendSetFmMode = (FNCFrontendSetFmMode) GetProcAddress(priv->dll, "FrontendSetFmMode"); priv->FrontendGetFmMode = (FNCFrontendGetFmMode) GetProcAddress(priv->dll, "FrontendGetFmMode"); return RIG_OK; } int dwtdll_open(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; /* Open DWT receiver */ ret = priv->FrontendOpen(); if (ret < 0) { return -RIG_EIO; /* huh! */ } /* default to DRM mode */ ret = priv->FrontendSetMode(eFrontendModeDrm); if (ret < 0) { return -RIG_EIO; /* huh! */ } return RIG_OK; } int dwtdll_close(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; /* Open DWT receiver */ ret = priv->FrontendClose(); if (ret < 0) { return -RIG_EIO; /* huh! */ } return RIG_OK; } int dwtdll_cleanup(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; ret = priv->FrontendSetFrequency((double) freq); return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->FrontendGetFrequency(); return RIG_OK; } int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; tFrontendMode dwtmode; short ret; switch (mode) { case RIG_MODE_USB: dwtmode = eFrontendModeDrm; break; case RIG_MODE_AM: dwtmode = eFrontendModeAm; break; case RIG_MODE_WFM: dwtmode = eFrontendModeFm; break; default: return -RIG_EINVAL; } ret = priv->FrontendSetMode(dwtmode); return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; tFrontendMode dwtmode; dwtmode = priv->FrontendGetMode(); switch (dwtmode) { case eFrontendModeDrm: *mode = RIG_MODE_USB; break; case eFrontendModeAm: *mode = RIG_MODE_AM; break; case eFrontendModeFm: *mode = RIG_MODE_WFM; break; default: return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret = 0; switch (level) { case RIG_LEVEL_ATT: ret = priv->FrontendSetRfAttenuator(val.i ? 1 : 0); break; default: return -RIG_EINVAL; } return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; signed short ret = 0; switch (level) { case RIG_LEVEL_ATT: ret = priv->FrontendGetRfAttenuator(); if (ret < 0) { break; } /* local vs. DX mode */ val->i = ret ? 0 : rig->caps->attenuator[0]; break; case RIG_LEVEL_STRENGTH: /* actual RMS signal strength in dBuV */ ret = priv->FrontendGetRfLevel(); if (ret < 0) { break; } /* return actual RMS signal strength in dBuV, -34 to get dB rel S9 */ val->i = ret - 34; break; case RIG_LEVEL_RAWSTR: /* actual RMS signal strength in dBuV */ ret = priv->FrontendGetRfLevel(); if (ret < 0) { break; } val->i = ret; break; default: return -RIG_EINVAL; } return ret < 0 ? -RIG_EIO : RIG_OK; } static const char *dwtdll_get_info(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; static char info[22]; if (priv->FrontendGetId(info) < 0) { return NULL; } info[21] = '\0'; return info; } #elif defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "token.h" #define USB_VID_CT 0x1539 /* AFG Engineering */ #define USB_PID_CT_DWT 0x1730 /* Digital World Traveller */ #define DWT_MODES (RIG_MODE_NONE) #define DWT_FUNC (RIG_FUNC_NONE) #define DWT_LEVEL_ALL (RIG_LEVEL_NONE) #define DWT_PARM_ALL (RIG_PARM_NONE) #define DWT_VFO (RIG_VFO_A) static int dwt_init(RIG *rig); static int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static const char *dwt_get_info(RIG *rig); /* * Coding Technologies Digital World Traveller DRM tuner. * * The receiver is controlled via USB. * * see dsbr100.c as an example */ struct rig_caps dwt_caps = { RIG_MODEL(RIG_MODEL_DWT), .model_name = "Digital World Traveller", .mfg_name = "Coding Technologies", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DWT_FUNC, .has_set_func = DWT_FUNC, .has_get_level = DWT_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DWT_LEVEL_ALL), .has_get_parm = DWT_PARM_ALL, .has_set_parm = RIG_PARM_SET(DWT_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DWT_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(22)}, /* FIXME */ {RIG_MODE_AM, kHz(9)}, /* FIXME */ {RIG_MODE_WFM, kHz(230)}, /* FIXME */ RIG_FLT_END, }, .rig_init = dwt_init, .set_freq = dwt_set_freq, .get_info = dwt_get_info, }; int dwt_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); rp->parm.usb.vid = USB_VID_CT; rp->parm.usb.pid = USB_PID_CT_DWT; rp->parm.usb.conf = 1; rp->parm.usb.iface = 0; rp->parm.usb.alt = 0; return RIG_OK; } #define MSG_LEN 16 int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { libusb_device_handle *udh = RIGPORT(rig)->handle; int request, value, index; unsigned char buf[MSG_LEN] = { 0x4a, 0x00, 0x03, 0x00, 0xff, 0xff, 0x32 }; int requesttype, r; int ifreq = (int)(freq / 1000); /* FIXME */ requesttype = 0x00; request = 0x00; value = 0x00; index = 0x00; buf[8] = ifreq & 0xff; buf[7] = (ifreq >> 8) & 0xff; r = libusb_control_transfer(udh, requesttype, request, value, index, buf, 9, 1000); if (r < 0) { rig_debug(RIG_DEBUG_ERR, "libusb_control_transfer failed: %s\n", libusb_error_name(r)); return -RIG_EIO; } return RIG_OK; } /* Rem: not reentrant */ const char *dwt_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "Dev %04d", desc.bcdDevice); return buf; } #endif /* HAVE_LIBUSB */ hamlib-4.6.5/rigs/kit/Makefile.am0000664000175000017500000000175415056640443012252 AM_CFLAGS += $(LIBUSB_CFLAGS) # FIXME: compile usrp only if CXX available KITSRC = elektor304.c drt1.c dwt.c usrp.c elektor507.c dds60.c miniVNA.c \ si570avrusb.c si570avrusb.h funcube.c funcube.h fifisdr.c hiqsdr.c \ kit.c kit.h usrp_impl.h rs_hfiq.c if HAVE_USRP # Append to the already defined AM_CXXFLAGS that exists outside the conditional. AM_CXXFLAGS += $(USRP_CFLAGS) KITSRC += usrp_impl.cc libhamlib_kit_la_LINK = $(CXXLINK) $(libhamlib_kit_la_LDFLAGS) else # automake gets confused and invokes the C++ linker via libtool regardless # of whether or not HAVE_USRP enables the .cc source. This override forces # automake to invoke the C linker as no C++ is involved: libhamlib_kit_la_LINK = $(LINK) $(libhamlib_kit_la_LDFLAGS) endif KITROTSRC = pcrotor.c noinst_LTLIBRARIES = libhamlib-kit.la libhamlib_kit_la_SOURCES = $(KITSRC) $(KITROTSRC) libhamlib_kit_la_LIBADD = $(USRP_LIBS) $(LIBUSB_LIBS) $(MATH_LIBS) EXTRA_DIST = README.funcubedongle Android.mk hamlib-4.6.5/rigs/lowe/0000775000175000017500000000000015056640477010455 5hamlib-4.6.5/rigs/lowe/hf235.c0000664000175000017500000000677615056640443011401 /* * Hamlib Lowe backend - HF-235 description * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "lowe.h" #define HF235_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) #define HF235_FUNC (RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define HF235_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define HF235_PARM_ALL (RIG_PARM_NONE) #define HF235_VFO (RIG_VFO_A) #define HF235_VFO_OPS (RIG_OP_NONE) /* * HF-235 rig capabilities. * */ struct rig_caps hf235_caps = { RIG_MODEL(RIG_MODEL_HF235), .model_name = "HF-235", .mfg_name = "Lowe", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, /* and only basic support */ .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = HF235_FUNC, .has_set_func = HF235_FUNC, .has_get_level = HF235_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(HF235_LEVEL_ALL), .has_get_parm = HF235_PARM_ALL, .has_set_parm = RIG_PARM_SET(HF235_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = HF235_VFO_OPS, .chan_list = { RIG_CHAN_END, /* FIXME */ }, .rx_range_list1 = { {kHz(30), MHz(30), HF235_MODES, -1, -1, HF235_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), HF235_MODES, -1, -1, HF235_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {HF235_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = NULL, .set_freq = lowe_set_freq, .get_freq = lowe_get_freq, .set_mode = lowe_set_mode, .get_mode = lowe_get_mode, //.set_func = lowe_set_func, .get_level = lowe_get_level, .reset = lowe_reset, .get_info = lowe_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/lowe/Android.mk0000664000175000017500000000037615056640443012305 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := hf235.c lowe.c LOCAL_MODULE := lowe LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/lowe/Makefile.in0000664000175000017500000005262315056640452012443 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/lowe ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_lowe_la_LIBADD = am__objects_1 = hf235.lo lowe.lo am_libhamlib_lowe_la_OBJECTS = $(am__objects_1) libhamlib_lowe_la_OBJECTS = $(am_libhamlib_lowe_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/hf235.Plo ./$(DEPDIR)/lowe.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_lowe_la_SOURCES) DIST_SOURCES = $(libhamlib_lowe_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ LOWESRC = hf235.c lowe.c lowe.h noinst_LTLIBRARIES = libhamlib-lowe.la libhamlib_lowe_la_SOURCES = $(LOWESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/lowe/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/lowe/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-lowe.la: $(libhamlib_lowe_la_OBJECTS) $(libhamlib_lowe_la_DEPENDENCIES) $(EXTRA_libhamlib_lowe_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_lowe_la_OBJECTS) $(libhamlib_lowe_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hf235.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lowe.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/hf235.Plo -rm -f ./$(DEPDIR)/lowe.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/hf235.Plo -rm -f ./$(DEPDIR)/lowe.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/lowe/lowe.c0000664000175000017500000001705715056640443011512 /* * Hamlib Lowe backend - main file * Copyright (c) 2003-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "lowe.h" #define BUFSZ 64 #define CR "\x0d" #define EOM CR #define MD_USB "USB" #define MD_LSB "LSB" #define MD_FAX "FAX" #define MD_CW "CW" #define MD_FM "FM" #define MD_AM "AM" #define MD_AMS "AMS" /* * lowe_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int lowe_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * lowe_set_freq * Assumes rig!=NULL */ int lowe_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16], ackbuf[16]; int ack_len, retval; /* */ SNPRINTF(freqbuf, sizeof(freqbuf), "FRQ%f" EOM, (float)freq / 1000); retval = lowe_transaction(rig, freqbuf, strlen(freqbuf), ackbuf, &ack_len); return retval; } /* * lowe_get_freq * Assumes rig!=NULL */ int lowe_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[16]; int freq_len, retval; double f_freq; retval = lowe_transaction(rig, "FRQ?" EOM, 5, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } freqbuf[freq_len < 16 ? freq_len : 15] = '\0'; sscanf(freqbuf + 1, "%lf", &f_freq); *freq = f_freq * 1000; return retval; } /* * lowe_set_mode * Assumes rig!=NULL */ int lowe_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[16], ackbuf[16]; char *mode_sel; int ack_len, retval; switch (mode) { case RIG_MODE_CW: mode_sel = MD_CW; break; case RIG_MODE_USB: mode_sel = MD_USB; break; case RIG_MODE_LSB: mode_sel = MD_LSB; break; case RIG_MODE_FM: mode_sel = MD_FM; break; case RIG_MODE_AM: mode_sel = MD_AM; break; case RIG_MODE_FAX: mode_sel = MD_FAX; break; case RIG_MODE_AMS: mode_sel = MD_AMS; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "MOD%s" EOM, mode_sel); retval = lowe_transaction(rig, mdbuf, strlen(mdbuf), ackbuf, &ack_len); return retval; } /* * lowe_get_mode * Assumes rig!=NULL */ int lowe_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char mdbuf[16]; int mdbuf_len, retval; retval = lowe_transaction(rig, "MOD?" EOM, 5, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (!strcmp(mdbuf + 1, MD_CW)) { *mode = RIG_MODE_CW; } else if (!strcmp(mdbuf + 1, MD_USB)) { *mode = RIG_MODE_USB; } else if (!strcmp(mdbuf + 1, MD_LSB)) { *mode = RIG_MODE_LSB; } else if (!strcmp(mdbuf + 1, MD_FM)) { *mode = RIG_MODE_FM; } else if (!strcmp(mdbuf + 1, MD_FAX)) { *mode = RIG_MODE_FAX; } else if (!strcmp(mdbuf + 1, MD_AMS)) { *mode = RIG_MODE_AMS; } else if (!strcmp(mdbuf + 1, MD_AM)) { *mode = RIG_MODE_AM; } else { rig_debug(RIG_DEBUG_WARN, "%s: unknown mode '%s'\n", __func__, mdbuf); return -RIG_EPROTO; } *width = RIG_PASSBAND_NORMAL; return retval; } /* * lowe_get_level * Assumes rig!=NULL */ int lowe_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[16]; int lvl_len, retval; if (level != RIG_LEVEL_STRENGTH) { return -RIG_EINVAL; } retval = lowe_transaction(rig, "RSS?" EOM, 5, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } lvlbuf[lvl_len < 16 ? lvl_len : 15] = '\0'; sscanf(lvlbuf + 1, "%d", &val->i); val->i += 60; /* dBm */ return retval; } /* * lowe_reset * Assumes rig!=NULL */ int lowe_reset(RIG *rig, reset_t reset) { static char ackbuf[BUFSZ]; int retval, ack_len; retval = lowe_transaction(rig, "RES" EOM, 4, ackbuf, &ack_len); return retval; } /* * lowe_get_info * Assumes rig!=NULL */ const char *lowe_get_info(RIG *rig) { static char idbuf[BUFSZ]; int retval, id_len; /* hack: no idea what INF is for */ retval = lowe_transaction(rig, "INF?" EOM, 5, idbuf, &id_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: INF didn't work\n", __func__); // non-fatal } /* this is the real one */ retval = lowe_transaction(rig, "TYP?" EOM, 5, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } idbuf[id_len] = '\0'; return idbuf; } /* * probe_lowe(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(lowe) { static char idbuf[BUFSZ]; int retval, id_len; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->parm.serial.rate = hf235_caps.serial_rate_max; port->write_delay = port->post_write_delay = 0; port->timeout = 50; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "TYP?" EOM, 4); id_len = read_string(port, (unsigned char *) idbuf, BUFSZ, CR, 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len <= 0 || id_len >= BUFSZ) { return RIG_MODEL_NONE; } idbuf[id_len] = '\0'; if (!strcmp(idbuf, "HF-235")) { if (cfunc) { (*cfunc)(port, RIG_MODEL_HF235, data); } return RIG_MODEL_HF235; } /* * not found... */ if (memcmp(idbuf, "ID" EOM, 3)) /* catch loopback serial */ rig_debug(RIG_DEBUG_VERBOSE, "probe_lowe: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf); return RIG_MODEL_NONE; } /* * initrigs_lowe is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(lowe) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&hf235_caps); return RIG_OK; } hamlib-4.6.5/rigs/lowe/lowe.h0000664000175000017500000000260315056640443011506 /* * Hamlib Lowe backend - main header * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _LOWE_H #define _LOWE_H 1 #include #define BACKEND_VER "20200112" int lowe_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int lowe_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int lowe_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int lowe_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int lowe_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int lowe_reset(RIG *rig, reset_t reset); const char *lowe_get_info(RIG *rig); extern struct rig_caps hf235_caps; #endif /* _LOWE_H */ hamlib-4.6.5/rigs/lowe/Makefile.am0000664000175000017500000000021015056640443012413 LOWESRC = hf235.c lowe.c lowe.h noinst_LTLIBRARIES = libhamlib-lowe.la libhamlib_lowe_la_SOURCES = $(LOWESRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/flexradio/0000775000175000017500000000000015056640476011463 5hamlib-4.6.5/rigs/flexradio/flexradio.c0000664000175000017500000000340415056640443013517 /* * Hamlib Flexradio backend * Copyright (c) 2003-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "flexradio.h" #include "register.h" #ifdef HAVE_NETINET_IN_H # include #endif #if HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_SYS_IOCTL_H) # include # include #endif DECLARE_INITRIG_BACKEND(flexradio) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rig_register(&sdr1k_rig_caps); //rig_register(&sdr1krfe_rig_caps); rig_register(&dttsp_rig_caps); rig_register(&dttsp_udp_rig_caps); rig_register(&smartsdr_a_rig_caps); rig_register(&smartsdr_b_rig_caps); rig_register(&smartsdr_c_rig_caps); rig_register(&smartsdr_d_rig_caps); rig_register(&smartsdr_e_rig_caps); rig_register(&smartsdr_f_rig_caps); rig_register(&smartsdr_g_rig_caps); rig_register(&smartsdr_h_rig_caps); return RIG_OK; } hamlib-4.6.5/rigs/flexradio/sdr1k.c0000664000175000017500000003105415056640443012570 /* * Hamlib backend - SDR-1000 * Copyright (c) 2003-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "parallel.h" #include "misc.h" #include "bandplan.h" static int sdr1k_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int sdr1k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int sdr1k_reset(RIG *rig, reset_t reset); static int sdr1k_init(RIG *rig); static int sdr1k_open(RIG *rig); static int sdr1k_close(RIG *rig); static int sdr1k_cleanup(RIG *rig); static int sdr1k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); typedef enum { L_EXT = 0, L_BAND = 1, L_DDS0 = 2, L_DDS1 = 3 } latch_t; #define TR 0x40 #define MUTE 0x80 #define GAIN 0x80 #define WRB 0x40 #define RESET 0x80 /* DDS Control Constants */ #define COMP_PD 0x10 /* DDS Comparator power down */ #define DIG_PD 0x01 /* DDS Digital Power down */ #define BYPASS_PLL 0x20 /* Bypass DDS PLL */ #define INT_IOUD 0x01 /* Internal IO Update */ #define OSK_EN 0x20 /* Offset Shift Keying enable */ #define OSK_INT 0x10 /* Offset Shift Keying */ #define BYPASS_SINC 0x40 /* Bypass Inverse Sinc Filter */ #define PLL_RANGE 0x40 /* Set PLL Range */ static int write_latch(RIG *rig, latch_t which, unsigned value, unsigned mask); static int dds_write_reg(RIG *rig, unsigned addr, unsigned data); static int set_bit(RIG *rig, latch_t reg, unsigned bit, unsigned state); #define DEFAULT_XTAL MHz(200) #define DEFAULT_PLL_MULT 1 #define DEFAULT_DAC_MULT 4095 struct sdr1k_priv_data { unsigned shadow[4]; /* shadow latches */ freq_t dds_freq; /* current freq */ freq_t xtal; /* base XTAL */ int pll_mult; /* PLL mult */ }; #define SDR1K_FUNC RIG_FUNC_MUTE #define SDR1K_LEVEL RIG_LEVEL_PREAMP #define SDR1K_PARM RIG_PARM_NONE #define SDR1K_MODES (RIG_MODE_USB|RIG_MODE_CW) #define SDR1K_VFO RIG_VFO_A #define SDR1K_ANTS 0 /* ************************************************************************* */ /* * http://www.flex-radio.com * SDR-1000 rig capabilities. * * * TODO: RIG_FUNC_MUTE, set_external_pin? * * def set_mute (self, mute = 1): * self.set_bit(1, 7, mute) * * def set_unmute (self): * self.set_bit(1, 7, 0) * * def set_external_pin (self, pin, on = 1): * assert (pin < 8 and pin > 0), "Out of range 1..7" * self.set_bit(0, pin-1, on) * * def read_input_pin * * set_conf(XTAL,PLL_mult,spur_red) * * What about IOUD_Clock? */ struct rig_caps sdr1k_rig_caps = { RIG_MODEL(RIG_MODEL_SDR1000), .model_name = "SDR-1000", .mfg_name = "FlexRadio", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_PARALLEL, .has_get_func = SDR1K_FUNC, .has_set_func = SDR1K_FUNC, .has_get_level = SDR1K_LEVEL, .has_set_level = RIG_LEVEL_SET(SDR1K_LEVEL), .has_get_parm = SDR1K_PARM, .has_set_parm = RIG_PARM_SET(SDR1K_PARM), .chan_list = { RIG_CHAN_END, }, .scan_ops = RIG_SCAN_NONE, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { 14, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = Hz(1), .endf = MHz(65), .modes = SDR1K_MODES, .low_power = -1, .high_power = -1, SDR1K_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { /* restricted to ham band */ FRQ_RNG_HF(1, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), FRQ_RNG_6m(1, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { { .startf = Hz(1), .endf = MHz(65), .modes = SDR1K_MODES, .low_power = -1, .high_power = -1, SDR1K_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { /* restricted to ham band */ FRQ_RNG_HF(2, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), FRQ_RNG_6m(2, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), RIG_FRNG_END, }, .tuning_steps = { {SDR1K_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* priv */ .rig_init = sdr1k_init, .rig_open = sdr1k_open, .rig_close = sdr1k_close, .rig_cleanup = sdr1k_cleanup, .set_freq = sdr1k_set_freq, .get_freq = sdr1k_get_freq, .set_ptt = sdr1k_set_ptt, .reset = sdr1k_reset, .set_level = sdr1k_set_level, // .set_func = sdr1k_set_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ************************************************************************* */ int sdr1k_init(RIG *rig) { struct sdr1k_priv_data *priv; struct rig_state *rs = STATE(rig); rs->priv = (struct sdr1k_priv_data *)calloc(1, sizeof( struct sdr1k_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = rs->priv; priv->dds_freq = RIG_FREQ_NONE; priv->xtal = DEFAULT_XTAL; priv->pll_mult = DEFAULT_PLL_MULT; return RIG_OK; } static void pdelay(RIG *rig) { unsigned char r; par_read_data(RIGPORT(rig), &r); /* ~1us */ } int sdr1k_open(RIG *rig) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; priv->shadow[0] = 0; priv->shadow[1] = 0; priv->shadow[2] = 0; priv->shadow[3] = 0; sdr1k_reset(rig, 1); return RIG_OK; } int sdr1k_close(RIG *rig) { /* TODO: release relays? */ return RIG_OK; } int sdr1k_cleanup(RIG *rig) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; if (priv) { free(priv); } STATE(rig)->priv = NULL; return RIG_OK; } static int set_band(RIG *rig, freq_t freq) { int band, ret; /* set_band */ if (freq <= MHz(2.25)) { band = 0; } else if (freq <= MHz(5.5)) { band = 1; } else if (freq <= MHz(11)) { band = 3; /* due to wiring mistake on board */ } else if (freq <= MHz(22)) { band = 2; /* due to wiring mistake on board */ } else if (freq <= MHz(37.5)) { band = 4; } else { band = 5; } ret = write_latch(rig, L_BAND, 1 << band, 0x3f); // cppcheck-suppress * rig_debug(RIG_DEBUG_VERBOSE, "%s %"PRIll" band %d\n", __func__, (int64_t)freq, band); return ret; } /* * set DDS frequency. * NB: due to spur reduction, effective frequency might not be the expected one */ int sdr1k_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; int i; double ftw; double DDS_step_size; freq_t frqval; // why is spur_red always true? // int spur_red = 1; #define spur_red 1 int ret; ret = set_band(rig, freq); if (ret != RIG_OK) { return ret; } /* Calculate DDS step for spu reduction * DDS steps = 3051.7578125Hz */ DDS_step_size = ((double)priv->xtal * priv->pll_mult) / 65536; rig_debug(RIG_DEBUG_VERBOSE, "%s DDS step size %g %g %g\n", __func__, DDS_step_size, (double)freq / DDS_step_size, rint((double)freq / DDS_step_size)); // why is spur_red always true? if (spur_red) { frqval = (freq_t)(DDS_step_size * rint((double)freq / DDS_step_size)); } else { frqval = freq; } rig_debug(RIG_DEBUG_VERBOSE, "%s curr %"PRIll" frqval %"PRIll"\n", __func__, (int64_t)freq, (int64_t)frqval); if (priv->dds_freq == frqval) { return RIG_OK; } /*** */ ftw = (double)frqval / priv->xtal ; for (i = 0; i < 6; i++) { unsigned word; if (spur_red && i == 2) { word = 128; } else if (spur_red && i > 2) { word = 0; } else { word = (unsigned)(ftw * 256); ftw = ftw * 256 - word; } rig_debug(RIG_DEBUG_TRACE, "DDS %d [%02x]\n", i, word); ret = dds_write_reg(rig, 4 + i, word); if (ret != RIG_OK) { return ret; } } priv->dds_freq = frqval; return ret; } int sdr1k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; *freq = priv->dds_freq; rig_debug(RIG_DEBUG_TRACE, "%s: %"PRIll"\n", __func__, (int64_t)priv->dds_freq); return RIG_OK; } /* Set DAC multiplier value */ static int DAC_mult(RIG *rig, unsigned mult) { rig_debug(RIG_DEBUG_TRACE, "DAC [%02x,%02x]\n", mult >> 8, mult & 0xff); /* Output Shape Key I Mult */ dds_write_reg(rig, 0x21, mult >> 8); dds_write_reg(rig, 0x22, mult & 0xff); /* Output Shape Key Q Mult */ dds_write_reg(rig, 0x23, mult >> 8); dds_write_reg(rig, 0x24, mult & 0xff); return RIG_OK; } int sdr1k_reset(RIG *rig, reset_t reset) { /* Reset all Latches (relays off) */ write_latch(rig, L_BAND, 0x00, 0xff); write_latch(rig, L_DDS1, 0x00, 0xff); write_latch(rig, L_DDS0, 0x00, 0xff); write_latch(rig, L_EXT, 0x00, 0xff); /* Reset DDS */ write_latch(rig, L_DDS1, RESET | WRB, 0xff); /* reset the DDS chip */ write_latch(rig, L_DDS1, WRB, 0xff); /* leave WRB high */ dds_write_reg(rig, 0x1d, COMP_PD); /* Power down comparator */ /* TODO: add PLL multiplier property and logic */ dds_write_reg(rig, 0x1e, BYPASS_PLL); /* Bypass PLL */ dds_write_reg(rig, 0x20, BYPASS_SINC | OSK_EN); /* Bypass Inverse Sinc and enable DAC */ DAC_mult(rig, DEFAULT_DAC_MULT); /* Set DAC multiplier value */ return RIG_OK; } int sdr1k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { return set_bit(rig, L_BAND, 6, ptt == RIG_PTT_ON); } int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: %s %d\n", __func__, rig_strlevel(level), val.i); switch (level) { case RIG_LEVEL_PREAMP: return set_bit(rig, L_EXT, 7, !(val.i == rig->caps->preamp[0])); break; default: return -RIG_EINVAL; } } int write_latch(RIG *rig, latch_t which, unsigned value, unsigned mask) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; hamlib_port_t *pport = RIGPORT(rig); if (!(L_EXT <= which && which <= L_DDS1)) { return -RIG_EINVAL; } par_lock(pport); priv->shadow[which] = (priv->shadow[which] & ~mask) | (value & mask); par_write_data(pport, priv->shadow[which]); pdelay(rig); par_write_control(pport, 0x0F ^ (1 << which)); pdelay(rig); par_write_control(pport, 0x0F); pdelay(rig); par_unlock(pport); return RIG_OK; } int dds_write_reg(RIG *rig, unsigned addr, unsigned data) { #if 0 write_latch(rig, L_DDS1, addr & 0x3f, 0x3f); write_latch(rig, L_DDS0, data, 0xff); write_latch(rig, L_DDS1, 0x40, 0x40); write_latch(rig, L_DDS1, 0x00, 0x40); #else /* set up data bits */ write_latch(rig, L_DDS0, data, 0xff); /* set up address bits with WRB high */ //write_latch (rig, L_DDS1, addr & 0x3f, 0x3f); write_latch(rig, L_DDS1, WRB | addr, 0xff); /* send write command with WRB low */ write_latch(rig, L_DDS1, addr, 0xff); /* return WRB high */ write_latch(rig, L_DDS1, WRB, 0xff); #endif return RIG_OK; } int set_bit(RIG *rig, latch_t reg, unsigned bit, unsigned state) { unsigned val; val = state ? 1 << bit : 0; return write_latch(rig, reg, val, 1 << bit); } hamlib-4.6.5/rigs/flexradio/dttsp.c0000664000175000017500000006010715056640443012703 /* * Hamlib DttSP backend - main file * Copyright (c) 2001-2012 by Stephane Fillod * * Some code derived from DttSP * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by Frank Brickle, AB2KT and Bob McGwier, N4HY * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "hamlib/rig.h" #include "iofunc.h" #include "misc.h" #include "token.h" #include "cal.h" /* * This backend is a two layer rig control: DttSP core over a mundane tuner * * 2 interfaces of DttSP are supported: IPC & UDP * * TODO: Transmit setup * http://openhpsdr.org/wiki/index.php?title=Ghpsdr */ #define DEFAULT_DTTSP_CMD_PATH "/dev/shm/SDRcommands" #define DEFAULT_DTTSP_CMD_NET_ADDR "127.0.0.1:19001" #define DEFAULT_SAMPLE_RATE 48000 /* DttSP constants */ #define MAXRX 4 #define RXMETERPTS 5 #define TXMETERPTS 9 #define MAXMETERPTS 9 #define DTTSP_PORT_CLIENT_COMMAND 19001 #define DTTSP_PORT_CLIENT_SPECTRUM 19002 #define DTTSP_PORT_CLIENT_METER 19003 #define DTTSP_PORT_CLIENT_BUFSIZE 65536 struct dttsp_priv_data { /* tuner providing IF */ rig_model_t tuner_model; RIG *tuner; shortfreq_t IF_center_freq; int sample_rate; int rx_delta_f; hamlib_port_t meter_port; }; static int dttsp_init(RIG *rig); static int dttsp_cleanup(RIG *rig); static int dttsp_open(RIG *rig); static int dttsp_close(RIG *rig); static int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dttsp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int dttsp_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int dttsp_get_conf(RIG *rig, hamlib_token_t token, char *val); static int dttsp_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int dttsp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int dttsp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int dttsp_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int dttsp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int dttsp_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); #define TOK_TUNER_MODEL TOKEN_BACKEND(1) #define TOK_SAMPLE_RATE TOKEN_BACKEND(2) const struct confparams dttsp_cfg_params[] = { { TOK_TUNER_MODEL, "tuner_model", "Tuner model", "Hamlib rig tuner model number", "1" /* RIG_MODEL_DUMMY */, RIG_CONF_NUMERIC, { /* .n = */ { 0, 100000, 1 } } }, { TOK_SAMPLE_RATE, "sample_rate", "Sample rate", "DttSP sample rate in Spls/sec", "48000", RIG_CONF_NUMERIC, { /* .n = */ { 8000, 192000, 1 } } }, /* * TODO: IF_center_freq, etc. */ { RIG_CONF_END, NULL, } }; /* * DttSP dsr-core rig capabilities. */ #define DTTSP_FUNC (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_NR|RIG_FUNC_MUTE) #define DTTSP_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AGC) #define DTTSP_PARM RIG_PARM_NONE #define DTTSP_VFO_OP RIG_OP_NONE #define DTTSP_SCAN RIG_SCAN_NONE #define DTTSP_VFO (RIG_VFO_A) #define DTTSP_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_SAM|RIG_MODE_DSB| \ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB) enum dttsp_mode_e { LSB, USB, DSB, CWL, CWU, FMN, AM, DIGU, SPEC, DIGL, SAM, DRM }; static const struct hamlib_vs_dttsp { rmode_t hamlib_mode; enum dttsp_mode_e dttsp_mode; } hamlib_vs_dttsp_modes[] = { { RIG_MODE_USB, USB }, { RIG_MODE_LSB, LSB }, { RIG_MODE_CW, CWU }, { RIG_MODE_CWR, CWL }, { RIG_MODE_AM, AM }, { RIG_MODE_SAM, SAM }, { RIG_MODE_FM, FMN }, { RIG_MODE_DSB, DSB }, }; #define HAMLIB_VS_DTTSP_MODES_COUNT (sizeof(hamlib_vs_dttsp_modes)/sizeof(struct hamlib_vs_dttsp)) #define DTTSP_REAL_STR_CAL { 16, \ { \ { -73, -73 }, /* S0 */ \ { 50, 40 }, /* +40 */ \ } } struct rig_caps dttsp_rig_caps = { RIG_MODEL(RIG_MODEL_DTTSP), .model_name = "DttSP IPC", .mfg_name = "DTTS Microwave Society", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .targetable_vfo = RIG_TARGETABLE_ALL, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_DEVICE, .has_get_func = DTTSP_FUNC, .has_set_func = DTTSP_FUNC, .has_get_level = DTTSP_LEVEL, .has_set_level = RIG_LEVEL_SET(DTTSP_LEVEL), .has_get_parm = DTTSP_PARM, .has_set_parm = RIG_PARM_SET(DTTSP_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = DTTSP_SCAN, .vfo_ops = DTTSP_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { RIG_DBLST_END, }, /* In fact, RX and TX ranges are dependent on the tuner */ .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* TODO */ .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* TODO */ .tuning_steps = { {DTTSP_MODES, 1}, {DTTSP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_DSB | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, {DTTSP_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .str_cal = DTTSP_REAL_STR_CAL, .priv = NULL, .rig_init = dttsp_init, .rig_cleanup = dttsp_cleanup, .rig_open = dttsp_open, .rig_close = dttsp_close, .cfgparams = dttsp_cfg_params, .set_conf = dttsp_set_conf, .get_conf = dttsp_get_conf, .set_freq = dttsp_set_freq, .get_freq = dttsp_get_freq, .set_mode = dttsp_set_mode, .set_level = dttsp_set_level, .get_level = dttsp_get_level, .set_func = dttsp_set_func, .set_rit = dttsp_set_rit, .get_rit = dttsp_get_rit, .set_ant = dttsp_set_ant, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * The same as the previous IPC, but of type RIG_PORT_UDP_NETWORK */ struct rig_caps dttsp_udp_rig_caps = { RIG_MODEL(RIG_MODEL_DTTSP_UDP), .model_name = "DttSP UDP", .mfg_name = "DTTS Microwave Society", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .targetable_vfo = RIG_TARGETABLE_ALL, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 500, .has_get_func = DTTSP_FUNC, .has_set_func = DTTSP_FUNC, .has_get_level = DTTSP_LEVEL, .has_set_level = RIG_LEVEL_SET(DTTSP_LEVEL), .has_get_parm = DTTSP_PARM, .has_set_parm = RIG_PARM_SET(DTTSP_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = DTTSP_SCAN, .vfo_ops = DTTSP_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { RIG_DBLST_END, }, /* In fact, RX and TX ranges are dependent on the tuner */ .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* TODO */ .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* TODO */ .tuning_steps = { {DTTSP_MODES, 1}, {DTTSP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_DSB | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, {DTTSP_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .str_cal = DTTSP_REAL_STR_CAL, .priv = NULL, .rig_init = dttsp_init, .rig_cleanup = dttsp_cleanup, .rig_open = dttsp_open, .rig_close = dttsp_close, .cfgparams = dttsp_cfg_params, .set_conf = dttsp_set_conf, .get_conf = dttsp_get_conf, .set_freq = dttsp_set_freq, .get_freq = dttsp_get_freq, .set_mode = dttsp_set_mode, .set_level = dttsp_set_level, .get_level = dttsp_get_level, .set_func = dttsp_set_func, .set_rit = dttsp_set_rit, .get_rit = dttsp_get_rit, .set_ant = dttsp_set_ant, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int send_command(RIG *rig, const char *cmdstr, size_t buflen) { int ret; ret = write_block(RIGPORT(rig), (unsigned char *) cmdstr, buflen); return ret; } static int fetch_meter(RIG *rig, int *label, float *data, int npts) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret, buf_len; if (priv->meter_port.type.rig == RIG_PORT_UDP_NETWORK) { char buf[sizeof(float)*MAXMETERPTS * MAXRX]; buf_len = sizeof(buf); ret = read_block(&priv->meter_port, (unsigned char *) buf, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } /* copy payload back to client space */ memcpy((void *) label, buf, sizeof(int)); memcpy((void *) data, buf + sizeof(int), npts * sizeof(float)); } else { /* IPC */ buf_len = sizeof(int); ret = read_block(&priv->meter_port, (unsigned char *) label, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } if (ret < 0) { return ret; } buf_len = (int) sizeof(float) * npts; if (sizeof(float) != 4) { rig_debug(RIG_DEBUG_ERR, "%s: sizeof(float)!=4, instead = %d\n", __func__, (int)sizeof(float)); return -RIG_EINTERNAL; } ret = read_block(&priv->meter_port, (unsigned char *) data, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } if (ret < 0) { return ret; } } return ret; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int dttsp_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dttsp_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct dttsp_priv_data *)rs->priv; switch (token) { case TOK_TUNER_MODEL: priv->tuner_model = atoi(val); break; case TOK_SAMPLE_RATE: priv->sample_rate = atoi(val); break; default: /* if it's not for the dttsp backend, maybe it's for the tuner */ if (priv->tuner) { return rig_set_conf(priv->tuner, token, val); } else { return -RIG_EINVAL; } } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int dttsp_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct dttsp_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct dttsp_priv_data *)rs->priv; switch (token) { case TOK_TUNER_MODEL: SNPRINTF(val, val_len, "%u", priv->tuner_model); break; case TOK_SAMPLE_RATE: SNPRINTF(val, val_len, "%d", priv->sample_rate); break; default: /* if it's not for the dttsp backend, maybe it's for the tuner */ if (priv->tuner) { return rig_get_conf(priv->tuner, token, val); } else { return -RIG_EINVAL; } } return RIG_OK; } int dttsp_get_conf(RIG *rig, hamlib_token_t token, char *val) { return dttsp_get_conf2(rig, token, val, 128); } int dttsp_init(RIG *rig) { struct dttsp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); const char *cmdpath; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct dttsp_priv_data *)calloc(1, sizeof(struct dttsp_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->tuner = NULL; priv->tuner_model = RIG_MODEL_DUMMY; priv->IF_center_freq = 0; p = getenv("SDR_DEFRATE"); if (p) { priv->sample_rate = atoi(p); } else { priv->sample_rate = DEFAULT_SAMPLE_RATE; } cmdpath = getenv("SDR_PARMPATH"); if (!cmdpath) cmdpath = rp->type.rig == RIG_PORT_UDP_NETWORK ? DEFAULT_DTTSP_CMD_NET_ADDR : DEFAULT_DTTSP_CMD_PATH; strncpy(rp->pathname, cmdpath, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int dttsp_open(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret; char *p; char *meterpath; hamlib_port_t *rp = RIGPORT(rig); struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * prevent l8ps */ if (priv->tuner_model == RIG_MODEL_DTTSP || priv->tuner_model == RIG_MODEL_DTTSP_UDP) { return -RIG_ECONF; } priv->tuner = rig_init(priv->tuner_model); if (!priv->tuner) { /* FIXME: wrong rig model? */ return -RIG_ENOMEM; } ret = rig_open(priv->tuner); if (ret != RIG_OK) { rig_cleanup(priv->tuner); priv->tuner = NULL; return ret; } /* open DttSP meter pipe */ priv->meter_port.post_write_delay = rp->post_write_delay; priv->meter_port.timeout = rp->timeout; priv->meter_port.retry = rp->retry; p = getenv("SDR_METERPATH"); if (!p) { meterpath = priv->meter_port.pathname; SNPRINTF(meterpath, HAMLIB_FILPATHLEN, "%s", rp->pathname); if (rp->type.rig == RIG_PORT_UDP_NETWORK) { p = strrchr(meterpath, ':'); if (p) { strcpy(p + 1, "19003"); } else { strcat(meterpath, ":19003"); } p = meterpath; } else { p = strrchr(meterpath, '/'); if (p) { strcpy(p + 1, "SDRmeter"); } } } if (!p) { /* disabled */ priv->meter_port.fd = -1; } else { priv->meter_port.type.rig = rp->type.rig; ret = port_open(&priv->meter_port); if (ret < 0) { return ret; } } /* TODO: * copy priv->tuner->rx_range/tx_range to rig->state */ #if 1 rs->has_set_func |= STATE(priv->tuner)->has_set_func; rs->has_get_func |= STATE(priv->tuner)->has_get_func; rs->has_set_level |= STATE(priv->tuner)->has_set_level; rs->has_get_level |= STATE(priv->tuner)->has_get_level; rs->has_set_parm |= STATE(priv->tuner)->has_set_parm; rs->has_get_parm |= STATE(priv->tuner)->has_get_parm; #endif /* Because model dummy has funky init value */ if (priv->tuner_model == RIG_MODEL_DUMMY) { dttsp_set_freq(rig, RIG_VFO_CURR, priv->IF_center_freq); } dttsp_set_func(rig, RIG_VFO_CURR, RIG_FUNC_MUTE, 0); return RIG_OK; } int dttsp_close(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); port_close(&priv->meter_port, priv->meter_port.type.rig); rig_close(priv->tuner); return RIG_OK; } int dttsp_cleanup(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (priv && priv->tuner) { rig_cleanup(priv->tuner); priv->tuner = NULL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_set_freq is a good candidate for the GNUradio GUI setFrequency callback? */ int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; freq_t tuner_freq; int ret; char fstr[20]; char buf[32]; shortfreq_t max_delta; freq_t freq_offset; max_delta = priv->sample_rate / 2 - kHz(2); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } freq_offset = freq - tuner_freq; /* TODO: take into account the mode width and the IF dead zone */ if (fabs(freq_offset) > max_delta) { tuner_freq = priv->IF_center_freq + freq - kHz(6); ret = rig_set_freq(priv->tuner, RIG_VFO_CURR, tuner_freq); if (ret != RIG_OK) { return ret; } /* reread the tuner freq because some rigs can't tune to exact frequency. * The rx_delta_f will correct that */ ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } } priv->rx_delta_f = freq - tuner_freq; sprintf_freq(fstr, sizeof(fstr), tuner_freq); rig_debug(RIG_DEBUG_TRACE, "%s: tuner=%s, rx_delta=%d Hz\n", __func__, fstr, priv->rx_delta_f); /* setRxFrequenc */ SNPRINTF(buf, sizeof(buf), "setOsc %d\n", priv->rx_delta_f); ret = send_command(rig, buf, strlen(buf)); return ret; } int dttsp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; freq_t tuner_freq; int ret; ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *freq = tuner_freq - priv->rx_delta_f; return RIG_OK; } static enum dttsp_mode_e rmode2dttsp(rmode_t mode) { int i; for (i = 0; i < HAMLIB_VS_DTTSP_MODES_COUNT; i++) { if (hamlib_vs_dttsp_modes[i].hamlib_mode == mode) { return hamlib_vs_dttsp_modes[i].dttsp_mode; } } return 0; } /* * WIP */ int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32]; int ret = RIG_OK; int filter_l, filter_h; /* DttSP set mode */ SNPRINTF(buf, sizeof(buf), "setMode %d\n", rmode2dttsp(mode)); ret = send_command(rig, buf, strlen(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, buf); if (ret != RIG_OK || RIG_PASSBAND_NOCHANGE == width) { return ret; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } sprintf_freq(buf, sizeof(buf), width); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strrmode(mode), buf); switch (mode) { case RIG_MODE_USB: case RIG_MODE_CW: filter_l = 10; filter_h = width; break; case RIG_MODE_LSB: case RIG_MODE_CWR: filter_l = -width; filter_h = -10; break; case RIG_MODE_AM: case RIG_MODE_SAM: case RIG_MODE_FM: case RIG_MODE_DSB: filter_l = -width / 2; filter_h = width / 2; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "setFilter %d %d\n", filter_l, filter_h); ret = send_command(rig, buf, strlen(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, buf); return ret; } static int agc_level2dttsp(enum agc_level_e agc) { switch (agc) { case RIG_AGC_OFF: return 0; case RIG_AGC_SLOW: return 2; case RIG_AGC_MEDIUM: return 3; case RIG_AGC_FAST: return 4; default: return 0; } return 0; } /* */ int dttsp_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret = RIG_OK; char buf[32]; switch (level) { case RIG_LEVEL_AGC: SNPRINTF(buf, sizeof(buf), "setRXAGC %d\n", agc_level2dttsp(val.i)); ret = send_command(rig, buf, strlen(buf)); break; default: rig_debug(RIG_DEBUG_TRACE, "%s: level %s, try tuner\n", __func__, rig_strlevel(level)); return rig_set_level(priv->tuner, vfo, level, val); } return ret; } int dttsp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret = RIG_OK; char buf[32]; float rxm[MAXRX][RXMETERPTS]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strlevel(level)); switch (level) { case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: SNPRINTF(buf, sizeof(buf), "reqRXMeter %d\n", getpid()); ret = send_command(rig, buf, strlen(buf)); if (ret < 0) { return ret; } ret = fetch_meter(rig, (int *)buf, (float *)rxm, MAXRX * RXMETERPTS); if (ret < 0) { return ret; } val->i = (int)rxm[0][0]; if (level == RIG_LEVEL_STRENGTH) { val->i = (int)rig_raw2val(val->i, &STATE(rig)->str_cal); } ret = RIG_OK; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: level %s, try tuner\n", __func__, rig_strlevel(level)); return rig_get_level(priv->tuner, vfo, level, val); } return ret; } int dttsp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; char buf[32]; const char *cmd; int ret; status = status ? 1 : 0; switch (func) { case RIG_FUNC_MUTE: cmd = "setRunState"; status = status ? 0 : 2; break; case RIG_FUNC_NB: cmd = "setNB"; break; case RIG_FUNC_ANF: cmd = "setANF"; break; case RIG_FUNC_NR: cmd = "setNR"; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: func %s, try tuner\n", __func__, rig_strfunc(func)); return rig_set_func(priv->tuner, vfo, func, status); } SNPRINTF(buf, sizeof(buf), "%s %d\n", cmd, status); ret = send_command(rig, buf, strlen(buf)); return ret; } /* * TODO */ int dttsp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } int dttsp_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } int dttsp_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: ant %u, try tuner\n", __func__, ant); return rig_set_ant(priv->tuner, vfo, ant, option); } hamlib-4.6.5/rigs/flexradio/flexradio.h0000664000175000017500000000271215056640443013525 /* * Hamlib FLEXRADIO backend - main header * Copyright (c) 2004-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLEXRADIO_H #define _FLEXRADIO_H 1 #include "hamlib/rig.h" extern struct rig_caps sdr1k_rig_caps; extern struct rig_caps sdr1krfe_rig_caps; extern struct rig_caps dttsp_rig_caps; extern struct rig_caps dttsp_udp_rig_caps; extern struct rig_caps smartsdr_a_rig_caps; extern struct rig_caps smartsdr_b_rig_caps; extern struct rig_caps smartsdr_c_rig_caps; extern struct rig_caps smartsdr_d_rig_caps; extern struct rig_caps smartsdr_e_rig_caps; extern struct rig_caps smartsdr_f_rig_caps; extern struct rig_caps smartsdr_g_rig_caps; extern struct rig_caps smartsdr_h_rig_caps; #endif /* _FLEXRADIO_H */ hamlib-4.6.5/rigs/flexradio/Android.mk0000664000175000017500000000045315056640443013310 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := flexradio.c sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h LOCAL_MODULE := flexradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/flexradio/smartsdr.c0000664000175000017500000004507515056640443013413 /* * Hamlib backend - SmartSDR TCP on port 4952 * See https://github.com/flexradio/smartsdr-api-docs/wiki/SmartSDR-TCPIP-API * Copyright (c) 2024 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "parallel.h" #include "misc.h" #include "bandplan.h" #include "cache.h" #include "network.h" static int smartsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int smartsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); //static int smartsdr_reset(RIG *rig, reset_t reset); static int smartsdr_init(RIG *rig); static int smartsdr_open(RIG *rig); static int smartsdr_close(RIG *rig); static int smartsdr_cleanup(RIG *rig); static int smartsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int smartsdr_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int smartsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int smartsdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int smartsdr_send_morse(RIG *rig, vfo_t vfo, const char *msg); static int smartsdr_stop_morse(RIG *rig, vfo_t vfo); //static int smartsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); struct smartsdr_priv_data { int slicenum; // slice 0-7 maps to A-H int seqnum; int ptt; int tx; // when 1 this slice has PTT control double freqA; double freqB; rmode_t modeA; rmode_t modeB; int widthA; int widthB; }; #define DEFAULTPATH "127.0.0.1:4992" #define SMARTSDR_FUNC RIG_FUNC_MUTE #define SMARTSDR_LEVEL RIG_LEVEL_PREAMP #define SMARTSDR_PARM RIG_PARM_NONE #define SMARTSDR_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_SAM) #define SMARTSDR_VFO (RIG_VFO_A) #define SMARTSDR_ANTS 3 static int smartsdr_parse_S(RIG *rig, char *s); struct rig_caps smartsdr_a_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_A), .model_name = "SmartSDR Slice A", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_b_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_B), .model_name = "SmartSDR Slice B", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_c_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_C), .model_name = "SmartSDR Slice C", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_d_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_D), .model_name = "SmartSDR Slice D", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_e_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_E), .model_name = "SmartSDR Slice E", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_f_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_F), .model_name = "SmartSDR Slice F", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_g_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_G), .model_name = "SmartSDR Slice G", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_h_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_H), .model_name = "SmartSDR Slice H", #include "smartsdr_caps.h" }; /* ************************************************************************* */ int smartsdr_init(RIG *rig) { struct smartsdr_priv_data *priv; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rs->priv = (struct smartsdr_priv_data *)calloc(1, sizeof( struct smartsdr_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ RETURNFUNC(-RIG_ENOMEM); } priv = rs->priv; strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); switch (rs->rig_model) { case RIG_MODEL_SMARTSDR_A: priv->slicenum = 0; break; case RIG_MODEL_SMARTSDR_B: priv->slicenum = 1; break; case RIG_MODEL_SMARTSDR_C: priv->slicenum = 2; break; case RIG_MODEL_SMARTSDR_D: priv->slicenum = 3; break; case RIG_MODEL_SMARTSDR_E: priv->slicenum = 4; break; case RIG_MODEL_SMARTSDR_F: priv->slicenum = 5; break; case RIG_MODEL_SMARTSDR_G: priv->slicenum = 6; break; case RIG_MODEL_SMARTSDR_H: priv->slicenum = 7; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig model=%s\n", __func__, rs->model_name); RETURNFUNC(-RIG_ENIMPL); } priv->ptt = 0; RETURNFUNC(RIG_OK); } // flush any messages in the queue and process them too // return 0 if OK, otherwise SMARTSDR error code static int smartsdr_flush(RIG *rig) { char buf[8192]; int buf_len = 8192; char stopset[1] = { 0x0a }; int len = 0; int retval = RIG_OK; ENTERFUNC; #if 0 // for this flush routine we expect at least one message for sure -- might be more len = read_string(RIGPORT(rig), (unsigned char *)buf, buf_len, stopset, 1, 0, 1); if (buf[0] == 'S') { smartsdr_parse_S(rig, buf); } rig_debug(RIG_DEBUG_VERBOSE, "%s: read %d bytes\n", __func__, len); #endif do { buf[0] = 0; len = network_flush2(RIGPORT(rig), (unsigned char *)stopset, buf, buf_len); if (buf[0] == 'S') { smartsdr_parse_S(rig, buf); } else if (buf[0] == 'R') { sscanf(buf, "R%d", &retval); } else if (strlen(buf) > 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unknown packet type=%s\n", __func__, buf); } } while (len > 0); RETURNFUNC(retval); } static int smartsdr_transaction(RIG *rig, char *buf) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[4096]; int retval; if (priv->seqnum > 999999) { priv->seqnum = 0; } if (buf) { sprintf(cmd, "C%d|%s%c", priv->seqnum++, buf, 0x0a); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SmartSDR write_block err=0x%x\n", __func__, retval); } } retval = smartsdr_flush(rig); if (retval != 0) { rig_debug(RIG_DEBUG_ERR, "%s: SmartSDR flush err=0x%x\n", __func__, retval); retval = -RIG_EPROTO; } return retval; } int smartsdr_open(RIG *rig) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; int loops = 20; ENTERFUNC; // Once we've connected and hit here we should have two messages queued from the initial connect sprintf(cmd, "sub slice %d", priv->slicenum); //sprintf(cmd, "sub slice all"); smartsdr_transaction(rig, cmd); do { hl_usleep(100 * 1000); smartsdr_transaction(rig, NULL); } while (priv->freqA == 0 && --loops > 0); //smartsdr_transaction(rig, "info", buf, sizeof(buf)); //rig_debug(RIG_DEBUG_VERBOSE, "%s: info=%s", __func__, buf); RETURNFUNC(RIG_OK); } int smartsdr_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } int smartsdr_cleanup(RIG *rig) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; if (priv) { free(priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } #if 0 #if defined(HAVE_PTHREAD) typedef struct smartsdr_data_handler_args_s { RIG *rig; } smartsdr_data_handler_args; typedef struct smartsdr_data_handler_priv_data_s { pthread_t thread_id; smartsdr_data_handler_args args; int smartsdr_data_handler_thread_run; } smartsdr_data_handler_priv_data; void *smartsdr_data_handler(void *arg) { struct smartsdr_priv_data *priv; struct smartsdr_data_handler_args_s *args = (struct smartsdr_data_handler_args_s *) arg; smartsdr_data_handler_priv_data *smartsdr_data_handler_priv; //RIG *rig = args->rig; //const struct rig_state *rs = STATE(rig); //int result; rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting morse data handler thread\n", __func__); while (priv->smartsdr_data_handler_priv_data->smartsdr_data_handler_thread_run) { } pthread_exit(NULL); return NULL; } static int smartsdr_data_handler_start(RIG *rig) { struct smartsdr_priv_data *priv; smartsdr_data_handler_priv_data *smartsdr_data_handler_priv; ENTERFUNC; priv->smartsdr_data_handler_thread_run = 1; priv->smartsdr_data_handler_priv_data = calloc(1, sizeof(smartsdr_data_handler_priv_data)); if (priv->smartsdr_data_handler_priv_data == NULL) { RETURNFUNC(-RIG_ENOMEM); } smartsdr_data_handler_priv = (smartsdr_data_handler_priv_data *) priv->smartsdr_data_handler_priv_data; smartsdr_data_handler_priv->args.rig = rig; int err = pthread_create(&smartsdr_data_handler_priv->thread_id, NULL, smartsdr_data_handler, &smartsdr_data_handler_priv->args); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(RIG_OK); fset = 1500 post_demod_bypass = 0 rfgain = 24 tx_ant_list = ANT1, ANT2, XVTA, XVTB } #endif #endif /* Example response to "sub slice 0" 511+511+35 S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_lev direct=1 el=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB S67319A86|waveform installed_list= R0|0| */ int smartsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char buf[4096]; char cmd[64]; ENTERFUNC; sprintf(cmd, "slice tune %d %.6f autopan=1", priv->slicenum, freq / 1e6); smartsdr_transaction(rig, cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq answer: %s", __func__, buf); rig_set_cache_freq(rig, vfo, freq); if (vfo == RIG_VFO_A) { priv->freqA = freq; } else { priv->freqB = freq; } RETURNFUNC(RIG_OK); } static int smartsdr_parse_S(RIG *rig, char *s) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; freq_t freq; char mode[16]; char state[16]; char *s2 = strdup(s); char *sep = "| \n"; char *p = strtok(s2, sep); int gotFreq = 0, gotMode = 0; do { rig_debug(RIG_DEBUG_VERBOSE, "%s: parsing '%s'\n", __func__, p); if (sscanf(p, "RF_frequency=%lf", &freq) == 1) { priv->freqA = freq * 1e6; rig_debug(RIG_DEBUG_VERBOSE, "%s: got freq=%.0f\n", __func__, priv->freqA); gotFreq = 1; rig_set_cache_freq(rig, RIG_VFO_A, priv->freqA); } else if (sscanf(p, "filter_hi=%d\n", &priv->widthA) == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: got width=%d\n", __func__, priv->widthA); rig_set_cache_mode(rig, RIG_VFO_A, priv->modeA, priv->widthA); } else if (sscanf(p, "mode=%s\n", mode) == 1) { if (strcmp(mode, "USB") == 0) { priv->modeA = RIG_MODE_USB; } else if (strcmp(mode, "LSB") == 0) { priv->modeA = RIG_MODE_LSB; } else if (strcmp(mode, "DIGU") == 0) { priv->modeA = RIG_MODE_PKTUSB; } else if (strcmp(mode, "DIGL") == 0) { priv->modeA = RIG_MODE_PKTLSB; } else if (strcmp(mode, "AM") == 0) { priv->modeA = RIG_MODE_AM; } else if (strcmp(mode, "CW") == 0) { priv->modeA = RIG_MODE_CW; } else if (strcmp(mode, "SAM") == 0) { priv->modeA = RIG_MODE_SAM; } else if (strcmp(mode, "FM") == 0) { priv->modeA = RIG_MODE_FM; } else if (strcmp(mode, "FMN") == 0) { priv->modeA = RIG_MODE_FMN; } else if (strcmp(mode, "RTTY") == 0) { priv->modeA = RIG_MODE_RTTY; } else { priv->modeA = RIG_MODE_NONE; rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, mode); return -RIG_EPROTO; } rig_set_cache_mode(rig, RIG_VFO_A, priv->modeA, priv->widthA); gotMode = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: got mode=%s\n", __func__, rig_strrmode(priv->modeA)); } else if (sscanf(p, "state=%s\n", state) == 1) { if (strcmp(state, "TRANSMITTING") == 0) { priv->ptt = 1; } else { priv->ptt = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: PTT state=%s, ptt=%d\n", __func__, state, priv->ptt); } else if (sscanf(p, "tx=%d\n", &priv->tx) == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tx=%d\n", __func__, priv->tx); } } while ((p = strtok(NULL, sep))); free(s2); rig_debug(RIG_DEBUG_VERBOSE, "%s gotFreq=%d, gotMode=%d\n", __func__, gotFreq, gotMode); return RIG_OK; } int smartsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; //char cmd[64]; ENTERFUNC; //int retval = -RIG_EINTERNAL; // doing the sub slice causes audio problems //sprintf(cmd, "sub slice %d", priv->slicenum); //sprintf(cmd, "info"); smartsdr_transaction(rig, NULL); if (vfo == RIG_VFO_A || vfo == RIG_VFO_CURR) { *freq = priv->freqA; } else { *freq = priv->freqB; } RETURNFUNC(RIG_OK); } int smartsdr_reset(RIG *rig, reset_t reset) { return -RIG_ENIMPL; } int smartsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; char slicechar[] = { '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' }; ENTERFUNC; if (priv->ptt && ptt) // abort ptt if we're already transmitting { rig_debug(RIG_DEBUG_ERR, "%s: abort PTT on slice %c, another slice has PTT control\n", __func__, slicechar[priv->slicenum]); RETURNFUNC(-RIG_ENTARGET); } priv->ptt = ptt; if (ptt) { sprintf(cmd, "dax audio set %d tx=1", priv->slicenum + 1); smartsdr_transaction(rig, cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s: slice set answer: %s", __func__, cmd); } sprintf(cmd, "slice set %d tx=1", priv->slicenum); smartsdr_transaction(rig, cmd); sprintf(cmd, "xmit %d", ptt); smartsdr_transaction(rig, cmd); RETURNFUNC(RIG_OK); } int smartsdr_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; smartsdr_transaction(rig, NULL); *ptt = 0; if (priv->tx) { *ptt = priv->ptt; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, *ptt); RETURNFUNC(RIG_OK); } int smartsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; char *rmode = RIG_MODE_NONE; ENTERFUNC; switch (mode) { case RIG_MODE_CW: rmode = "CW"; break; case RIG_MODE_USB: rmode = "USB"; break; case RIG_MODE_LSB: rmode = "LSB"; break; case RIG_MODE_PKTUSB: rmode = "DIGU"; break; case RIG_MODE_PKTLSB: rmode = "DIGL"; break; case RIG_MODE_AM: rmode = "AM"; break; case RIG_MODE_FM: rmode = "FM"; break; case RIG_MODE_FMN: rmode = "FMN"; break; case RIG_MODE_SAM: rmode = "SAM"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); } sprintf(cmd, "slice set %d mode=%s", priv->slicenum, rmode); smartsdr_transaction(rig, cmd); if (width != RIG_PASSBAND_NOCHANGE) { sprintf(cmd, "filt %d 0 %ld", priv->slicenum, width); } RETURNFUNC(RIG_OK); } int smartsdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; *mode = priv->modeA; *width = priv->widthA; RETURNFUNC(RIG_OK); } #if 0 int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: %s %d\n", __func__, rig_strlevel(level), val.i); switch (level) { case RIG_LEVEL_PREAMP: return set_bit(rig, L_EXT, 7, !(val.i == rig->caps->preamp[0])); int smartsdr_set_ptt(RIG * rig, vfo_t vfo, ptt_t ptt) break; default: return -RIG_EINVAL; } } #endif int smartsdr_send_morse(RIG *rig, vfo_t vfo, const char *msg) { ENTERFUNC; int retval; size_t msg_len = strlen(msg); size_t buf_len = msg_len + 20; char newmsg[msg_len + 1]; strncpy(newmsg, msg, msg_len + 1); // Replace spaces with 0x7f for (size_t i = 0; newmsg[i] != '\0'; i++) { if (newmsg[i] == ' ') { newmsg[i] = 0x7f; } } char cmd[buf_len]; snprintf(cmd, sizeof(cmd), "cwx send \"%s\"", newmsg); retval = smartsdr_transaction(rig, cmd); RETURNFUNC(retval); } int smartsdr_stop_morse(RIG *rig, vfo_t vfo) { int retval; char cmd[64]; ENTERFUNC; sprintf(cmd, "cwx clear"); retval = smartsdr_transaction(rig, cmd); RETURNFUNC(retval); }hamlib-4.6.5/rigs/flexradio/Makefile.in0000664000175000017500000005360015056640452013446 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/flexradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_flexradio_la_LIBADD = am_libhamlib_flexradio_la_OBJECTS = flexradio.lo sdr1k.lo dttsp.lo \ smartsdr.lo libhamlib_flexradio_la_OBJECTS = $(am_libhamlib_flexradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dttsp.Plo ./$(DEPDIR)/flexradio.Plo \ ./$(DEPDIR)/sdr1k.Plo ./$(DEPDIR)/smartsdr.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_flexradio_la_SOURCES) DIST_SOURCES = $(libhamlib_flexradio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-flexradio.la libhamlib_flexradio_la_SOURCES = flexradio.c flexradio.h sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/flexradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/flexradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-flexradio.la: $(libhamlib_flexradio_la_OBJECTS) $(libhamlib_flexradio_la_DEPENDENCIES) $(EXTRA_libhamlib_flexradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_flexradio_la_OBJECTS) $(libhamlib_flexradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dttsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flexradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdr1k.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smartsdr.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dttsp.Plo -rm -f ./$(DEPDIR)/flexradio.Plo -rm -f ./$(DEPDIR)/sdr1k.Plo -rm -f ./$(DEPDIR)/smartsdr.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dttsp.Plo -rm -f ./$(DEPDIR)/flexradio.Plo -rm -f ./$(DEPDIR)/sdr1k.Plo -rm -f ./$(DEPDIR)/smartsdr.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/flexradio/smartsdr_caps.h0000664000175000017500000000504515056640443014417 .mfg_name = "FlexRadio", .version = "20240814.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_NONE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 2, .has_get_func = SMARTSDR_FUNC, .has_set_func = SMARTSDR_FUNC, .has_get_level = SMARTSDR_LEVEL, .has_set_level = RIG_LEVEL_SET(SMARTSDR_LEVEL), .has_get_parm = SMARTSDR_PARM, .has_set_parm = RIG_PARM_SET(SMARTSDR_PARM), .chan_list = { RIG_CHAN_END, }, .scan_ops = RIG_SCAN_NONE, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { 14, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(30), .endf = MHz(54), .modes = SMARTSDR_MODES, .low_power = -1, .high_power = -1, SMARTSDR_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { /* restricted to ham band */ FRQ_RNG_HF(1, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), FRQ_RNG_6m(1, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(30), .endf = MHz(100), .modes = SMARTSDR_MODES, .low_power = -1, .high_power = -1, SMARTSDR_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { /* restricted to ham band */ FRQ_RNG_HF(2, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), FRQ_RNG_6m(2, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), RIG_FRNG_END, }, .tuning_steps = { {SMARTSDR_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* priv */ .rig_init = smartsdr_init, .rig_open = smartsdr_open, .rig_close = smartsdr_close, .rig_cleanup = smartsdr_cleanup, .set_freq = smartsdr_set_freq, .get_freq = smartsdr_get_freq, .get_mode= smartsdr_get_mode, .set_mode= smartsdr_set_mode, .set_ptt = smartsdr_set_ptt, .get_ptt = smartsdr_get_ptt, // .reset = smartsdr_reset, // .set_level = smartsdr_set_level, // .set_func = _set_func, .send_morse = smartsdr_send_morse, .stop_morse = smartsdr_stop_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPShamlib-4.6.5/rigs/flexradio/Makefile.am0000664000175000017500000000025215056640443013430 noinst_LTLIBRARIES = libhamlib-flexradio.la libhamlib_flexradio_la_SOURCES = flexradio.c flexradio.h sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/flexradio/README0000664000175000017500000000011315056640443012250 See https://github.com/flexradio/smartsdr-api-docs/wiki/SmartSDR-TCPIP-API hamlib-4.6.5/rigs/mds/0000775000175000017500000000000015056640500010255 5hamlib-4.6.5/rigs/mds/9710.c0000664000175000017500000000562515056640443010757 #include "mds.h" struct rig_caps mds_9710_caps = { RIG_MODEL(RIG_MODEL_MDS9710), .model_name = "9710", .mfg_name = "MDS", .version = "20221116.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 110, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = MDS_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = { { .startf = MHz(800), .endf = MHz(880), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_ALL_MODES, RIG_ANT_1, }, { .startf = MHz(880), .endf = MHz(960), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_ALL_MODES, RIG_ANT_1, }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = { {MHz(380), MHz(530), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE}, RIG_FRNG_END, }, // .tx_range_list2 = {RIG_FRNG_END,} .tuning_steps = { // Rem: no support for changing tuning step {MDS_ALL_MODES, 6250}, RIG_TS_END, }, .filters = { {MDS_ALL_MODES, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = mds_init, .rig_open = mds_open, .rig_cleanup = mds_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = mds_set_freq, .get_freq = mds_get_freq, // .set_mode = mds_set_mode, // .get_mode = mds_get_mode, // .set_level = dummy_set_level, // .get_level = mds_get_level, .get_info = mds_get_info, .set_ptt = mds_set_ptt, .get_ptt = mds_get_ptt, // .get_dcd = dummy_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/mds/Android.mk0000664000175000017500000000036415056640443012117 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := mds.c LOCAL_MODULE := mds LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/mds/4710.c0000664000175000017500000000600515056640443010743 #include "mds.h" struct rig_caps mds_4710_caps = { RIG_MODEL(RIG_MODEL_MDS4710), .model_name = "4710", .mfg_name = "MDS", .version = "20221114.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 110, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = MDS_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = { { .startf = MHz(380), .endf = MHz(530), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = { {MHz(380), MHz(400), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(400), MHz(450), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(450), MHz(512), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(406), MHz(530), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, RIG_FRNG_END, }, // .tx_range_list2 = {RIG_FRNG_END,} .tuning_steps = { // Rem: no support for changing tuning step {MDS_ALL_MODES, 6250}, RIG_TS_END, }, .filters = { {MDS_ALL_MODES, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = mds_init, .rig_open = mds_open, .rig_cleanup = mds_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = mds_set_freq, .get_freq = mds_get_freq, // .set_mode = mds_set_mode, // .get_mode = mds_get_mode, // .set_level = dummy_set_level, // .get_level = mds_get_level, .get_info = mds_get_info, .set_ptt = mds_set_ptt, .get_ptt = mds_get_ptt, // .get_dcd = dummy_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/mds/Makefile.in0000664000175000017500000005305615056640452012261 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/mds ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_mds_la_LIBADD = am__objects_1 = mds.lo 4710.lo 9710.lo am_libhamlib_mds_la_OBJECTS = $(am__objects_1) libhamlib_mds_la_OBJECTS = $(am_libhamlib_mds_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/4710.Plo ./$(DEPDIR)/9710.Plo \ ./$(DEPDIR)/mds.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_mds_la_SOURCES) DIST_SOURCES = $(libhamlib_mds_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MDSSRC = mds.c mds.h 4710.c 9710.c noinst_LTLIBRARIES = libhamlib-mds.la libhamlib_mds_la_SOURCES = $(MDSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/mds/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/mds/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-mds.la: $(libhamlib_mds_la_OBJECTS) $(libhamlib_mds_la_DEPENDENCIES) $(EXTRA_libhamlib_mds_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_mds_la_OBJECTS) $(libhamlib_mds_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/9710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mds.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/4710.Plo -rm -f ./$(DEPDIR)/9710.Plo -rm -f ./$(DEPDIR)/mds.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/4710.Plo -rm -f ./$(DEPDIR)/9710.Plo -rm -f ./$(DEPDIR)/mds.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/mds/mds.h0000664000175000017500000000135615056640443011144 #include #define MDS_DATA_LEN 256 #define MDS_RET_LEN 256 #define MDS_VFOS (RIG_VFO_A) #define MDS_ALL_MODES (RIG_MODE_USB) #define MDS_LEVELS (RIG_LEVEL_NONE) struct mds_priv_data { char cmd_str[MDS_DATA_LEN]; /* command string buffer */ char ret_data[MDS_RET_LEN]; /* returned data--max value, most are less */ }; extern struct rig_caps mds_4710_caps; extern struct rig_caps mds_9710_caps; int mds_init(RIG *rig); int mds_open(RIG *rig); int mds_cleanup(RIG *rig); int mds_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int mds_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int mds_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int mds_set_freq(RIG *rig, vfo_t vfo, freq_t freq); const char *mds_get_info(RIG *rig); hamlib-4.6.5/rigs/mds/mds.c0000664000175000017500000003142515056640443011137 /* * Hamlib MDS 4710/9710 backend - main file * Copyright (c) 2022 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "mds.h" #define MAXCMDLEN 32 extern struct rig_caps mds_4710_caps; extern struct rig_caps mds_9710_caps; DECLARE_INITRIG_BACKEND(mds) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&mds_4710_caps); rig_register(&mds_9710_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } int mds_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; hamlib_port_t *rp = RIGPORT(rig); struct mds_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s\n", cmd); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } if (expected == 0) { return RIG_OK; } else { char cmdtrm_str[2]; /* Default Command/Reply termination char */ cmdtrm_str[0] = 0x0d; cmdtrm_str[1] = 0x00; retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), cmdtrm_str, strlen(cmdtrm_str), 0, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } } if (result != NULL) { rig_debug(RIG_DEBUG_VERBOSE, "%s: setting result\n", __func__); *result = &(priv->ret_data[0]); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int mds_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct mds_priv_data *)calloc(1, sizeof(struct mds_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } /* * mds_cleanup * */ int mds_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * mds_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int mds_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; retval = mds_transaction(rig, "TX", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "%lg", freq); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } // TC command does not work on 4050 -- not implemented as of 2022-01-12 /* * mds_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int mds_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; freq_t tfreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); retval = rig_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq failed: %s\n", __func__, strerror(retval)); return retval; } if (tfreq == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq not changing\n", __func__); return RIG_OK; } // If we are not explicitly asking for VFO_B then we'll set the receive side also if (vfo != RIG_VFO_B) { char cmd_buf[MAXCMDLEN]; char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TX%.4f", freq / 1e6); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: TX failed\n", __func__); return retval; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "RX%.4f", freq / 1e6); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: RX failed\n", __func__); return retval; } } return RIG_OK; } /* * mds_set_ptt * Assumes rig!=NULL */ int mds_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s", ptt ? "KEY" : "DKEY"); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd:IP result=%s\n", __func__, response); return RIG_OK; } /* * mds_get_ptt * Assumes rig!=NULL */ int mds_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; char c; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = mds_transaction(rig, "IP", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } c = response[0]; if (c == '1' || c == '0') { *ptt = c - '0'; } else { rig_debug(RIG_DEBUG_ERR, "%s: error response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * mds_set_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ #if 0 int mds_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], ttmode; int retval; rmode_t tmode; pbwidth_t twidth; //struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = rig_get_mode(rig, vfo, &tmode, &twidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed %s\n", __func__, strerror(retval)); } if (tmode == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already mode %s so not changing\n", __func__, rig_strrmode(mode)); return RIG_OK; } switch (mode) { case RIG_MODE_USB: ttmode = 'U'; break; case RIG_MODE_LSB: ttmode = 'L'; break; case RIG_MODE_CW: ttmode = 'C'; break; case RIG_MODE_AM: ttmode = 'A'; break; case RIG_MODE_RTTY: ttmode = 'F'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TB%c\n", ttmode); retval = mds_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } #endif /* * mds_get_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ #if 0 int mds_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = mds_transaction(rig, "IB", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } //dump_hex((unsigned char *)result,strlen(result)); switch (result[1]) { case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'A': *mode = RIG_MODE_AM; break; case 'F': *mode = RIG_MODE_RTTY; break; case 'C': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode='%c%c'\n", __func__, result[0], result[1]); return -RIG_EPROTO; } *width = 3000; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } #endif #if 0 int mds_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } #endif /* * mds_get_level */ #if 0 int mds_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval = 0; char *response = NULL; switch (level) { int strength; int n; case RIG_LEVEL_STRENGTH: retval = mds_transaction(rig, "IAL", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } n = sscanf(response, "%2d", &strength); if (n == 1) { val->i = strength; } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse STRENGTH from %s\n", __func__, response); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s val=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level), response); return RIG_OK; } #endif /* * mds_get_info */ const char *mds_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = mds_transaction(rig, "MODEL", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: MODEL command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Model: %s\n", response); } response = NULL; retval = mds_transaction(rig, "SER", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: SER command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Serial# %s\n", response); } response = NULL; retval = mds_transaction(rig, "SREV", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: SREV command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Firmware %s\n", response); } response = NULL; retval = mds_transaction(rig, "SHOW DC", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SHOW DC failed result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "DC %s\n", response); } return response; } int mds_open(RIG *rig) { char *response = NULL; int retval; ENTERFUNC; mds_get_info(rig); retval = mds_transaction(rig, "MODEM NONE", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: MODEM cmd failed: %s\n", __func__, rigerror(retval)); } else { retval = mds_transaction(rig, "PTT 0", 0, &response); } RETURNFUNC(retval); } hamlib-4.6.5/rigs/mds/Makefile.am0000664000175000017500000000021015056640443012230 MDSSRC = mds.c mds.h 4710.c 9710.c noinst_LTLIBRARIES = libhamlib-mds.la libhamlib_mds_la_SOURCES = $(MDSSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/elad/0000775000175000017500000000000015056640476010413 5hamlib-4.6.5/rigs/elad/elad.c0000664000175000017500000025762615056640443011420 /* * Hamlib ELAD backend - main file * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2018 by Giovanni Franza, info@hb9eik.ch * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "cal.h" #include "elad.h" #ifndef max #define max(a,b) (((a) (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct elad_id { rig_model_t model; int id; }; struct elad_id_string { rig_model_t model; const char *id; }; #define UNKNOWN_ID -1 /* * Identification number as returned by "ID;" * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF * * TODO: sort this list with most frequent rigs first. */ static const struct elad_id elad_id_list[] = { { RIG_MODEL_ELAD_FDM_DUO, 1 }, { RIG_MODEL_NONE, UNKNOWN_ID }, /* end marker */ }; /* XXX numeric ids have been tested only with the TS-450 */ static const struct elad_id_string elad_id_string_list[] = { { RIG_MODEL_ELAD_FDM_DUO, "001" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; rmode_t elad_mode_table[ELAD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode */ [9] = RIG_MODE_RTTYR }; /* * 38 CTCSS sub-audible tones */ const tone_t elad38_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; /* * 42 CTCSS sub-audible tones */ const tone_t elad42_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* Token definitions for .cfgparams in rig_caps * * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams elad_cfg_params[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /** * elad_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * Parameters: * cmdstr: Command to be sent to the rig. cmdstr can also be NULL, * indicating that only a reply is needed (nothing will be sent). * data: Buffer for reply string. Can be NULL, indicating that no reply * is needed and will return with RIG_OK after command was sent. * datasize: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int elad_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize) { struct elad_priv_data *priv = STATE(rig)->priv; const struct elad_priv_caps *caps = elad_caps(rig); struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; char cmdtrm[2]; /* Default Command/Reply termination char */ char *cmd; size_t len; int retry_read = 0; char buffer[ELAD_MAX_BUF_LEN]; /* use our own buffer since verification may need a longer buffer than the user supplied one */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if ((!cmdstr && !datasize) || (datasize && !data)) { return -RIG_EINVAL; } rs = STATE(rig); rs->transaction_active = 1; /* Emulators don't need any post_write_delay */ if (priv->is_emulation) { rp->post_write_delay = 0; } cmdtrm[0] = caps->cmdtrm; cmdtrm[1] = '\0'; transaction_write: if (cmdstr) { rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); len = strlen(cmdstr); cmd = calloc(1, len + 2); if (cmd == NULL) { retval = -RIG_ENOMEM; goto transaction_quit; } memcpy(cmd, cmdstr, len); /* XXX the if is temporary, until all invocations are fixed */ if (cmdstr[len - 1] != ';' && cmdstr[len - 1] != '\r') { cmd[len] = caps->cmdtrm; len++; } /* flush anything in the read buffer before command is sent */ rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, len); free(cmd); if (retval != RIG_OK) { goto transaction_quit; } } if (!datasize) { rs->transaction_active = 0; /* no reply expected so we need to write a command that always gives a reply so we can read any error replies from the actual command being sent without blocking */ if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { goto transaction_quit; } } transaction_read: /* allow one extra byte for terminator we don't return */ len = min(datasize ? datasize + 1 : strlen(priv->verify_cmd) + 13, ELAD_MAX_BUF_LEN); retval = read_string(rp, (unsigned char *) buffer, len, cmdtrm, strlen(cmdtrm), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } /* Check that command termination is correct */ if (strchr(cmdtrm, buffer[strlen(buffer) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, buffer); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strlen(buffer) == 2) { switch (buffer[0]) { case 'N': /* Command recognised by rig but invalid data entered. */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, cmdstr); } retval = -RIG_ENAVAIL; goto transaction_quit; case 'O': /* Too many characters sent without a carriage return */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; case 'E': /* Communication error */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EIO; goto transaction_quit; case '?': /* Command not understood by rig or rig busy */ if (cmdstr) { rig_debug(RIG_DEBUG_ERR, "%s: Unknown command or rig busy '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: Retrying shortly\n", __func__); hl_usleep(rig->caps->timeout * 1000); goto transaction_read; } retval = -RIG_ERJCTED; goto transaction_quit; } } /* * Check that we received the correct reply. The first two characters * should be the same as command. Because the Elecraft XG3 uses * single character commands we only check the first character in * that case. */ if (datasize) { if (cmdstr && (buffer[0] != cmdstr[0] || (cmdstr[1] && buffer[1] != cmdstr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Wrong reply %c%c for command %c%c\n", __func__, buffer[0], buffer[1], cmdstr[0], cmdstr[1]); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (retval > 0) { /* move the result excluding the command terminator into the caller buffer */ len = min(datasize, retval) - 1; strncpy(data, buffer, len); data[len] = '\0'; } } else { if (priv->verify_cmd[0] != buffer[0] || (priv->verify_cmd[1] && priv->verify_cmd[1] != buffer[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: WRONG reply %c%c for command verification %c%c (datasize=%d)\n", __func__, buffer[0], buffer[1] , priv->verify_cmd[0], priv->verify_cmd[1], (int)datasize); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /** * elad_safe_transaction * A wrapper for elad_transaction to check returned data against * expected length, * * Parameters: * cmd Same as elad_transaction() cmdstr * buf Same as kenwwod_transaction() data * buf_size Same as elad_transaction() datasize * expected Value of expected string length * * Returns: * RIG_OK - if no error occurred. * RIG_EPROTO if returned string and expected are not equal * Error from elad_transaction() if any * */ int elad_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected) { int err; int retry = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (expected == 0) { buf_size = 0; } do { size_t length; err = elad_transaction(rig, cmd, buf, buf_size); if (err != RIG_OK) /* return immediately on error as any retries handled at lower level */ { return err; } length = strlen(buf); if (length != expected) /* worth retrying as some rigs occasionally send short results */ { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer; len for cmd %s: " "expected = %d, got %d\n", __func__, cmd, (int)expected, (int)length); err = -RIG_EPROTO; hl_usleep(rig->caps->timeout * 1000); } } while (err != RIG_OK && ++retry < RIGPORT(rig)->retry); return err; } rmode_t elad2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode >= ELAD_MODE_TABLE_MAX) { return RIG_MODE_NONE; } return mode_table[mode]; } char rmode2elad(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode != RIG_MODE_NONE) { int i; for (i = 0; i < ELAD_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { return i; } } } return -1; } int elad_init(RIG *rig) { struct elad_priv_data *priv; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct elad_priv_data)); if (STATE(rig)->priv == NULL) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct elad_priv_data)); strcpy(priv->verify_cmd, RIG_MODEL_XG3 == rig->caps->rig_model ? ";" : "ID;"); priv->split = RIG_SPLIT_OFF; priv->trn_state = -1; priv->curr_mode = 0; /* default mode_table */ if (caps->mode_table == NULL) { caps->mode_table = elad_mode_table; } /* default if_len */ if (caps->if_len == 0) { caps->if_len = 37; } rig_debug(RIG_DEBUG_TRACE, "%s: if_len = %d\n", __func__, caps->if_len); return RIG_OK; } int elad_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int elad_open(RIG *rig) { struct elad_priv_data *priv = STATE(rig)->priv; int err, i; char *idptr; char id[ELAD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS590S == rig->caps->rig_model) { char *dot_pos; /* we need the firmware version for these rigs to deal with f/w defects */ static char fw_version[7]; err = elad_transaction(rig, "FV", fw_version, sizeof(fw_version)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); return err; } /* store the data after the "FV" which should be a f/w version string of the form n.n e.g. 1.07 */ priv->fw_rev = &fw_version[2]; dot_pos = strchr(fw_version, '.'); if (dot_pos) { priv->fw_rev_uint = atoi(&fw_version[2]) * 100 + atoi(dot_pos + 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: found f/w version %s\n", __func__, priv->fw_rev); } /* get id in buffer, will be null terminated */ err = elad_get_id(rig, id); if (RIG_MODEL_XG3 != rig->caps->rig_model && -RIG_ETIMEOUT == err) { /* Some Kenwood emulations have no ID command response :( * Try an FA command to see is anyone is listening */ char buffer[ELAD_MAX_BUF_LEN]; err = elad_transaction(rig, "FA", buffer, sizeof(buffer)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response from rig\n", __func__); return err; } /* here we know there is something that responds to FA but not to ID so use FA as the command verification command */ strcpy(priv->verify_cmd, "FA;"); strcpy(id, "ID019"); /* fake a TS-2000 */ } else { if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", __func__); return err; } } /* id is something like 'IDXXX' or 'ID XXX' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unknown id type (%s)\n", __func__, id); return -RIG_EPROTO; } if (!strcmp("IDID900", id) /* DDUtil in TS-2000 mode */ || !strcmp("ID900", id) /* PowerSDR after ZZID; command */ || !strcmp("ID904", id) /* SmartSDR Flex-6700 */ || !strcmp("ID905", id) /* PowerSDR Flex-6500 */ || !strcmp("ID906", id) /* PowerSDR Flex-6700R */ || !strcmp("ID907", id) /* PowerSDR Flex-6300 */ || !strcmp("ID908", id) /* PowerSDR Flex-6400 */ || !strcmp("ID909", id) /* PowerSDR Flex-6600 */ ) { priv->is_emulation = 1; /* Emulations don't have SAT mode */ strcpy(id, "ID019"); /* fake it */ } /* check for a white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } /* compare id string */ for (i = 0; elad_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (strcmp(elad_id_string_list[i].id, idptr) != 0) { continue; } /* found matching id, verify driver */ rig_debug(RIG_DEBUG_TRACE, "%s: found match %s\n", __func__, elad_id_string_list[i].id); if (elad_id_string_list[i].model == rig->caps->rig_model) { /* get current AI state so it can be restored */ elad_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ elad_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } /* driver mismatch */ rig_debug(RIG_DEBUG_ERR, "%s: wrong driver selected (%u instead of %u)\n", __func__, rig->caps->rig_model, elad_id_string_list[i].model); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_ERR, "%s: your rig (%s) is unknown\n", __func__, id); return -RIG_EPROTO; } int elad_close(RIG *rig) { const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!no_restore_ai && priv->trn_state >= 0) { /* restore AI state */ elad_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } return RIG_OK; } /* ID * Reads transceiver ID number * * caller must give a buffer of ELAD_MAX_BUF_LEN size * */ int elad_get_id(RIG *rig, char *buf) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_transaction(rig, "ID", buf, ELAD_MAX_BUF_LEN); } /* IF * Retrieves the transceiver status * */ static int elad_get_if(RIG *rig) { struct elad_priv_data *priv = STATE(rig)->priv; const struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_safe_transaction(rig, "IF", priv->info, ELAD_MAX_BUF_LEN, caps->if_len); } /* FN FR FT * Sets the RX/TX VFO or M.CH mode of the transceiver, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int elad_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[6]; int retval; char vfo_function; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Emulations do not need to set VFO since VFOB is a copy of VFOA * except for frequency. And we can change freq without changing VFOS * This prevents a 1.8 second delay in PowerSDR when switching VFOs * We'll do this once if curr_mode has not been set yet */ if (priv->is_emulation && priv->curr_mode > 0) { return RIG_OK; } switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } //if rig=ts2000 then check Satellite mode status if (rig->caps->rig_model == RIG_MODEL_TS2000 && !priv->is_emulation) { char retbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s: Checking Satellite mode status\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "SA"); retval = elad_transaction(rig, cmdbuf, retbuf, 20); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "Satellite mode status %s\n", retbuf); //Satellite mode ON if (retbuf[2] == '1') { //SAT mode doesn't allow FR command (cannot select VFO) //selecting VFO is useless in SAT MODE return RIG_OK; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); if (rig->caps->rig_model == RIG_MODEL_TS50 || rig->caps->rig_model == RIG_MODEL_TS940) { cmdbuf[1] = 'N'; } /* set RX VFO */ retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* if FN command then there's no FT or FR */ /* If split mode on, the don't change TxVFO */ if ('N' == cmdbuf[1] || priv->split != RIG_SPLIT_OFF) { return RIG_OK; } /* set TX VFO */ cmdbuf[1] = 'T'; return elad_transaction(rig, cmdbuf, NULL, 0); } /* CB * Sets the operating VFO, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int elad_set_vfo_main_sub(RIG *rig, vfo_t vfo) { char cmdbuf[6]; char vfo_function; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_function = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_function = '1'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "CB%c", vfo_function); return elad_transaction(rig, cmdbuf, NULL, 0); } /* CB * Gets the operating VFO * */ int elad_get_vfo_main_sub(RIG *rig, vfo_t *vfo) { char buf[4]; int rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_OK == (rc = elad_safe_transaction(rig, "CB", buf, sizeof(buf), 3))) { *vfo = buf[2] == '1' ? RIG_VFO_SUB : RIG_VFO_MAIN; } return rc; } /* FR FT TB * Sets the split RX/TX VFO or M.CH mode of the transceiver. * */ int elad_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { // this is a bogus suppress which complains priv is not used -- but it is 20231012 // cppcheck-suppress unreadVariable struct elad_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; unsigned char vfo_function; split_t tsplit; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_split_vfo_if(rig, vfo, &tsplit, &tvfo); if (retval != RIG_OK) { return retval; } if (split == tsplit) { rig_debug(RIG_DEBUG_TRACE, "%s: No change detected...ignoring request\n", __func__); } rig_debug(RIG_DEBUG_TRACE, "%s: Change detected requested split %d!=%d\n", __func__, split, tsplit); if (split) { // Rx MAIN/Tx SUB is the only split method retval = elad_set_vfo_main_sub(rig, RIG_VFO_MAIN); if (retval != RIG_OK) { return retval; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '1' : '0'); return elad_transaction(rig, cmdbuf, NULL, 0); /* Split off means Rx and Tx are the same */ if (split == RIG_SPLIT_OFF) { txvfo = RIG_VFO_MAIN; if (txvfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &txvfo); if (retval != RIG_OK) { return retval; } } } switch (txvfo) { case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_A: vfo_function = '0'; txvfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB: case RIG_VFO_B: vfo_function = '1'; txvfo = RIG_VFO_SUB; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(txvfo)); return -RIG_EINVAL; } /* set TX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c", vfo_function); retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } retval = elad_set_split(rig, vfo, split, txvfo); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for elad_set_vfo */ priv->split = split; return RIG_OK; } /* SP * Sets the split mode of the transceivers that have the FN command. * */ int elad_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct elad_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // we want stand-alone split so we can control it SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '2' : '0'); retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for elad_set_vfo */ priv->split = split; return RIG_OK; } /* IF TB * Gets split VFO status from elad_get_if() * */ int elad_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { struct elad_priv_data *priv = STATE(rig)->priv; int retval; int transmitting; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!split || !txvfo) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char buf[4]; if (RIG_OK == (retval = elad_safe_transaction(rig, "SP", buf, sizeof(buf), 3))) { if ('1' == buf[2]) { *split = RIG_SPLIT_ON; *txvfo = RIG_VFO_SUB; } else { *split = RIG_SPLIT_OFF; *txvfo = RIG_VFO_MAIN; } } return retval; } retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } switch (priv->info[32]) { case '0': *split = RIG_SPLIT_OFF; break; case '1': *split = RIG_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %c\n", __func__, priv->info[32]); return -RIG_EPROTO; } /* Remember whether split is on, for elad_set_vfo */ priv->split = *split; /* find where is the txvfo.. */ /* Elecraft info[30] does not track split VFO when transmitting */ transmitting = '1' == priv->info[28] && RIG_MODEL_K2 != rig->caps->rig_model && RIG_MODEL_K3 != rig->caps->rig_model; switch (priv->info[30]) { case '0': *txvfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; break; case '1': *txvfo = (*split && !transmitting) ? RIG_VFO_A : RIG_VFO_B; break; case '2': *txvfo = RIG_VFO_MEM; /* SPLIT MEM operation doesn't involve VFO A or VFO B */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); return -RIG_EPROTO; } return RIG_OK; } /* * elad_get_vfo_if using byte 31 of the IF information field * * Specifically this needs to return the RX VFO, the IF command tells * us the TX VFO in split TX mode when transmitting so we need to swap * results sometimes. */ int elad_get_vfo_if(RIG *rig, vfo_t *vfo) { int retval; struct elad_priv_data *priv = STATE(rig)->priv; int split_and_transmitting; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } /* Elecraft info[30] does not track split VFO when transmitting */ split_and_transmitting = '1' == priv->info[28] /* transmitting */ && '1' == priv->info[32] /* split */ && RIG_MODEL_K2 != rig->caps->rig_model && RIG_MODEL_K3 != rig->caps->rig_model; switch (priv->info[30]) { case '0': *vfo = split_and_transmitting ? RIG_VFO_B : RIG_VFO_A; break; case '1': *vfo = split_and_transmitting ? RIG_VFO_A : RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); return -RIG_EPROTO; } return RIG_OK; } /* * elad_set_freq */ int elad_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16]; unsigned char vfo_letter = '\0'; vfo_t tvfo; int err; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ err = rig_get_vfo(rig, &tvfo); if (RIG_OK != err) { return err; } } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll, vfo_letter, (int64_t)freq); err = elad_transaction(rig, freqbuf, NULL, 0); if (RIG_OK == err && RIG_MODEL_TS590S == rig->caps->rig_model && priv->fw_rev_uint <= 107 && ('A' == vfo_letter || 'B' == vfo_letter)) { /* TS590s f/w rev 1.07 or earlier has a defect that means frequency set on TX VFO in split mode may not be set correctly. The symptom of the defect is either TX on the wrong frequency (i.e. TX on a frequency different from that showing on the TX VFO) or no output. We use an IF command to find out if we have just set the "back" VFO when the rig is in split mode. If we have; we then read the other VFO and set it to what we read - a null transaction that fixes the defect. */ err = elad_get_if(rig); if (RIG_OK != err) { return err; } if ('1' == priv->info[32] && priv->info[30] != ('A' == vfo_letter ? '0' : '1')) { /* split mode and setting "back" VFO */ /* set other VFO to whatever it is at currently */ err = elad_safe_transaction(rig, 'A' == vfo_letter ? "FB" : "FA", freqbuf, 16, 13); if (RIG_OK != err) { return err; } err = elad_transaction(rig, freqbuf, NULL, 0); } } return err; } int elad_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) { const struct elad_priv_data *priv = STATE(rig)->priv; char freqbuf[50]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } memcpy(freqbuf, priv->info, 15); freqbuf[14] = '\0'; sscanf(freqbuf + 2, "%"SCNfreq, freq); return RIG_OK; } /* * elad_get_freq */ int elad_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[50]; char cmdbuf[4]; int retval; unsigned char vfo_letter = '\0'; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ retval = rig_get_vfo(rig, &tvfo); if (RIG_OK != retval) { return retval; } } /* memory frequency cannot be read with an Fx command, use IF */ if (tvfo == RIG_VFO_MEM) { return elad_get_freq_if(rig, vfo, freq); } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "F%c", vfo_letter); retval = elad_safe_transaction(rig, cmdbuf, freqbuf, 50, 13); if (retval != RIG_OK) { return retval; } sscanf(freqbuf + 2, "%"SCNfreq, freq); return RIG_OK; } int elad_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[6]; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } memcpy(buf, &priv->info[18], 5); buf[5] = '\0'; *rit = atoi(buf); return RIG_OK; } /* * rit can only move up/down by 10 Hz, so we use a loop... */ int elad_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[4]; int retval, i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rit == 0) { return elad_transaction(rig, "RC", NULL, 0); } SNPRINTF(buf, sizeof(buf), "R%c", (rit > 0) ? 'U' : 'D'); retval = elad_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = elad_transaction(rig, buf, NULL, 0); } return retval; } /* * rit and xit are the same */ int elad_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rit) { return -RIG_EINVAL; } return elad_get_rit(rig, vfo, rit); } int elad_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_set_rit(rig, vfo, rit); } int elad_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { return elad_transaction(rig, scan == RIG_SCAN_STOP ? "SC00" : "SC01", NULL, 0); } else { return elad_transaction(rig, scan == RIG_SCAN_STOP ? "SC0" : "SC1", NULL, 0); } } /* * 000 No select * 002 FM Wide * 003 FM Narrow * 005 AM * 007 SSB * 009 CW * 010 CW NARROW */ /* XXX revise */ static int elad_set_filter(RIG *rig, pbwidth_t width) { char *cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (width <= Hz(250)) { cmd = "FL010009"; } else if (width <= Hz(500)) { cmd = "FL009009"; } else if (width <= kHz(2.7)) { cmd = "FL007007"; } else if (width <= kHz(6)) { cmd = "FL005005"; } else { cmd = "FL002002"; } return elad_transaction(rig, cmd, NULL, 0); } /* * elad_set_mode */ int elad_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct elad_priv_data *priv = STATE(rig)->priv; struct elad_priv_caps *caps = elad_caps(rig); char buf[6]; char kmode; int err; char data_mode = '0'; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { /* supports DATA sub modes */ switch (mode) { case RIG_MODE_PKTUSB: data_mode = '1'; mode = RIG_MODE_USB; break; case RIG_MODE_PKTLSB: data_mode = '1'; mode = RIG_MODE_LSB; break; case RIG_MODE_PKTFM: data_mode = '1'; mode = RIG_MODE_FM; break; default: break; } } if (priv->is_emulation || rig->caps->rig_model == RIG_MODEL_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ if (RIG_MODE_PKTLSB == mode) { mode = RIG_MODE_RTTY; } if (RIG_MODE_PKTUSB == mode) { mode = RIG_MODE_RTTYR; } } kmode = rmode2elad(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { /* The TS990s has targetable read mode but can only set the mode of the current VFO :( So we need to toggle the operating VFO to set the "back" VFO mode. This is done here rather than not setting caps.targetable_vfo to not include RIG_TARGETABLE_MODE since the toggle is not required for reading the mode. */ char c; vfo_t curr_vfo; err = elad_get_vfo_main_sub(rig, &curr_vfo); if (err != RIG_OK) { return err; } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { err = elad_set_vfo_main_sub(rig, vfo); if (err != RIG_OK) { return err; } } SNPRINTF(buf, sizeof(buf), "OM0%c", c); /* target vfo is ignored */ err = elad_transaction(rig, buf, NULL, 0); if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { int err2 = elad_set_vfo_main_sub(rig, curr_vfo); if (RIG_OK == err && err2 != RIG_OK) { return err2; } } } else { SNPRINTF(buf, sizeof(buf), "MD%c", '0' + kmode); err = elad_transaction(rig, buf, NULL, 0); } if (err != RIG_OK) { return err; } if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { if (!(RIG_MODE_CW == mode || RIG_MODE_CWR == mode || RIG_MODE_AM == mode || RIG_MODE_RTTY == mode || RIG_MODE_RTTYR == mode)) { /* supports DATA sub modes - see above */ SNPRINTF(buf, sizeof(buf), "DA%c", data_mode); err = elad_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } } } if (RIG_PASSBAND_NOCHANGE == width) { return RIG_OK; } if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } elad_set_filter(rig, width); /* non fatal */ } return RIG_OK; } static int elad_get_filter(RIG *rig, pbwidth_t *width) { int err, f, f1, f2; char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!width) { return -RIG_EINVAL; } err = elad_safe_transaction(rig, "FL", buf, sizeof(buf), 8); if (err != RIG_OK) { return err; } f2 = atoi(&buf[5]); buf[5] = '\0'; f1 = atoi(&buf[2]); if (f2 > f1) { f = f2; } else { f = f1; } switch (f) { case 2: *width = kHz(12); break; case 3: case 5: *width = kHz(6); break; case 7: *width = kHz(2.7); break; case 9: *width = Hz(500); break; case 10: *width = Hz(250); break; } return RIG_OK; } /* * elad_get_mode */ int elad_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct elad_priv_data *priv = STATE(rig)->priv; struct elad_priv_caps *caps = elad_caps(rig); char cmd[4]; char modebuf[10]; int offs; int retval; int kmode; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } /* for emulation do not read mode from VFOB as it is copy of VFOA */ /* we avoid the VFO swapping most of the time this way */ /* only need to get it if it has to be initialized */ if (priv->curr_mode > 0 && priv->is_emulation && vfo == RIG_VFO_B) { return priv->curr_mode; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "OM%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "MD"); offs = 2; } retval = elad_safe_transaction(rig, cmd, modebuf, 6, offs + 1); if (retval != RIG_OK) { return retval; } if (modebuf[offs] <= '9') { kmode = modebuf[offs] - '0'; } else { kmode = modebuf[offs] - 'A' + 10; } *mode = elad2rmode(kmode, caps->mode_table); if (priv->is_emulation || rig->caps->rig_model == RIG_MODEL_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ if (RIG_MODE_RTTY == *mode) { *mode = RIG_MODE_PKTLSB; } if (RIG_MODE_RTTYR == *mode) { *mode = RIG_MODE_PKTUSB; } } if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { /* supports DATA sub-modes */ retval = elad_safe_transaction(rig, "DA", modebuf, 6, 3); if (retval != RIG_OK) { return retval; } if ('1' == modebuf[2]) { switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; default: break; } } } /* XXX ? */ *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* This is used when the radio does not support MD; for mode reading */ int elad_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; struct elad_priv_caps *caps = elad_caps(rig); const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } err = elad_get_if(rig); if (err != RIG_OK) { return err; } *mode = elad2rmode(priv->info[29] - '0', caps->mode_table); *width = rig_passband_normal(rig, *mode); if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { elad_get_filter(rig, width); /* non fatal */ } return RIG_OK; } int elad_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, elad_val; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { elad_val = val.f * 255; } else { elad_val = val.i; } switch (level) { case RIG_LEVEL_RFPOWER: /* * Best estimate: 1.0 corresponds to 100W * Anything better must be done in rig-specific files. */ if (RIG_LEVEL_IS_FLOAT(level)) { elad_val = val.f * 100; } SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", elad_val); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", elad_val); break; case RIG_LEVEL_RF: /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", elad_val); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", elad_val); break; case RIG_LEVEL_AGC: if (elad_val > 3) { elad_val = 3; /* 0.. 255 */ } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", 84 * elad_val); break; case RIG_LEVEL_ATT: /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->attenuator[i]; i++) { if (val.i == STATE(rig)->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->preamp[i]; i++) { if (val.i == STATE(rig)->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_SLOPE_HIGH: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", (val.i)); break; case RIG_LEVEL_SLOPE_LOW: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", (val.i)); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "PT%02d", (val.i / 50) - 8); break; case RIG_LEVEL_KEYSPD: if (val.i > 50 || val.i < 5) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return elad_transaction(rig, levelbuf, NULL, 0); } int get_elad_level(RIG *rig, const char *cmd, float *f) { char lvlbuf[10]; int retval; int lvl; int len = strlen(cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!f) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 3); if (retval != RIG_OK) { return retval; } /* 000..255 */ sscanf(lvlbuf + len, "%d", &lvl); *f = lvl / 255.0; return RIG_OK; }; /* * elad_get_level */ int elad_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[ELAD_MAX_BUF_LEN]; char *cmd; int retval; int lvl; int i, ret, agclevel, len; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RAWSTR: if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { cmd = "SM0"; len = 3; } else { cmd = "SM"; len = 2; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { return retval; } /* XXX atoi ? */ sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ break; case RIG_LEVEL_STRENGTH: if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { cmd = "SM0"; len = 3; } else { cmd = "SM"; len = 2; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ if (rig->caps->str_cal.size) { val->i = (int) rig_raw2val(val->i, &rig->caps->str_cal); } else { val->i = (val->i * 4) - 54; } break; case RIG_LEVEL_ATT: retval = elad_safe_transaction(rig, "RA", lvlbuf, 50, 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected att level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_PREAMP: retval = elad_safe_transaction(rig, "PA", lvlbuf, 50, 3); if (retval != RIG_OK) { return retval; } if (lvlbuf[2] == '0') { val->i = 0; } else if (isdigit((int)lvlbuf[2])) { lvl = lvlbuf[2] - '0'; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->preamp[i - 1]; } else { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp char '%c'\n", __func__, lvlbuf[2]); return -RIG_EPROTO; } break; case RIG_LEVEL_RFPOWER: /* * an answer "PC100" means 100 Watt * which is val=1.0 on most rigs, but * get_elad_level maps 0...255 onto 0.0 ... 1.0 */ ret = get_elad_level(rig, "PC", &val->f); val->f = val->f * (255.0 / 100.0); return ret; case RIG_LEVEL_AF: return get_elad_level(rig, "AG", &val->f); case RIG_LEVEL_RF: return get_elad_level(rig, "RG", &val->f); case RIG_LEVEL_SQL: return get_elad_level(rig, "SQ", &val->f); case RIG_LEVEL_MICGAIN: return get_elad_level(rig, "MG", &val->f); case RIG_LEVEL_AGC: ret = get_elad_level(rig, "GT", &val->f); agclevel = 255 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; case RIG_LEVEL_SLOPE_LOW: retval = elad_transaction(rig, "SL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_SLOPE_HIGH: retval = elad_transaction(rig, "SH", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_CWPITCH: retval = elad_safe_transaction(rig, "PT", lvlbuf, 50, 4); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * 1000) + 1000; /* 00 - 08 */ break; case RIG_LEVEL_KEYSPD: retval = elad_safe_transaction(rig, "KS", lvlbuf, 50, 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &val->i); break; case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int elad_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[6]; /* longest cmd is GTxxx */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_NB: SNPRINTF(buf, sizeof(buf), "NB%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_ABM: SNPRINTF(buf, sizeof(buf), "AM%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_COMP: SNPRINTF(buf, sizeof(buf), "PR%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_TONE: SNPRINTF(buf, sizeof(buf), "TO%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_TSQL: SNPRINTF(buf, sizeof(buf), "CT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_VOX: SNPRINTF(buf, sizeof(buf), "VX%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_FAGC: SNPRINTF(buf, sizeof(buf), "GT00%c", (status == 0) ? '4' : '2'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_NR: SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_BC: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_ANF: SNPRINTF(buf, sizeof(buf), "NT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_AIP: SNPRINTF(buf, sizeof(buf), "MX%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s", rig_strfunc(func)); return -RIG_EINVAL; } return -RIG_EINVAL; } /* * works for any 'format 1' command * answer is always 4 bytes: two byte command id, status and terminator */ int get_elad_func(RIG *rig, const char *cmd, int *status) { int retval; char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!cmd || !status) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, cmd, buf, 10, 3); if (retval != RIG_OK) { return retval; } *status = buf[2] == '0' ? 0 : 1; return RIG_OK; }; /* * elad_get_func */ int elad_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fctbuf[20]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_FAGC: retval = elad_safe_transaction(rig, "GT", fctbuf, 20, 5); if (retval != RIG_OK) { return retval; } *status = fctbuf[4] != '4' ? 1 : 0; return RIG_OK; case RIG_FUNC_NB: return get_elad_func(rig, "NB", status); case RIG_FUNC_ABM: return get_elad_func(rig, "AM", status); case RIG_FUNC_COMP: return get_elad_func(rig, "PR", status); case RIG_FUNC_TONE: return get_elad_func(rig, "TO", status); case RIG_FUNC_TSQL: return get_elad_func(rig, "CT", status); case RIG_FUNC_VOX: return get_elad_func(rig, "VX", status); case RIG_FUNC_NR: return get_elad_func(rig, "NR", status); /* FIXME on TS2000 */ case RIG_FUNC_BC: return get_elad_func(rig, "BC", status); case RIG_FUNC_ANF: return get_elad_func(rig, "NT", status); case RIG_FUNC_LOCK: return get_elad_func(rig, "LK", status); case RIG_FUNC_AIP: return get_elad_func(rig, "MX", status); default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %s", rig_strfunc(func)); return -RIG_EINVAL; } return -RIG_EINVAL; } /* * elad_set_ctcss_tone * Assumes rig->caps->ctcss_list != NULL * * Warning! This is untested stuff! May work at least on TS-870S * Please owners report to me , thanks. --SF */ int elad_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; /* TODO: replace 200 by something like RIGTONEMAX */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } /* TODO: replace menu no 57 by a define */ SNPRINTF(tonebuf, sizeof(tonebuf), "EX%03d%04d", 57, i + 1); return elad_transaction(rig, tonebuf, NULL, 0); } int elad_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* XXX 40 is a fixed constant */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "TN%c%02d", c, i + 1); } else { SNPRINTF(buf, sizeof(buf), "TN%02d", i + 1); } return elad_transaction(rig, buf, NULL, 0); } /* * elad_get_ctcss_tone * Assumes STATE(rig)->priv != NULL */ int elad_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct elad_priv_data *priv = STATE(rig)->priv; struct rig_caps *caps; char tonebuf[3]; int i, retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; if (RIG_MODEL_TS990S == caps->rig_model) { char cmd[4]; char buf[6]; char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "TN%c", c); retval = elad_safe_transaction(rig, cmd, buf, sizeof(buf), 5); memcpy(tonebuf, &buf[3], 2); } else { retval = elad_get_if(rig); memcpy(tonebuf, &priv->info[34], 2); } if (retval != RIG_OK) { return retval; } tonebuf[2] = '\0'; tone_idx = atoi(tonebuf); if (tone_idx == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS tone is zero (%s)\n", __func__, tonebuf); return -RIG_EPROTO; } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } } *tone = caps->ctcss_list[tone_idx - 1]; return RIG_OK; } int elad_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "CN%c%02d", c, i + 1); } else { SNPRINTF(buf, sizeof(buf), "CN%02d", i + 1); } return elad_transaction(rig, buf, NULL, 0); } int elad_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char cmd[4]; char tonebuf[6]; int offs; int i, retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "CN%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "CT"); offs = 2; } retval = elad_safe_transaction(rig, cmd, tonebuf, 6, offs + 2); if (retval != RIG_OK) { return retval; } tone_idx = atoi(tonebuf + offs); if (tone_idx == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS is zero (%s)\n", __func__, tonebuf); return -RIG_EPROTO; } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } } *tone = caps->ctcss_list[tone_idx - 1]; return RIG_OK; } /* * set the aerial/antenna to use */ int elad_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[8]; char a; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ant) { case RIG_ANT_1: a = '1'; break; case RIG_ANT_2: a = '2'; break; case RIG_ANT_3: a = '3'; break; case RIG_ANT_4: a = '4'; break; default: return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "AN0%c%c99", c, a); } else { SNPRINTF(cmd, sizeof(cmd), "AN%c", a); } return elad_transaction(rig, cmd, NULL, 0); } int elad_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant) { const char *cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ant) { case RIG_ANT_1: cmd = "AN1"; break; case RIG_ANT_2: cmd = "AN2"; break; case RIG_ANT_3: cmd = "AN3"; break; case RIG_ANT_4: cmd = "AN4"; break; default: return -RIG_EINVAL; } return elad_transaction(rig, cmd, NULL, 0); } /* * get the aerial/antenna in use */ int elad_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char ackbuf[8]; int offs; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { retval = elad_safe_transaction(rig, "AN0", ackbuf, sizeof(ackbuf), 7); offs = 4; } else { retval = elad_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 3); offs = 2; } if (retval != RIG_OK) { return retval; } if (ackbuf[offs] < '1' || ackbuf[offs] > '9') { return -RIG_EPROTO; } *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); /* XXX check that the returned antenna is valid for the current rig */ return RIG_OK; } /* * elad_get_ptt */ int elad_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct elad_priv_data *priv = STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } *ptt = priv->info[28] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } int elad_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; char busybuf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; break; case RIG_PTT_ON_MIC: ptt_cmd = "TX0"; break; case RIG_PTT_ON_DATA: ptt_cmd = "TX1"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: return -RIG_EINVAL; } return elad_transaction(rig, ptt_cmd, busybuf, 4); } int elad_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) { char busybuf[10]; int err; ptt_t current_ptt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elad_get_ptt(rig, vfo, ¤t_ptt); if (err != RIG_OK) { return err; } if (current_ptt == ptt) { return RIG_OK; } return elad_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", busybuf, 4); } /* * elad_get_dcd */ int elad_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char busybuf[10]; int retval; int offs = 2; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_safe_transaction(rig, "BY", busybuf, 10, 3); if (retval != RIG_OK) { return retval; } if (RIG_MODEL_TS990S == rig->caps->rig_model && RIG_VFO_SUB == vfo) { offs = 3; } *dcd = (busybuf[offs] == '1') ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* * elad_set_trn */ int elad_set_trn(RIG *rig, int trn) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { return elad_transaction(rig, (trn == RIG_TRN_RIG) ? "AI2" : "AI0", NULL, 0); } else { return elad_transaction(rig, (trn == RIG_TRN_RIG) ? "AI1" : "AI0", NULL, 0); } } /* * elad_get_trn */ int elad_get_trn(RIG *rig, int *trn) { char trnbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!trn) { return -RIG_EINVAL; } /* these rigs only have AI[0|1] set commands and no AI query */ if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS790 || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { return -RIG_ENAVAIL; } retval = elad_safe_transaction(rig, "AI", trnbuf, 6, 3); if (retval != RIG_OK) { return retval; } *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * elad_set_powerstat */ int elad_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_transaction(rig, (status == RIG_POWER_ON) ? "PS1" : "PS0", NULL, 0); } /* * elad_get_powerstat */ int elad_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, "PS", pwrbuf, 6, 3); if (retval != RIG_OK) { return retval; } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } /* * elad_reset */ int elad_reset(RIG *rig, reset_t reset) { char rstbuf[6]; char rst; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { switch (reset) { case RIG_RESET_SOFT: rst = '4'; break; case RIG_RESET_VFO: rst = '3'; break; case RIG_RESET_MCALL: rst = '2'; break; case RIG_RESET_MASTER: rst = '5'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } else { switch (reset) { case RIG_RESET_VFO: rst = '1'; break; case RIG_RESET_MASTER: rst = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } SNPRINTF(rstbuf, sizeof(rstbuf), "SR%c", rst); /* this command has no answer */ return elad_transaction(rig, rstbuf, NULL, 0); } /* * elad_send_morse */ int elad_send_morse(RIG *rig, vfo_t vfo, const char *msg) { char morsebuf[40], m2[30]; int msg_len, retval, i; const char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); p = msg; msg_len = strlen(msg); while (msg_len > 0) { int buff_len; /* * Check with "KY" if char buffer is available. * if not, sleep. */ for (;;) { retval = elad_transaction(rig, "KY;", m2, 4); if (retval != RIG_OK) { return retval; } /* * If answer is "KY0;", there is space in buffer and we can proceed. * If answer is "KY1;", we have to wait a while * If answer is something else, return with error to prevent infinite loops */ if (!strncmp(m2, "KY0", 3)) { break; } if (!strncmp(m2, "KY1", 3)) { hl_usleep(500000); } else { return -RIG_EINVAL; } } buff_len = msg_len > 24 ? 24 : msg_len; strncpy(m2, p, 24); m2[24] = '\0'; /* * Make the total message segments 28 characters * in length because some Kenwoods demand it. * 0x20 fills in the message end. * Some rigs don't need the fill */ switch (rig->caps->rig_model) { case RIG_MODEL_K3: // probably a lot more rigs need to go here SNPRINTF(morsebuf, sizeof(morsebuf), "KY %s", m2); break; default: /* the command must consist of 28 bytes 0x20 padded */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %-24s", m2); for (i = strlen(morsebuf) - 1; i > 0 && morsebuf[i] == ' '; --i) { morsebuf[i] = 0x20; } } retval = elad_transaction(rig, morsebuf, NULL, 0); if (retval != RIG_OK) { return retval; } msg_len -= buff_len; p += buff_len; } return RIG_OK; } /* * elad_vfo_op */ int elad_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (op) { case RIG_OP_UP: return elad_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return elad_transaction(rig, "DN", NULL, 0); case RIG_OP_BAND_UP: return elad_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return elad_transaction(rig, "BD", NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } /* * elad_set_mem */ int elad_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[7]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MN%c%03d", c, ch); } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(buf, sizeof(buf), "MC %02d", ch); } return elad_transaction(rig, buf, NULL, 0); } /* * elad_get_mem */ int elad_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[4]; char membuf[10]; int offs; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "MN%c", c); offs = 3; } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(cmd, sizeof(cmd), "MC"); offs = 2; } retval = elad_safe_transaction(rig, cmd, membuf, sizeof(membuf), 3 + offs); if (retval != RIG_OK) { return retval; } *ch = atoi(membuf + offs); return RIG_OK; } int elad_get_mem_if(RIG *rig, vfo_t vfo, int *ch) { int err; char buf[4]; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elad_get_if(rig); if (err != RIG_OK) { return err; } memcpy(buf, &priv->info[26], 2); buf[2] = '\0'; *ch = atoi(buf); return RIG_OK; } int elad_get_channel(RIG *rig, channel_t *chan) { int err; char buf[26]; char cmd[8]; char bank = ' '; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* put channel num in the command string */ if (rig->caps->rig_model == RIG_MODEL_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(cmd, sizeof(cmd), "MR0%c%02d", bank, chan->channel_num); err = elad_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { return err; } memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_VFO; /* MR0 1700005890000510 ; * MRsbccfffffffffffMLTtt ; */ /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ if (buf[19] == '0' || buf[19] == ' ') { chan->ctcss_tone = 0; } else { buf[22] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[atoi(&buf[20])]; } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } chan->mode = elad2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[4]); if (buf[3] >= '0' && buf[3] <= '9') { chan->bank_num = buf[3] - '0'; } /* split freq */ cmd[2] = '1'; err = elad_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { return err; } chan->tx_mode = elad2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } return RIG_OK; } int elad_set_channel(RIG *rig, const channel_t *chan) { char buf[128]; char mode, tx_mode = 0; int err; int tone = 0; char bank = ' '; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2elad(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2elad(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (tone = 0; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = 0; } } if (rig->caps->rig_model == RIG_MODEL_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(buf, sizeof(buf), "MW0%c%02d%011"PRIll"%c%c%c%02d ", /* note the space at the end */ bank, chan->channel_num, (int64_t)chan->freq, '0' + mode, (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); err = elad_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } SNPRINTF(buf, sizeof(buf), "MW1%c%02d%011"PRIll"%c%c%c%02d ", bank, chan->channel_num, (int64_t)(chan->split == RIG_SPLIT_ON ? chan->tx_freq : 0), (chan->split == RIG_SPLIT_ON) ? ('0' + tx_mode) : '0', (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); return elad_transaction(rig, buf, NULL, 0); } int elad_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { char buf[4]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_VOICE: return elad_transaction(rig, "VR", NULL, 0); case TOK_FINE: SNPRINTF(buf, sizeof(buf), "FS%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case TOK_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case TOK_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); } return -RIG_EINVAL; } int elad_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { int err; struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_FINE: return get_elad_func(rig, "FS", &val->i); case TOK_XIT: err = elad_get_if(rig); if (err != RIG_OK) { return err; } val->i = (priv->info[24] == '1') ? 1 : 0; return RIG_OK; case TOK_RIT: err = elad_get_if(rig); if (err != RIG_OK) { return err; } val->i = (priv->info[23] == '1') ? 1 : 0; return RIG_OK; } return -RIG_ENIMPL; } /* * elad_get_info * supposed to work only for TS2000... */ const char *elad_get_info(RIG *rig) { char firmbuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_safe_transaction(rig, "TY", firmbuf, 10, 5); if (retval != RIG_OK) { return NULL; } switch (firmbuf[4]) { case '0': return "Firmware: Overseas type"; case '1': return "Firmware: Japanese 100W type"; case '2': return "Firmware: Japanese 20W type"; default: return "Firmware: unknown"; } } #define IDBUFSZ 16 /* * proberigs_elad * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_elad(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(elad) { char idbuf[IDBUFSZ]; int id_len = -1, i, k_id; int retval = -1; int rates[] = { 115200, 57600, 38400, 19200, 9600, 4800, 1200, 0 }; /* possible baud rates */ int rates_idx; idbuf[0] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 2; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "ID;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || !strcmp(idbuf, "ID;")) { return RIG_MODEL_NONE; } /* * reply should be something like 'IDxxx;' */ if (id_len != 5 && id_len != 6) { idbuf[7] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: protocol error, " " expected %d, received %d: %s\n", 6, id_len, idbuf); return RIG_MODEL_NONE; } /* first, try ID string */ for (i = 0; elad_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!strncmp(elad_id_string_list[i].id, idbuf + 2, 16)) { rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: " "found %s\n", idbuf + 2); if (cfunc) { (*cfunc)(port, elad_id_string_list[i].model, data); } return elad_id_string_list[i].model; } } /* then, try ID numbers */ k_id = atoi(idbuf + 2); /* * Elecraft K2 returns same ID as TS570 */ if (k_id == 17) { retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "K2;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK) { return RIG_MODEL_NONE; } /* * reply should be something like 'K2n;' */ if (id_len == 4 || !strcmp(idbuf, "K2")) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found K2\n", __func__); if (cfunc) { (*cfunc)(port, RIG_MODEL_K2, data); } return RIG_MODEL_K2; } } for (i = 0; elad_id_list[i].model != RIG_MODEL_NONE; i++) { if (elad_id_list[i].id == k_id) { rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: " "found %03d\n", k_id); if (cfunc) { (*cfunc)(port, elad_id_list[i].model, data); } return elad_id_list[i].model; } } /* * not found in known table.... * update elad_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_elad: found unknown device " "with ID %03d, please report to Hamlib " "developers.\n", k_id); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay=%d\n", __func__, port->post_write_delay); return RIG_MODEL_NONE; } /* * initrigs_elad is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(elad) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // rig_debug(RIG_DEBUG_VERBOSE, "elad: _init called\n"); rig_register(&fdm_duo_caps); return RIG_OK; } hamlib-4.6.5/rigs/elad/fdm_duo.c0000664000175000017500000003565415056640443012123 /* * Hamlib ELAD backend - FDM_DUO description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * Copyright (c) 2018 by Giovanni Franza HB9EIK * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "elad.h" #define FDM_DUO_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FDM_DUO_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define FDM_DUO_AM_TX_MODES RIG_MODE_AM #define FDM_DUO_VFO (RIG_VFO_A|RIG_VFO_B) #define FDM_DUO_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC) #define FDM_DUO_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC) /* * elad_fdm_duo_get_info * Assumes rig!=NULL */ static const char * elad_fdm_duo_get_info(RIG *rig) { char firmbuf[50]; int retval; size_t firm_len; retval = elad_transaction(rig, "TY", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len != 5) { rig_debug(RIG_DEBUG_ERR, "elad_get_info: wrong answer len=%d\n", (int)firm_len); return NULL; } switch (firmbuf[4]) { case '0': return "FDM-DUOHX (200W)"; case '1': return "FDM-DUOSAT (100W + AT)"; case '2': return "Japanese 50W type"; case '3': return "Japanese 20W type"; default: return "Firmware: unknown"; } } /* * elad_fdm_duo_set_level * Assumes rig!=NULL * * set levels of most functions * * WARNING: the commands differ slightly from the general versions in elad.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ int elad_fdm_duo_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int elad_val; switch (level) { case RIG_LEVEL_RFPOWER: elad_val = val.f * 100; /* level for FDM_DUOSAT is from 0.. 100W in SSB */ SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", elad_val); break; case RIG_LEVEL_AF: elad_val = val.f * 255; /* possible values for FDM_DUO are 000.. 255 */ SNPRINTF(levelbuf, sizeof(levelbuf), "AG0%03d", elad_val); break; case RIG_LEVEL_RF: elad_val = val.f * 100; /* possible values for FDM_DUO are 000.. 100 */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", elad_val); break; case RIG_LEVEL_SQL: elad_val = val.f * 255; /* possible values for FDM_DUO are 000.. 255 */ SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", elad_val); break; case RIG_LEVEL_AGC: /* possible values for FDM_DUO 000(=off), 001(=fast), 002(=slow) */ /* hamlib argument is int, possible values rig.h:enum agc_level_e */ switch (val.i) { case RIG_AGC_OFF: elad_val = 0; break; case RIG_AGC_FAST: elad_val = 1; break; case RIG_AGC_SLOW: elad_val = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported agc value", __func__); return -RIG_EINVAL; }; SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", elad_val); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return elad_transaction(rig, levelbuf, NULL, 0); } /* * elad_get_level * Assumes rig!=NULL, val!=NULL */ int elad_fdm_duo_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len; int levelint; int retval; switch (level) { case RIG_LEVEL_RFPOWER: retval = elad_transaction(rig, "PC", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_AF: retval = elad_transaction(rig, "AG0", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (6 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 255.; return RIG_OK; case RIG_LEVEL_RF: retval = elad_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_SQL: retval = elad_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (6 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 255.; return RIG_OK; case RIG_LEVEL_AGC: retval = elad_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } switch (ackbuf[4]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_SLOW; break; default: return -RIG_EPROTO; } return RIG_OK; case RIG_LEVEL_MICGAIN: case RIG_LEVEL_PREAMP: case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; /* never reached */ } static struct elad_priv_caps fdm_duo_priv_caps = { .cmdtrm = EOM_KEN, }; /* * fdm_duo rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! */ struct rig_caps fdm_duo_caps = { RIG_MODEL(RIG_MODEL_ELAD_FDM_DUO), .model_name = "FDM-DUO", .mfg_name = "ELAD", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 10, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {kHz(100), Hz(59999999), FDM_DUO_ALL_MODES, -1, -1, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, /* 100W class */ {kHz(1810), kHz(1850), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, /* 25W class */ {kHz(3500), kHz(3800), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(3500), kHz(3800), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(7), kHz(7200), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(7), kHz(7200), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), FDM_DUO_ALL_MODES, -1, -1, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(3500), MHz(4) - 1, FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(5250), kHz(5450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(5250), kHz(5450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(7), kHz(7300), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(7), kHz(7300), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {FDM_DUO_ALL_MODES, kHz(1)}, {FDM_DUO_ALL_MODES, Hz(2500)}, {FDM_DUO_ALL_MODES, kHz(5)}, {FDM_DUO_ALL_MODES, Hz(6250)}, {FDM_DUO_ALL_MODES, kHz(10)}, {FDM_DUO_ALL_MODES, Hz(12500)}, {FDM_DUO_ALL_MODES, kHz(15)}, {FDM_DUO_ALL_MODES, kHz(20)}, {FDM_DUO_ALL_MODES, kHz(25)}, {FDM_DUO_ALL_MODES, kHz(30)}, {FDM_DUO_ALL_MODES, kHz(100)}, {FDM_DUO_ALL_MODES, kHz(500)}, {FDM_DUO_ALL_MODES, MHz(1)}, {FDM_DUO_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& fdm_duo_priv_caps, .rig_init = elad_init, .rig_cleanup = elad_cleanup, .set_freq = elad_set_freq, .get_freq = elad_get_freq, .set_rit = elad_set_rit, /* FIXME should this switch to rit mode or just set the frequency? */ .get_rit = elad_get_rit, .set_xit = elad_set_xit, /* FIXME should this switch to xit mode or just set the frequency? */ .get_xit = elad_get_xit, .set_mode = elad_set_mode, .get_mode = elad_get_mode, .set_vfo = elad_set_vfo, .get_vfo = elad_get_vfo_if, .set_split_vfo = elad_set_split_vfo, .get_split_vfo = elad_get_split_vfo_if, .get_ptt = elad_get_ptt, .set_ptt = elad_set_ptt, .get_dcd = elad_get_dcd, .set_powerstat = elad_set_powerstat, .get_powerstat = elad_get_powerstat, .get_info = elad_fdm_duo_get_info, .reset = elad_reset, .set_ant = elad_set_ant, .get_ant = elad_get_ant, .scan = elad_scan, /* not working, invalid arguments using rigctl; elad_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = FDM_DUO_LEVEL_ALL, .has_get_level = FDM_DUO_LEVEL_ALL, .set_level = elad_fdm_duo_set_level, .get_level = elad_fdm_duo_get_level, .has_get_func = FDM_DUO_FUNC_ALL, .has_set_func = FDM_DUO_FUNC_ALL, .set_func = elad_set_func, .get_func = elad_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * my notes: * format with: indent --line-length 200 fdm_duo.c * * for the FDM_DUO the function NR and BC have tree state: NR0,1,2 and BC0,1,2 * this cannot be send through the on/off logic of set_function! */ /* * Function definitions below */ hamlib-4.6.5/rigs/elad/elad.h0000664000175000017500000001546615056640443011417 /* * Hamlib ELAD backend - main header * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2018 by Giovanni Franza, info@hb9eik.ch * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ELAD_H #define _ELAD_H 1 #include #include "rig.h" #include "token.h" #define BACKEND_VER "20220608" #define EOM_KEN ';' #define EOM_TH '\r' #define ELAD_MODE_TABLE_MAX 24 #define ELAD_MAX_BUF_LEN 128 /* max answer len, arbitrary */ /* Tokens for Parameters common to multiple rigs. * Use token # >= 1 or <= 100. Defined here so they will be * available in Kenwood name space. */ #define TOK_VOICE TOKEN_BACKEND(1) #define TOK_FINE TOKEN_BACKEND(2) #define TOK_XIT TOKEN_BACKEND(3) #define TOK_RIT TOKEN_BACKEND(4) /* Token structure assigned to .cfgparams in rig_caps */ extern const struct confparams elad_cfg_params[]; /* * modes in use by the "MD" command */ #define MD_NONE '0' #define MD_LSB '1' #define MD_USB '2' #define MD_CW '3' #define MD_FM '4' #define MD_AM '5' #define MD_FSK '6' #define MD_CWR '7' #define MD_FSKR '9' struct elad_priv_caps { char cmdtrm; /* Command termination chars (ken=';' or th='\r') */ int if_len; /* length of IF; answer excluding ';' terminator */ rmode_t *mode_table; }; struct elad_priv_data { char info[ELAD_MAX_BUF_LEN]; split_t split; /* current split state */ int k2_ext_lvl; /* Initial K2 extension level */ int k3_ext_lvl; /* Initial K3 extension level */ int k2_md_rtty; /* K2 RTTY mode available flag, 1 = RTTY, 0 = N/A */ char *fw_rev; /* firmware revision level */ int trn_state; /* AI state discovered at startup */ unsigned fw_rev_uint; /* firmware revision as a number 1.07 -> 107 */ char verify_cmd[4]; /* command used to verify set commands */ int is_emulation; /* flag for TS-2000 emulations */ void * data; /* model specific data */ rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ }; #define elad_caps(rig) ((struct elad_priv_caps *)(rig)->caps->priv) extern rmode_t elad_mode_table[ELAD_MODE_TABLE_MAX]; extern const tone_t elad38_ctcss_list[]; extern const tone_t elad42_ctcss_list[]; int elad_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize); int elad_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected); rmode_t elad2rmode(unsigned char mode, const rmode_t mode_table[]); char rmode2elad(rmode_t mode, const rmode_t mode_table[]); int elad_init(RIG *rig); int elad_cleanup(RIG *rig); int elad_open(RIG *rig); int elad_close(RIG *rig); int elad_set_vfo(RIG *rig, vfo_t vfo); int elad_set_vfo_main_sub(RIG *rig, vfo_t vfo); int elad_get_vfo_if(RIG *rig, vfo_t *vfo); int elad_get_vfo_main_sub(RIG *rig, vfo_t *vfo); int elad_set_split(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int elad_set_split_vfo(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int elad_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); int elad_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int elad_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int elad_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq); int elad_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int elad_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int elad_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int elad_get_xit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int elad_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int elad_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int elad_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int elad_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int elad_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int elad_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int elad_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int elad_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int elad_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int elad_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int elad_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone); int elad_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int elad_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int elad_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int elad_set_powerstat(RIG *rig, powerstat_t status); int elad_get_powerstat(RIG *rig, powerstat_t *status); int elad_reset(RIG *rig, reset_t reset); int elad_send_morse(RIG *rig, vfo_t vfo, const char *msg); int elad_set_ant (RIG * rig, vfo_t vfo, ant_t ant, value_t option); int elad_set_ant_no_ack(RIG * rig, vfo_t vfo, ant_t ant); int elad_get_ant (RIG * rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int elad_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int elad_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int elad_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt); int elad_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int elad_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int elad_set_mem(RIG *rig, vfo_t vfo, int ch); int elad_get_mem(RIG *rig, vfo_t vfo, int *ch); int elad_get_mem_if(RIG *rig, vfo_t vfo, int *ch); int elad_get_channel(RIG *rig, channel_t *chan); int elad_set_channel(RIG *rig, const channel_t *chan); int elad_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char * elad_get_info(RIG *rig); int elad_get_id(RIG *rig, char *buf); int elad_set_trn(RIG *rig, int trn); int elad_get_trn(RIG *rig, int *trn); /* only use if returned string has length 6, e.g. 'SQ011;' */ int get_elad_level(RIG *rig, const char *cmd, float *f); int get_elad_func(RIG *rig, const char *cmd, int *status); extern struct rig_caps fdm_duo_caps; #if 0 /* use when not interested in the answer, but want to check its len */ static int inline elad_simple_transaction(RIG *rig, const char *cmd, size_t expected) { struct elad_priv_data *priv = STATE(rig)->priv; return elad_safe_transaction(rig, cmd, priv->info, ELAD_MAX_BUF_LEN, expected); } #endif #endif /* _ELAD_H */ hamlib-4.6.5/rigs/elad/Android.mk0000664000175000017500000000040015056640443012230 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := elad.c fdm_duo.c LOCAL_MODULE := elad LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/elad/Makefile.in0000664000175000017500000005263715056640452012407 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/elad ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_elad_la_LIBADD = am__objects_1 = elad.lo fdm_duo.lo am_libhamlib_elad_la_OBJECTS = $(am__objects_1) libhamlib_elad_la_OBJECTS = $(am_libhamlib_elad_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/elad.Plo ./$(DEPDIR)/fdm_duo.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_elad_la_SOURCES) DIST_SOURCES = $(libhamlib_elad_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ELADSRC = elad.c elad.h fdm_duo.c noinst_LTLIBRARIES = libhamlib-elad.la libhamlib_elad_la_SOURCES = $(ELADSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/elad/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/elad/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-elad.la: $(libhamlib_elad_la_OBJECTS) $(libhamlib_elad_la_DEPENDENCIES) $(EXTRA_libhamlib_elad_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_elad_la_OBJECTS) $(libhamlib_elad_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdm_duo.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/elad.Plo -rm -f ./$(DEPDIR)/fdm_duo.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/elad.Plo -rm -f ./$(DEPDIR)/fdm_duo.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/elad/Makefile.am0000664000175000017500000000021215056640443012354 ELADSRC = elad.c elad.h fdm_duo.c noinst_LTLIBRARIES = libhamlib-elad.la libhamlib_elad_la_SOURCES = $(ELADSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/uniden/0000775000175000017500000000000015056640500010754 5hamlib-4.6.5/rigs/uniden/bc895.c0000664000175000017500000001027615056640443011706 /* * Hamlib Uniden backend - BC895 description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC895_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC895_FUNC (RIG_FUNC_MUTE) #define BC895_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC895_PARM_ALL (RIG_PARM_NONE) #define BC895_VFO RIG_VFO_A #define BC895_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .ctcss_sql=1, \ .dcs_sql=1 /* The BC895 seems to max out at 32 while 12 seems to be about minimum. */ #define BC895_STR_CAL { 4, \ { \ { 0, -54 }, \ { 12, -20 }, /* TBC */ \ { 32, 4 }, /* TBC */ \ { 255, 60 }, \ } } /* * bc895 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc895_caps = { RIG_MODEL(RIG_MODEL_BC895), .model_name = "BC895xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC895_FUNC, .has_set_func = BC895_FUNC, .has_get_level = BC895_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC895_LEVEL_ALL), .has_get_parm = BC895_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC895_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .str_cal = BC895_STR_CAL, .chan_list = { { 1, 300, RIG_MTYPE_MEM, {BC895_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(956), BC895_MODES, -1, -1, BC895_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC895_MODES, kHz(5)}, {BC895_MODES, kHz(7.5)}, {BC895_MODES, kHz(10)}, {BC895_MODES, kHz(12.5)}, {BC895_MODES, kHz(25)}, {BC895_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/bc780.c0000664000175000017500000001025315056640443011672 /* * Hamlib Uniden backend - BC780 description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC780_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC780_FUNC (RIG_FUNC_MUTE) #define BC780_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC780_PARM_ALL (RIG_PARM_NONE) #define BC780_VFO RIG_VFO_A #define BC780_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .channel_desc=1, \ .ctcss_sql=1, \ .dcs_sql=1 #define BC780_STR_CAL UNIDEN_STR_CAL /* * bc780 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc780_caps = { RIG_MODEL(RIG_MODEL_BC780), .model_name = "BC780xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC780_FUNC, .has_set_func = BC780_FUNC, .has_get_level = BC780_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC780_LEVEL_ALL), .has_get_parm = BC780_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC780_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 16, .str_cal = BC780_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, {BC780_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BC780_MODES, -1, -1, BC780_VFO}, {MHz(806), MHz(956), BC780_MODES, -1, -1, BC780_VFO}, /* (minus Cellular frequencies) */ {MHz(1240), MHz(1300), BC780_MODES, -1, -1, BC780_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC780_MODES, kHz(5)}, {BC780_MODES, kHz(7.5)}, {BC780_MODES, kHz(10)}, {BC780_MODES, kHz(12.5)}, {BC780_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq_2, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/bc250.c0000664000175000017500000001023515056640443011662 /* * Hamlib Uniden backend - BC250 description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC250_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC250_FUNC (RIG_FUNC_MUTE) #define BC250_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC250_PARM_ALL (RIG_PARM_NONE) #define BC250_VFO RIG_VFO_A #define BC250_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .channel_desc=1, \ .ctcss_sql=1, \ .dcs_sql=1 #define BC250_STR_CAL UNIDEN_STR_CAL /* * bc250 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc250_caps = { RIG_MODEL(RIG_MODEL_BC250), .model_name = "BC250D", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC250_FUNC, .has_set_func = BC250_FUNC, .has_get_level = BC250_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC250_LEVEL_ALL), .has_get_parm = BC250_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC250_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 16, .str_cal = BC250_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, {BC250_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BC250_MODES, -1, -1, BC250_VFO}, {MHz(806), MHz(956), BC250_MODES, -1, -1, BC250_VFO}, /* (minus Cellular frequencies) */ {MHz(1240), MHz(1300), BC250_MODES, -1, -1, BC250_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC250_MODES, kHz(5)}, {BC250_MODES, kHz(7.5)}, {BC250_MODES, kHz(10)}, {BC250_MODES, kHz(12.5)}, {BC250_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/uniden.h0000664000175000017500000000530715056640443012342 /* * Hamlib Uniden backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _UNIDEN_H #define _UNIDEN_H 1 #include #include #define BACKEND_VER "20200621" /* TODO: Trunk, Delay, Recording * * .channel_desc=1 is only on BC780 BC250 BC785 * .ctcss_sql=1, * .dcs_sql=1, */ #define UNIDEN_CHANNEL_CAPS \ .freq=1,\ .levels=RIG_LEVEL_ATT,\ .flags=1, /* L/O */ /* Calibration, actually from the BC785D */ #define UNIDEN_STR_CAL { 8, \ { \ { 0, -54 }, \ { 134, -20 }, /* < 0.50uV */ \ { 157, -12 }, \ { 173, -9 }, \ { 189, -5 }, \ { 204, -1 }, \ { 221, 4 }, /* < 7.50uV */ \ { 255, 60 }, \ } } extern tone_t uniden_ctcss_list[]; extern tone_t uniden_dcs_list[]; int uniden_transaction (RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize); int uniden_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int uniden_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int uniden_get_freq_2(RIG *rig, vfo_t vfo, freq_t *freq); int uniden_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int uniden_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int uniden_set_mem(RIG *rig, vfo_t vfo, int ch); int uniden_get_mem(RIG *rig, vfo_t vfo, int *ch); int uniden_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int uniden_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int uniden_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int uniden_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int uniden_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); const char* uniden_get_info(RIG *rig); extern struct rig_caps bc895_caps; extern struct rig_caps bc898_caps; extern struct rig_caps bc245_caps; extern struct rig_caps bc780_caps; extern struct rig_caps bc250_caps; extern struct rig_caps pro2052_caps; extern struct rig_caps bcd396t_caps; extern struct rig_caps bcd996t_caps; #endif /* _UNIDEN_H */ hamlib-4.6.5/rigs/uniden/uniden_digital.c0000664000175000017500000002723615056640443014037 /* * Hamlib Uniden backend - uniden_digital backend * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "uniden_digital.h" /* * Uniden Digital backend should work for: * BCD996T as well as the BCD396T. Some protocols available for the * BCD996T may not be available for the BCD396T or modified to work. * * Protocol information can be found here: * http://www.uniden.com/files/BCD396T_Protocol.pdf * http://www.uniden.com/files/BCD996T_Protocol.pdf * * There are undocumented commands such as firmware_dump and * firmware_load. These commands are defined within DSctl code. * * There are two methods of retrieving the next memory location * (aka frequency bank). Use either the "Get Next Location" or * use the address returned from one of the commands. If you decide * the latter method, the order is slightly confusing but, I have it * well documented within DSctl. The latter method is also as much * as 30% faster than using the Uniden software or "Get Next * Location" command. */ #if 0 // deactivated temporarily because uniden_id_string_list is nowhere used static const struct { rig_model_t model; const char *id; } uniden_id_string_list[] = { { RIG_MODEL_BCD396T, "BCD396T" }, { RIG_MODEL_BCD996T, "BCD996T" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; #endif /* EOM is not consistent with this BCD996T! * Some commands return newline while others carriage return. * Some commands return nothing special for End of Line char. */ #define EOM "\r" /* end of message */ /* I'm still getting clipped output from buffers being too small elsewhere! */ #define BUFSZ 256 /* Wild guess, 64 was too small. */ /** * uniden_transaction * uniden_digital_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * cmdstr - Command to be sent to the rig. Cmdstr can also be NULL, indicating * that only a reply is needed (nothing will be send). * replystr - Reply prefix to be expected. Replystr can also be NULL, indicating * that the prefix is either the cmdstr prefix or OK. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed and will return with RIG_OK after command was sent. * datasize - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * out: location where to store number of bytes read. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int uniden_digital_transaction(RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize) { struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; int retry_read = 0; char replybuf[BUFSZ]; size_t reply_len = BUFSZ; rs = STATE(rig); rs->transaction_active = 1; transaction_write: rig_flush(rp); if (cmdstr) { retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to known if it went OK */ if (!data) { data = replybuf; } if (!datasize) { datasize = &reply_len; } memset(data, 0, *datasize); retval = read_string(rp, (unsigned char *) data, *datasize, EOM, strlen(EOM), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } else { *datasize = retval; } /* Check that command termination is correct * FIXME: Sometimes the BCD996T DOES NOT return a * consistent carriage return or newline. * ie: STS command will not return either "\r" or "\n"! */ /*if (strchr(EOM, data[strlen(data)-1])==NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rp->retry) goto transaction_write; retval = -RIG_EPROTO; goto transaction_quit; }*/ if (strcmp(data, "OK"EOM)) { /* everything is fine */ retval = RIG_OK; goto transaction_quit; } /* Any syntax returning NG indicates a VALID Command but not entered * in the right mode or using the correct parameters. ERR indicates * an INVALID Command. */ if (strcmp(data, "NG"EOM)) { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Command Format Error / Value Error for '%s'\n", __func__, cmdstr); retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "ERR"EOM)) { /* Command format error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: The Command is Invalid at this Time for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } if (strcmp(data, "FER"EOM)) { /* Framing error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Framing Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } if (strcmp(data, "ORER"EOM)) { /* Overrun error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Overrun Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } #define CONFIG_STRIP_CMDTRM 1 #ifdef CONFIG_STRIP_CMDTRM if (strlen(data) > 0) { data[strlen(data) - 1] = '\0'; /* not very elegant, but should work. */ } else { data[0] = '\0'; } #endif /* Special case for SQuelch */ /*if (!memcmp(cmdstr,"SQ",2) && (replystr[0] == '-' || replystr[0] == '+')) { retval = RIG_OK; goto transaction_quit; }*/ /* Command prefix if no replystr supplied */ if (!replystr) { replystr = cmdstr; } /* * Check that received the correct reply. The first two characters * should be the same as command. */ if (replystr && replystr[0] && (data[0] != replystr[0] || (replystr[1] && data[1] != replystr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /* * uniden_get_info * Assumes rig!=NULL */ const char *uniden_digital_get_info(RIG *rig) { static char infobuf[BUFSZ]; size_t info_len = BUFSZ / 2, mdlinfo_len = BUFSZ / 2; int ret; /* GET CURRENT STATUS -- STS */ ret = uniden_digital_transaction(rig, "STS" EOM, 3, NULL, infobuf, &info_len); /* NOTE FOR ME: Check Buffer Size with what we got returned in info_len. * Don't know the max length of return on these units, so check frequently! * Use five v's (-vvvvv) to activate output. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG BUFSZ'%i'\n", __func__, BUFSZ); rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG info_len'%i'\n", __func__, (int)info_len); if (ret != RIG_OK) { return NULL; } /* Example output: * STS,011000, XXX ,,Fa * * STS command returns 3 lines including system, truck, freq info * * XXX indicates the BCD996T returns some non-printable ascii chars * within its comma separated fields. See pg 30-32 of BCD996T_Protocol.pdf. * These chars cause anomalies on stdout! */ /* FIXME: Strip or replace non-printable chars return from STS command! * (Below is a snip from DSctl utils.c file) * * For example, search each character. For each sequence of chars found, replace with normal printable ascii [KEY] * if (strstr(bcd_chars, "\213") != 0) * strncat(tmp_line, "[FUNCTION KEY] ", 15); * * if (strstr(bcd_chars, "\215\216\217\220") != 0) * strncat(tmp_line, "[HOLD] ", 7); */ if (info_len < 4) { return NULL; } if (info_len >= BUFSZ) { rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG Max BUFSZ Reached: info_len = '%i'\n", __func__, (int)info_len); info_len = BUFSZ - 1; } infobuf[info_len] = '\0'; /* VR not on every rig <- This doesn't belong here for the newer BCD* units*/ /* VR1.00 */ /*ret = uniden_digital_transaction (rig, "VR" EOM, 2, NULL, infobuf+info_len, &vrinfo_len); if (ret == RIG_OK) {*/ /* overwrite "VR" */ /* FIXME: need to filter \r or it screws w/ stdout */ /*infobuf[info_len] = '\n'; infobuf[info_len+1] = ' '; } else { infobuf[info_len] = '\0'; }*/ /* GET MODEL INFO -- MDL */ ret = uniden_digital_transaction(rig, "MDL" EOM, 3, NULL, infobuf + info_len, &mdlinfo_len); if (ret == RIG_OK) { infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* GET FIRMWARE VERSION -- VER */ ret = uniden_digital_transaction(rig, "VER" EOM, 3, NULL, infobuf + info_len, &mdlinfo_len); if (ret == RIG_OK) { infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* skip beginning "STS, " */ /* FIXME: What about clipping the above two other MDL & VER Commands? */ return infobuf + 4; } /* * skeleton */ int uniden_digital_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { #if 0 char freqbuf[BUFSZ]; /* freq in hundreds of Hz */ freq /= 100; /* exactly 8 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "RF%08u" EOM, (unsigned)freq); return uniden_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL, NULL); #else return -RIG_ENIMPL; #endif } /* * skeleton */ int uniden_digital_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #if 0 char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RF" EOM, 3, NULL, freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 2, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; #else return -RIG_ENIMPL; #endif } hamlib-4.6.5/rigs/uniden/Android.mk0000664000175000017500000000053115056640443012612 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c \ bcd396t.c bcd996t.c \ uniden.c uniden_digital.c LOCAL_MODULE := uniden LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/uniden/uniden.c0000664000175000017500000005120515056640443012333 /* * Hamlib Uniden backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "uniden.h" static const struct { rig_model_t model; const char *id; } uniden_id_string_list[] = { { RIG_MODEL_BC780, "BC780" }, { RIG_MODEL_BC245, "BC245XLT" }, { RIG_MODEL_BC250, "BC250D" }, { RIG_MODEL_BC895, "BC895" }, { RIG_MODEL_BC235, "BC235XLT" }, { RIG_MODEL_BC785, "BC785" }, { RIG_MODEL_BC786, "BC786D" }, { RIG_MODEL_PRO2052, "PRO2052" }, /* ?? */ { RIG_MODEL_BCT8, "BCT8" }, /* ?? */ { RIG_MODEL_BC898, "BC898T" }, /* TBC */ { RIG_MODEL_NONE, NULL }, /* end marker */ }; tone_t uniden_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; tone_t uniden_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; /* * Uniden backend: should work for: * BC235XLT, BC895XLT, BC245XLT, BC780XLT, BC250D, BC785D and BCT8 * and most probably for the RadioShack PRO-2052. * * Protocol information available at http://www.cantonmaine.com/pro2052.htm * and http://www.freqofnature.com/software/protocols.html * * It seems like these rigs have no VFO, I mean only mem channels. * Is that correct? --SF */ #define EOM "\r" #define BUFSZ 64 /** * uniden_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * cmdstr - Command to be sent to the rig. Cmdstr can also be NULL, indicating * that only a reply is needed (nothing will be send). * replystr - Reply prefix to be expected. Replystr can also be NULL, indicating * that the prefix is either the cmdstr prefix or OK. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed and will return with RIG_OK after command was sent. * datasize - in: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * out: location where to store number of bytes read. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int uniden_transaction(RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize) { struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; int retry_read = 0; char replybuf[BUFSZ]; size_t reply_len = BUFSZ; rs = STATE(rig); rs->transaction_active = 1; transaction_write: rig_flush(rp); if (cmdstr) { retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to known if it went OK */ if (!data) { data = replybuf; } if (!datasize) { datasize = &reply_len; } memset(data, 0, *datasize); retval = read_string(rp, (unsigned char *) data, *datasize, EOM, strlen(EOM), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } else { *datasize = retval; } /* Check that command termination is correct */ if (strchr(EOM, data[strlen(data) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "OK"EOM) == 0) { /* everything is fine */ retval = RIG_OK; goto transaction_quit; } /* Any syntax returning NG indicates a VALID Command but not entered * in the right mode or using the correct parameters. ERR indicates * an INVALID Command. */ if (strcmp(data, "NG"EOM) == 0 || strcmp(data, "ORER"EOM) == 0) { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NG/Overflow for '%s'\n", __func__, cmdstr); retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "ERR"EOM) == 0) { /* Command format error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } #define CONFIG_STRIP_CMDTRM 1 #ifdef CONFIG_STRIP_CMDTRM if (strlen(data) > 0) { data[strlen(data) - 1] = '\0'; /* not very elegant, but should work. */ } else { data[0] = '\0'; } #endif /* Special case for SQuelch */ if (replystr && !memcmp(cmdstr, "SQ", 2) && (data[0] == '-' || data[0] == '+')) { retval = RIG_OK; goto transaction_quit; } /* Command prefix if no replystr supplied */ if (!replystr) { replystr = cmdstr; } /* * Check that received the correct reply. The first two characters * should be the same as command. */ if (replystr && replystr[0] && (data[0] != replystr[0] || (replystr[1] && data[1] != replystr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /* * uniden_set_freq * Assumes rig!=NULL */ int uniden_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* freq in hundreds of Hz */ freq /= 100; /* exactly 8 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "RF%08u" EOM, (unsigned)freq); return uniden_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL, NULL); } /* * uniden_get_freq * Assumes rig!=NULL */ int uniden_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RF" EOM, 3, NULL, freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 2, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; } /* * uniden_get_freq * Assumes rig!=NULL */ int uniden_get_freq_2(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "SG" EOM, 3, "S", freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 6, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; } int uniden_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *modebuf; switch (mode) { case RIG_MODE_AM: modebuf = "RM AM"EOM; break; case RIG_MODE_FM: if (width > 0 && width < rig_passband_normal(rig, mode)) { modebuf = "RM NFM"EOM; } else { modebuf = "RM FM"EOM; } break; case RIG_MODE_WFM: modebuf = "RM WFM"EOM; break; default: return -RIG_EINVAL; } return uniden_transaction(rig, modebuf, strlen(modebuf), NULL, NULL, NULL); } int uniden_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char modebuf[BUFSZ]; size_t mode_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RM" EOM, 3, NULL, modebuf, &mode_len); if (ret != RIG_OK) { return ret; } if (mode_len < 4) { return -RIG_EPROTO; } *width = 0; if (!strcmp(modebuf + 3, "AM")) { *mode = RIG_MODE_AM; } else if (!strcmp(modebuf + 3, "WFM")) { *mode = RIG_MODE_WFM; } else if (!strcmp(modebuf + 3, "FM")) { *mode = RIG_MODE_FM; } else if (!strcmp(modebuf + 3, "NFM")) { *mode = RIG_MODE_FM; *width = rig_passband_narrow(rig, RIG_MODE_FM); } if (*width == 0) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } int uniden_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int retval; switch (level) { case RIG_LEVEL_ATT: if (STATE(rig)->attenuator[0] == 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "AT%c"EOM, val.i != 0 ? 'N' : 'F'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = uniden_transaction(rig, levelbuf, strlen(levelbuf), NULL, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * uniden_get_level * Assumes rig!=NULL, val!=NULL */ int uniden_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[BUFSZ]; int retval; size_t lvl_len = BUFSZ; switch (level) { case RIG_LEVEL_RAWSTR: retval = uniden_transaction(rig, "SG"EOM, 3, "S", lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* S182 F08594375 */ sscanf(lvlbuf + 1, "%d", &val->i); /* rawstr */ break; case RIG_LEVEL_ATT: retval = uniden_transaction(rig, "AT"EOM, 3, NULL, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[2] == 'N' ? STATE(rig)->attenuator[0] : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * uniden_get_dcd * Assumes rig!=NULL */ int uniden_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; size_t dcd_len = BUFSZ; int ret; ret = uniden_transaction(rig, "SQ" EOM, 3, NULL, dcdbuf, &dcd_len); if (ret != RIG_OK) { return ret; } if (dcd_len < 1 || (dcdbuf[0] != '+' && dcdbuf[0] != '-')) { return -RIG_EPROTO; } *dcd = (dcdbuf[0] == '-') ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * uniden_set_mem * Assumes rig!=NULL */ int uniden_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "MA%03d" EOM, ch); return uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL, NULL); } /* * uniden_get_mem * Assumes rig!=NULL */ int uniden_get_mem(RIG *rig, vfo_t vfo, int *ch) { char membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; ret = uniden_transaction(rig, "MA" EOM, 3, "C", membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (mem_len < 4) { return -RIG_EPROTO; } sscanf(membuf + 1, "%d", ch); return RIG_OK; } /* * uniden_get_channel * Assumes rig!=NULL */ int uniden_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char cmdbuf[BUFSZ], membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; int tone; if (chan->vfo == RIG_VFO_MEM) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "PM%03d" EOM, chan->channel_num); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "MA" EOM); } ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), "C", membuf, &mem_len); if (ret != RIG_OK) { return ret; } /* * 0123456789012345678901234567890123456789 * C089 F08511625 TN DN LF AF RF N000 */ if (mem_len < 30 || membuf[5] != 'F' || membuf[15] != 'T' || membuf[18] != 'D' || membuf[21] != 'L' || membuf[24] != 'A' || membuf[27] != 'R' || membuf[30] != 'N') { return -RIG_EPROTO; } sscanf(membuf + 1, "%d", &chan->channel_num); sscanf(membuf + 6, "%"SCNfreq, &chan->freq); /* returned freq in hundreds of Hz */ chan->freq *= 100; /* TODO: Trunk, Delay, Recording */ chan->flags = (membuf[22] == 'N') ? RIG_CHFLAG_SKIP : 0; chan->levels[LVL_ATT].i = (membuf[25] == 'N') ? STATE(rig)->attenuator[0] : 0; sscanf(membuf + 41, "%d", &tone); if (tone >= 1 && tone <= 38) { chan->ctcss_sql = rig->caps->ctcss_list[tone - 1]; /* 1..38 */ } else if (tone > 38) { chan->dcs_sql = rig->caps->dcs_list[tone - 39]; /* 39..142 */ } if (chan->vfo == RIG_VFO_MEM && rig->caps->chan_desc_sz != 0) { /* only BC780 BC250 BC785 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "TA C %03d" EOM, chan->channel_num); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (mem_len < 10 || memcmp(membuf, cmdbuf, 8)) { return -RIG_EPROTO; } /* TA C 001 My Alpha Tag */ strncpy(chan->channel_desc, membuf + 9, rig->caps->chan_desc_sz); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * uniden_set_channel * * Only freq can be set? */ int uniden_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[BUFSZ], membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; if (chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* PM089T08511625 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "PM%03d%c%08u" EOM, chan->channel_num, ' ', (unsigned)(chan->freq / 100)); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (rig->caps->chan_desc_sz != 0) { /* only BC780 BC250 BC785 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "TA C %03d %s" EOM, chan->channel_num, chan->channel_desc); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL, NULL); if (ret != RIG_OK) { return ret; } } return RIG_OK; } /* * uniden_get_info * Assumes rig!=NULL */ const char *uniden_get_info(RIG *rig) { static char infobuf[BUFSZ]; size_t info_len = BUFSZ / 2, vrinfo_len = BUFSZ / 2; int ret; ret = uniden_transaction(rig, "SI" EOM, 3, NULL, infobuf, &info_len); if (ret != RIG_OK) { return NULL; } /* SI BC250D,0000000000,104 */ if (info_len < 4) { return NULL; } if (info_len >= BUFSZ) { info_len = BUFSZ - 1; } infobuf[info_len] = '\0'; /* VR not on every rig */ /* VR1.00 */ ret = uniden_transaction(rig, "VR" EOM, 3, NULL, infobuf + info_len, &vrinfo_len); if (ret == RIG_OK) { /* overwrite "VR" */ /* FIXME: need to filter \r or it screws w/ stdout */ infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* skip "SI " */ return infobuf + 3; } #define IDBUFSZ 32 /* * proberigs_uniden * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_uniden(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(uniden) { char idbuf[IDBUFSZ]; int id_len = -1, i; int retval = -1; int rates[] = { 9600, 19200, 0 }; /* possible baud rates */ int rates_idx; memset(idbuf, 0, IDBUFSZ); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 1; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "SI"EOM, 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, EOM, 1, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || memcmp(idbuf, "SI ", 3)) { return RIG_MODEL_NONE; } /* * reply should be something like 'SI xxx,xx,xx\x0d' */ if (id_len < 4) { idbuf[id_len] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_uniden: protocol error," " received %d: '%s'\n", id_len, idbuf); return RIG_MODEL_NONE; } /* search ID string */ for (i = 0; uniden_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!memcmp(uniden_id_string_list[i].id, idbuf + 3, strlen(uniden_id_string_list[i].id))) { rig_debug(RIG_DEBUG_VERBOSE, "probe_uniden: " "found '%s'\n", idbuf + 3); if (cfunc) { (*cfunc)(port, uniden_id_string_list[i].model, data); } return uniden_id_string_list[i].model; } } /* * not found in known table.... * update uniden_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_uniden: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf + 3); return RIG_MODEL_NONE; } /* * initrigs_uniden is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(uniden) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&bc895_caps); rig_register(&bc898_caps); rig_register(&bc245_caps); rig_register(&bc780_caps); rig_register(&bc250_caps); rig_register(&pro2052_caps); rig_register(&bcd396t_caps); rig_register(&bcd996t_caps); return RIG_OK; } hamlib-4.6.5/rigs/uniden/Makefile.in0000664000175000017500000005606515056640453012764 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/uniden ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_uniden_la_LIBADD = am__objects_1 = bc895.lo bc898.lo bc245.lo pro2052.lo bc780.lo \ bc250.lo bcd396t.lo bcd996t.lo uniden.lo uniden_digital.lo am_libhamlib_uniden_la_OBJECTS = $(am__objects_1) libhamlib_uniden_la_OBJECTS = $(am_libhamlib_uniden_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/bc245.Plo ./$(DEPDIR)/bc250.Plo \ ./$(DEPDIR)/bc780.Plo ./$(DEPDIR)/bc895.Plo \ ./$(DEPDIR)/bc898.Plo ./$(DEPDIR)/bcd396t.Plo \ ./$(DEPDIR)/bcd996t.Plo ./$(DEPDIR)/pro2052.Plo \ ./$(DEPDIR)/uniden.Plo ./$(DEPDIR)/uniden_digital.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_uniden_la_SOURCES) DIST_SOURCES = $(libhamlib_uniden_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ UNIDENSRC = bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c bcd396t.c \ bcd996t.c uniden.c uniden.h uniden_digital.c uniden_digital.h noinst_LTLIBRARIES = libhamlib-uniden.la libhamlib_uniden_la_SOURCES = $(UNIDENSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/uniden/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/uniden/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-uniden.la: $(libhamlib_uniden_la_OBJECTS) $(libhamlib_uniden_la_DEPENDENCIES) $(EXTRA_libhamlib_uniden_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_uniden_la_OBJECTS) $(libhamlib_uniden_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc245.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc250.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc780.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc895.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc898.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcd396t.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcd996t.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pro2052.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniden.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniden_digital.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/bc245.Plo -rm -f ./$(DEPDIR)/bc250.Plo -rm -f ./$(DEPDIR)/bc780.Plo -rm -f ./$(DEPDIR)/bc895.Plo -rm -f ./$(DEPDIR)/bc898.Plo -rm -f ./$(DEPDIR)/bcd396t.Plo -rm -f ./$(DEPDIR)/bcd996t.Plo -rm -f ./$(DEPDIR)/pro2052.Plo -rm -f ./$(DEPDIR)/uniden.Plo -rm -f ./$(DEPDIR)/uniden_digital.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/bc245.Plo -rm -f ./$(DEPDIR)/bc250.Plo -rm -f ./$(DEPDIR)/bc780.Plo -rm -f ./$(DEPDIR)/bc895.Plo -rm -f ./$(DEPDIR)/bc898.Plo -rm -f ./$(DEPDIR)/bcd396t.Plo -rm -f ./$(DEPDIR)/bcd996t.Plo -rm -f ./$(DEPDIR)/pro2052.Plo -rm -f ./$(DEPDIR)/uniden.Plo -rm -f ./$(DEPDIR)/uniden_digital.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/uniden/pro2052.c0000664000175000017500000001151315056640443012160 /* * Hamlib Uniden backend - Radio Shack PRO-2052 description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define PRO2052_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define PRO2052_FUNC (RIG_FUNC_MUTE) #define PRO2052_LEVEL_ALL (RIG_LEVEL_NONE) #define PRO2052_PARM_ALL (RIG_PARM_NONE) #define PRO2052_VFO RIG_VFO_A #define PRO2052_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS /* * PRO-2052 rig capabilities. * * From http://www.cantonmaine.com/pro2052.htm: * After connecting the cable, turn on the computer and the scanner and then * press and hold the Remote/Hold button on the scanner until you see "SFT" * flashing on the right side of the LCD. You should now be communicating * with the scanner. If it doesn't work, check all the normal stuff for * whatever it was you overlooked. NOTE: You can change the scanner's * default * baud rate by holding down the Remote/Hold button while turning * on the scanner.) * * TODO: check this with manual or web site. */ struct rig_caps pro2052_caps = { RIG_MODEL(RIG_MODEL_PRO2052), .model_name = "PRO-2052", .mfg_name = "Radio Shack", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = PRO2052_FUNC, .has_set_func = PRO2052_FUNC, .has_get_level = PRO2052_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(PRO2052_LEVEL_ALL), .has_get_parm = PRO2052_PARM_ALL, .has_set_parm = RIG_PARM_SET(PRO2052_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: 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), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .chan_list = { { 0, 999, RIG_MTYPE_MEM, {PRO2052_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(54), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(108), MHz(174), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(179.75), MHz(512), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(806), MHz(823.9375), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(851), MHz(868.9875), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(896.1125), MHz(956), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(1240), MHz(1300), PRO2052_MODES, -1, -1, PRO2052_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {PRO2052_MODES, kHz(5)}, {PRO2052_MODES, kHz(7.5)}, {PRO2052_MODES, kHz(10)}, {PRO2052_MODES, kHz(12.5)}, {PRO2052_MODES, kHz(25)}, {PRO2052_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/bcd996t.c0000664000175000017500000000751515056640443012242 /* * Hamlib Uniden backend - BCD996T description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" /*#include "uniden.h"*/ #include "uniden_digital.h" /* TODO: All these defines have to be filled in properly */ #define BCD996T_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BCD996T_FUNC (RIG_FUNC_MUTE) #define BCD996T_LEVEL_ALL (RIG_LEVEL_ATT) #define BCD996T_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define BCD996T_VFO (RIG_VFO_A|RIG_VFO_B) #define BCD996T_CHANNEL_CAPS \ .freq=1,\ .flags=1, /* L/O */ /* * bcd996t rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bcd996t_caps = { RIG_MODEL(RIG_MODEL_BCD996T), .model_name = "BCD-996T", .mfg_name = "Uniden", .version = BACKEND_DIGITAL_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 2000, .retry = 3, .has_get_func = BCD996T_FUNC, .has_set_func = BCD996T_FUNC, .has_get_level = BCD996T_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BCD996T_LEVEL_ALL), .has_get_parm = BCD996T_PARM_ALL, .has_set_parm = RIG_PARM_SET(BCD996T_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: 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), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 5999, RIG_MTYPE_MEM, {BCD996T_CHANNEL_CAPS} }, /* Really 6000 channels? */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(764), MHz(776), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(794), MHz(956), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(1240), MHz(1300), BCD996T_MODES, -1, -1, BCD996T_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BCD996T_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .get_info = uniden_digital_get_info, .set_freq = uniden_digital_set_freq, .get_freq = uniden_digital_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/uniden_digital.h0000664000175000017500000000247015056640443014035 /* * Hamlib Uniden backend - uniden_digital header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _UNIDEN_DIGITAL_H #define _UNIDEN_DIGITAL_H 1 #include "hamlib/rig.h" #define BACKEND_DIGITAL_VER "20170808" int uniden_digital_transaction (RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize); const char* uniden_digital_get_info(RIG *rig); int uniden_digital_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int uniden_digital_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); #endif /* _UNIDEN_DIGITAL_H */ hamlib-4.6.5/rigs/uniden/bc898.c0000664000175000017500000001124115056640443011702 /* * Hamlib Uniden backend - BC898 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC898_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC898_FUNC (RIG_FUNC_MUTE) #define BC898_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC898_PARM_ALL (RIG_PARM_NONE) #define BC898_VFO RIG_VFO_A #define BC898_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .ctcss_sql=1, \ .dcs_sql=1 /* The BC898 seems to max out at 32 while 12 seems to be about minimum. */ #define BC898_STR_CAL { 4, \ { \ { 0, -54 }, \ { 12, -20 }, /* TBC */ \ { 32, 4 }, /* TBC */ \ { 255, 60 }, \ } } static tone_t bc898_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; /* * bc898 rig capabilities. * * TODO: check this with manual or web site. * http://www.uniden.com/products/productdetail.cfm?product=BC898T&filter=Mobile */ struct rig_caps bc898_caps = { RIG_MODEL(RIG_MODEL_BC898), .model_name = "BC898T", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC898_FUNC, .has_set_func = BC898_FUNC, .has_get_level = BC898_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC898_LEVEL_ALL), .has_get_parm = BC898_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC898_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = bc898_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .str_cal = BC898_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, {BC898_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(956), BC898_MODES, -1, -1, BC898_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* TODO: is it really continuous coverage ? what about cellular? */ {MHz(25), MHz(956), BC898_MODES, -1, -1, BC898_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC898_MODES, kHz(5)}, {BC898_MODES, kHz(6.25)}, {BC898_MODES, kHz(12.5)}, {BC898_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/bc245.c0000664000175000017500000000751015056640443011670 /* * Hamlib Uniden backend - BC245 description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC245_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC245_FUNC (RIG_FUNC_MUTE) #define BC245_LEVEL_ALL (RIG_LEVEL_ATT) #define BC245_PARM_ALL (RIG_PARM_NONE) #define BC245_VFO RIG_VFO_A /* * bc245 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc245_caps = { RIG_MODEL(RIG_MODEL_BC245), .model_name = "BC245xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC245_FUNC, .has_set_func = BC245_FUNC, .has_get_level = BC245_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC245_LEVEL_ALL), .has_get_parm = BC245_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC245_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: 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), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 300, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(54), BC245_MODES, -1, -1, BC245_VFO}, {MHz(108), MHz(174), BC245_MODES, -1, -1, BC245_VFO}, {MHz(406), MHz(512), BC245_MODES, -1, -1, BC245_VFO}, {MHz(806), MHz(956), BC245_MODES, -1, -1, BC245_VFO}, /* TODO: less cellular */ RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC245_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/bcd396t.c0000664000175000017500000000774015056640443012234 /* * Hamlib Uniden backend - BCD396T description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" /*#include "uniden.h"*/ #include "uniden_digital.h" /* TODO: All these defines have to be filled in properly */ #define BCD396T_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BCD396T_FUNC (RIG_FUNC_MUTE) #define BCD396T_LEVEL_ALL (RIG_LEVEL_ATT) #define BCD396T_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define BCD396T_VFO (RIG_VFO_A|RIG_VFO_B) #define BCD396T_CHANNEL_CAPS \ .freq=1,\ .flags=1, /* L/O */ /* * bcd396t rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bcd396t_caps = { RIG_MODEL(RIG_MODEL_BCD396T), .model_name = "BCD-396T", .mfg_name = "Uniden", .version = BACKEND_DIGITAL_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 2000, .retry = 3, .has_get_func = BCD396T_FUNC, .has_set_func = BCD396T_FUNC, .has_get_level = BCD396T_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BCD396T_LEVEL_ALL), .has_get_parm = BCD396T_PARM_ALL, .has_set_parm = RIG_PARM_SET(BCD396T_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: 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), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 5999, RIG_MTYPE_MEM, {BCD396T_CHANNEL_CAPS} }, /* Really 6000 channels? */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(764), MHz(775.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(794), MHz(823.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(849.0125), MHz(868.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(894.0125), MHz(956), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(1240), MHz(1300), BCD396T_MODES, -1, -1, BCD396T_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BCD396T_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .get_info = uniden_digital_get_info, .set_freq = uniden_digital_set_freq, .get_freq = uniden_digital_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/uniden/Makefile.am0000664000175000017500000000036715056640443012744 UNIDENSRC = bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c bcd396t.c \ bcd996t.c uniden.c uniden.h uniden_digital.c uniden_digital.h noinst_LTLIBRARIES = libhamlib-uniden.la libhamlib_uniden_la_SOURCES = $(UNIDENSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/adat/0000775000175000017500000000000015056640475010416 5hamlib-4.6.5/rigs/adat/Android.mk0000664000175000017500000000042215056640442012237 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := adat.c adt_200a.c LOCAL_MODULE := adat LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := $(LOCAL_SHARED_LIBRARIES) -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/adat/adat.h0000664000175000017500000004371215056640442011421 // --------------------------------------------------------------------------- // ADAT // --------------------------------------------------------------------------- // // adat.h // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #if !defined( __ADAT_INCLUDED__ ) #define __ADAT_INCLUDED__ // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "token.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- #define BACKEND_VER "20230927" #define ADAT_BUFSZ 255 #define ADAT_RESPSZ 255 #define ADAT_CR "\x0d" #define ADAT_EOL "\x0a" #define ADAT_BOM "$" // Begin of message #define ADAT_EOM ADAT_CR // End of message #define ADAT_ON 1 #define ADAT_OFF 0 #define ADAT_TOGGLE_ON ADAT_ON #define ADAT_TOGGLE_OFF ADAT_OFF #define ADAT_FREQ_UNIT_HZ "Hz" #define ADAT_FREQ_UNIT_HZ_LEN 2 #define ADAT_FREQ_UNIT_KHZ "kHz" #define ADAT_FREQ_UNIT_KHZ_LEN 3 #define ADAT_FREQ_UNIT_MHZ "MHz" #define ADAT_FREQ_UNIT_MHZ_LEN 3 #define ADAT_FREQ_UNIT_GHZ "GHz" #define ADAT_FREQ_UNIT_GHZ_LEN 3 #define TOKEN_ADAT_PRODUCT_NAME TOKEN_BACKEND(1) #define ADAT_SLEEP_MICROSECONDS_BETWEEN_CMDS (11*1000) // = 11 ms #define ADAT_SLEEP_AFTER_RIG_CLOSE 2 // unit: seconds #define ADAT_SLEEP_AFTER_RIG_OPEN 2 // unit: seconds // ADAT VFO SET/GET DEFINITIONS #define ADAT_NR_VFOS 3 // Each mode is defined by three values: // ADAT_VFO_STR_... -> The string as given back by TRX when asked by // $VFO? // ADAT_VFO_RNR_... -> The Hamlib number of the mode: RIG_VFO_... // ADAT_VFO_ANR_... -> The ADAT Nr representing the VFO when setting it #define ADAT_VFO_STR_A "A" #define ADAT_VFO_RNR_A RIG_VFO_A #define ADAT_VFO_ANR_A 1 #define ADAT_VFO_STR_B "B" #define ADAT_VFO_RNR_B RIG_VFO_B #define ADAT_VFO_ANR_B 2 #define ADAT_VFO_STR_C "C" #define ADAT_VFO_RNR_C RIG_VFO_C #define ADAT_VFO_ANR_C 3 // ADAT MODE DEFINITIONS #define ADAT_MODE_LENGTH 15 #define ADAT_NR_MODES 8 // Each mode is defined by three values: // ADAT_MODE_STR_... -> The string as given back by TRX when asked by // $MOD? // ADAT_MODE_RNR_... -> The Hamlib number of the mode: RIG_MODE_... // ADAT_MODE_ANR_... -> The ADAT Nr representing the mode when setting it #define ADAT_MODE_STR_CW_R "CW-R" #define ADAT_MODE_RNR_CW_R RIG_MODE_CWR #define ADAT_MODE_ANR_CW_R 0 #define ADAT_MODE_STR_CW "CW" #define ADAT_MODE_RNR_CW RIG_MODE_CW #define ADAT_MODE_ANR_CW 1 #define ADAT_MODE_STR_LSB "LSB" #define ADAT_MODE_RNR_LSB RIG_MODE_LSB #define ADAT_MODE_ANR_LSB 2 #define ADAT_MODE_STR_USB "USB" #define ADAT_MODE_RNR_USB RIG_MODE_USB #define ADAT_MODE_ANR_USB 3 #define ADAT_MODE_STR_AM "AM" #define ADAT_MODE_RNR_AM RIG_MODE_AM #define ADAT_MODE_ANR_AM 5 #define ADAT_MODE_STR_AM_SL "AM-SL" #define ADAT_MODE_RNR_AM_SL RIG_MODE_SAL #define ADAT_MODE_ANR_AM_SL 6 #define ADAT_MODE_STR_AM_SU "AM-SU" #define ADAT_MODE_RNR_AM_SU RIG_MODE_SAH #define ADAT_MODE_ANR_AM_SU 7 #define ADAT_MODE_STR_FM "FM" #define ADAT_MODE_RNR_FM RIG_MODE_FM #define ADAT_MODE_ANR_FM 8 // ADAT PTT DEFINITIONS #define ADAT_PTT_STATUS_ANR_ON ADAT_ON #define ADAT_PTT_STATUS_RNR_ON RIG_PTT_ON #define ADAT_PTT_STATUS_ANR_OFF ADAT_OFF #define ADAT_PTT_STATUS_RNR_OFF RIG_PTT_OFF // ADAT POWER LEVEL DEFINITIONS #define ADAT_PWR_LVL_ANR_00 0 #define ADAT_PWR_LVL_RNR_00 100 // 100 mW #define ADAT_PWR_LVL_ANR_01 1 #define ADAT_PWR_LVL_RNR_01 300 // 300 mW #define ADAT_PWR_LVL_ANR_02 2 #define ADAT_PWR_LVL_RNR_02 1000 // ... #define ADAT_PWR_LVL_ANR_03 3 #define ADAT_PWR_LVL_RNR_03 2000 #define ADAT_PWR_LVL_ANR_04 4 #define ADAT_PWR_LVL_RNR_04 3000 #define ADAT_PWR_LVL_ANR_05 5 #define ADAT_PWR_LVL_RNR_05 5000 #define ADAT_PWR_LVL_ANR_06 6 #define ADAT_PWR_LVL_RNR_06 7000 #define ADAT_PWR_LVL_ANR_07 7 #define ADAT_PWR_LVL_RNR_07 10000 #define ADAT_PWR_LVL_ANR_08 8 #define ADAT_PWR_LVL_RNR_08 15000 #define ADAT_PWR_LVL_ANR_09 9 #define ADAT_PWR_LVL_RNR_09 20000 #define ADAT_PWR_LVL_ANR_10 10 #define ADAT_PWR_LVL_RNR_10 25000 #define ADAT_PWR_LVL_ANR_11 11 #define ADAT_PWR_LVL_RNR_11 30000 #define ADAT_PWR_LVL_ANR_12 12 #define ADAT_PWR_LVL_RNR_12 35000 #define ADAT_PWR_LVL_ANR_13 13 #define ADAT_PWR_LVL_RNR_13 40000 #define ADAT_PWR_LVL_ANR_14 14 // Default value after reset #define ADAT_PWR_LVL_RNR_14 45000 #define ADAT_PWR_LVL_ANR_15 15 #define ADAT_PWR_LVL_RNR_15 50000 // 50 W #define ADAT_MAX_POWER_IN_mW ADAT_PWR_LVL_RNR_15 // ADAT CHANNEL CAPS #define ADAT_MEM_CAPS \ { \ .vfo = 1, \ .ant = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .tx_vfo = 1, \ .rit = 1, \ .xit = 1, \ .tuning_step = 1, \ .channel_desc = 1 \ } #define ADAT_MEM_DESC_SIZE 64 // ADAT OPCODES - Kind of an internal command within ADAT Hamlib Backend #define ADAT_OPCODE_BASE_PTT 110000 #define ADAT_OPCODE_PTT_SWITCH_ON (ADAT_OPCODE_BASE_PTT + 1) #define ADAT_OPCODE_PTT_SWITCH_OFF (ADAT_OPCODE_BASE_PTT + 2) // --------------------------------------------------------------------------- // Individual ADAT CAT commands // --------------------------------------------------------------------------- #define ADAT_CMD_DEF_ADAT_SPECIAL (1<<30) // -- NIL -- (Marks the end of a cmd list) #define ADAT_CMD_DEF_NIL 0 // -- ADAT SPECIAL: DISPLAY OFF -- #define ADAT_CMD_DEF_STRING_DISPLAY_OFF "$VRU>"ADAT_CR // -- ADAT SPECIAL: DISPLAY ON -- #define ADAT_CMD_DEF_STRING_DISPLAY_ON "$VRU<"ADAT_CR // -- ADAT SPECIAL: GET SERIAL NR -- #define ADAT_CMD_DEF_STRING_GET_SERIAL_NR "$CIS?"ADAT_CR // -- ADAT SPECIAL: GET FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_FW_VERSION "$CIF?"ADAT_CR // -- ADAT SPECIAL: GET HARDWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_HW_VERSION "$CIH?"ADAT_CR // -- ADAT SPECIAL: GET FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_ID_CODE "$CID?"ADAT_CR // -- ADAT SPECIAL: GET GUI FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION "$CIG?"ADAT_CR // -- ADAT SPECIAL: GET OPTIONS -- #define ADAT_CMD_DEF_STRING_GET_OPTIONS "$CIO?"ADAT_CR // -- ADAT SPECIAL: GET CALLSIGN -- #define ADAT_CMD_DEF_STRING_GET_CALLSIGN "$CAL?"ADAT_CR // -- ADAT SPECIAL: SET CALLSIGN -- #define ADAT_CMD_DEF_STRING_SET_CALLSIGN "$CAL:" // -- HAMLIB DEFINED COMMANDS -- // -- GET FREQ -- #define ADAT_CMD_DEF_GET_FREQ (1<<0) #define ADAT_CMD_DEF_STRING_GET_FREQ "$FRA?"ADAT_CR // -- SET FREQ -- #define ADAT_CMD_DEF_SET_FREQ (1<<1) #define ADAT_CMD_DEF_STRING_SET_FREQ "$FR1:" // -- GET VFO -- // -- GET MODE -- #define ADAT_CMD_DEF_GET_MODE (1<<2) #define ADAT_CMD_DEF_STRING_GET_MODE "$MOD?"ADAT_CR // -- SET VFO -- #define ADAT_CMD_DEF_SET_VFO (1<<3) #define ADAT_CMD_DEF_STRING_SWITCH_ON_VFO "$VO%1d>%s" #define ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO "$VO%1d%%%s" // -- SET MODE -- #define ADAT_CMD_DEF_SET_MODE (1<<4) #define ADAT_CMD_DEF_STRING_SET_MODE "$MOD:" // -- SET PTT -- #define ADAT_CMD_DEF_SET_PTT (1<<5) #define ADAT_CMD_DEF_STRING_SET_PTT "$MOX%s%s" #define ADAT_CMD_PTT_STR_OFF "<" #define ADAT_CMD_PTT_STR_ON ">" // -- GET PTT -- #define ADAT_CMD_DEF_GET_PTT (1<<6) #define ADAT_CMD_DEF_STRING_GET_PTT "$MTR?"ADAT_CR // -- GET POWER STATUS -- // -- GET INFO -- // Nothing to define here // -- OPEN ADAT -- // Nothing to define here // -- ADAT SPECIAL: RECOVER FROM ERROR -- // Nothing to define here // --------------------------------------------------------------------------- // ADAT PRIVATE DATA // --------------------------------------------------------------------------- #define ADAT_PRIV_DATA_PRODUCTNAME_LENGTH 255 #define ADAT_PRIV_DATA_SERIALNR_LENGTH 255 #define ADAT_PRIV_DATA_IDCODE_LENGTH 255 #define ADAT_PRIV_DATA_OPTIONS_LENGTH 255 #define ADAT_PRIV_DATA_FWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_HWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_GUIFWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_CALLSIGN_LENGTH 255 #define ADAT_PRIV_DATA_CMD_LENGTH 255 #define ADAT_PRIV_DATA_RESULT_LENGTH 255 typedef struct _adat_priv_data { int nOpCode; char acProductName[ ADAT_PRIV_DATA_PRODUCTNAME_LENGTH + 1]; // Future use (USB direct I/O) // ADAT device info char acSerialNr[ ADAT_PRIV_DATA_SERIALNR_LENGTH + 1 ]; char acIDCode[ ADAT_PRIV_DATA_IDCODE_LENGTH + 1 ]; char acOptions[ ADAT_PRIV_DATA_OPTIONS_LENGTH + 1 ]; char acFWVersion[ ADAT_PRIV_DATA_FWVERSION_LENGTH + 1 ]; char acHWVersion[ ADAT_PRIV_DATA_HWVERSION_LENGTH + 1 ]; char acGUIFWVersion[ ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1 ]; char acCallsign[ ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1 ]; // ADAT Operational Settings: will change during TRX use int nCurrentVFO; vfo_t nRIGVFONr; freq_t nFreq; char acRXFreq[ ADAT_BUFSZ ]; char acTXFreq[ ADAT_BUFSZ ]; rmode_t nRIGMode; char acADATMode[ ADAT_MODE_LENGTH + 1 ]; int nADATMode; pbwidth_t nWidth; int nADATPTTStatus; ptt_t nRIGPTTStatus; value_t mNB1; value_t mNB2; value_t mAGC; value_t mRFGain; value_t mIFShift; value_t mRawStr; // ADAT Command-related Values char acCmd[ ADAT_PRIV_DATA_CMD_LENGTH + 1 ]; int nCmdKind; char acResult[ ADAT_PRIV_DATA_RESULT_LENGTH + 1 ]; int nRC; } adat_priv_data_t, * adat_priv_data_ptr; // --------------------------------------------------------------------------- // ADAT CAT COMMAND DATA TYPE DECLARATIONS // --------------------------------------------------------------------------- typedef unsigned long long adat_cmd_id_t; // Bit mask for commands. Each command // is represented by 1 bit. // adat_cmd_def : ADAT COMMAND DEFINITION. // Basic idea: Each command can be made of several strings to be sent // to the ADAT device. Therefore it is possible to build aggregated // commands which will be executed as a set of individual commands // executed by adat_transaction(). The last value as returned by the // commands will be set as overall command result. typedef enum { ADAT_CMD_KIND_WITH_RESULT = 0, // After sending a command to the ADAT, // a result has to be read. ADAT_CMD_KIND_WITHOUT_RESULT = 1 } adat_cmd_kind_t; typedef struct _adat_cmd_def_t { adat_cmd_id_t nCmdId; // Bit indicating this cmd adat_cmd_kind_t nCmdKind; // Defines if result expected int (*pfCmdFn)(RIG *pRig); // Fn to be called to execute this cmd int nNrCmdStrs; // Oh my, C as a language ... I'd love to // switch to Common Lisp ... What a hack here ... char *pacCmdStrs[]; // Commands to be executed if no CmdFn given } adat_cmd_def_t, * adat_cmd_def_ptr; typedef struct _adat_cmd_table_t { int nNrCmds; adat_cmd_def_ptr adat_cmds[]; } adat_cmd_table_t, * adat_cmd_table_ptr; typedef struct _adat_cmd_list_t { int nNrCmds; adat_cmd_def_ptr adat_cmds[]; } adat_cmd_list_t, * adat_cmd_list_ptr; // --------------------------------------------------------------------------- // OTHER ADAT DATA TYPES // --------------------------------------------------------------------------- typedef enum { ADAT_FREQ_PARSE_MODE_WITH_VFO = 0, ADAT_FREQ_PARSE_MODE_WITHOUT_VFO = 1 } adat_freq_parse_mode_t; // ADAT MODE DEFINITION typedef struct _adat_mode_def { char *pcADATModeStr; rmode_t nRIGMode; int nADATMode; } adat_mode_def_t, * adat_mode_def_ptr; typedef struct _adat_mode_list { int nNrModes; adat_mode_def_t adat_modes[ ADAT_NR_MODES ]; } adat_mode_list_t, * adat_mode_list_ptr; // ADAT VFO DEFINITION typedef struct _adat_vfo_def { char *pcADATVFOStr; vfo_t nRIGVFONr; int nADATVFONr; } adat_vfo_def_t, * adat_vfo_def_ptr; typedef struct _adat_vfo_list { int nNrVFOs; adat_vfo_def_t adat_vfos[ ADAT_NR_VFOS ]; } adat_vfo_list_t, * adat_vfo_list_ptr; // --------------------------------------------------------------------------- // ADAT INTERNAL FUNCTION DECLARATIONS // --------------------------------------------------------------------------- // Helper functions size_t trimwhitespace(char *, size_t, const char *); int adat_print_cmd(adat_cmd_def_ptr); int adat_parse_freq(char *, adat_freq_parse_mode_t, int *, freq_t *); int adat_parse_mode(char *, rmode_t *, char *); int adat_mode_rnr2anr(rmode_t, int *); #ifdef XXREMOVEDXX // this function wasn't referenced anywhere int adat_mode_anr2rnr(int, rmode_t *); #endif #ifdef XXREMOVEDXX // this function wasn't referenced anywhere int adat_parse_vfo(char *, vfo_t *, int *); #endif int adat_vfo_rnr2anr(vfo_t, int *); int adat_vfo_anr2rnr(int, vfo_t *); int adat_parse_ptt(char *, int *); int adat_ptt_rnr2anr(ptt_t, int *); int adat_ptt_anr2rnr(int, ptt_t *); int adat_send(RIG *, char *); int adat_receive(RIG *, char *); int adat_priv_set_cmd(RIG *, char *, int); int adat_priv_set_result(RIG *, char *); int adat_priv_clear_result(RIG *); int adat_get_single_cmd_result(RIG *); int adat_cmd_recover_from_error(RIG *, int); int adat_transaction(RIG *, adat_cmd_list_ptr); // Command implementation int adat_cmd_fn_get_serial_nr(RIG *); int adat_cmd_fn_get_fw_version(RIG *); int adat_cmd_fn_get_hw_version(RIG *); int adat_cmd_fn_get_gui_fw_version(RIG *); int adat_cmd_fn_get_id_code(RIG *); int adat_cmd_fn_get_options(RIG *); int adat_cmd_fn_get_callsign(RIG *); int adat_cmd_fn_set_freq(RIG *); int adat_cmd_fn_get_freq(RIG *); int adat_cmd_fn_get_mode(RIG *); int adat_cmd_fn_set_mode(RIG *); int adat_cmd_fn_get_vfo(RIG *); int adat_cmd_fn_set_vfo(RIG *); int adat_cmd_fn_get_ptt(RIG *); int adat_cmd_fn_set_ptt(RIG *); // --------------------------------------------------------------------------- // ADAT FUNCTION DECLARATIONS // --------------------------------------------------------------------------- int adat_init(RIG *); int adat_cleanup(RIG *); int adat_reset(RIG *, reset_t); int adat_open(RIG *); int adat_close(RIG *); int adat_set_conf(RIG *, hamlib_token_t, const char *val); int adat_get_conf(RIG *, hamlib_token_t, char *val); int adat_set_freq(RIG *, vfo_t, freq_t); int adat_get_freq(RIG *, vfo_t, freq_t *); int adat_set_vfo(RIG *, vfo_t); int adat_get_vfo(RIG *, vfo_t *); int adat_set_ptt(RIG *, vfo_t, ptt_t); int adat_get_ptt(RIG *, vfo_t, ptt_t *); int adat_set_mode(RIG *, vfo_t, rmode_t, pbwidth_t); int adat_get_mode(RIG *, vfo_t, rmode_t *, pbwidth_t *); int adat_set_func(RIG *, vfo_t, setting_t func, int); int adat_get_func(RIG *, vfo_t, setting_t func, int *); int adat_set_level(RIG *, vfo_t, setting_t level, value_t); int adat_get_level(RIG *, vfo_t, setting_t level, value_t *); int adat_handle_event(RIG *); const char *adat_get_info(RIG *); int adat_mW2power(RIG *, float *, unsigned int, freq_t, rmode_t); int adat_power2mW(RIG *, unsigned int *, float, freq_t, rmode_t); int adat_get_powerstat(RIG *, powerstat_t *); extern struct rig_caps adt_200a_caps; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- #endif hamlib-4.6.5/rigs/adat/adat.c0000664000175000017500000025603715056640442011422 // --------------------------------------------------------------------------- // ADAT Hamlib Backend // --------------------------------------------------------------------------- // // adat.c // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include #include #include #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "serial.h" #include "misc.h" #include "register.h" #include "riglist.h" // --------------------------------------------------------------------------- // ADAT INCLUDES // --------------------------------------------------------------------------- #include "adat.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- #if !defined(NDEBUG) # define ADAT_DEBUG 1 #endif // --------------------------------------------------------------------------- // ADAT GLOBAL VARIABLES // --------------------------------------------------------------------------- // DEBUG STUFF static int gFnLevel = 0; static adat_priv_data_t gsADATPrivData; // ADAT private state data // ADAT MODES static adat_mode_list_t the_adat_mode_list = { ADAT_NR_MODES, { { ADAT_MODE_STR_CW_R, ADAT_MODE_RNR_CW_R, ADAT_MODE_ANR_CW_R }, { ADAT_MODE_STR_CW, ADAT_MODE_RNR_CW, ADAT_MODE_ANR_CW }, { ADAT_MODE_STR_LSB, ADAT_MODE_RNR_LSB, ADAT_MODE_ANR_LSB }, { ADAT_MODE_STR_USB, ADAT_MODE_RNR_USB, ADAT_MODE_ANR_USB }, { ADAT_MODE_STR_AM, ADAT_MODE_RNR_AM, ADAT_MODE_ANR_AM }, { ADAT_MODE_STR_AM_SL, ADAT_MODE_RNR_AM_SL, ADAT_MODE_ANR_AM_SL }, { ADAT_MODE_STR_AM_SU, ADAT_MODE_RNR_AM_SU, ADAT_MODE_ANR_AM_SU }, { ADAT_MODE_STR_FM, ADAT_MODE_RNR_FM, ADAT_MODE_ANR_FM } } }; // ADAT VFOS static adat_vfo_list_t the_adat_vfo_list = { ADAT_NR_VFOS, { { ADAT_VFO_STR_A, ADAT_VFO_RNR_A, ADAT_VFO_ANR_A }, { ADAT_VFO_STR_B, ADAT_VFO_RNR_B, ADAT_VFO_ANR_B }, { ADAT_VFO_STR_C, ADAT_VFO_RNR_C, ADAT_VFO_ANR_C } } }; // --------------------------------------------------------------------------- // Individual ADAT CAT commands // --------------------------------------------------------------------------- // -- NIL -- (Marks the end of a cmd list) #if 0 static adat_cmd_def_t adat_cmd_nil = { ADAT_CMD_DEF_NIL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 0, { NULL } }; #endif // -- ADAT SPECIAL: DISPLAY OFF -- static adat_cmd_def_t adat_cmd_display_off = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 1, { ADAT_CMD_DEF_STRING_DISPLAY_OFF } }; // -- ADAT SPECIAL: DISPLAY ON -- static adat_cmd_def_t adat_cmd_display_on = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 1, { ADAT_CMD_DEF_STRING_DISPLAY_ON } }; // -- ADAT SPECIAL: SELECT VFO -- // -- ADAT SPECIAL: GET SERIAL NR -- static adat_cmd_def_t adat_cmd_get_serial_nr = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_serial_nr, 1, { ADAT_CMD_DEF_STRING_GET_SERIAL_NR } }; // -- ADAT SPECIAL: GET FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_fw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_fw_version, 1, { ADAT_CMD_DEF_STRING_GET_FW_VERSION } }; // -- ADAT SPECIAL: GET HARDWARE VERSION -- static adat_cmd_def_t adat_cmd_get_hw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_hw_version, 1, { ADAT_CMD_DEF_STRING_GET_HW_VERSION } }; // -- ADAT SPECIAL: GET FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_id_code = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_id_code, 1, { ADAT_CMD_DEF_STRING_GET_ID_CODE } }; // -- ADAT SPECIAL: GET GUI FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_gui_fw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_gui_fw_version, 1, { ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION } }; // -- ADAT SPECIAL: GET OPTIONS -- static adat_cmd_def_t adat_cmd_get_options = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_options, 1, { ADAT_CMD_DEF_STRING_GET_OPTIONS } }; // -- ADAT SPECIAL: GET CALLSIGN -- static adat_cmd_def_t adat_cmd_get_callsign = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_callsign, 1, { ADAT_CMD_DEF_STRING_GET_CALLSIGN } }; // -- HAMLIB DEFINED COMMANDS -- // -- GET FREQ -- static adat_cmd_def_t adat_cmd_get_freq = { ADAT_CMD_DEF_GET_FREQ, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_freq, 1, { ADAT_CMD_DEF_STRING_GET_FREQ } }; static adat_cmd_list_t adat_cmd_list_get_freq = { 2, { &adat_cmd_display_off, &adat_cmd_get_freq } }; // -- SET FREQ -- static adat_cmd_def_t adat_cmd_set_freq = { ADAT_CMD_DEF_SET_FREQ, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_freq, 1, { ADAT_CMD_DEF_STRING_SET_FREQ } }; static adat_cmd_list_t adat_cmd_list_set_freq = { 3, { &adat_cmd_display_off, &adat_cmd_set_freq, &adat_cmd_get_freq, } }; // -- GET VFO -- static adat_cmd_list_t adat_cmd_list_get_vfo = { 2, { &adat_cmd_display_off, &adat_cmd_get_freq, } }; // -- GET MODE -- static adat_cmd_def_t adat_cmd_get_mode = { ADAT_CMD_DEF_GET_MODE, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_mode, 1, { ADAT_CMD_DEF_STRING_GET_MODE } }; static adat_cmd_list_t adat_cmd_list_get_mode = { 2, { &adat_cmd_display_off, &adat_cmd_get_mode } }; // -- SET VFO -- static adat_cmd_def_t adat_cmd_set_vfo = { ADAT_CMD_DEF_SET_VFO, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_vfo, 2, { ADAT_CMD_DEF_STRING_SWITCH_ON_VFO, ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO } }; static adat_cmd_list_t adat_cmd_list_set_vfo = { 2, { &adat_cmd_display_off, &adat_cmd_set_vfo } }; // -- SET MODE -- static adat_cmd_def_t adat_cmd_set_mode = { ADAT_CMD_DEF_SET_MODE, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_mode, 1, { ADAT_CMD_DEF_STRING_SET_MODE } }; static adat_cmd_list_t adat_cmd_list_set_mode = { 3, { &adat_cmd_display_off, &adat_cmd_set_vfo, &adat_cmd_set_mode, } }; // -- SET PTT -- static adat_cmd_def_t adat_cmd_set_ptt = { ADAT_CMD_DEF_SET_PTT, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_ptt, 1, { ADAT_CMD_DEF_STRING_SET_PTT } }; static adat_cmd_list_t adat_cmd_list_set_ptt = { 2, { &adat_cmd_set_ptt, &adat_cmd_display_off } }; // -- GET PTT -- static adat_cmd_def_t adat_cmd_get_ptt = { ADAT_CMD_DEF_GET_PTT, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_ptt, 1, { ADAT_CMD_DEF_STRING_GET_PTT } }; static adat_cmd_list_t adat_cmd_list_get_ptt = { 2, { &adat_cmd_display_off, &adat_cmd_get_ptt } }; // -- GET POWER STATUS -- static adat_cmd_list_t adat_cmd_list_get_powerstatus = { 1, { &adat_cmd_get_id_code } }; // -- GET INFO -- static adat_cmd_list_t adat_cmd_list_get_info = { 7, { &adat_cmd_get_serial_nr, &adat_cmd_get_id_code, &adat_cmd_get_fw_version, &adat_cmd_get_gui_fw_version, &adat_cmd_get_hw_version, &adat_cmd_get_options, &adat_cmd_get_callsign } }; // -- OPEN ADAT -- static adat_cmd_list_t adat_cmd_list_open_adat = { 8, { &adat_cmd_display_off, &adat_cmd_get_serial_nr, &adat_cmd_get_id_code, &adat_cmd_get_fw_version, &adat_cmd_get_gui_fw_version, &adat_cmd_get_hw_version, &adat_cmd_get_options, &adat_cmd_get_callsign } }; // -- CLOSE ADAT -- static adat_cmd_list_t adat_cmd_list_close_adat = { 1, { &adat_cmd_display_on } }; // -- ADAT SPECIAL: RECOVER FROM ERROR -- static adat_cmd_list_t adat_cmd_list_recover_from_error = { 1, { &adat_cmd_display_on } }; // --------------------------------------------------------------------------- // IMPLEMENTATION // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // trimwhitespace - taken from Stackoverflow // http://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way // --------------------------------------------------------------------------- // Status: RELEASED size_t trimwhitespace(char *out, size_t len, const char *str) { char *end = NULL; size_t out_size = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. In -> '%s', %d\n", gFnLevel, __func__, __FILE__, __LINE__, str, (int)len); if (len == 0) { gFnLevel--; return 0; } // Trim leading space while (isspace((int)*str)) { str++; } if (*str == 0) // All spaces? { out = NULL; gFnLevel--; return 1; } // Trim trailing space end = (char *)(str + strlen(str) - 1); while (end > str && isspace((int)*end)) { *end = '\0'; end--; } // Set output size to minimum of trimmed string length and buffer size minus 1 //out_size = (end - str) < len-1 ? (end - str) : len - 1; out_size = strlen(str); // Copy trimmed string and add null terminator memcpy(out, str, out_size); out[out_size] = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Out -> \"%s\", %d\n", gFnLevel, __func__, __FILE__, __LINE__, out, (int)out_size); gFnLevel--; return out_size; } // --------------------------------------------------------------------------- // adat_print_cmd // --------------------------------------------------------------------------- // Status: RELEASED int adat_print_cmd(adat_cmd_def_ptr pCmd) { int nRC = RIG_OK; int nI = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %s (%s:%d): ENTRY.\n", __func__, __FILE__, __LINE__); rig_debug(RIG_DEBUG_TRACE, "*** -> Command ID = %u\n", (unsigned int)(pCmd->nCmdId)); rig_debug(RIG_DEBUG_TRACE, "*** -> Command kind = %d\n", pCmd->nCmdKind); while (nI < pCmd->nNrCmdStrs) { rig_debug(RIG_DEBUG_TRACE, "*** -> Command String %d = \"%s\"\n", nI, pCmd->pacCmdStrs[ nI ]); nI++; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %s (%s:%d): EXIT. Return Code = %d\n", __func__, __FILE__, __LINE__, nRC); return nRC; } // --------------------------------------------------------------------------- // adat_parse_freq // --------------------------------------------------------------------------- // Status: RELEASED // Can be used to parse strings with VFO nr and without VFO nr in it: // "1 123.456kHz" => nMode = ADAT_FREQ_PARSE_MODE_WITH_VFO // "800Hz" => nMode = ADAT_FREQ_PARSE_MODE_WITHOUT_VFO int adat_parse_freq(char *pcStr, adat_freq_parse_mode_t nMode, int *nVFO, freq_t *nFreq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int _nVFO = 0; char *pcEnd = NULL; if (nMode == ADAT_FREQ_PARSE_MODE_WITH_VFO) { // Get VFO from response string _nVFO = strtol(pcStr, &pcEnd, 10); // Save VFO *nVFO = _nVFO; } else { pcEnd = pcStr; } if ((_nVFO != 0) // VFO = 0 -> Current VFO not active. || (nMode == ADAT_FREQ_PARSE_MODE_WITHOUT_VFO)) { char acValueBuf[ ADAT_BUFSZ + 1 ]; char acUnitBuf[ ADAT_BUFSZ + 1 ]; int nI = 0; double dTmpFreq = 0.0; freq_t _nFreq; memset(acValueBuf, 0, ADAT_BUFSZ + 1); memset(acUnitBuf, 0, ADAT_BUFSZ + 1); // Get Freq Value from response string while ((isalpha((int)*pcEnd) == 0) || (*pcEnd == '.')) { acValueBuf[ nI++ ] = *pcEnd; pcEnd += sizeof(char); } dTmpFreq = strtod(acValueBuf, (char **) NULL); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acValueBuf = \"%s\", dTmpFreq = %f, *pcEnd = %c\n", gFnLevel, acValueBuf, dTmpFreq, *pcEnd); // Get Freq Unit from response string nI = 0; while (isalpha((int)*pcEnd) != 0) { acUnitBuf[ nI++ ] = *pcEnd; pcEnd += sizeof(char); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acUnitBuf = \"%s\"\n", gFnLevel, acUnitBuf); // Normalize to Hz if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_HZ, ADAT_FREQ_UNIT_HZ_LEN)) { _nFreq = Hz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_KHZ, ADAT_FREQ_UNIT_KHZ_LEN)) { _nFreq = kHz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_MHZ, ADAT_FREQ_UNIT_MHZ_LEN)) { _nFreq = MHz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_GHZ, ADAT_FREQ_UNIT_GHZ_LEN)) { _nFreq = GHz(dTmpFreq); } else { _nFreq = 0; nRC = -RIG_EINVAL; } } } } // Save Freq *nFreq = _nFreq; } } else { // If input string is NULL set Freq and VFO also to NULL *nFreq = 0; *nVFO = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, nVFO = %d, nFreq = %f\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nVFO, *nFreq); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_parse_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_mode(char *pcStr, rmode_t *nRIGMode, char *pcADATMode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int nI = 0; int nFini = 0; while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (!strcmp(pcStr, the_adat_mode_list.adat_modes[ nI ].pcADATModeStr)) { *nRIGMode = the_adat_mode_list.adat_modes[ nI ].nRIGMode; nFini = 1; // Done. } else { nI++; } } } else { // If input string is NULL ... *nRIGMode = RIG_MODE_NONE; *pcADATMode = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, Mode = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, (int)*nRIGMode); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_mode_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_mode_rnr2anr(rmode_t nRIGMode, int *nADATMode) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGMode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, (unsigned int)nRIGMode); while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (the_adat_mode_list.adat_modes[ nI ].nRIGMode == nRIGMode) { *nADATMode = the_adat_mode_list.adat_modes[ nI ].nADATMode; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT Mode = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATMode); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_mode_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_mode_anr2rnr(int nADATMode, rmode_t *nRIGMode) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGMode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, (unsigned int)*nRIGMode); while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (the_adat_mode_list.adat_modes[ nI ].nADATMode == nADATMode) { *nRIGMode = the_adat_mode_list.adat_modes[ nI ].nRIGMode; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG Mode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, (unsigned int)*nRIGMode); gFnLevel--; return nRC; } #ifdef XXREMOVEDXX // this function wasn't referenced anywhere // --------------------------------------------------------------------------- // adat_parse_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_vfo(char *pcStr, vfo_t *nRIGVFONr, int *nADATVFONr) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int nI = 0; int nFini = 0; while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (!strcmp(pcStr, the_adat_vfo_list.adat_vfos[ nI ].pcADATVFOStr)) { *nRIGVFONr = the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr; *nADATVFONr = the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { nRC = -RIG_EINVAL; } } else { // If input string is NULL ... *nRIGVFONr = RIG_VFO_NONE; *nADATVFONr = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG VFO Nr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGVFONr); gFnLevel--; return nRC; } #endif // --------------------------------------------------------------------------- // adat_vfo_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_vfo_rnr2anr(vfo_t nRIGVFONr, int *nADATVFONr) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGVFONr = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRIGVFONr); while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr == nRIGVFONr) { *nADATVFONr = the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT VFO Nr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATVFONr); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_vfo_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_vfo_anr2rnr(int nADATVFONr, vfo_t *nRIGVFONr) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nADATVFONr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nADATVFONr); while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr == nADATVFONr) { *nRIGVFONr = the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid ADAT VFO Nr given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG VFO Nr = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGVFONr); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_parse_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_ptt(char *pcStr, int *nADATPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if ((pcStr != NULL) && (strlen(pcStr) > 0)) { *nADATPTTStatus = strtol(pcStr, NULL, 10); } else { // If input string is NULL ... *nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } #ifdef XXREMOVEDXX // this function wasn't referenced anywhere // --------------------------------------------------------------------------- // adat_ptt_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_ptt_rnr2anr(ptt_t nRIGPTTStatus, int *nADATPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGPTTStatus = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRIGPTTStatus); switch (nRIGPTTStatus) { case ADAT_PTT_STATUS_RNR_ON: *nADATPTTStatus = ADAT_PTT_STATUS_ANR_ON; break; case ADAT_PTT_STATUS_RNR_OFF: *nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; break; default: nRC = -RIG_EINVAL; break; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT PTT Status = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATPTTStatus); gFnLevel--; return nRC; } #endif // --------------------------------------------------------------------------- // adat_ptt_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_ptt_anr2rnr(int nADATPTTStatus, ptt_t *nRIGPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nADATPTTStatus = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nADATPTTStatus); switch (nADATPTTStatus) { case ADAT_PTT_STATUS_ANR_ON: *nRIGPTTStatus = ADAT_PTT_STATUS_RNR_ON; break; case ADAT_PTT_STATUS_ANR_OFF: *nRIGPTTStatus = ADAT_PTT_STATUS_RNR_OFF; break; default: nRC = -RIG_EINVAL; break; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG PTT Status = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGPTTStatus); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_send // --------------------------------------------------------------------------- // Status: RELEASED int adat_send(RIG *pRig, char *pcData) { int nRC = RIG_OK; hamlib_port_t *pRigPort = RIGPORT(pRig); gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcData = %s\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcData); rig_flush(pRigPort); nRC = write_block(pRigPort, (unsigned char *) pcData, strlen(pcData)); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_receive // --------------------------------------------------------------------------- // Status: RELEASED int adat_receive(RIG *pRig, char *pcData) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); nRC = read_string(RIGPORT(pRig), (unsigned char *) pcData, ADAT_RESPSZ, ADAT_EOL, 1, 0, 1); if (nRC > 0) { nRC = RIG_OK; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_set_cmd // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_set_cmd(RIG *pRig, char *pcCmd, int nCmdKind) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcCmd = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcCmd); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acCmd, 0, ADAT_PRIV_DATA_CMD_LENGTH + 1); snprintf(pPriv->acCmd, ADAT_PRIV_DATA_CMD_LENGTH + 1, "%s", pcCmd); pPriv->nCmdKind = nCmdKind; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_set_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_set_result(RIG *pRig, char *pcResult) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcResult = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcResult); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); snprintf(pPriv->acResult, ADAT_PRIV_DATA_RESULT_LENGTH + 1, "%s", pcResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acResult = \"%s\"\n", gFnLevel, pPriv->acResult); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_clear_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_clear_result(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_get_single_cmd_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_single_cmd_result(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_send(pRig, pPriv->acCmd); if ((nRC == RIG_OK) && (pPriv->nCmdKind == ADAT_CMD_KIND_WITH_RESULT)) { char acBuf[ ADAT_RESPSZ + 1 ]; char acBuf2[ ADAT_RESPSZ + 1 ]; char *pcBufEnd = NULL; char *pcPos = NULL; char *pcResult = NULL; memset(acBuf, 0, ADAT_RESPSZ + 1); memset(acBuf2, 0, ADAT_RESPSZ + 1); nRC = adat_receive(pRig, acBuf); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acBuf ........ = %p\n", gFnLevel, acBuf); pcPos = acBuf; if (nRC == RIG_OK) { int nBufLength = 0; // cppcheck-suppress knownConditionTrueFalse if (*pcPos == 0) // Adjust for 00 byte at beginning ... { pcPos++; // No, please don't ask me why this happens ... ;-) } nBufLength = strlen(pcPos); pcBufEnd = pcPos + nBufLength - 1; pcResult = pcPos; // Save position if (pcPos < pcBufEnd) { int nLength = strlen(pcPos); if (nLength > 0) { char *pcPos2 = strchr(pcPos, (char) 0x0d); if (pcPos2 != NULL) { *pcPos2 = '\0'; // Truncate \0d\0a } pcPos = strchr(pcPos, ' '); if ((pcPos != NULL) && (pcPos < pcBufEnd)) { pcPos += sizeof(char); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcPos ........ = %p\n", gFnLevel, pcPos); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcBufEnd ..... = %p\n", gFnLevel, pcBufEnd); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d nBufLength ... = %d\n", gFnLevel, nBufLength); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcPos2 ....... = %p\n", gFnLevel, pcPos2); trimwhitespace(acBuf2, strlen(pcPos), pcPos); pcResult = acBuf2; } } else { nRC = -RIG_EINVAL; } } else { nRC = -RIG_EINVAL; } adat_priv_clear_result(pRig); if (nRC == RIG_OK) { adat_priv_set_result(pRig, pcResult); } } } rig_flush(RIGPORT(pRig)); pPriv->nRC = nRC; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_recover_from_error // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_recover_from_error(RIG *pRig, int nError) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; // Recover from communication error if ((nError == RIG_ETIMEOUT) || (nError == RIG_EPROTO) || (nError == RIG_EIO)) { rig_close(pRig); sleep(ADAT_SLEEP_AFTER_RIG_CLOSE); rig_open(pRig); } // Reset critical Priv values pPriv->nRC = RIG_OK; // Execute recovery commands (void) adat_transaction(pRig, &adat_cmd_list_recover_from_error); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_callsign // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_callsign(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_CALLSIGN, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acCallsign, 0, ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1); snprintf(pPriv->acCallsign, ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acCallsign = \"%s\"\n", gFnLevel, pPriv->acCallsign); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_serial_nr // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_serial_nr(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_SERIAL_NR, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acSerialNr, 0, ADAT_PRIV_DATA_SERIALNR_LENGTH + 1); snprintf(pPriv->acSerialNr, ADAT_PRIV_DATA_SERIALNR_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acSerialNr = \"%s\"\n", gFnLevel, pPriv->acSerialNr); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_fw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_fw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_FW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acFWVersion, 0, ADAT_PRIV_DATA_FWVERSION_LENGTH + 1); snprintf(pPriv->acFWVersion, ADAT_PRIV_DATA_FWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acFWVersion = \"%s\"\n", gFnLevel, pPriv->acFWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_hw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_hw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_HW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acHWVersion, 0, ADAT_PRIV_DATA_HWVERSION_LENGTH + 1); snprintf(pPriv->acHWVersion, ADAT_PRIV_DATA_HWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acHWVersion = \"%s\"\n", gFnLevel, pPriv->acHWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_gui_fw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_gui_fw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acGUIFWVersion, 0, ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1); snprintf(pPriv->acGUIFWVersion, ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acGUIFWVersion = \"%s\"\n", gFnLevel, pPriv->acGUIFWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_id_code // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_id_code(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_ID_CODE, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acIDCode, 0, ADAT_PRIV_DATA_IDCODE_LENGTH + 1); snprintf(pPriv->acIDCode, ADAT_PRIV_DATA_IDCODE_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acIDCode = \"%s\"\n", gFnLevel, pPriv->acIDCode); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_options // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_options(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_OPTIONS, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acOptions, 0, ADAT_PRIV_DATA_OPTIONS_LENGTH + 1); snprintf(pPriv->acOptions, ADAT_PRIV_DATA_OPTIONS_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acOptions = \"%s\"\n", gFnLevel, pPriv->acOptions); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_mode(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_MODE, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_mode(pPriv->acResult, &(pPriv->nRIGMode), pPriv->acADATMode); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_mode(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; // Translate Mode from RIG Mode Nr to ADAT Mode Nr nRC = adat_mode_rnr2anr(pPriv->nRIGMode, &(pPriv->nADATMode)); if (nRC == RIG_OK) { // Prepare Command char acBuf[ ADAT_BUFSZ + 1 ]; memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), "%s%02d%s", ADAT_CMD_DEF_STRING_SET_MODE, (int) pPriv->nADATMode, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); // Execute Command if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_freq(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_FREQ, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_freq(pPriv->acResult, ADAT_FREQ_PARSE_MODE_WITH_VFO, &(pPriv->nCurrentVFO), &(pPriv->nFreq)); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->nCurrentVFO = %d, Freq [Hz] = %f\n", gFnLevel, pPriv->nCurrentVFO, pPriv->nFreq); if (nRC == RIG_OK) { nRC = adat_vfo_anr2rnr(pPriv->nCurrentVFO, &(pPriv->nRIGVFONr)); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_freq(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_BUFSZ + 1 ]; // Get frequency of selected VFO memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), "%s%d%s", ADAT_CMD_DEF_STRING_SET_FREQ, (int) pPriv->nFreq, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_vfo // --------------------------------------------------------------------------- // Status: RELEASED // Setting a VFO on an ADAT is actually two steps: // 1. Switching on that VFO // 2. Setting this VFO as the main VFO int adat_cmd_fn_set_vfo(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_BUFSZ + 1 ]; // Switch on VFO memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SWITCH_ON_VFO, (int) pPriv->nCurrentVFO, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO, (int) pPriv->nCurrentVFO, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_ptt(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_PTT, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_ptt(pPriv->acResult, &(pPriv->nADATPTTStatus)); if (nRC == RIG_OK) { nRC = adat_ptt_anr2rnr(pPriv->nADATPTTStatus, &(pPriv->nRIGPTTStatus)); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_ptt(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char *pcPTTStr = NULL; // Switch PTT switch (pPriv->nOpCode) { case ADAT_OPCODE_PTT_SWITCH_ON: pPriv->nADATPTTStatus = ADAT_PTT_STATUS_ANR_ON; nRC = adat_ptt_anr2rnr(ADAT_PTT_STATUS_ANR_ON, &(pPriv->nRIGPTTStatus)); pcPTTStr = ADAT_CMD_PTT_STR_ON; break; case ADAT_OPCODE_PTT_SWITCH_OFF: pPriv->nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; nRC = adat_ptt_anr2rnr(ADAT_PTT_STATUS_ANR_OFF, &(pPriv->nRIGPTTStatus)); pcPTTStr = ADAT_CMD_PTT_STR_OFF; break; default: nRC = -RIG_EINVAL; break; } if (nRC == RIG_OK) { char acBuf[ ADAT_BUFSZ + 1 ]; memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SET_PTT, pcPTTStr, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_transaction // --------------------------------------------------------------------------- // Status: RELEASED // adat_transaction is a generalized command processor able to execute // commands of type adat_cmd_def_t . int adat_transaction(RIG *pRig, adat_cmd_list_ptr pCmdList) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { int nI = 0; int nFini = 0; // = 1 -> Stop executing commands adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): Nr of commands = %d\n", gFnLevel, __func__, __FILE__, __LINE__, pCmdList->nNrCmds); while ((nRC == RIG_OK) && (nFini == 0) && (nI < pCmdList->nNrCmds)) { adat_cmd_def_ptr pCmd = pCmdList->adat_cmds[ nI ]; if ((pCmd != NULL) && (pCmd->nCmdId != ADAT_CMD_DEF_NIL)) { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d About to execute ADAT Command ... \n", gFnLevel); adat_print_cmd(pCmd); // Execute Command if (pCmd->pfCmdFn != NULL) { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Calling function via fn ptr ... \n", gFnLevel); nRC = pCmd->pfCmdFn(pRig); } else { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Sending command string ... \n", gFnLevel); if (pCmd->nNrCmdStrs > 0) { int nJ = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pacCmdStrs[%d] = %s\n", gFnLevel, nJ, pCmd->pacCmdStrs[ nJ ]); while ((nJ < pCmd->nNrCmdStrs) && (nRC == RIG_OK) && (pCmd->pacCmdStrs[ nJ ] != NULL)) { nRC = adat_send(pRig, pCmd->pacCmdStrs[ nJ ]); if (nRC == RIG_OK) { if (pCmd->nCmdKind == ADAT_CMD_KIND_WITH_RESULT) { char acBuf[ ADAT_RESPSZ + 1 ]; memset(acBuf, 0, ADAT_RESPSZ + 1); nRC = adat_receive(pRig, acBuf); while ((nRC == RIG_OK) && (strncmp(acBuf, ADAT_BOM, strlen(ADAT_BOM)) != 0)) { nRC = adat_receive(pRig, acBuf); } memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); snprintf(pPriv->acResult, ADAT_PRIV_DATA_RESULT_LENGTH + 1, "%s", acBuf); } } nJ++; } } } if (nRC != RIG_OK) { (void) adat_cmd_recover_from_error(pRig, nRC); } nI++; } else { nFini = 1; } // sleep between cmds - ADAT needs time to act upoon cmds hl_usleep(ADAT_SLEEP_MICROSECONDS_BETWEEN_CMDS); } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_init // --------------------------------------------------------------------------- // Status: RELEASED int adat_init(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig != NULL) { // Set Rig Priv data memset(&gsADATPrivData, 0, sizeof(adat_priv_data_t)); STATE(pRig)->priv = &gsADATPrivData; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_cleanup // --------------------------------------------------------------------------- // Status: RELEASED int adat_cleanup(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { STATE(pRig)->priv = NULL; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_open // --------------------------------------------------------------------------- // Status: RELEASED int adat_open(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // grace period for the radio to be there sleep(ADAT_SLEEP_AFTER_RIG_OPEN); // Now get basic info from ADAT TRX nRC = adat_transaction(pRig, &adat_cmd_list_open_adat); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_close // --------------------------------------------------------------------------- // Status: RELEASED int adat_close(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Now switch to interactive mode (end Remote Operation mode) nRC = adat_transaction(pRig, &adat_cmd_list_close_adat); // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_info // --------------------------------------------------------------------------- // Status: RELEASED const char *adat_get_info(RIG *pRig) { static char acBuf[ 2048 ]; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); memset(acBuf, 0, 2048); if (pRig != NULL) { int nRC = adat_transaction(pRig, &adat_cmd_list_get_info); if (nRC == RIG_OK) { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; snprintf(acBuf, 2048, "ADAT ADT-200A, Callsign: %s, S/N: %s, ID Code: %s, Options: %s, FW: %s, GUI FW: %s, HW: %s", pPriv->acCallsign, pPriv->acSerialNr, pPriv->acIDCode, pPriv->acOptions, pPriv->acFWVersion, pPriv->acGUIFWVersion, pPriv->acHWVersion); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Value ='%s'\n", gFnLevel, __func__, __FILE__, __LINE__, acBuf); gFnLevel--; return acBuf; } // --------------------------------------------------------------------------- // Function adat_set_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_freq(RIG *pRig, vfo_t vfo, freq_t freq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; pPriv->nFreq = freq; nRC = adat_transaction(pRig, &adat_cmd_list_set_freq); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_freq(RIG *pRig, vfo_t vfo, freq_t *freq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_freq); *freq = pPriv->nFreq; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_level // --------------------------------------------------------------------------- // Status: IN WORK int adat_set_level(RIG *pRig, vfo_t vfo, setting_t level, value_t val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_level // --------------------------------------------------------------------------- // Status: IN WORK int adat_get_level(RIG *pRig, vfo_t vfo, setting_t level, value_t *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_mode(RIG *pRig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int nRC; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; pPriv->nRIGMode = mode; adat_vfo_rnr2anr(vfo, &(pPriv->nCurrentVFO)); if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(pRig, mode); } pPriv->nWidth = width; } nRC = adat_transaction(pRig, &adat_cmd_list_set_mode); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_mode(RIG *pRig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_mode); if (nRC == RIG_OK) { *mode = pPriv->nRIGMode; *width = pPriv->nWidth; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_vfo(RIG *pRig, vfo_t *vfo) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_vfo); *vfo = pPriv->nRIGVFONr; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_vfo(RIG *pRig, vfo_t vfo) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_vfo_rnr2anr(vfo, &(pPriv->nCurrentVFO)); if (nRC == RIG_OK) { nRC = adat_transaction(pRig, &adat_cmd_list_set_vfo); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_ptt(RIG *pRig, vfo_t vfo, ptt_t *ptt) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_ptt); *ptt = pPriv->nRIGPTTStatus; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_ptt(RIG *pRig, vfo_t vfo, ptt_t ptt) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (ptt) { case RIG_PTT_ON: pPriv->nOpCode = ADAT_OPCODE_PTT_SWITCH_ON; break; case RIG_PTT_OFF: pPriv->nOpCode = ADAT_OPCODE_PTT_SWITCH_OFF; break; default: nRC = -RIG_EINVAL; break; } if (nRC == RIG_OK) { nRC = adat_transaction(pRig, &adat_cmd_list_set_ptt); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_power2mW // --------------------------------------------------------------------------- // Status: RELEASED int adat_power2mW(RIG *pRig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if ((pRig == NULL) || (mwpower == NULL)) { nRC = -RIG_EARG; } else { *mwpower = power * ADAT_MAX_POWER_IN_mW; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_mW2power // --------------------------------------------------------------------------- // Status: RELEASED int adat_mW2power(RIG *pRig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if ((pRig == NULL) || (power == NULL)) { nRC = -RIG_EARG; } else { *power = mwpower / ((float)ADAT_MAX_POWER_IN_mW); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_powerstat // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_powerstat(RIG *pRig, powerstat_t *status) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { nRC = adat_transaction(pRig, &adat_cmd_list_get_powerstatus); // nRC < 0 -> Power is off. if (nRC == RIG_OK) { *status = RIG_POWER_ON; } else { *status = RIG_POWER_OFF; nRC = RIG_OK; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_conf // --------------------------------------------------------------------------- // Status: IN WORK int adat_set_conf(RIG *pRig, hamlib_token_t token, const char *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (token) { case TOKEN_ADAT_PRODUCT_NAME: snprintf(pPriv->acProductName, ADAT_PRIV_DATA_PRODUCTNAME_LENGTH + 1, "%s", val); break; default: nRC = -RIG_EINVAL; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_conf // --------------------------------------------------------------------------- // Status: IN WORK int adat_get_conf(RIG *pRig, hamlib_token_t token, char *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (token) { case TOKEN_ADAT_PRODUCT_NAME: if (strlen(pPriv->acProductName) > 0) { strcpy(val, pPriv->acProductName); } else { strcpy(val, "Unknown product"); } break; default: nRC = -RIG_EINVAL; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_reset // --------------------------------------------------------------------------- // Status: IN WORK int adat_reset(RIG *pRig, reset_t reset) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_handle_event // --------------------------------------------------------------------------- // Status: IN WORK int adat_handle_event(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_RESPSZ + 1 ]; memset(acBuf, 0, ADAT_RESPSZ + 1); adat_receive(pRig, acBuf); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Event data = \"%s\"\n", gFnLevel, acBuf); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // initrigs_adat is called by rig_backend_load // --------------------------------------------------------------------------- // Status: RELEASED DECLARE_INITRIG_BACKEND(adat) { int nRC = RIG_OK; gFnLevel++; #if 0 rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY.\n", gFnLevel, __func__, __FILE__, __LINE__); #endif rig_register(&adt_200a_caps); #if 0 rig_debug(RIG_DEBUG_VERBOSE, "ADAT: Rig ADT-200A registered.\n"); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); #endif gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // proberig_adat // --------------------------------------------------------------------------- DECLARE_PROBERIG_BACKEND(adat) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY.\n", gFnLevel, __func__, __FILE__, __LINE__); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 10; port->parm.serial.stop_bits = 2; port->retry = 1; nRC = serial_open(port); if (nRC != RIG_OK) { nRC = RIG_MODEL_NONE; } else { char acBuf[ ADAT_RESPSZ + 1 ]; int nRead = 0; memset(acBuf, 0, ADAT_RESPSZ + 1); nRC = write_block(port, (unsigned char *)ADAT_CMD_DEF_STRING_GET_ID_CODE, strlen(ADAT_CMD_DEF_STRING_GET_ID_CODE)); nRead = read_string(port, (unsigned char *) acBuf, ADAT_RESPSZ, ADAT_EOM, 1, 0, 1); close(port->fd); if ((nRC != RIG_OK || nRead < 0)) { nRC = RIG_MODEL_NONE; } else { rig_debug(RIG_DEBUG_VERBOSE, "ADAT: %d Received ID = %s.", gFnLevel, acBuf); nRC = RIG_MODEL_ADT_200A; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.5/rigs/adat/Makefile.in0000664000175000017500000005266015056640452012407 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/adat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_adat_la_LIBADD = am__objects_1 = adt_200a.lo adat.lo am_libhamlib_adat_la_OBJECTS = $(am__objects_1) libhamlib_adat_la_OBJECTS = $(am_libhamlib_adat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/adat.Plo ./$(DEPDIR)/adt_200a.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_adat_la_SOURCES) DIST_SOURCES = $(libhamlib_adat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ADATSRC = adt_200a.c adt_200a.h adat.c adat.h noinst_LTLIBRARIES = libhamlib-adat.la libhamlib_adat_la_SOURCES = $(ADATSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/adat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/adat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-adat.la: $(libhamlib_adat_la_OBJECTS) $(libhamlib_adat_la_DEPENDENCIES) $(EXTRA_libhamlib_adat_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_adat_la_OBJECTS) $(libhamlib_adat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adat.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adt_200a.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/adat.Plo -rm -f ./$(DEPDIR)/adt_200a.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/adat.Plo -rm -f ./$(DEPDIR)/adt_200a.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/adat/adt_200a.h0000664000175000017500000001220615056640442011774 // --------------------------------------------------------------------------- // ADT-200A // --------------------------------------------------------------------------- // // adt_200a.h // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012 Frank Goenninger. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #if !defined( __ADT_200A_INCLUDED__ ) #define __ADT_200A_INCLUDED__ // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include "rig.h" // --------------------------------------------------------------------------- // ADAT INCLUDES // --------------------------------------------------------------------------- #include "adat.h" // --------------------------------------------------------------------------- // ADT-200A USB DEFINITIONS // --------------------------------------------------------------------------- #define ADT_200A_VENDOR_ID 0x0403 #define ADT_200A_PRODUCT_ID 0x6001 #define ADT_200A_VENDOR_NAME "FTDI" #define ADT_200A_PRODUCT_NAME "TRX3C Serial C945D5B" #define ADT_200A_USB_INTERFACE_NR 0x00 #define ADT_200A_USB_CONFIGURATION_VALUE 0x01 #define ADT_200A_ALTERNATE_SETTIMG 0x00 #define ADT_200A_USB_INPUT_ENDPOINT 0x81 #define ADT_200A_USB_INPUT_MAX_PACKET_SIZE 64 #define ADT_200A_USB_OUTPUT_ENDPOINT b0x02 #define ADT_200A_USB_OUTPUT_MAX_PACKET_SIZE 64 // --------------------------------------------------------------------------- // ADT-200A CAPS DEFINITIONS // --------------------------------------------------------------------------- #define ADT_200A_GET_LEVEL \ ( \ RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_NR | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_RFPOWER | \ RIG_LEVEL_MICGAIN | \ RIG_LEVEL_KEYSPD | \ RIG_LEVEL_METER | \ RIG_LEVEL_BKIN_DLYMS | \ RIG_LEVEL_RAWSTR | \ RIG_LEVEL_SWR | \ RIG_LEVEL_ALC ) #define ADT_200A_SET_LEVEL \ ( \ RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_NR | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_RFPOWER | \ RIG_LEVEL_MICGAIN | \ RIG_LEVEL_KEYSPD | \ RIG_LEVEL_METER | \ RIG_LEVEL_BKIN_DLYMS | \ RIG_LEVEL_ALC ) #define ADT_200A_MODES \ ( \ RIG_MODE_AM | \ RIG_MODE_CW | \ RIG_MODE_USB | \ RIG_MODE_LSB | \ RIG_MODE_FM | \ RIG_MODE_CWR | \ RIG_MODE_SAL | \ RIG_MODE_SAH ) // ADT-200A VFO #defines #define ADT_200A_FRA RIG_VFO_N(0) #define ADT_200A_FRB RIG_VFO_N(1) #define ADT_200A_FRC RIG_VFO_N(2) #define ADT_200A_VFO (ADT_200A_FRA|ADT_200A_FRB|ADT_200A_FRC) #define ADT_200A_RIT 9999 #define ADT_200A_XIT 9999 // This is more-than-likely not accurate #define ADT_200A_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } // ADT-200A FUNCs #define ADT_200A_FUNCS (RIG_FUNC_VOX|RIG_FUNC_NB|RIG_FUNC_NR) // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- #endif hamlib-4.6.5/rigs/adat/adt_200a.c0000664000175000017500000001753715056640442012003 // --------------------------------------------------------------------------- // ADT-200A HAMLIB BACKEND // --------------------------------------------------------------------------- // // adt_200a.c // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // 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.1 of the License, or (at your option) any later version. // // 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 // Lesser General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // ADT-200A INCLUDES // --------------------------------------------------------------------------- #include "adt_200a.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- // GLOBAL VARS // static const struct confparams adt_200a_cfg_params[] = // { // { TOKEN_PRODUCT_NAME, "usb_product_name", "USB Product Name", "USB Product Name (DSP Bo // Model + ' Serial '+ ID Code, e.g. 'TRX3C Serial C945D5B' )", // ADT_200A_PRODUCT_NAME, RIG_CONF_STRING, { .n = { 0,0,0 } } // }, // // { RIG_CONF_END, NULL, } //}; // --------------------------------------------------------------------------- // ADT-200A HAMLIB CAPS / DESCRIPTION // --------------------------------------------------------------------------- struct rig_caps adt_200a_caps = { RIG_MODEL(RIG_MODEL_ADT_200A), .model_name = "ADT-200A", .mfg_name = "ADAT www.adat.ch", .version = BACKEND_VER ".0", .copyright = "Frank Goenninger, DG1SBG. License: Creative Commons", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 250, .retry = 3, .has_get_func = ADT_200A_FUNCS, .has_set_func = ADT_200A_FUNCS, .has_get_level = ADT_200A_GET_LEVEL, .has_set_level = RIG_LEVEL_SET(ADT_200A_SET_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 5, 10, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, 20, 25, RIG_DBLST_END, }, .max_rit = ADT_200A_RIT, .max_xit = ADT_200A_XIT, .max_ifshift = Hz(500), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = 0, .bank_qty = 1, .chan_desc_sz = ADAT_MEM_DESC_SIZE, .chan_list = { { 0, 99, RIG_MTYPE_MEM, ADAT_MEM_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(10), MHz(30), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(50), MHz(50.5), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(70), MHz(70.7), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(146), MHz(148), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(10), MHz(30), ADT_200A_MODES, mW(100), W(50), ADT_200A_VFO }, { MHz(50), MHz(50.5), ADT_200A_MODES, mW(10), W(1), ADT_200A_FRA }, { MHz(70), MHz(70.7), ADT_200A_MODES, mW(10), W(1), ADT_200A_FRA }, { MHz(146), MHz(148), ADT_200A_MODES, mW(10), mW(100), ADT_200A_FRA }, RIG_FRNG_END, }, .rx_range_list2 = { { kHz(10), MHz(30), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(10), MHz(30), ADT_200A_MODES, mW(100), W(50), ADT_200A_VFO }, RIG_FRNG_END, }, .tuning_steps = { { ADT_200A_MODES, RIG_TS_ANY }, // TODO: get actual list here RIG_TS_END, }, .filters = { { RIG_MODE_CW | RIG_MODE_CWR, Hz(50) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(75) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(100) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(150) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(200) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(300) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(750) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(1000) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(1200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(300) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(500) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(750) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1000) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1500) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1800) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2000) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2400) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2700) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(3500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(3000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(3500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(4000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(4500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(5000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(6000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(7000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(8000) }, { RIG_MODE_FM, Hz(6000) }, { RIG_MODE_FM, Hz(7000) }, { RIG_MODE_FM, Hz(8000) }, { RIG_MODE_FM, Hz(9000) }, { RIG_MODE_FM, Hz(10000) }, { RIG_MODE_FM, Hz(12000) }, { RIG_MODE_FM, Hz(15000) }, { RIG_MODE_FM, Hz(20000) }, { RIG_MODE_FM, Hz(25000) }, RIG_FLT_END, }, .str_cal = ADT_200A_STR_CAL, // .cfgparams = adt_200a_cfg_params, .rig_init = adat_init, .rig_cleanup = adat_cleanup, .rig_open = adat_open, .reset = adat_reset, .rig_close = adat_close, .set_conf = adat_set_conf, .get_conf = adat_get_conf, .set_freq = adat_set_freq, .get_freq = adat_get_freq, .get_level = adat_get_level, .set_level = adat_set_level, .set_mode = adat_set_mode, .get_mode = adat_get_mode, .get_vfo = adat_get_vfo, .set_vfo = adat_set_vfo, .get_ptt = adat_get_ptt, .set_ptt = adat_set_ptt, .decode_event = adat_handle_event, .get_info = adat_get_info, .power2mW = adat_power2mW, .mW2power = adat_mW2power, .get_powerstat = adat_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.5/rigs/adat/Makefile.am0000664000175000017500000000022615056640442012364 ADATSRC = adt_200a.c adt_200a.h adat.c adat.h noinst_LTLIBRARIES = libhamlib-adat.la libhamlib_adat_la_SOURCES = $(ADATSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/dorji/0000775000175000017500000000000015056640476010615 5hamlib-4.6.5/rigs/dorji/dra818.c0000664000175000017500000004277515056640443011721 /* * Hamlib Dorji DRA818 backend * Copyright (c) 2017 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "tones.h" #include "dra818.h" static const char *dra818_handshake_cmd = "AT+DMOCONNECT\r\n"; static const char *dra818_handshake_res = "+DMOCONNECT:0\r\n"; static const char *dra818_setgroup_res = "+DMOSETGROUP:0\r\n"; static const char *dra818_setvolume_res = "+DMOSETVOLUME:0\r\n"; struct dra818_priv { shortfreq_t tx_freq; shortfreq_t rx_freq; shortfreq_t bw; split_t split; tone_t ctcss_tone; tone_t ctcss_sql; tone_t dcs_code; tone_t dcs_sql; int sql; int vol; }; static int dra818_response(RIG *rig, const char *expected) { char response[80]; int r = read_string(RIGPORT(rig), (unsigned char *) response, sizeof(response), "\n", 1, 0, 1); if (r != strlen(expected)) { return -RIG_EIO; } if (strcmp(expected, response) != 0) { rig_debug(RIG_DEBUG_VERBOSE, "dra818: response: %s\n", response); return -RIG_ERJCTED; } return RIG_OK; } static void dra818_subaudio(RIG *rig, char *subaudio, int subaudio_len, tone_t tone, tone_t code) { if (code) { SNPRINTF(subaudio, subaudio_len, "%03uI", code % 10000); return; } else if (tone) { int i; for (i = 0; rig->caps->ctcss_list[i]; i++) { if (rig->caps->ctcss_list[i] == tone) { SNPRINTF(subaudio, subaudio_len, "%04d", (i + 1) % 10000); return; } } } subaudio[0] = '0'; subaudio[1] = '0'; subaudio[2] = '0'; subaudio[3] = '0'; } static int dra818_setgroup(RIG *rig) { const struct dra818_priv *priv = STATE(rig)->priv; char cmd[80]; char subtx[8] = { 0 }; char subrx[8] = { 0 }; dra818_subaudio(rig, subtx, sizeof(subtx), priv->ctcss_tone, priv->dcs_code); dra818_subaudio(rig, subrx, sizeof(subrx), priv->ctcss_sql, priv->dcs_sql); SNPRINTF(cmd, sizeof(cmd), "AT+DMOSETGROUP=%1d,%03d.%04d,%03d.%04d,%4s,%1d,%4s\r\n", priv->bw == 12500 ? 0 : 1, (int)(priv->tx_freq / 1000000), (int)((priv->tx_freq % 1000000) / 100), (int)(priv->rx_freq / 1000000), (int)((priv->rx_freq % 1000000) / 100), subtx, priv->sql, subrx); write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); return dra818_response(rig, dra818_setgroup_res); } static int dra818_setvolume(RIG *rig) { const struct dra818_priv *priv = STATE(rig)->priv; char cmd[80]; SNPRINTF(cmd, sizeof(cmd), "AT+DMOSETVOLUME=%1d\r\n", priv->vol); write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); return dra818_response(rig, dra818_setvolume_res); } int dra818_init(RIG *rig) { struct dra818_priv *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: dra818_init called\n", __func__); STATE(rig)->priv = calloc(sizeof(*priv), 1); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; switch (rig->caps->rig_model) { case RIG_MODEL_DORJI_DRA818V: priv->rx_freq = 145000000; break; case RIG_MODEL_DORJI_DRA818U: priv->rx_freq = 435000000; break; } priv->tx_freq = priv->rx_freq; priv->bw = 12500; priv->split = RIG_SPLIT_OFF; priv->ctcss_tone = 0; priv->ctcss_sql = 0; priv->dcs_code = 0; priv->dcs_sql = 0; priv->sql = 4; priv->vol = 6; return RIG_OK; } int dra818_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: dra818_cleanup called\n", __func__); free(STATE(rig)->priv); return RIG_OK; } int dra818_open(RIG *rig) { int i; int r = -1; for (i = 0; i < 3; i++) { write_block(RIGPORT(rig), (unsigned char *) dra818_handshake_cmd, strlen(dra818_handshake_cmd)); r = dra818_response(rig, dra818_handshake_res); if (r == RIG_OK) { break; } } if (r != RIG_OK) { return r; } r = dra818_setvolume(rig); if (r != RIG_OK) { return r; } return dra818_setgroup(rig); } int dra818_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dra818_priv *priv = STATE(rig)->priv; /* Nearest channel */ shortfreq_t sfreq = ((freq + priv->bw / 2) / priv->bw); sfreq *= priv->bw; rig_debug(RIG_DEBUG_VERBOSE, "dra818: requested freq = %"PRIfreq" Hz, set freq = %d Hz\n", freq, (int)sfreq); if (vfo == RIG_VFO_RX) { priv->rx_freq = sfreq; if (priv->split == RIG_SPLIT_OFF) { priv->tx_freq = sfreq; } } else if (vfo == RIG_VFO_TX) { priv->tx_freq = sfreq; if (priv->split == RIG_SPLIT_OFF) { priv->rx_freq = sfreq; } } else { return -RIG_EINVAL; } return dra818_setgroup(rig); } int dra818_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dra818_priv *priv = STATE(rig)->priv; if (width > 12500) { priv->bw = 25000; } else { priv->bw = 12500; } rig_debug(RIG_DEBUG_VERBOSE, "dra818: bandwidth: %d\n", (int)priv->bw); return dra818_setgroup(rig); } int dra818_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct dra818_priv *priv = STATE(rig)->priv; *mode = RIG_MODE_FM; *width = priv->bw; return RIG_OK; } int dra818_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { const struct dra818_priv *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmd[80]; char response[8]; int r; SNPRINTF(cmd, sizeof(cmd), "S+%03d.%04d\r\n", (int)(priv->rx_freq / 1000000), (int)((priv->rx_freq % 1000000) / 100)); write_block(rp, (unsigned char *) cmd, strlen(cmd)); r = read_string(rp, (unsigned char *) response, sizeof(response), "\n", 1, 0, 1); if (r != 5) { return -RIG_EIO; } if (response[3] == 1) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } int dra818_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct dra818_priv *priv = STATE(rig)->priv; switch (vfo) { case RIG_VFO_RX: *freq = priv->rx_freq; break; case RIG_VFO_TX: *freq = priv->tx_freq; break; default: return -RIG_EINVAL; } return RIG_OK; } int dra818_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct dra818_priv *priv = STATE(rig)->priv; priv->split = split; if (split == RIG_SPLIT_OFF) { priv->tx_freq = priv->rx_freq; } return dra818_setgroup(rig); } int dra818_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct dra818_priv *priv = STATE(rig)->priv; *split = priv->split; if (priv->split == RIG_SPLIT_ON) { *tx_vfo = RIG_VFO_TX; } else { *tx_vfo = RIG_VFO_RX; } return RIG_OK; } int dra818_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct dra818_priv *priv = STATE(rig)->priv; switch (level) { case RIG_LEVEL_SQL: /* SQL range: 0..8 (0=monitor) */ val->f = (priv->sql / 8.0); break; case RIG_LEVEL_AF: /* AF range: 1..8 */ val->f = (priv->vol / 8.0); break; default: return -RIG_EINVAL; } return RIG_OK; } int dra818_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dra818_priv *priv = STATE(rig)->priv; switch (level) { case RIG_LEVEL_SQL: /* SQL range: 0..8 (0=monitor) */ priv->sql = val.f * 8; if (priv->sql < 0) { priv->sql = 0; } if (priv->sql > 8) { priv->sql = 8; } return dra818_setgroup(rig); case RIG_LEVEL_AF: /* AF range: 1..8 */ priv->vol = val.f * 8; if (priv->vol < 1) { priv->vol = 1; } if (priv->vol > 8) { priv->vol = 8; } return dra818_setvolume(rig); default: break; } return -RIG_EINVAL; } int dra818_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct dra818_priv *priv = STATE(rig)->priv; priv->dcs_code = code; if (code) { priv->ctcss_tone = 0; } return dra818_setgroup(rig); } int dra818_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct dra818_priv *priv = STATE(rig)->priv; priv->ctcss_tone = tone; if (tone) { priv->dcs_code = 0; } return dra818_setgroup(rig); } int dra818_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct dra818_priv *priv = STATE(rig)->priv; priv->dcs_sql = code; if (code) { priv->ctcss_sql = 0; } return dra818_setgroup(rig); } int dra818_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct dra818_priv *priv = STATE(rig)->priv; priv->ctcss_sql = tone; if (tone) { priv->dcs_sql = 0; } return dra818_setgroup(rig); } int dra818_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { const struct dra818_priv *priv = STATE(rig)->priv; *tone = priv->ctcss_sql; return RIG_OK; } int dra818_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { const struct dra818_priv *priv = STATE(rig)->priv; *code = priv->dcs_sql; return RIG_OK; } int dra818_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { const struct dra818_priv *priv = STATE(rig)->priv; *code = priv->dcs_code; return RIG_OK; } int dra818_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct dra818_priv *priv = STATE(rig)->priv; *tone = priv->ctcss_tone; return RIG_OK; } struct rig_caps dra818u_caps = { RIG_MODEL(RIG_MODEL_DORJI_DRA818U), .model_name = "DRA818U", .mfg_name = "Dorji", .version = "20191209.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .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 = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_set_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = /* 38 according to doc, are they all correct? */ (tone_t[]) { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(400), MHz(480), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(400), MHz(480), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_70cm(1, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_70cm(2, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_FM, Hz(12500)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, Hz(12500)}, {RIG_MODE_FM, Hz(25000)}, RIG_FLT_END, }, .rig_init = dra818_init, .rig_cleanup = dra818_cleanup, .rig_open = dra818_open, .set_freq = dra818_set_freq, .get_freq = dra818_get_freq, .set_split_vfo = dra818_set_split_vfo, .get_split_vfo = dra818_get_split_vfo, .set_mode = dra818_set_mode, .get_mode = dra818_get_mode, .get_dcd = dra818_get_dcd, .set_level = dra818_set_level, .get_level = dra818_get_level, .set_dcs_code = dra818_set_dcs_code, .set_ctcss_tone = dra818_set_ctcss_tone, .set_dcs_sql = dra818_set_dcs_sql, .set_ctcss_sql = dra818_set_ctcss_sql, .get_dcs_code = dra818_get_dcs_code, .get_ctcss_tone = dra818_get_ctcss_tone, .get_dcs_sql = dra818_get_dcs_sql, .get_ctcss_sql = dra818_get_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps dra818v_caps = { RIG_MODEL(RIG_MODEL_DORJI_DRA818V), .model_name = "DRA818V", .mfg_name = "Dorji", .version = "20191209.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .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 = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_set_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = /* 38 according to doc, are they all correct? */ (tone_t[]) { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(134), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(134), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_2m(1, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_2m(2, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_FM, Hz(12500)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, Hz(12500)}, {RIG_MODE_FM, Hz(25000)}, RIG_FLT_END, }, .rig_init = dra818_init, .rig_cleanup = dra818_cleanup, .rig_open = dra818_open, .set_freq = dra818_set_freq, .get_freq = dra818_get_freq, .set_split_vfo = dra818_set_split_vfo, .get_split_vfo = dra818_get_split_vfo, .set_mode = dra818_set_mode, .get_mode = dra818_get_mode, .get_dcd = dra818_get_dcd, .set_level = dra818_set_level, .get_level = dra818_get_level, .set_dcs_code = dra818_set_dcs_code, .set_ctcss_tone = dra818_set_ctcss_tone, .set_dcs_sql = dra818_set_dcs_sql, .set_ctcss_sql = dra818_set_ctcss_sql, .get_dcs_code = dra818_get_dcs_code, .get_ctcss_tone = dra818_get_ctcss_tone, .get_dcs_sql = dra818_get_dcs_sql, .get_ctcss_sql = dra818_get_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/dorji/Android.mk0000664000175000017500000000040115056640443012433 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dorji.c dra818.c LOCAL_MODULE := dorji LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/dorji/Makefile.in0000664000175000017500000005267415056640452012612 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/dorji ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_dorji_la_LIBADD = am__objects_1 = dorji.lo dra818.lo am_libhamlib_dorji_la_OBJECTS = $(am__objects_1) libhamlib_dorji_la_OBJECTS = $(am_libhamlib_dorji_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dorji.Plo ./$(DEPDIR)/dra818.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_dorji_la_SOURCES) DIST_SOURCES = $(libhamlib_dorji_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DORJISRC = dorji.c dorji.h dra818.c dra818.h noinst_LTLIBRARIES = libhamlib-dorji.la libhamlib_dorji_la_SOURCES = $(DORJISRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/dorji/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/dorji/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-dorji.la: $(libhamlib_dorji_la_OBJECTS) $(libhamlib_dorji_la_DEPENDENCIES) $(EXTRA_libhamlib_dorji_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_dorji_la_OBJECTS) $(libhamlib_dorji_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dorji.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dra818.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dorji.Plo -rm -f ./$(DEPDIR)/dra818.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dorji.Plo -rm -f ./$(DEPDIR)/dra818.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/dorji/dorji.h0000664000175000017500000000177315056640443012017 /* * Hamlib Dorji backend - main header * Copyright (c) 2017 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DORJI_H #define _DORJI_H 1 #include "hamlib/rig.h" extern struct rig_caps dra818u_caps; extern struct rig_caps dra818v_caps; #endif /* _DORJI_H */ hamlib-4.6.5/rigs/dorji/dorji.c0000664000175000017500000000222115056640443011777 /* * Hamlib Dorji backend - main file * Copyright (c) 2017 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "register.h" #include "dorji.h" /* * initrigs_dorji is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(dorji) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dra818u_caps); rig_register(&dra818v_caps); return RIG_OK; } hamlib-4.6.5/rigs/dorji/Makefile.am0000664000175000017500000000023015056640443012556 DORJISRC = dorji.c dorji.h dra818.c dra818.h noinst_LTLIBRARIES = libhamlib-dorji.la libhamlib_dorji_la_SOURCES = $(DORJISRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/dorji/dra818.h0000664000175000017500000000162415056640443011712 /* * Hamlib Dorji DRA818 backend * Copyright (c) 2017 by Jeroen Vreeken * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DRA818_H #define _DRA818_H 1 #endif /* _DRA818_H */ hamlib-4.6.5/rigs/kachina/0000775000175000017500000000000015056640477011105 5hamlib-4.6.5/rigs/kachina/kachina.h0000664000175000017500000000241115056640443012563 /* * Hamlib Kachina backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KACHINA_H #define _KACHINA_H 1 #include #define BACKEND_VER "20240420" int kachina_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int kachina_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int kachina_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int kachina_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern struct rig_caps k505dsp_caps; #endif /* _KACHINA_H */ hamlib-4.6.5/rigs/kachina/505dsp.c0000664000175000017500000001315615056640443012210 /* * Hamlib Kachina backend - 505DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kachina.h" #include #define K505DSP_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define K505DSP_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define K505DSP_AM_TX_MODES RIG_MODE_AM #define K505DSP_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TONE|RIG_FUNC_COMP) #define K505DSP_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|RIG_LEVEL_BKINDL|RIG_LEVEL_CWPITCH) #define K505DSP_PARM_ALL (RIG_PARM_NONE) #define K505DSP_VFO (RIG_VFO_A) #define dBm2S9(x) ((x)+73) #define K505DSP_STR_CAL { 2, { \ { 0, dBm2S9(-130) }, \ { 127, dBm2S9(20) }, \ } } /* * 505DSP rig capabilities. * * protocol is documented at * http://www.kachina-az.com/develope.htm * * TODO: * - so many ... */ struct rig_caps k505dsp_caps = { RIG_MODEL(RIG_MODEL_505DSP), .model_name = "505DSP", .mfg_name = "Kachina", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .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 = 0, .post_write_delay = 0, .timeout = 200, .retry = 2, .has_get_func = K505DSP_FUNC, .has_set_func = K505DSP_FUNC, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_SET(K505DSP_LEVEL_ALL), .has_get_parm = K505DSP_PARM_ALL, .has_set_parm = RIG_PARM_SET(K505DSP_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(9900), .max_xit = Hz(0), .max_ifshift = Hz(1270), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), K505DSP_ALL_MODES, -1, -1, K505DSP_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(1800), MHz(2) - 100, K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(3500), MHz(4) - 100, K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(3500), MHz(4) - 100, K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(7), kHz(7300), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(7), kHz(7300), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(10100), kHz(10150), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(10100), kHz(10150), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(14), kHz(14350), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(14), kHz(14350), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(18068), kHz(18168), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(18068), kHz(18168), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(21), kHz(21450), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(21), kHz(21450), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(24895), kHz(24995), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(24895), kHz(24995), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(28), kHz(29700), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(28), kHz(29700), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, RIG_FRNG_END, }, .tuning_steps = { {K505DSP_ALL_MODES, 1}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.1)}, {RIG_MODE_SSB, kHz(3.5)}, {RIG_MODE_SSB, kHz(1.7)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = K505DSP_STR_CAL, .set_freq = kachina_set_freq, .set_mode = kachina_set_mode, .set_ptt = kachina_set_ptt, .get_level = kachina_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kachina/Android.mk0000664000175000017500000000040515056640443012726 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := 505dsp.c kachina.c LOCAL_MODULE := kachina LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/kachina/kachina.c0000664000175000017500000001506315056640443012565 /* * Hamlib Kachina backend - main file * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "kachina.h" /* * protocol format */ #define STX 0x02 #define ETX 0x03 #define GDCMD 0xff #define ERRCMD 0xfe /* * modes in use by the "M" command */ #define M_AM 0x01 #define M_CW 0x02 #define M_FM 0x03 #define M_USB 0x04 #define M_LSB 0x05 #define DDS_CONST 2.2369621333 #define DDS_BASE 75000000 /* uppermost 2 bits of the high byte * designating the antenna port in DDS calculation */ #define PORT_AB 0x00 #define PORT_A 0x40 #define PORT_B 0x80 #define PORT_BA 0xc0 /* * kachina_transaction * We assume that rig!=NULL, STATE(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int kachina_transaction(RIG *rig, unsigned char cmd1, unsigned char cmd2) { int count, retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf4[4]; buf4[0] = STX; buf4[1] = cmd1; buf4[2] = cmd2; buf4[3] = ETX; rig_flush(rp); retval = write_block(rp, buf4, 4); if (retval != RIG_OK) { return retval; } count = read_string(rp, buf4, 1, "", 0, 0, 1); if (count != 1) { return count; } return (buf4[0] == GDCMD) ? RIG_OK : -RIG_EPROTO; } static int kachina_trans_n(RIG *rig, unsigned char cmd1, const char *data, int data_len) { int cmd_len, count, retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf[16]; buf[0] = STX; buf[1] = cmd1; memcpy(buf + 2, data, data_len); buf[data_len + 2] = ETX; cmd_len = data_len + 3; rig_flush(rp); retval = write_block(rp, buf, cmd_len); if (retval != RIG_OK) { return retval; } count = read_string(rp, buf, 1, "", 0, 0, 1); if (count != 1) { return count; } return (buf[0] == GDCMD) ? RIG_OK : -RIG_EPROTO; } /* * convert a frequency in Hz in the range of 30kHz to 30MHz * to DDS value, as expected by the Kachina. */ static void freq2dds(freq_t freq, int ant_port, unsigned char fbuf[4]) { double dds; unsigned long dds_ulong; dds = DDS_CONST * (DDS_BASE + freq); dds_ulong = (unsigned long)dds; /* * byte 0 transferred first, * dds is big endian format */ fbuf[0] = ant_port | ((dds_ulong >> 24) & 0x3f); fbuf[1] = (dds_ulong >> 16) & 0xff; fbuf[2] = (dds_ulong >> 8) & 0xff; fbuf[3] = dds_ulong & 0xff; } /* * kachina_set_freq * Assumes rig!=NULL */ int kachina_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; unsigned char freqbuf[4]; freq2dds(freq, PORT_A, freqbuf); /* receive frequency */ retval = kachina_trans_n(rig, 'R', (char *) freqbuf, 4); if (retval != RIG_OK) { return retval; } /* transmit frequency */ retval = kachina_trans_n(rig, 'T', (char *) freqbuf, 4); return retval; } int kachina_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char c = ptt == 0 ? 0x00 : 0x01; int retval = kachina_trans_n(rig, 'x', &c, 1); return retval; } /* * kachina_set_mode * Assumes rig!=NULL * * FIXME: pbwidth handling */ int kachina_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char k_mode; switch (mode) { case RIG_MODE_CW: k_mode = M_CW; break; case RIG_MODE_USB: k_mode = M_USB; break; case RIG_MODE_LSB: k_mode = M_LSB; break; case RIG_MODE_FM: k_mode = M_FM; break; case RIG_MODE_AM: k_mode = M_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } retval = kachina_transaction(rig, 'M', k_mode); if (retval != RIG_OK) { return retval; } return retval; } /* * kachina_get_level * Assumes rig!=NULL */ int kachina_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int i, count; unsigned char buf[32]; hamlib_port_t *rp = RIGPORT(rig); static const char rcv_signal_range[128] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; /* so far, only RAWSTR supported! */ if (level != RIG_LEVEL_RAWSTR) { return -RIG_ENIMPL; } /* telemetry sent to the PC automatically at a 50msec rate */ rig_flush(rp); count = read_string(rp, buf, 31, rcv_signal_range, 128, 0, 1); if (count < 1) { return count; } for (i = 0; i < count; i++) { if (buf[i] <= 0x7f) { break; } } val->i = buf[i]; return RIG_OK; } /* * initrigs_kachina is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kachina) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&k505dsp_caps); return RIG_OK; } hamlib-4.6.5/rigs/kachina/Makefile.in0000664000175000017500000005274715056640452013102 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/kachina ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_kachina_la_LIBADD = am__objects_1 = 505dsp.lo kachina.lo am_libhamlib_kachina_la_OBJECTS = $(am__objects_1) libhamlib_kachina_la_OBJECTS = $(am_libhamlib_kachina_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/505dsp.Plo ./$(DEPDIR)/kachina.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_kachina_la_SOURCES) DIST_SOURCES = $(libhamlib_kachina_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ KACHINASRC = 505dsp.c kachina.c kachina.h noinst_LTLIBRARIES = libhamlib-kachina.la libhamlib_kachina_la_SOURCES = $(KACHINASRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kachina/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kachina/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-kachina.la: $(libhamlib_kachina_la_OBJECTS) $(libhamlib_kachina_la_DEPENDENCIES) $(EXTRA_libhamlib_kachina_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_kachina_la_OBJECTS) $(libhamlib_kachina_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/505dsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kachina.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/505dsp.Plo -rm -f ./$(DEPDIR)/kachina.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/505dsp.Plo -rm -f ./$(DEPDIR)/kachina.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/kachina/Makefile.am0000664000175000017500000000023315056640443013050 KACHINASRC = 505dsp.c kachina.c kachina.h noinst_LTLIBRARIES = libhamlib-kachina.la libhamlib_kachina_la_SOURCES = $(KACHINASRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/icom/0000775000175000017500000000000015056640476010435 5hamlib-4.6.5/rigs/icom/icr8500.c0000664000175000017500000001530515056640443011611 /* * Hamlib CI-V backend - IC-R8500 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #define ICR8500_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_APF) #define ICR8500_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_APF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) #define ICR8500_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR8500_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) /* FIXME: real measure */ #define ICR8500_STR_CAL { 16, { \ { 0, -54 }, /* S0 */ \ { 10, -48 }, \ { 32, -42 }, \ { 46, -36 }, \ { 62, -30 }, \ { 82, -24 }, \ { 98, -18 }, \ { 112, -12 }, \ { 124, -6 }, \ { 134, 0 }, /* S9 */ \ { 156, 10 }, \ { 177, 20 }, \ { 192, 30 }, \ { 211, 40 }, \ { 228, 50 }, \ { 238, 60 }, \ } } int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static struct icom_priv_caps icr8500_priv_caps = { 0x4a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list }; /* * IC-R8500 rig capabilities. */ struct rig_caps icr8500_caps = { RIG_MODEL(RIG_MODEL_ICR8500), .model_name = "IC-R8500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = ICR8500_FUNC_ALL, .has_get_level = ICR8500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR8500_LEVEL_ALL | RIG_LEVEL_AF), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS/DCS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .vfo_ops = ICR8500_OPS, .scan_ops = ICR8500_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 12, .chan_desc_sz = 0, .str_cal = ICR8500_STR_CAL, .chan_list = { /* FIXME: memory channel list */ { 1, 999, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(824) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(849) + 10, MHz(869) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(894) + 10, GHz(2) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(824) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(849) + 10, MHz(869) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(894) + 10, GHz(2) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR8500_MODES, 10}, {ICR8500_MODES, 50}, {ICR8500_MODES, 100}, {ICR8500_MODES, kHz(1)}, {ICR8500_MODES, 2500}, {ICR8500_MODES, kHz(5)}, {ICR8500_MODES, kHz(9)}, {ICR8500_MODES, kHz(10)}, {ICR8500_MODES, 12500}, {ICR8500_MODES, kHz(20)}, {ICR8500_MODES, kHz(25)}, {ICR8500_MODES, kHz(100)}, {ICR8500_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* FIXME: To be confirmed! --SF */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, /* narrow */ {RIG_MODE_AM, kHz(15)}, /* wide */ {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, /* narrow */ {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr8500_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icr8500_set_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_NB: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_NBON : S_FUNC_NBOFF, 0, NULL, 0, 0); case RIG_FUNC_FAGC: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_AGCON : S_FUNC_AGCOFF, 0, NULL, 0, 0); case RIG_FUNC_APF: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_APFON : S_FUNC_APFOFF, 0, NULL, 0, 0); default: return icom_set_func(rig, vfo, func, status); } } hamlib-4.6.5/rigs/icom/ic725.c0000664000175000017500000001141715056640443011350 /* * Hamlib CI-V backend - description of IC-725 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC725_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC725_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC725_AM_TX_MODES (RIG_MODE_AM) #define IC725_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC725_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC725_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC725_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic725_priv_caps = { 0x28, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic725_caps = { RIG_MODEL(RIG_MODEL_IC725), .model_name = "IC-725", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC725_VFO_OPS, .scan_ops = IC725_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(33) - 10, IC725_ALL_RX_MODES, -1, -1, IC725_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(2, IC725_OTHER_TX_MODES, W(10), W(100), IC725_VFO_ALL, IC725_ANTS), FRQ_RNG_HF(2, IC725_AM_TX_MODES, W(10), W(40), IC725_VFO_ALL, IC725_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(33) - 10, IC725_ALL_RX_MODES, -1, -1, IC725_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC725_OTHER_TX_MODES, W(10), W(100), IC725_VFO_ALL, IC725_ANTS), FRQ_RNG_HF(2, IC725_AM_TX_MODES, W(10), W(40), IC725_VFO_ALL, IC725_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC725_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic725_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic775.c0000664000175000017500000001501415056640443011352 /* * Hamlib CI-V backend - description of IC-775 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "bandplan.h" #define IC775_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC775_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM) #define IC775_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) /* * 100W in all modes but AM (40W) */ #define IC775_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC775_AM_TX_MODES (RIG_MODE_AM) #define IC775_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC775_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC775_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic775_priv_caps = { 0x46, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic775_caps = { RIG_MODEL(RIG_MODEL_IC775), .model_name = "IC-775", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC775_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 10, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 11, 12, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC775_ALL_RX_MODES, -1, -1, IC775_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC775_OTHER_TX_MODES, W(10), W(100), IC775_VFO_ALL, IC775_ANTS), FRQ_RNG_HF(1, IC775_AM_TX_MODES, W(10), W(40), IC775_VFO_ALL, IC775_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC775_ALL_RX_MODES, -1, -1, IC775_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(7), kHz(7300), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(7), kHz(7300), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(10100), kHz(10150), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(10100), kHz(10150), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(14), kHz(14350), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(14), kHz(14350), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(18068), kHz(18168), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(18068), kHz(18168), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(21), kHz(21450), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(21), kHz(21450), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(24890), kHz(24990), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(24890), kHz(24990), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(28), kHz(29700), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(28), kHz(29700), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC775_1HZ_TS_MODES, 1}, {IC775_ALL_RX_MODES, 10}, {IC775_ALL_RX_MODES, 100}, {IC775_ALL_RX_MODES, kHz(1)}, {IC775_ALL_RX_MODES, kHz(5)}, {IC775_ALL_RX_MODES, kHz(9)}, {IC775_ALL_RX_MODES, kHz(10)}, {IC775_ALL_RX_MODES, 12500}, {IC775_ALL_RX_MODES, kHz(20)}, {IC775_ALL_RX_MODES, kHz(25)}, {IC775_ALL_RX_MODES, kHz(100)}, {IC775_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic775_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/os456.c0000664000175000017500000001305015056640443011372 /* * Hamlib CI-V backend - description of the OptoScan456 * Copyright (c) 2000-2004 by Stephane Fillod and Michael Smith * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * This backend is currently being maintained by Michael Smith, KE4RJQ. * Email: james (dot) m (dot) smith (at) earthlink (dot) net */ #include #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #include "optoscan.h" extern struct confparams opto_ext_parms[]; #define OS456_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define OS456_VFO_ALL (RIG_VFO_A) #define OS456_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_AF) #define OS456_SCAN_OPS (RIG_SCAN_PLT) /* * The signal strength data is in the form of two bytes, each consisting * of two BCD digits. The signal strength is reported in units of absolute * dBm as measured at the antenna connector. The reported signal strength * ranges from a maximum signal of 0 dBm to a minimum signal of - 125 dBm. * A minus sign is implied. */ #define OS456_STR_CAL { 2, { \ { 0, 60 }, \ { 125, -60 }, \ } } /* TBC */ /* * The OptoScan is not actually a rig. This is an add-in circuit board * for the Realistic PRO-2006 and PRO-2005 Scanning VHF-UHF Receivers. * http://www.optoelectronics.com/tech/pdf/os535/os535_ci5_spec_v10.pdf * * TODO: srch_dcs, srch_ctcss, rcv_dtmf, and make icom_probe opto aware */ static struct icom_priv_caps os456_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL, .settle_time = 20, }; struct rig_caps os456_caps = { RIG_MODEL(RIG_MODEL_OS456), .model_name = "OptoScan456", .mfg_name = "Optoelectronics", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_SERIAL_CAR, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = OS456_LEVELS, .has_set_level = RIG_LEVEL_AF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = full_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .scan_ops = OS456_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { MHz(25), MHz(520), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(760), MHz(1300), OS456_MODES, -1, -1, OS456_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* this is a scanner */ .rx_range_list2 = { { MHz(25), MHz(520), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(760), MHz(823.995), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(849), MHz(868.995), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(894), MHz(1300), OS456_MODES, -1, -1, OS456_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* this is a scanner */ .tuning_steps = { {OS456_MODES, kHz(5)}, {OS456_MODES, kHz(12.5)}, {OS456_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .str_cal = OS456_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& os456_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = optoscan_open, .rig_close = optoscan_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .get_info = optoscan_get_info, .get_ctcss_tone = optoscan_get_ctcss_tone, .get_dcs_code = optoscan_get_dcs_code, .recv_dtmf = optoscan_recv_dtmf, .extparms = opto_ext_parms, .set_ext_parm = optoscan_set_ext_parm, .get_ext_parm = optoscan_get_ext_parm, .set_level = optoscan_set_level, .get_level = optoscan_get_level, .scan = optoscan_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic736.c0000664000175000017500000001360615056640443011354 /* * Hamlib CI-V backend - description of IC-736 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-736 */ #define IC736_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC736_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC736_AM_TX_MODES (RIG_MODE_AM) #define IC736_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC736_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC736_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC736_ANTS 0 /* FIXME: declare both antenna connectors */ #define IC736_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic736_priv_caps = { 0x40, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic736_caps = { RIG_MODEL(RIG_MODEL_IC736), .model_name = "IC-736", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC736_VFO_OPS, .scan_ops = IC736_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 89, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 90, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* FIXME: split */ { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, {MHz(50), MHz(54), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_6m(1, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_HF(1, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ FRQ_RNG_6m(1, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, {MHz(50), MHz(54), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_6m(2, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_HF(2, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ FRQ_RNG_6m(2, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { /* TBC */ {IC736_ALL_RX_MODES, 10}, {IC736_ALL_RX_MODES, kHz(1)}, {IC736_ALL_RX_MODES, kHz(2)}, {IC736_ALL_RX_MODES, kHz(3)}, {IC736_ALL_RX_MODES, kHz(4)}, {IC736_ALL_RX_MODES, kHz(5)}, {IC736_ALL_RX_MODES, kHz(6)}, {IC736_ALL_RX_MODES, kHz(7)}, {IC736_ALL_RX_MODES, kHz(8)}, {IC736_ALL_RX_MODES, kHz(9)}, {IC736_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic736_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/id1.c0000664000175000017500000001261115056640443011171 /* * Hamlib CI-V backend - description of ID-1 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define ID1_MODES (RIG_MODE_FM /* |RIG_MODE_DIGVOICE|RIG_MODE_DIGDATA*/ ) #define ID1_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_MON|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_AFC) #define ID1_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define ID1_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT /* |RIG_PARM_FAN */) #define ID1_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ID1_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ID1_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* * FIXME: real measurement */ #define ID1_STR_CAL UNKNOWN_IC_STR_CAL const struct ts_sc_list id1_ts_sc_list[] = { { kHz(5), 0x00 }, { kHz(10), 0x01 }, { 12500, 0x02 }, { kHz(20), 0x03 }, { kHz(25), 0x04 }, { kHz(50), 0x05 }, { kHz(100), 0x06 }, { kHz(6.25), 0x07 }, { 0, 0 }, }; /* */ static struct icom_priv_caps id1_priv_caps = { 0x01, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ id1_ts_sc_list }; struct rig_caps id1_caps = { RIG_MODEL(RIG_MODEL_ICID1), .model_name = "IC ID-1", .mfg_name = "Icom", .version = BACKEND_VER ".0", .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 = 19200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID1_FUNC_ALL, .has_set_func = ID1_FUNC_ALL, .has_get_level = ID1_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID1_LEVEL_ALL), .has_get_parm = ID1_PARM_ALL, .has_set_parm = ID1_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID1_VFO_OPS, .scan_ops = ID1_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 102, 104, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {GHz(1.240), GHz(1.3), ID1_MODES, -1, -1, ID1_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {GHz(1.240), GHz(1.3), ID1_MODES, W(1), W(10), ID1_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {GHz(1.240), GHz(1.3), ID1_MODES, -1, -1, ID1_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {GHz(1.240), GHz(1.3), ID1_MODES, W(1), W(10), ID1_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {ID1_MODES, kHz(5)}, {ID1_MODES, kHz(6.25)}, {ID1_MODES, kHz(10)}, {ID1_MODES, kHz(12.5)}, {ID1_MODES, kHz(20)}, {ID1_MODES, kHz(25)}, {ID1_MODES, kHz(25)}, {ID1_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, #if 0 {RIG_MODE_DIGVOICE, kHz(6)}, {RIG_MODE_DIGDATA, kHz(140)}, #endif RIG_FLT_END, }, .str_cal = ID1_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id1_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic706.c0000664000175000017500000005601515056640443011352 /* * Hamlib CI-V backend - description of IC-706 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "tones.h" /* * This function does the special bandwidth coding for IC-706, IC-706MKII * and IC-706MKIIG * (0 - wide, 1 - normal, 2 - narrow) */ static int ic706_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } if (width != RIG_PASSBAND_NOCHANGE) { if (*pd == -1) { *pd = PD_MEDIUM_2; } else { (*pd)--; } } return RIG_OK; } #define IC706_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_WFM) #define IC706_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define IC706_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) /* tx doesn't have WFM. * 100W in all modes but AM (40W) */ #define IC706_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC706_AM_TX_MODES (RIG_MODE_AM) #define IC706IIG_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) #define IC706IIG_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define IC706_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #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) /* * IC706IIG_REAL_STR_CAL is accurate measurements * IC706IIG_STR_CAL is what the S-meter displays * * calibration data was obtained from W8WWV * http://www.seed-solutions.com/gregordy/ */ #define IC706IIG_REAL_STR_CAL { 16, \ { \ { 46, -27 }, /* S0 */ \ { 54, -25 }, \ { 64, -24 }, \ { 76, -23 }, \ { 84, -22 }, \ { 94, -20 }, \ { 104, -16 }, \ { 113, -11 }, \ { 123, -5 }, \ { 133, 0 }, /* S9 */ \ { 144, 5 }, /* +10 */ \ { 156, 10 }, /* +20 */ \ { 170, 16 }, /* +30 */ \ { 181, 21 }, /* +40 */ \ { 192, 26 }, /* +50 */ \ { 204, 35 } /* +60 */ \ } } #define IC706IIG_STR_CAL { 17, \ { \ { 45, -60 }, \ { 46, -54 }, /* S0 */ \ { 54, -48 }, \ { 64, -42 }, \ { 76, -36 }, \ { 84, -30 }, \ { 94, -24 }, \ { 104, -18 }, \ { 113, -12 }, \ { 123, -6 }, \ { 133, 0 }, /* S9 */ \ { 144, 10 }, /* +10 */ \ { 156, 20 }, /* +20 */ \ { 170, 30 }, /* +30 */ \ { 181, 40 }, /* +40 */ \ { 192, 50 }, /* +50 */ \ { 204, 60 } /* +60 */ \ } } /* * ic706 rigs capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! */ static const struct icom_priv_caps ic706_priv_caps = { 0x48, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706_caps = { RIG_MODEL(RIG_MODEL_IC706), .model_name = "IC-706", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), 199999999, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), 1999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), 3999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), 3999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, /* not sure.. */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, /* anyone? */ RIG_FRNG_END, }, .tuning_steps = {{IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .priv = (void *)& ic706_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic706mkii_priv_caps = { 0x4e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706mkii_caps = { RIG_MODEL(RIG_MODEL_IC706MKII), .model_name = "IC-706MkII", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), 199999999, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), 1999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), 3999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), 3999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, /* not sure.. */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, /* anyone? */ RIG_FRNG_END, }, .tuning_steps = { {IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .priv = (void *)& ic706mkii_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC706MkIIG channel caps. */ #define IC706MKIIG_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, /* only set */ \ .funcs = IC706IIG_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC706IIG_LEVEL_ALL), \ } /* * Basically, the IC706MKIIG is an IC706MKII plus UHF, a DSP * and 50W VHF */ static const struct icom_priv_caps ic706mkiig_priv_caps = { 0x58, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706mkiig_caps = { RIG_MODEL(RIG_MODEL_IC706MKIIG), .model_name = "IC-706MkIIG", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC706IIG_FUNC_ALL, .has_set_func = IC706IIG_FUNC_ALL, .has_get_level = IC706IIG_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC706IIG_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .scan_ops = IC706_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC706MKIIG_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, IC706MKIIG_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, IC706MKIIG_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(200) - 1, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, /* this trx also has UHF */ {MHz(400), MHz(470), IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC706_OTHER_TX_MODES, W(5), W(100), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(1, IC706_AM_TX_MODES, W(2), W(40), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC706_OTHER_TX_MODES, W(5), W(100), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_6m(1, IC706_AM_TX_MODES, W(2), W(40), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, IC706_OTHER_TX_MODES, W(5), W(50), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_2m(1, IC706_AM_TX_MODES, W(2), W(20), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_70cm(1, IC706_OTHER_TX_MODES, W(5), W(20), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_70cm(1, IC706_AM_TX_MODES, W(2), W(8), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(200) - 1, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, /* this trx also has UHF */ {MHz(400), MHz(470), IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 50000, IC706_VFO_ALL}, /* 50W */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 20000, IC706_VFO_ALL}, /* AM VHF is 20W */ {MHz(430), MHz(450), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, {MHz(430), MHz(450), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic706mkiig_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic765.c0000664000175000017500000001445715056640443011363 /* * Hamlib CI-V backend - description of IC-765 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC765_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) /* * IC-765 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic765/specs.htm * */ #define IC765_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define IC765_AM_TX_MODES (RIG_MODE_AM) #define IC765_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC765_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC765_SCAN_OPS (RIG_SCAN_PROG|RIG_SCAN_MEM) #define IC765_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic765_priv_caps = { 0x2c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic765_caps = { RIG_MODEL(RIG_MODEL_IC765), .model_name = "IC-765", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC765_VFO_OPS, .scan_ops = IC765_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC765_ALL_RX_MODES, -1, -1, IC765_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC765_OTHER_TX_MODES, W(10), W(100), IC765_VFO_ALL, IC765_ANTS), FRQ_RNG_HF(1, IC765_AM_TX_MODES, W(10), W(40), IC765_VFO_ALL, IC765_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC765_ALL_RX_MODES, -1, -1, IC765_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {kHz(1800), 1999999, IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, /* 40W class */ {kHz(3400), 4099999, IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(3400), 4099999, IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(9.9), MHz(1049999), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(9.9), MHz(1049999), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {kHz(17900), kHz(18499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(17900), kHz(18499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {kHz(24400), kHz(25099.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(24400), kHz(25099.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(28), MHz(30), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(28), MHz(30), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC765_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic765_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/id51.c0000664000175000017500000001524215056640443011261 /* * Hamlib CI-V backend - description of ID-51 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "token.h" #include "icom.h" #include "idx_builtin.h" #include "icom_defs.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 17 of ID-51A_E_PLUS2_CD_0.pdf * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP" for rig control. * */ #define ID51_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID51_ALL_RX_MODES (RIG_MODE_AM|ID51_MODES) #define ID51_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ID51_SCAN_OPS RIG_SCAN_NONE #define ID51_VFO_OPS RIG_OP_NONE #define ID51_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID51_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID51_PARM_ALL RIG_PARM_NONE int id51_tokens[] = { TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_DSTAR_MY_CS, TOK_DSTAR_TX_CS, TOK_DSTAR_TX_MESS, TOK_BACKEND_NONE }; /* * FIXME: real measurement */ #define ID51_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id51_priv_caps = { 0x86, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id51_caps = { RIG_MODEL(RIG_MODEL_ID51), .model_name = "ID-51", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID51_FUNC_ALL, .has_set_func = ID51_FUNC_ALL, .has_get_level = ID51_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID51_LEVEL_ALL), .has_get_parm = ID51_PARM_ALL, .has_set_parm = ID51_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .ext_tokens = id51_tokens, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID51_VFO_OPS, .scan_ops = ID51_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, {MHz(375), MHz(550), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID51_MODES, W(5), W(25), ID51_VFO_ALL}, {MHz(430), MHz(440), ID51_MODES, W(5), W(25), ID51_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, {MHz(375), MHz(550), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID51_MODES, W(5), W(50), ID51_VFO_ALL}, {MHz(430), MHz(450), ID51_MODES, W(5), W(50), ID51_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID51_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id51_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // not capable .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/os535.c0000664000175000017500000001231315056640443011371 /* * Hamlib CI-V backend - description of the OptoScan535 * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * This backend is currently being maintained by Michael Smith, KE4RJQ. * Email: james (dot) m (dot) smith (at) earthlink (dot) net */ #include #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #include "optoscan.h" extern struct confparams opto_ext_parms[]; #define OS535_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define OS535_VFO_ALL (RIG_VFO_A) #define OS535_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_AF) #define OS535_SCAN_OPS (RIG_SCAN_PLT) #define OS535_STR_CAL { 2, { \ { 20, 60 }, \ { 137, -60 }, \ } } /* TBC */ /* * The OptoScan is not actually a rig. This is an add-in circuit board * for the Realistic PRO-2035 and PRO-2045 Scanning VHF-UHF Receivers. * http://www.optoelectronics.com/tech/pdf/os535/os535_ci5_spec_v10.pdf * * TODO: srch_dcs, srch_ctcss, rcv_dtmf, and make icom_probe opto aware */ static struct icom_priv_caps os535_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL, .settle_time = 12, }; struct rig_caps os535_caps = { RIG_MODEL(RIG_MODEL_OS535), .model_name = "OptoScan535", .mfg_name = "Optoelectronics", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_SERIAL_CAR, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = OS535_LEVELS, .has_set_level = RIG_LEVEL_AF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = full_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .scan_ops = OS535_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { MHz(25), MHz(520), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(760), MHz(1300), OS535_MODES, -1, -1, OS535_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* this is a scanner */ .rx_range_list2 = { { MHz(25), MHz(520), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(760), MHz(823.995), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(849), MHz(868.995), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(894), MHz(1300), OS535_MODES, -1, -1, OS535_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* this is a scanner */ .tuning_steps = { {OS535_MODES, kHz(5)}, {OS535_MODES, kHz(12.5)}, {OS535_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .str_cal = OS535_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& os535_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = optoscan_open, .rig_close = optoscan_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .get_info = optoscan_get_info, .get_ctcss_tone = optoscan_get_ctcss_tone, .get_dcs_code = optoscan_get_dcs_code, .recv_dtmf = optoscan_recv_dtmf, .extparms = opto_ext_parms, .set_ext_parm = optoscan_set_ext_parm, .get_ext_parm = optoscan_get_ext_parm, .set_level = optoscan_set_level, .get_level = optoscan_get_level, .scan = optoscan_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/frame.h0000664000175000017500000000353115056640443011614 /* * Hamlib CI-V backend - low level communication header * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FRAME_H #define _FRAME_H 1 #include #include "rig.h" // Has to be big enough for 0xfe sequence to wake up rig #define MAXFRAMELEN 200 /* * helper functions */ int make_cmd_frame(unsigned char frame[], unsigned char re_id, unsigned char ctrl_id, unsigned char cmd, int subcmd, const unsigned char *data, int data_len); int icom_frame_fix_preamble(int frame_len, unsigned char *frame); int icom_transaction (RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len); int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); int read_icom_frame_direct(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); int rig2icom_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); #endif /* _FRAME_H */ hamlib-4.6.5/rigs/icom/icrx7.c0000664000175000017500000001023215056640443011545 /* * Hamlib CI-V backend - description of IC-RX7 * Copyright (c) 2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICRX7_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICRX7_FUNC_ALL (RIG_FUNC_NONE) #define ICRX7_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICRX7_VFO_ALL (RIG_VFO_A) #define ICRX7_VFO_OPS (RIG_OP_NONE) #define ICRX7_SCAN_OPS (RIG_SCAN_NONE) /* * FIXME: S-meter measurement */ #define ICRX7_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icrx7_priv_caps = { 0x78, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icrx7_caps = { RIG_MODEL(RIG_MODEL_ICRX7), .model_name = "IC-RX7", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICRX7_FUNC_ALL, .has_set_func = ICRX7_FUNC_ALL, .has_get_level = ICRX7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICRX7_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICRX7_VFO_OPS, .scan_ops = ICRX7_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* Unfortunately, not accessible through CI-V */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), GHz(1.3), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(821.995), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, {MHz(851), MHz(866.995), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, {MHz(896), GHz(1.3), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICRX7_MODES, Hz(100)}, RIG_TS_END, }, .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICRX7_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icrx7_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icr7000.c0000664000175000017500000002202215056640443011575 /* * Hamlib CI-V backend - IC-R7000 and IC-R7100 descriptions * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #define ICR7000_MODES (RIG_MODE_AM|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR7000_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) static int r7000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); #define ICR7100_FUNCS (RIG_FUNC_VSC) #define ICR7100_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define ICR7100_PARMS (RIG_PARM_ANN) #define ICR7100_SCAN_OPS (RIG_SCAN_MEM) /* TBC */ /* FIXME: S-Meter measurements */ #define ICR7100_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icr7000_priv_caps = { 0x08, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r7100_ts_sc_list }; /* * ICR7000 rigs capabilities. */ struct rig_caps icr7000_caps = { RIG_MODEL(RIG_MODEL_ICR7000), .model_name = "IC-R7000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR7000_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(1000), ICR7000_MODES, -1, -1, RIG_VFO_A}, {MHz(1025), MHz(2000), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(1000), ICR7000_MODES, -1, -1, RIG_VFO_A}, {MHz(1025), MHz(2000), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR7000_MODES, 100}, /* resolution */ #if 0 {ICR7000_MODES, kHz(1)}, {ICR7000_MODES, kHz(5)}, {ICR7000_MODES, kHz(10)}, {ICR7000_MODES, 12500}, {ICR7000_MODES, kHz(25)}, #endif RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr7000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = r7000_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps icr7100_priv_caps = { 0x34, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r7100_ts_sc_list }; /* * ICR7100A rig capabilities. */ struct rig_caps icr7100_caps = { RIG_MODEL(RIG_MODEL_ICR7100), .model_name = "IC-R7100", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR7100_FUNCS, .has_set_func = ICR7100_FUNCS, .has_get_level = ICR7100_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR7100_LEVELS), .has_get_parm = ICR7100_PARMS, .has_set_parm = RIG_PARM_SET(ICR7100_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR7000_OPS, .scan_ops = ICR7100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, /* TBC */ { 0x0900, 0x0909, RIG_MTYPE_EDGE }, /* 2 by 2 */ { 0x0910, 0x0919, RIG_MTYPE_EDGE }, /* 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(1999.9999), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(1999.9999), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR7000_MODES, 100}, /* resolution */ {ICR7000_MODES, kHz(1)}, {ICR7000_MODES, kHz(5)}, {ICR7000_MODES, kHz(10)}, {ICR7000_MODES, 12500}, {ICR7000_MODES, kHz(20)}, {ICR7000_MODES, kHz(25)}, {ICR7000_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR7100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr7100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = r7000_set_freq, /* TBC for R7100 */ .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, #ifdef XXREMOVEDXX .set_parm = icom_set_parm, .get_parm = icom_get_parm, #endif .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, }; /* * Function definitions below */ /* * r7000_set_freq */ static int r7000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { long long f = (long long)freq; /* * The R7000 cannot set frequencies higher than 1GHz, * this is done by flipping a switch on the front panel and * stripping the most significant digit. * This is the only change with the common icom_set_freq */ f %= (long long)GHz(1); return icom_set_freq(rig, vfo, (freq_t)f); } hamlib-4.6.5/rigs/icom/id5100.c0000664000175000017500000004520515056640443011423 /* * Hamlib CI-V backend - description of ID-5100 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" enum { MAIN_ON_LEFT, MAIN_ON_RIGHT }; /* * Specs and protocol details comes from the chapter 13 of ID-5100_Full-Inst_Manual.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP2" for rig control. * * TODO: * - DV mode * - GPS support * - Single/dual watch (RIG_LEVEL_BALANCE) */ #define ID5100_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_DSTAR) #define ID5100_ALL_RX_MODES (RIG_MODE_AM|ID5100_MODES) #define ID5100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB) #define ID5100_SCAN_OPS RIG_SCAN_NONE #define ID5100_VFO_OPS RIG_OP_NONE #define ID5100_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_DUAL_WATCH| \ RIG_FUNC_VOX) #define ID5100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID5100_PARM_ALL RIG_PARM_NONE int id5100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int id5100_set_vfo(RIG *rig, vfo_t vfo) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } // if user requests VFOA/B we automatically turn of dual watch mode // if user requests Main/Sub we automatically turn on dual watch mode // hopefully this is a good idea and just prevents users/clients from having set the mode themselves #if 0 if (vfo == RIG_VFO_A || vfo == RIG_VFO_B) { // and 0x25 works in this mode priv->x25cmdfails = 1; if (priv->dual_watch) { // then we need to turn off dual watch if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, 0))) { RETURNFUNC(retval); } priv->dual_watch = 0; } } else if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) { // x25 does not work in DUAL_WATCH mode priv->x25cmdfails = 1; if (priv->dual_watch == 0) { if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, 1))) { RETURNFUNC(retval); } priv->dual_watch = 1; } } #endif int myvfo = S_MAIN; priv->dual_watch_main_sub = MAIN_ON_LEFT; rs->current_vfo = RIG_VFO_A; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { myvfo = S_SUB; priv->dual_watch_main_sub = MAIN_ON_RIGHT; rs->current_vfo = vfo; } if (RIG_OK != (retval = icom_transaction(rig, C_SET_VFO, myvfo, NULL, 0, ackbuf, &ack_len))) { RETURNFUNC(retval); } RETURNFUNC(retval); } int id5100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int cmd = C_SET_FREQ; int subcmd = -1; unsigned char freqbuf[MAXFRAMELEN]; int freq_len = 5; int retval; struct rig_state *rs = STATE(rig); //struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; vfo_t currvfo = rs->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (rs->dual_watch == 0 && (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB)) { id5100_set_split_vfo(rig, RIG_VFO_SUB, 1, RIG_VFO_MAIN); } if (rs->dual_watch == 1 && (vfo == RIG_VFO_A || vfo == RIG_VFO_B)) { id5100_set_split_vfo(rig, RIG_VFO_A, 0, RIG_VFO_A); } if (vfo != currvfo) { id5100_set_vfo(rig, vfo); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); to_bcd(freqbuf, freq, freq_len * 2); retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); if (vfo != currvfo) { id5100_set_vfo(rig, currvfo); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_freq failed: %s\n", __func__, rigerror(retval)); return retval; } return RIG_OK; } static int id5100_get_freq2(RIG *rig, vfo_t vfo, freq_t *freq) { unsigned char freqbuf[MAXFRAMELEN]; int freq_len = 5; int retval; int freqbuf_offset = 1; int cmd = 0x03; int subcmd = -1; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); retval = icom_transaction(rig, cmd, subcmd, NULL, 0, freqbuf, &freq_len); if (retval != RIG_OK) { return -retval; } *freq = from_bcd(freqbuf + freqbuf_offset, freq_len * 2); return RIG_OK; } int id5100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retval; vfo_t currvfo = rs->current_vfo; if (rs->dual_watch == 1 && rs->current_vfo != RIG_VFO_SUB) { id5100_set_split_vfo(rig, RIG_VFO_SUB, 0, RIG_VFO_MAIN); } if (rs->dual_watch) // dual watch is different { rig_debug(RIG_DEBUG_VERBOSE, "%s: Dual watch is on\n", __func__); if (priv->dual_watch_main_sub == MAIN_ON_LEFT || currvfo == RIG_VFO_A) // Then Main is on left { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main on left\n", __func__, __LINE__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { rig_debug(RIG_DEBUG_ERR, "%s: Method#1\n", __func__); id5100_set_vfo(rig, RIG_VFO_A); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_B); return retval; } else // Sub read -- don't need to do anything as it's on the left side { rig_debug(RIG_DEBUG_ERR, "%s: Method#2\n", __func__); retval = id5100_get_freq2(rig, vfo, freq); return retval; } } else // { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub on left\n", __func__, __LINE__); if ((currvfo == RIG_VFO_B || currvfo == RIG_VFO_SUB) && (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB)) { rig_debug(RIG_DEBUG_ERR, "%s: Method#3\n", __func__); id5100_set_vfo(rig, RIG_VFO_MAIN); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_SUB); return retval; } else { rig_debug(RIG_DEBUG_ERR, "%s: Method#4\n", __func__); retval = id5100_get_freq2(rig, vfo, freq); return retval; } } } else // not dual watch { if (currvfo != vfo) { id5100_set_vfo(rig, vfo); } retval = id5100_get_freq2(rig, vfo, freq); if (currvfo != vfo) { id5100_set_vfo(rig, currvfo); } return retval; } #if 0 else if ((vfo == RIG_VFOvfo == RIG_VFO_SUB && rs->dual_watch_main_sub == MAIN_ON_RIGHT) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub/A vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); *freq = CACHE(rig)->freqSubA; int cache_ms_freq, cache_ms_mode, cache_ms_width; pbwidth_t width; freq_t tfreq; rmode_t mode; retval = rig_get_cache(rig, RIG_VFO_SUB, &tfreq, &cache_ms_freq, &mode, &cache_ms_mode, } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: Dual watch is off\n", __func__); } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (vfo == RIG_VFO_MAIN && priv->dual_watch_main_sub == MAIN_ON_LEFT) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main/A vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); } if (priv->dual_watch_main_sub == MAIN_ON_LEFT || currvfo == RIG_VFO_A || currvfo == RIG_VFO_MAIN) // Then Main is on left { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main on left\n", __func__, __LINE__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { return id5100_get_freq2(rig, vfo, freq); } else { id5100_set_vfo(rig, RIG_VFO_B); hl_usleep(50 * 1000); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_A); return retval; } } else // MAIN_ON_RIGHT { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub on left\n", __func__, __LINE__); if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { if (rs->dual_watch) { id5100_set_vfo(rig, RIG_VFO_A); } id5100_get_freq2(rig, vfo, freq); if (rs->dual_watch) { id5100_set_vfo(rig, RIG_VFO_B); } } else { retval = id5100_get_freq2(rig, vfo, freq); return retval; } } #endif return RIG_OK; } /* * FIXME: real measurement */ #define ID5100_STR_CAL UNKNOWN_IC_STR_CAL int id5100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char modebuf; unsigned char ackbuf[MAXFRAMELEN]; int icmode = 2; int ack_len = sizeof(ackbuf); switch (mode) { case RIG_MODE_AM: icmode = 2; modebuf = 1; break; case RIG_MODE_AMN: icmode = 2; modebuf = 2; break; case RIG_MODE_FM: icmode = 5; modebuf = 1; break; case RIG_MODE_FMN: icmode = 5; modebuf = 2; break; case RIG_MODE_DSTAR: icmode = 0x17; modebuf = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode=%s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: mode=%d, modebuf=%c\n", __func__, icmode, modebuf); retval = icom_transaction(rig, C_SET_MODE, icmode, &modebuf, 1, ackbuf, &ack_len); return retval; } int id5100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int mode_len; unsigned char modebuf[4]; retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); if (retval != RIG_OK) { return retval; } switch (modebuf[1]) { case 2: *mode = modebuf[2] == 1 ? RIG_MODE_AM : RIG_MODE_AMN; *width = modebuf[2] == 1 ? 12000 : 6000; break; case 5: *mode = modebuf[2] == 1 ? RIG_MODE_FM : RIG_MODE_FMN; *width = modebuf[2] == 1 ? 10000 : 5000; break; case 0x17: *mode = RIG_MODE_DSTAR; *width = 6000; break; } return RIG_OK; } int id5100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if (tx_vfo != RIG_VFO_MAIN) { rig_debug(RIG_DEBUG_ERR, "%s Split VFO must be Main\n", __func__); return -RIG_EINVAL; } if (rs->dual_watch == 0 || split == RIG_SPLIT_OFF) { if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, split))) { RETURNFUNC2(retval); } rs->dual_watch = split; // if (split == RIG_SPLIT_OFF) { rig_set_vfo(rig, RIG_VFO_A); } return RIG_OK; } priv->dual_watch_main_sub = MAIN_ON_LEFT; // ID5100 puts tx on Main and rx on Left side // So we put Main on right side to match gpredict positions // we must set RX vfo to SUB retval = id5100_set_vfo(rig, RIG_VFO_SUB); rs->current_vfo = RIG_VFO_SUB; priv->dual_watch_main_sub = MAIN_ON_RIGHT; return retval; } int id5100_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int freq_len = 5; int retval; int cmd; int subcmd; unsigned char freqbuf[MAXFRAMELEN]; ENTERFUNC; to_bcd(freqbuf, tx_freq, freq_len * 2); cmd = 0x0; subcmd = -1; // Main is always TX retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); RETURNFUNC(retval); } int id5100_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; //struct rig_state *rs = STATE(rig); //struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; //vfo_t currvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); #if 0 currvfo = rs->current_vfo; if (priv->dual_watch_main_sub == MAIN_ON_LEFT && (currvfo == RIG_VFO_MAIN || currvfo == RIG_VFO_A) && vfo == RIG_VFO_TX) { rig_set_vfo(rig, RIG_VFO_SUB); retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq); rig_set_vfo(rig, RIG_VFO_MAIN); } else #endif { retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq); } return retval; } /* */ static struct icom_priv_caps id5100_priv_caps = { 0x8C, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ .dualwatch_split = 1 }; struct rig_caps id5100_caps = { RIG_MODEL(RIG_MODEL_ID5100), .model_name = "ID-5100", .mfg_name = "Icom", .version = BACKEND_VER ".9", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = ID5100_FUNC_ALL, .has_set_func = ID5100_FUNC_ALL, .has_get_level = ID5100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID5100_LEVEL_ALL), .has_get_parm = ID5100_PARM_ALL, .has_set_parm = ID5100_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID5100_VFO_OPS, .scan_ops = ID5100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, {MHz(375), MHz(550), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID5100_MODES, W(5), W(25), ID5100_VFO_ALL}, {MHz(430), MHz(440), ID5100_MODES, W(5), W(25), ID5100_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, {MHz(375), MHz(550), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID5100_MODES, W(5), W(50), ID5100_VFO_ALL}, {MHz(430), MHz(450), ID5100_MODES, W(5), W(50), ID5100_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID5100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id5100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = id5100_set_freq, .get_freq = id5100_get_freq, .get_split_freq = id5100_get_split_freq, .set_split_freq = id5100_set_split_freq, .set_mode = id5100_set_mode, .get_mode = id5100_get_mode, .set_vfo = id5100_set_vfo, .set_split_vfo = id5100_set_split_vfo, .set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, // ID-5100 cannot get power status .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/level_gran_icom.h0000664000175000017500000001045715056640443013654 /* LVL_IF LVL_RAWSTR LVL_SPECTRUM_AVG LVL_SPECTRUM_REF LVL_SPECTRUM_SPEED LVL_PBT_IN LVL_PBT_OUT LVL_KEYSPD */ // Once included these values can be overridden in the back-end // Known variants are AGC_TIME, PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ #if !defined(NO_LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 5 } }, #endif [LVL_IF] = { .min = { .i = -1200 }, .max = { .i = 1200 }, .step = { .i = 20 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, /* levels with time units */ [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_AGC_TIME] = { .min = { .f = 0.0f }, .max = { .f = 8.0f }, .step = { .f = 0.1f } }, /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, /* levels with 0-1 values -- increment based on rig's range */ [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/15.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ANTIVOX] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/120.0f } }, #if !defined(NO_LVL_USB_AF) [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_PBT_IN) [LVL_PBT_IN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_PBT_OUT) [LVL_PBT_OUT] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif hamlib-4.6.5/rigs/icom/icom.h0000664000175000017500000007157115056640443011462 /* * Hamlib CI-V backend - main header * Copyright (c) 2000-2016 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICOM_H #define _ICOM_H 1 #include #include #include "hamlib/rig.h" #include "cal.h" #include "tones.h" #include "idx_builtin.h" #ifdef HAVE_SYS_TIME_H #include #endif #define BACKEND_VER "20250517" #define ICOM_IS_ID31 rig_is_model(rig, RIG_MODEL_ID31) #define ICOM_IS_ID51 rig_is_model(rig, RIG_MODEL_ID51) #define ICOM_IS_ID4100 rig_is_model(rig, RIG_MODEL_ID4100) #define ICOM_IS_ID5100 rig_is_model(rig, RIG_MODEL_ID5100) #define ICOM_IS_SECONDARY_VFO(vfo) ((vfo) & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B)) #define ICOM_GET_VFO_NUMBER(vfo) (ICOM_IS_SECONDARY_VFO(vfo) ? 0x01 : 0x00) #define ICOM_MAX_SPECTRUM_FREQ_RANGES 20 /* * defines used by comp_cal_str in rig.c * STR_CAL_LENGTH is the length of the S Meter calibration table * STR_CAL_S0 is the value in dB of the lowest value (not even in table) * MULTIB_SUBCMD allows the dsp rigs ie pro models to use multibyte subcommands for all the extra * parameters and levels. */ #define STR_CAL_LENGTH 16 #define STR_CAL_S0 (-54) #define MULTIB_SUBCMD /* * minimal channel caps. * If your rig has better/lesser, don't modify this define but clone it, * so you don't change other rigs. */ #define IC_MIN_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } /* * common channel caps. * If your rig has better/lesser, don't modify this define but clone it, * so you don't change other rigs. */ #define IC_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ } /* * S-Meter data for uncalibrated rigs */ #define UNKNOWN_IC_STR_CAL { 2, {{ 0, -60}, { 255, 60}} } struct ts_sc_list { shortfreq_t ts; /* tuning step */ unsigned char sc; /* sub command */ }; /** * \brief Pipelined tuning state data structure. */ typedef struct rig_pltstate { freq_t freq; freq_t next_freq; rmode_t mode; rmode_t next_mode; pbwidth_t width; pbwidth_t next_width; struct timeval timer_start; struct timeval timer_current; int usleep_time; /* dependent on radio module & serial data rate */ } pltstate_t; /** * \brief Mappings between Hamlib and Icom AGC levels */ struct icom_agc_level { enum agc_level_e level; /*!< Hamlib AGC level from agc_level_e enum, the last entry should have level -1 */ unsigned char icom_level; /*!< Icom AGC level for C_CTL_FUNC (0x16), S_FUNC_AGC (0x12) command */ }; typedef enum { CMD_PARAM_TYPE_NONE, CMD_PARAM_TYPE_LEVEL, CMD_PARAM_TYPE_PARM, CMD_PARAM_TYPE_TOKEN, CMD_PARAM_TYPE_FUNC, } cmd_param_t; /** * \brief Lookup table item for Icom levels & parms */ struct cmdparams { union { setting_t s; /*!< Level or parm */ hamlib_token_t t; /*!< TOKEN_BACKEND */ } id; cmd_param_t cmdparamtype; /*!< CMD_PARAM_TYPE_LEVEL or CMD_PARAM_TYPE_PARM */ int command; /*!< CI-V command */ int subcmd; /*!< CI-V Subcommand */ int submod; /*!< Subcommand modifier */ int sublen; /*!< Number of bytes for subcommand extension */ unsigned char subext[4]; /*!< Subcommand extension bytes */ int dattyp; /*!< Data type conversion */ int datlen; /*!< Number of data bytes in frame */ }; /** * \brief Icom-specific spectrum scope capabilities, if supported by the rig. */ struct icom_spectrum_scope_caps { int spectrum_line_length; /*!< Number of bytes in a complete spectrum scope line */ int single_frame_data_length; /*!< Number of bytes of specrtum data in a single CI-V frame when the data split to multiple frames */ int data_level_min; /*!< */ int data_level_max; double signal_strength_min; double signal_strength_max; }; /** * \brief Icom spectrum scope edge frequencies, if supported by the rig. * * Last entry should have zeros in all fields. */ struct icom_spectrum_edge_frequency_range { int range_id; /*!< ID of the range, as specified in the Icom CI-V manuals. First range ID is 1. */ freq_t low_freq; /*!< The low edge frequency if the range in Hz */ freq_t high_freq; /*!< The high edge frequency if the range in Hz */ }; /** * \brief Cached Icom spectrum scope data. * * This data is used to store data for current line of spectrum data as it is being received from the rig. * Caching the data is necessary for handling spectrum scope data split in multiple CI-V frames. */ struct icom_spectrum_scope_cache { int id; /*!< Numeric ID of the spectrum scope data stream identifying the VFO/receiver. First ID is zero. Icom rigs with multiple scopes have IDs: 0 = Main, 1 = Sub. */ int spectrum_metadata_valid; /*!< Boolean value to track validity of the cached data for spectrum scope. */ enum rig_spectrum_mode_e spectrum_mode; /*!< The spectrum mode of the current spectrum scope line being received. */ freq_t spectrum_center_freq; /*!< The center frequency of the current spectrum scope line being received */ freq_t spectrum_span_freq; /*!< The frequency span of the current spectrum scope line being received */ freq_t spectrum_low_edge_freq; /*!< The low edge frequency of the current spectrum scope line being received */ freq_t spectrum_high_edge_freq; /*!< The high edge frequency of the current spectrum scope line being received */ size_t spectrum_data_length; /*!< Number of bytes of 8-bit spectrum data in the data buffer. The amount of data may vary if the rig has multiple spectrum scopes, depending on the scope. */ unsigned char *spectrum_data; /*!< Dynamically allocated buffer for raw spectrum data */ }; struct icom_priv_caps { unsigned char re_civ_addr; /*!< The remote equipment's default CI-V address */ int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits plus passband setting */ // According to the CI-V+ manual the IC-781, IC-R9000, and IC-R7000 can select pas$ // The other rigs listed apparently cannot and may need the civ_731_mode=1 which are // 1-706 // 2-706MKII // 3-706MKIIG // 4-707 // 5-718 // 6-746 // 7-746PRO // 8-756 // 9-756PRO // 10-756PROII // 11-820H // 12-821H // 13-910H // 14-R10 // 15-R8500 // 16-703 // 17-7800 int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */ const struct ts_sc_list *ts_sc_list; // the 4 elements above are mandatory // everything below here is optional in the backends int settle_time; /*!< Receiver settle time, in ms */ int (*r2i_mode)(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); /*!< backend specific code to convert bandwidth and mode to cmd tokens */ void (*i2r_mode)(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); /*!< backend specific code to convert response tokens to bandwidth and mode */ int antack_len; /*!< Length of 0x12 cmd may be 3 or 4 bytes as of 2020-01-22 e.g. 7851 */ int ant_count; /*!< Number of antennas */ int serial_full_duplex; /*!< Whether RXD&TXD are not tied together */ int offs_len; /*!< Number of bytes in offset frequency field. 0 defaults to 3 */ int serial_USB_echo_check; /*!< Flag to test USB echo state */ int agc_levels_present; /*!< Flag to indicate that agc_levels array is populated */ struct icom_agc_level agc_levels[HAMLIB_MAX_AGC_LEVELS + 1]; /*!< Icom rig-specific AGC levels, the last entry should have level -1 */ struct icom_spectrum_scope_caps spectrum_scope_caps; /*!< Icom spectrum scope capabilities, if supported by the rig. Main/Sub scopes in Icom rigs have the same caps. */ struct icom_spectrum_edge_frequency_range spectrum_edge_frequency_ranges[ICOM_MAX_SPECTRUM_FREQ_RANGES]; /*!< Icom spectrum scope edge frequencies, if supported by the rig. Last entry should have zeros in all fields. */ struct cmdparams *extcmds; /*!< Pointer to extended operations array */ int dualwatch_split; /*!< Rig supports dual watch for split ops -- e.g. ID-5100 */ int x25x26_always; /*!< Rig should use 0x25 and 0x26 commands always */ int x25x26_possibly; /*!< Rig might support 0x25 and 0x26 commands if the firmware is upgraded */ int x1cx03_always; /*!< Rig should use 0x1C 0x03 command for getting TX frequency */ int x1cx03_possibly; /*!< Rig might support 0x1C 0x03 command if the firmware is upgraded TODO: is this added by FW upgrade ever? */ int x1ax03_supported; /*!< Rig supports setting/getting filter width */ int mode_with_filter; /*!< Rig mode commands include filter selection */ int data_mode_supported; /*!< Rig supports data mode flag */ int fm_filters[3]; /*!< For models with FIL1/2/3 for FM low-to-high fixed filters -- IC7300/9700 */ }; struct icom_priv_data { unsigned char re_civ_addr; /*!< The remote equipment's CI-V address */ int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits */ int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */ int no_1a_03_cmd; /*!< Rig does not support setting/getting filter width */ int split_on_deprecated; /*!< @deprecated Use rig_cache.split - Record split state */ pltstate_t *pltstate; /*!< Only on optoscan */ int serial_USB_echo_off; /*!< USB is not set to echo */ /** * Icom backends track VFOs internally for use with different functions like split. * This allows queries using CURR_VFO and Main/Sub to work correctly. * * The fields in this struct are no longer used, because rig_state and rig_cache structs provide * the same functionality for all rigs globally. */ vfo_t rx_vfo_deprecated; /*!< @deprecated Use rig_state.rx_vfo */ vfo_t tx_vfo_deprecated; /*!< @deprecated Use rig_state.tx_vfo */ freq_t curr_freq_deprecated; /*!< @deprecated Use rig_cache.freqCurr - Our current freq depending on which vfo is selected */ freq_t main_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of main -- not being used yet */ freq_t sub_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA - Track last setting of sub -- not being used yet */ freq_t maina_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA */ freq_t mainb_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB */ freq_t suba_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA */ freq_t subb_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubB */ freq_t vfoa_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of vfoa -- used to return last freq when ptt is asserted */ freq_t vfob_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB - Track last setting of vfob -- used to return last freq when ptt is asserted */ int x25cmdfails; /*!< This will get set if the 0x25 command fails so we try just once */ int x26cmdfails; /*!< This will get set if the 0x26 command fails so we try just once */ int x1cx03cmdfails; /*!< This will get set if the 0x1c 0x03 command fails so we try just once */ int poweron; /*!< To prevent powering on more than once */ unsigned char filter; /*!< Current filter selected */ unsigned char datamode; /*!< Current datamode */ int spectrum_scope_count; /*!< Number of spectrum scopes, calculated from caps */ struct icom_spectrum_scope_cache spectrum_scope_cache[HAMLIB_MAX_SPECTRUM_SCOPES]; /*!< Cached Icom spectrum scope data used during reception of the data. The array index must match the scope ID. */ freq_t other_freq_deprecated; /*!< @deprecated Use rig_cache.freqOther - Our other freq depending on which vfo is selected */ int vfo_flag; // used to skip vfo check when frequencies are equal int dual_watch_main_sub; // 0=main, 1=sub int tone_enable; /*!< Re-enable tone after freq change -- IC-705 bug with gpredict */ int filter_usbd; /*!< Filter number to use for USBD/LSBD when setting mode */ int filter_usb; /*!< Filter number to use for USB/LSB when setting mode */ int filter_cw; /*!< Filter number to use for CW/CWR when setting mode */ int filter_fm; /*!< Filter number to use for CW/CWR when setting mode */ }; extern const struct ts_sc_list r8500_ts_sc_list[]; extern const struct ts_sc_list r8600_ts_sc_list[]; extern const struct ts_sc_list ic737_ts_sc_list[]; extern const struct ts_sc_list r75_ts_sc_list[]; extern const struct ts_sc_list r7100_ts_sc_list[]; extern const struct ts_sc_list r9000_ts_sc_list[]; extern const struct ts_sc_list r9500_ts_sc_list[]; extern const struct ts_sc_list ic756_ts_sc_list[]; extern const struct ts_sc_list ic756pro_ts_sc_list[]; extern const struct ts_sc_list ic705_ts_sc_list[]; extern const struct ts_sc_list ic706_ts_sc_list[]; extern const struct ts_sc_list ic7000_ts_sc_list[]; extern const struct ts_sc_list ic7100_ts_sc_list[]; extern const struct ts_sc_list ic7200_ts_sc_list[]; extern const struct ts_sc_list ic7300_ts_sc_list[]; extern const struct ts_sc_list ic9700_ts_sc_list[]; extern const struct ts_sc_list ic910_ts_sc_list[]; extern const struct ts_sc_list ic718_ts_sc_list[]; extern const struct ts_sc_list x108g_ts_sc_list[]; extern const pbwidth_t rtty_fil[]; /* rtty filter passband width; available on 746pro and 756pro rigs */ pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode); int icom_init(RIG *rig); int icom_rig_open(RIG *rig); int icom_rig_close(RIG *rig); int icom_cleanup(RIG *rig); int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts); int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icom_get_vfo(RIG *rig, vfo_t *vfo); int icom_set_vfo(RIG *rig, vfo_t vfo); int icom_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); int icom_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs); int icom_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs); int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width); int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width); int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); int icom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icom_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icom_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int icom_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int icom_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int icom_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int icom_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int icom_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); int icom_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); int icom_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); int icom_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); int icom_set_bank(RIG *rig, vfo_t vfo, int bank); int icom_set_mem(RIG *rig, vfo_t vfo, int ch); int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); 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_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int icom_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icom_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status); int icom_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status); int icom_set_parm(RIG *rig, setting_t parm, value_t val); int icom_get_parm(RIG *rig, setting_t parm, value_t *val); int icom_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int icom_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int icom_set_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int icom_get_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int icom_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icom_get_conf(RIG *rig, hamlib_token_t token, char *val); int icom_set_powerstat(RIG *rig, powerstat_t status); int icom_get_powerstat(RIG *rig, powerstat_t *status); int icom_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int icom_decode_event(RIG *rig); int icom_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); int icom_send_morse(RIG *rig, vfo_t vfo, const char *msg); int icom_stop_morse(RIG *rig, vfo_t vfo); int icom_send_voice_mem(RIG *rig, vfo_t vfo, int bank); int icom_stop_voice_mem(RIG *rig, vfo_t vfo); /* Exposed routines */ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo); int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val); int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res); int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val); int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val); int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, value_t *val); int icom_set_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int val_bytes, int value); int icom_get_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *value); int icom_set_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int seconds); int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *seconds); int icom_get_freq_range(RIG *rig); int icom_is_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame); int icom_process_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame); int icom_read_frame_direct(RIG *rig, size_t buffer_length, const unsigned char *buffer); extern const struct confparams icom_cfg_params[]; extern const struct confparams icom_ext_levels[]; extern const struct confparams icom_ext_funcs[]; extern const struct confparams icom_ext_parms[]; extern const struct cmdparams icom_ext_cmds[]; extern struct rig_caps ic703_caps; extern struct rig_caps ic705_caps; extern struct rig_caps ic706_caps; extern struct rig_caps ic706mkii_caps; extern struct rig_caps ic706mkiig_caps; extern struct rig_caps ic707_caps; extern struct rig_caps ic718_caps; extern struct rig_caps ic725_caps; extern struct rig_caps ic726_caps; extern struct rig_caps ic728_caps; extern struct rig_caps ic729_caps; extern struct rig_caps ic735_caps; extern struct rig_caps ic736_caps; extern struct rig_caps ic737_caps; extern struct rig_caps ic738_caps; extern struct rig_caps ic746_caps; extern struct rig_caps ic7410_caps; extern struct rig_caps ic746pro_caps; extern struct rig_caps ic756_caps; extern struct rig_caps ic756pro_caps; extern struct rig_caps ic756pro2_caps; extern struct rig_caps ic756pro3_caps; extern struct rig_caps ic751_caps; extern struct rig_caps ic7600_caps; // need to modify targetable_vfo depending on response to 0x25 cmd extern struct rig_caps ic7610_caps; extern struct rig_caps ic761_caps; extern struct rig_caps ic765_caps; extern struct rig_caps ic7700_caps; extern struct rig_caps ic775_caps; extern struct rig_caps ic78_caps; extern struct rig_caps ic7800_caps; extern struct rig_caps ic785x_caps; extern struct rig_caps ic7000_caps; extern struct rig_caps ic7100_caps; extern struct rig_caps ic7200_caps; extern struct rig_caps ic7300_caps; extern struct rig_caps ic781_caps; extern struct rig_caps ic820h_caps; extern struct rig_caps ic821h_caps; extern struct rig_caps ic905_caps; extern struct rig_caps ic910_caps; extern struct rig_caps ic9100_caps; extern struct rig_caps ic970_caps; extern struct rig_caps ic9700_caps; extern struct rig_caps icrx7_caps; extern struct rig_caps icr10_caps; extern struct rig_caps icr20_caps; extern struct rig_caps icr6_caps; extern struct rig_caps icr71_caps; extern struct rig_caps icr72_caps; extern struct rig_caps icr75_caps; extern struct rig_caps icr7000_caps; extern struct rig_caps icr7100_caps; extern struct rig_caps icr8500_caps; extern struct rig_caps icr9000_caps; extern struct rig_caps icr9500_caps; extern struct rig_caps ic271_caps; extern struct rig_caps ic275_caps; extern struct rig_caps ic375_caps; extern struct rig_caps ic471_caps; extern struct rig_caps ic475_caps; extern struct rig_caps ic575_caps; extern struct rig_caps ic1275_caps; extern struct rig_caps icf8101_caps; extern struct rig_caps ic7760_caps; extern struct rig_caps omnivip_caps; extern struct rig_caps delta2_caps; extern struct rig_caps os456_caps; extern struct rig_caps os535_caps; extern struct rig_caps ic92d_caps; extern struct rig_caps id1_caps; extern struct rig_caps id31_caps; extern struct rig_caps id51_caps; extern struct rig_caps id4100_caps; extern struct rig_caps id5100_caps; extern struct rig_caps ic2730_caps; extern struct rig_caps perseus_caps; extern struct rig_caps x108g_caps; extern struct rig_caps x6100_caps; extern struct rig_caps g90_caps; extern struct rig_caps x5105_caps; extern struct rig_caps x6200_caps; extern struct rig_caps icr8600_caps; extern struct rig_caps icr30_caps; #define RIG_IS_IC1271 (STATE(rig)->rig_model == RIG_MODEL_IC1271) #define RIG_IS_IC1275 (STATE(rig)->rig_model == RIG_MODEL_IC1275) #define RIG_IS_IC271 (STATE(rig)->rig_model == RIG_MODEL_IC271) #define RIG_IS_IC2730 (STATE(rig)->rig_model == RIG_MODEL_IC2730) #define RIG_IS_IC275 (STATE(rig)->rig_model == RIG_MODEL_IC275) #define RIG_IS_IC375 (STATE(rig)->rig_model == RIG_MODEL_IC375) #define RIG_IS_IC471 (STATE(rig)->rig_model == RIG_MODEL_IC471) #define RIG_IS_IC475 (STATE(rig)->rig_model == RIG_MODEL_IC475) #define RIG_IS_IC575 (STATE(rig)->rig_model == RIG_MODEL_IC575) #define RIG_IS_IC7000 (STATE(rig)->rig_model == RIG_MODEL_IC7000) #define RIG_IS_IC703 (STATE(rig)->rig_model == RIG_MODEL_IC703) #define RIG_IS_IC705 (STATE(rig)->rig_model == RIG_MODEL_IC705) #define RIG_IS_IC706 (STATE(rig)->rig_model == RIG_MODEL_IC706) #define RIG_IS_IC706MKII (STATE(rig)->rig_model == RIG_MODEL_IC706MKII) #define RIG_IS_IC706MKIIG (STATE(rig)->rig_model == RIG_MODEL_IC706MKIIG) #define RIG_IS_IC707 (STATE(rig)->rig_model == RIG_MODEL_IC707) #define RIG_IS_IC7100 (STATE(rig)->rig_model == RIG_MODEL_IC7100) #define RIG_IS_IC718 (STATE(rig)->rig_model == RIG_MODEL_IC718) #define RIG_IS_IC7200 (STATE(rig)->rig_model == RIG_MODEL_IC7200) #define RIG_IS_IC725 (STATE(rig)->rig_model == RIG_MODEL_IC725) #define RIG_IS_IC726 (STATE(rig)->rig_model == RIG_MODEL_IC726) #define RIG_IS_IC728 (STATE(rig)->rig_model == RIG_MODEL_IC728) #define RIG_IS_IC729 (STATE(rig)->rig_model == RIG_MODEL_IC729) #define RIG_IS_IC7300 (STATE(rig)->rig_model == RIG_MODEL_IC7300) #define RIG_IS_IC731 (STATE(rig)->rig_model == RIG_MODEL_IC731) #define RIG_IS_IC735 (STATE(rig)->rig_model == RIG_MODEL_IC735) #define RIG_IS_IC736 (STATE(rig)->rig_model == RIG_MODEL_IC736) #define RIG_IS_IC737 (STATE(rig)->rig_model == RIG_MODEL_IC737) #define RIG_IS_IC738 (STATE(rig)->rig_model == RIG_MODEL_IC738) #define RIG_IS_IC7410 (STATE(rig)->rig_model == RIG_MODEL_IC7410) #define RIG_IS_IC746 (STATE(rig)->rig_model == RIG_MODEL_IC746) #define RIG_IS_IC746PRO (STATE(rig)->rig_model == RIG_MODEL_IC746PRO) #define RIG_IS_IC751 (STATE(rig)->rig_model == RIG_MODEL_IC751) #define RIG_IS_IC751A (STATE(rig)->rig_model == RIG_MODEL_IC751A) #define RIG_IS_IC756 (STATE(rig)->rig_model == RIG_MODEL_IC756) #define RIG_IS_IC756PRO (STATE(rig)->rig_model == RIG_MODEL_IC756PRO) #define RIG_IS_IC756PROII (STATE(rig)->rig_model == RIG_MODEL_IC756PROII) #define RIG_IS_IC756PROIII (STATE(rig)->rig_model == RIG_MODEL_IC756PROIII) #define RIG_IS_IC7600 (STATE(rig)->rig_model == RIG_MODEL_IC7600) #define RIG_IS_IC761 (STATE(rig)->rig_model == RIG_MODEL_IC761) #define RIG_IS_IC7610 (STATE(rig)->rig_model == RIG_MODEL_IC7610) #define RIG_IS_IC765 (STATE(rig)->rig_model == RIG_MODEL_IC765) #define RIG_IS_IC7700 (STATE(rig)->rig_model == RIG_MODEL_IC7700) #define RIG_IS_IC775 (STATE(rig)->rig_model == RIG_MODEL_IC775) #define RIG_IS_IC78 (STATE(rig)->rig_model == RIG_MODEL_IC78) #define RIG_IS_IC7800 (STATE(rig)->rig_model == RIG_MODEL_IC7800) #define RIG_IS_IC781 (STATE(rig)->rig_model == RIG_MODEL_IC781) #define RIG_IS_IC785X (STATE(rig)->rig_model == RIG_MODEL_IC785x) #define RIG_IS_IC820 (STATE(rig)->rig_model == RIG_MODEL_IC820) #define RIG_IS_IC821 (STATE(rig)->rig_model == RIG_MODEL_IC821) #define RIG_IS_IC821H (STATE(rig)->rig_model == RIG_MODEL_IC821H) #define RIG_IS_IC905 (STATE(rig)->rig_model == RIG_MODEL_IC905) #define RIG_IS_IC910 (STATE(rig)->rig_model == RIG_MODEL_IC910) #define RIG_IS_IC9100 (STATE(rig)->rig_model == RIG_MODEL_IC9100) #define RIG_IS_IC92D (STATE(rig)->rig_model == RIG_MODEL_IC92D) #define RIG_IS_IC970 (STATE(rig)->rig_model == RIG_MODEL_IC970) #define RIG_IS_IC9700 (STATE(rig)->rig_model == RIG_MODEL_IC9700) #define RIG_IS_IC8101 (STATE(rig)->rig_model == RIG_MODEL_ICF8101) #define RIG_IS_ICID1 (STATE(rig)->rig_model == RIG_MODEL_ICID1) #define RIG_IS_ICM700PRO (STATE(rig)->rig_model == RIG_MODEL_IC_M700PRO) #define RIG_IS_ICM710 (STATE(rig)->rig_model == RIG_MODEL_IC_M710) #define RIG_IS_ICM802 (STATE(rig)->rig_model == RIG_MODEL_IC_M802) #define RIG_IS_ICM803 (STATE(rig)->rig_model == RIG_MODEL_IC_M803) #define RIG_IS_ICR10 (STATE(rig)->rig_model == RIG_MODEL_ICR10) #define RIG_IS_ICR20 (STATE(rig)->rig_model == RIG_MODEL_ICR20) #define RIG_IS_ICR30 (STATE(rig)->rig_model == RIG_MODEL_ICR30) #define RIG_IS_ICR6 (STATE(rig)->rig_model == RIG_MODEL_ICR6) #define RIG_IS_ICR7000 (STATE(rig)->rig_model == RIG_MODEL_ICR7000) #define RIG_IS_ICR71 (STATE(rig)->rig_model == RIG_MODEL_ICR71) #define RIG_IS_ICR7100 (STATE(rig)->rig_model == RIG_MODEL_ICR7100) #define RIG_IS_ICR72 (STATE(rig)->rig_model == RIG_MODEL_ICR72) #define RIG_IS_ICR75 (STATE(rig)->rig_model == RIG_MODEL_ICR75) #define RIG_IS_ICR8500 (STATE(rig)->rig_model == RIG_MODEL_ICR8500) #define RIG_IS_ICR8600 (STATE(rig)->rig_model == RIG_MODEL_ICR8600) #define RIG_IS_ICR9000 (STATE(rig)->rig_model == RIG_MODEL_ICR9000) #define RIG_IS_ICR9500 (STATE(rig)->rig_model == RIG_MODEL_ICR9500) #define RIG_IS_ICRX7 (STATE(rig)->rig_model == RIG_MODEL_ICRX7) #define RIG_IS_ID5100 (STATE(rig)->rig_model == RIG_MODEL_ID5100) #define RIG_IS_OMNIVIP (STATE(rig)->rig_model == RIG_MODEL_OMNIVIP) #define RIG_IS_OS456 (STATE(rig)->rig_model == RIG_MODEL_OS456) #define RIG_IS_X5105 (STATE(rig)->rig_model == RIG_MODEL_X5105) #define RIG_IS_X6100 (STATE(rig)->rig_model == RIG_MODEL_X6100) #endif /* _ICOM_H */ hamlib-4.6.5/rigs/icom/icr9500.c0000664000175000017500000001636615056640443011622 /* * Hamlib CI-V backend - IC-R9500 descriptions * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define ICR9500_MODES (RIG_MODE_AM|RIG_MODE_AMS|\ RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_WFM) #define ICR9500_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR9500_FUNCS (RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_NR|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) #define ICR9500_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_AGC_TIME) #define ICR9500_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define ICR9500_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) /* TBC */ #define ICR9500_HF_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define ICR9500_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define ICR9500_MEM_CAP { /* FIXME */ \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT, \ } /* TODO: S-Meter measurements */ /* This is just a copy if IC9700_STR_CAL */ /* Hope it's correct */ #define ICR9500_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } static struct icom_priv_caps icr9500_priv_caps = { 0x72, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ .ts_sc_list = r9500_ts_sc_list, .antack_len = 2, .ant_count = 3 }; /* * ICR9500A rig capabilities. */ struct rig_caps icr9500_caps = { RIG_MODEL(RIG_MODEL_ICR9500), .model_name = "IC-R9500", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR9500_FUNCS, .has_set_func = ICR9500_FUNCS, .has_get_level = ICR9500_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR9500_LEVELS), .has_get_parm = ICR9500_PARMS, .has_set_parm = RIG_PARM_SET(ICR9500_PARMS), .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, 20, RIG_DBLST_END }, /* FIXME: TBC */ .attenuator = { 6, 10, 12, 18, 20, 24, 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR9500_OPS, .scan_ops = ICR9500_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 12, .chan_desc_sz = 0, /* FIXME */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, ICR9500_MEM_CAP }, /* TBC */ { 1000, 1099, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-A (Auto) */ { 1100, 1199, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-S (skip) */ { 1200, 1219, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-P (Scan edge), 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(5), MHz(30) - 1, ICR9500_MODES, -1, -1, ICR9500_VFOS, ICR9500_HF_ANTS}, {MHz(30), MHz(3335), ICR9500_MODES, -1, -1, ICR9500_VFOS, RIG_ANT_4}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(5), MHz(30) - 1, ICR9500_MODES, -1, -1, ICR9500_VFOS, ICR9500_HF_ANTS}, {MHz(30), MHz(3335), ICR9500_MODES, -1, -1, ICR9500_VFOS, RIG_ANT_4}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR9500_MODES, 1}, /* resolution */ {ICR9500_MODES, 10}, {ICR9500_MODES, 100}, {ICR9500_MODES, kHz(1)}, {ICR9500_MODES, kHz(2.5)}, {ICR9500_MODES, kHz(5)}, {ICR9500_MODES, kHz(6.25)}, {ICR9500_MODES, kHz(9)}, {ICR9500_MODES, kHz(10)}, {ICR9500_MODES, 12500}, {ICR9500_MODES, kHz(20)}, {ICR9500_MODES, kHz(25)}, {ICR9500_MODES, kHz(100)}, {ICR9500_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(350)}, RIG_FLT_END, }, .str_cal = ICR9500_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr9500_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/icom/icr30.c0000664000175000017500000002124115056640443011433 /* * Hamlib CI-V backend - description of IC-R30 * Copyright (c) 2018 Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "token.h" #include "icom.h" #include "idx_builtin.h" #include "icom_defs.h" #include "frame.h" #include "tones.h" #define ICR30_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_AM|RIG_MODE_AMN|\ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_WFM|\ RIG_MODE_RTTYR|RIG_MODE_SAM|RIG_MODE_SAL|RIG_MODE_SAH|RIG_MODE_P25|\ RIG_MODE_DSTAR|RIG_MODE_DPMR|RIG_MODE_NXDNVN|RIG_MODE_NXDN_N|RIG_MODE_DCR) #define ICR30_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_AFC|RIG_FUNC_VSC|\ RIG_FUNC_CSQL|RIG_FUNC_DSQL|RIG_FUNC_ANL|RIG_FUNC_CSQL|RIG_FUNC_SCEN) #define ICR30_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|\ RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR30_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ICR30_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR30_SCAN_OPS (RIG_SCAN_NONE) #define TOK_ANL TOKEN_BACKEND(001) #define TOK_EAR TOKEN_BACKEND(002) #define TOK_REC TOKEN_BACKEND(003) int icr30_tokens[] = { TOK_ANL, TOK_EAR, TOK_REC, TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_BACKEND_NONE }; struct confparams icr30_ext[] = { { TOK_ANL, "anl", "Auto noise limiter", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_EAR, "ear", "Earphone mode", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_REC, "record", "Recorder on/off", "", "", RIG_CONF_CHECKBUTTON, {} }, { 0 } }; struct cmdparams icr30_extcmds[] = { { {.t = TOK_ANL}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_ANL, SC_MOD_RW, 0, {}, CMD_DAT_BOL, 1 }, { {.t = TOK_EAR}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_EAR, SC_MOD_RW, 0, {}, CMD_DAT_BOL, 1 }, { {.t = TOK_REC}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_REC, SC_MOD_WR, 0, {}, CMD_DAT_BOL, 1 }, { {0} } }; #define ICR30_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } /* * This function does the special bandwidth coding for IC-R30 * (1 - normal, 2 - narrow) */ static int icr30_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } /* * This function handles the -N modes for IC-R30 */ int icr30_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { if (mode & (RIG_MODE_AMN | RIG_MODE_FMN)) { return icom_set_mode(rig, vfo, mode, (pbwidth_t)1); } else { return icom_set_mode(rig, vfo, mode, width); } } static struct icom_priv_caps icr30_priv_caps = { 0x9c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list, /* wrong, but don't have set_ts anyway */ .antack_len = 2, .ant_count = 2, .r2i_mode = icr30_r2i_mode, .offs_len = 4, .extcmds = icr30_extcmds /* Custom ext_parm parameters */ }; struct rig_caps icr30_caps = { RIG_MODEL(RIG_MODEL_ICR30), .model_name = "IC-R30", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR30_FUNC_ALL, .has_set_func = ICR30_FUNC_ALL, .has_get_level = ICR30_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR30_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ext_tokens = icr30_tokens, .extfuncs = icr30_ext, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 15, 30, 35, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR30_VFO_OPS, .scan_ops = ICR30_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 999, RIG_MTYPE_MEM }, /* TBC */ { 1000, 1199, RIG_MTYPE_MEM }, /* auto-write */ { 1200, 1299, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { /* Other countries but France */ {kHz(100), GHz(3.3049999), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(100), MHz(821.995), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, {MHz(851), MHz(866.995), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, {MHz(896), GHz(3.3049999), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR30_MODES, Hz(10)}, {ICR30_MODES, Hz(100)}, {ICR30_MODES, Hz(1000)}, {ICR30_MODES, Hz(3125)}, {ICR30_MODES, Hz(5000)}, {ICR30_MODES, Hz(6250)}, {ICR30_MODES, Hz(8330)}, {ICR30_MODES, Hz(9000)}, {ICR30_MODES, Hz(10000)}, {ICR30_MODES, Hz(12500)}, {ICR30_MODES, kHz(15)}, {ICR30_MODES, kHz(20)}, {ICR30_MODES, kHz(25)}, {ICR30_MODES, kHz(30)}, {ICR30_MODES, kHz(50)}, {ICR30_MODES, kHz(100)}, {ICR30_MODES, kHz(125)}, {ICR30_MODES, kHz(200)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_USB | RIG_MODE_LSB, kHz(1.8)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_AMN | RIG_MODE_FMN, kHz(12)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_AMN | RIG_MODE_FMN, kHz(6)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR30_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .priv = (void *)& icr30_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icr30_set_mode, .get_mode = icom_get_mode, .vfo_op = icom_vfo_op, .set_vfo = icom_set_vfo, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_bank = icom_set_bank, .set_mem = icom_set_mem, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .get_dcd = icom_get_dcd, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icom_defs.h0000664000175000017500000005601615056640443012460 /* * Hamlib CI-V backend - defines for the ICOM "CI-V" interface. * Copyright (c) 2000-2016 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICOM_DEFS_H #define _ICOM_DEFS_H 1 /* * CI-V frame codes */ #define PR 0xfe /* Preamble code */ #define CTRLID 0xe0 /* Controllers's default address */ #define BCASTID 0x00 /* Broadcast address */ #define FI 0xfd /* End of message code */ #define ACK 0xfb /* OK code */ #define NAK 0xfa /* NG code */ #define COL 0xfc /* CI-V bus collision detected */ #define PAD 0xff /* Transmit padding */ #define ACKFRMLEN 6 /* reply frame length */ #define S_NONE -1 /* * Arguments length in bytes */ #define CHAN_NB_LEN 2 #define BANK_NB_LEN 2 #define OFFS_LEN 3 /* * Cn controller commands * Most radios have 2 or 3 receive passbands available. Where only 2 are available they are selected by 01 for wide and 02 for narrow Actual bandwidth is determined by the filters installed. With the newer DSP rigs there are 3 presets 01 = wide 02 = middle and 03 = narrow. Actually, you can set change any of these presets to any thing you want. * Notes: * The following only applies to IC-706. * 1. When wide or normal op available: add "00" for wide, "01" normal * Normal or narrow op: add "00" for normal, "01" for narrow * Wide, normal or narrow op: add "00" for wide, "01" normal, "02" narrow * 2. Memory channel number 1A=0100/1b=0101, 2A=0102/2b=0103, * 3A=0104/3b=0105, C1=0106, C2=0107 */ #define C_SND_FREQ 0x00 /* Send frequency data transceive mode does not ack*/ #define C_SND_MODE 0x01 /* Send mode data, Sc for transceive mode does not ack */ #define C_RD_BAND 0x02 /* Read band edge frequencies */ #define C_RD_FREQ 0x03 /* Read display frequency */ #define C_RD_MODE 0x04 /* Read display mode */ #define C_SET_FREQ 0x05 /* Set frequency data(1) */ #define C_SET_MODE 0x06 /* Set mode data, Sc */ #define C_SET_VFO 0x07 /* Set VFO */ #define C_SET_MEM 0x08 /* Set channel, Sc(2) */ #define C_WR_MEM 0x09 /* Write memory */ #define C_MEM2VFO 0x0a /* Memory to VFO */ #define C_CLR_MEM 0x0b /* Memory clear */ #define C_RD_OFFS 0x0c /* Read duplex offset frequency; default changes with HF/6M/2M */ #define C_SET_OFFS 0x0d /* Set duplex offset frequency */ #define C_CTL_SCAN 0x0e /* Control scan, Sc */ #define C_CTL_SPLT 0x0f /* Control split, and duplex mode Sc */ #define C_SET_TS 0x10 /* Set tuning step, Sc */ #define C_CTL_ATT 0x11 /* Set/get attenuator, Sc */ #define C_CTL_ANT 0x12 /* Set/get antenna, Sc */ #define C_CTL_ANN 0x13 /* Control announce (speech synth.), Sc */ #define C_CTL_LVL 0x14 /* Set AF/RF/squelch, Sc */ #define C_RD_SQSM 0x15 /* Read squelch condition/S-meter level, Sc */ #define C_CTL_FUNC 0x16 /* Function settings (AGC,NB,etc.), Sc */ #define C_SND_CW 0x17 /* Send CW message */ #define C_SET_PWR 0x18 /* Set Power ON/OFF, Sc */ #define C_RD_TRXID 0x19 /* Read transceiver ID code */ #define C_CTL_MEM 0x1a /* Misc memory/bank/rig control functions, Sc */ #define C_SET_TONE 0x1b /* Set tone frequency */ #define C_CTL_PTT 0x1c /* Control Transmit On/Off, Sc */ #define C_CTL_EDGE 0x1e /* Band edges */ #define C_CTL_DVT 0x1f /* Digital modes calsigns & messages */ #define C_CTL_DIG 0x20 /* Digital modes settings & status */ #define C_CTL_RIT 0x21 /* RIT/XIT control */ #define C_CTL_DSD 0x22 /* D-STAR Data */ #define C_SEND_SEL_FREQ 0x25 /* Send/Recv sel/unsel VFO frequency */ #define C_SEND_SEL_MODE 0x26 /* Send/Recv sel/unsel VFO mode & filter */ #define C_CTL_SCP 0x27 /* Scope control & data */ #define C_SND_VOICE 0x28 /* Transmit Voice Memory Contents */ #define C_CTL_MTEXT 0x70 /* Microtelecom Extension */ #define C_CTL_MISC 0x7f /* Miscellaneous control, Sc */ /* * Sc controller sub commands */ /* * Set mode data (C_SET_MODE) sub commands */ #define S_LSB 0x00 /* Set to LSB */ #define S_USB 0x01 /* Set to USB */ #define S_AM 0x02 /* Set to AM */ #define S_AMN 0x02 /* Set to AM-N */ #define S_CW 0x03 /* Set to CW */ #define S_RTTY 0x04 /* Set to RTTY */ #define S_FM 0x05 /* Set to FM */ #define S_FMN 0x05 /* Set to FM-N */ #define S_WFM 0x06 /* Set to Wide FM */ #define S_CWR 0x07 /* Set to CW Reverse */ #define S_RTTYR 0x08 /* Set to RTTY Reverse */ #define S_AMS 0x11 /* Set to AMS */ #define S_PSK 0x12 /* 7800 PSK USB */ #define S_PSKR 0x13 /* 7800 PSK LSB */ #define S_SAML 0x14 /* Set to AMS-L */ #define S_SAMU 0x15 /* Set to AMS-U */ #define S_P25 0x16 /* Set to P25 */ #define S_DSTAR 0x17 /* Set to D-STAR */ #define S_DPMR 0x18 /* Set to dPMR */ #define S_NXDNVN 0x19 /* Set to NXDN_VN */ #define S_NXDN_N 0x20 /* Set to NXDN-N */ #define S_DCR 0x21 /* Set to DCR */ #define S_DD 0x22 /* Set to DD 1200Mhz only? */ #define S_R7000_SSB 0x05 /* Set to SSB on R-7000 */ /* filter width coding for older ICOM rigs with 2 filter width */ /* there is no special 'wide' for that rigs */ #define PD_MEDIUM_2 0x01 /* Medium */ #define PD_NARROW_2 0x02 /* Narrow */ /* filter width coding for newer ICOM rigs with 3 filter width */ #define PD_WIDE_3 0x01 /* Wide */ #define PD_MEDIUM_3 0x02 /* Medium */ #define PD_NARROW_3 0x03 /* Narrow */ /* * Set VFO (C_SET_VFO) sub commands */ #define S_VFOA 0x00 /* Set to VFO A */ #define S_VFOB 0x01 /* Set to VFO B */ #define S_BTOA 0xa0 /* VFO A=B */ #define S_XCHNG 0xb0 /* Switch VFO A and B */ #define S_SUBTOMAIN 0xb1 /* MAIN = SUB */ #define S_DUAL_OFF 0xc0 /* Dual watch off */ #define S_DUAL_ON 0xc1 /* Dual watch on */ #define S_DUAL 0xc2 /* Dual watch (0 = off, 1 = on) */ #define S_MAIN 0xd0 /* Select MAIN band */ #define S_SUB 0xd1 /* Select SUB band */ #define S_BAND_SEL 0xd2 /* Read/Set Main/Sub band selection */ #define S_FRONTWIN 0xe0 /* Select front window */ /* * Set MEM (C_SET_MEM) sub commands */ #define S_BANK 0xa0 /* Select memory bank (aka 'memory group' with IC-R8600) */ /* * Scan control (C_CTL_SCAN) subcommands */ #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 */ #define S_SCAN_FDFOF 0xA0 /* Fix dF OFF */ #define S_SCAN_FDF5I 0xA1 /* Fix range +/-5kHz */ #define S_SCAN_FDF1X 0xA2 /* Fix range +/-10kHz */ #define S_SCAN_FDF2X 0xA3 /* Fix range +/-20kHz */ #define S_SCAN_FDF5X 0xA4 /* Fix range +/-50kHz */ #define S_SCAN_FDF1C 0xA5 /* Fix range +/-100kHz */ #define S_SCAN_FDF5C 0xA6 /* Fix range +/-500kHz */ #define S_SCAN_FDF1M 0xA7 /* Fix range +/-1MHz */ #define S_SCAN_FDFON 0xAA /* Fix dF ON */ #define S_SCAN_NSLCT 0xB0 /* Set as non select channel */ #define S_SCAN_SLCT 0xB1 /* Set as select channel */ #define S_SCAN_SL_NUM 0xB2 /* select programmed mem scan 7800 only */ #define S_SCAN_RSMOFF 0xD0 /* Set scan resume OFF */ #define S_SCAN_RSMONP 0xD1 /* Set scan resume ON + pause time */ #define S_SCAN_RSMON 0xD3 /* Set scan resume ON */ /* * Split control (S_CTL_SPLT) subcommands */ #define S_SPLT_OFF 0x00 /* Split OFF */ #define S_SPLT_ON 0x01 /* Split ON */ #define S_DUP_OFF 0x10 /* Simplex mode */ #define S_DUP_M 0x11 /* Duplex - mode */ #define S_DUP_P 0x12 /* Duplex + mode */ #define S_DUP_DD_RPS 0x13 /* DD Repeater Simplex mode (RPS) */ /* * Set Attenuator (C_CTL_ATT) subcommands */ #define S_ATT_RD -1 /* Without subcommand, reads out setting */ #define S_ATT_OFF 0x00 /* Off */ #define S_ATT_6dB 0x06 /* 6 dB, IC-756Pro */ #define S_ATT_10dB 0x10 /* 10 dB */ #define S_ATT_12dB 0x12 /* 12 dB, IC-756Pro */ #define S_ATT_18dB 0x18 /* 18 dB, IC-756Pro */ #define S_ATT_20dB 0x20 /* 20 dB */ #define S_ATT_30dB 0x30 /* 30 dB, or Att on for IC-R75 */ /* * Set Preamp (S_FUNC_PAMP) data */ #define D_PAMP_OFF 0x00 #define D_PAMP1 0x01 #define D_PAMP2 0x02 /* * Set AGC (S_FUNC_AGC) data */ #define D_AGC_FAST 0x00 #define D_AGC_MID 0x01 #define D_AGC_SLOW 0x02 #define D_AGC_SUPERFAST 0x03 /* IC746 pro */ /* * Set antenna (C_SET_ANT) subcommands */ #define S_ANT_RD -1 /* Without subcommand, reads out setting */ #define S_ANT1 0x00 /* Antenna 1 */ #define S_ANT2 0x01 /* Antenna 2 */ /* * Announce control (C_CTL_ANN) subcommands */ #define S_ANN_ALL 0x00 /* Announce all */ #define S_ANN_FREQ 0x01 /* Announce freq */ #define S_ANN_MODE 0x02 /* Announce operating mode */ /* * Function settings (C_CTL_LVL) subcommands */ #define S_LVL_AF 0x01 /* AF level setting */ #define S_LVL_RF 0x02 /* RF level setting */ #define S_LVL_SQL 0x03 /* SQL level setting */ #define S_LVL_IF 0x04 /* IF shift setting */ #define S_LVL_APF 0x05 /* APF level setting */ #define S_LVL_NR 0x06 /* NR level setting */ #define S_LVL_PBTIN 0x07 /* Twin PBT setting (inside) */ #define S_LVL_PBTOUT 0x08 /* Twin PBT setting (outside) */ #define S_LVL_CWPITCH 0x09 /* CW pitch setting */ #define S_LVL_RFPOWER 0x0a /* RF power setting */ #define S_LVL_MICGAIN 0x0b /* MIC gain setting */ #define S_LVL_KEYSPD 0x0c /* Key Speed setting */ #define S_LVL_NOTCHF 0x0d /* Notch freq. setting */ #define S_LVL_COMP 0x0e /* Compressor level setting */ #define S_LVL_BKINDL 0x0f /* BKin delay setting */ #define S_LVL_BALANCE 0x10 /* Balance setting (Dual watch) */ #define S_LVL_AGC 0x11 /* AGC (7800) */ #define S_LVL_NB 0x12 /* NB setting */ #define S_LVL_DIGI 0x13 /* DIGI-SEL (7800) */ #define S_LVL_DRIVE 0x14 /* DRIVE gain setting */ #define S_LVL_MON 0x15 /* Monitor gain setting */ #define S_LVL_VOXGAIN 0x16 /* VOX gain setting */ #define S_LVL_ANTIVOX 0x17 /* Anti VOX gain setting */ #define S_LVL_CONTRAST 0x18 /* CONTRAST level setting */ #define S_LVL_BRIGHT 0x19 /* BRIGHT level setting */ #define S_LVL_BASS 0x1B /* Bass level setting */ #define S_LVL_TREBLE 0x1C /* Treble level setting */ #define S_LVL_SCNSPD 0x1D /* Scan speed */ #define S_LVL_SCNDEL 0x1E /* Scan delay */ #define S_LVL_PRIINT 0x1F /* PRIO interval */ #define S_LVL_RESTIM 0x20 /* Resume time */ /* * Read squelch condition/S-meter level/other meter levels (C_RD_SQSM) subcommands */ #define S_SQL 0x01 /* Read squelch condition */ #define S_SML 0x02 /* Read S-meter level */ #define S_SMF 0x03 /* Read S-meter level in AAAABBCC format */ #define S_CML 0x04 /* Read centre -meter level */ #define S_CSQL 0x05 /* Read combined squelch conditions */ #define S_SAMS 0x06 /* Read S-AM Sync indicator */ #define S_OVF 0x07 /* Read OVF indicator status */ #define S_RFML 0x11 /* Read RF-meter level */ #define S_SWR 0x12 /* Read SWR-meter level */ #define S_ALC 0x13 /* Read ALC-meter level */ #define S_CMP 0x14 /* Read COMP-meter level */ #define S_VD 0x15 /* Read Vd-meter level */ #define S_ID 0x16 /* Read Id-meter level */ /* * Function settings (C_CTL_FUNC) subcommands Set and Read */ #define S_FUNC_PAMP 0x02 /* Preamp setting */ #define S_FUNC_AGCOFF 0x10 /* IC-R8500 only */ #define S_FUNC_AGCON 0x11 /* IC-R8500 only */ #define S_FUNC_AGC 0x12 /* AGC setting presets: the dsp models allow these to be modified */ #define S_FUNC_NBOFF 0x20 /* IC-R8500 only */ #define S_FUNC_NBON 0x21 /* IC-R8500 only */ #define S_FUNC_NB 0x22 /* NB setting */ #define S_FUNC_APFOFF 0x30 /* IC-R8500 only */ #define S_FUNC_APFON 0x31 /* IC-R8500 only */ #define S_FUNC_APF 0x32 /* APF setting */ #define S_FUNC_NR 0x40 /* NR setting */ #define S_FUNC_ANF 0x41 /* ANF setting */ #define S_FUNC_TONE 0x42 /* TONE setting */ #define S_FUNC_TSQL 0x43 /* TSQL setting */ #define S_FUNC_COMP 0x44 /* COMP setting */ #define S_FUNC_MON 0x45 /* Monitor setting */ #define S_FUNC_VOX 0x46 /* VOX setting */ #define S_FUNC_BKIN 0x47 /* BK-IN setting */ #define S_FUNC_MN 0x48 /* Manual notch setting */ #define S_FUNC_RF 0x49 /* RTTY Filter setting */ #define S_FUNC_AFC 0x4A /* Auto Frequency Control (AFC) setting */ #define S_FUNC_CSQL 0x4B /* DTCS tone code squelch setting*/ #define S_FUNC_VSC 0x4C /* voice squelch control useful for scanning*/ #define S_FUNC_MANAGC 0x4D /* manual AGC */ #define S_FUNC_DIGISEL 0x4E /* DIGI-SEL */ #define S_FUNC_TW_PK 0x4F /* RTTY Twin Peak filter 0= off 1 = on */ #define S_FUNC_DIAL_LK 0x50 /* Dial lock */ #define S_FUNC_P25SQL 0x52 /* P25 DSQL */ #define S_FUNC_ANTRX 0x53 /* ANT-RX */ #define S_FUNC_IF1F 0x55 /* 1st IF filter */ #define S_FUNC_DSPF 0x56 /* DSP filter */ #define S_FUNC_MANN 0x57 /* Manual notch width */ #define S_FUNC_SSBT 0x58 /* SSB Tx bandwidth */ #define S_FUNC_SUBB 0x59 /* Sub band */ #define S_FUNC_SATM 0x5A /* Satellite mode */ #define S_FUNC_DSSQL 0x5B /* D-STAR DSQL */ #define S_FUNC_DPSQL 0x5F /* dPMR DSQL */ #define S_FUNC_NXSQL 0x60 /* NXDN DSQL */ #define S_FUNC_DCSQL 0x61 /* DCR DSQL */ #define S_FUNC_DPSCM 0x62 /* dPMR scrambler */ #define S_FUNC_NXENC 0x63 /* NXDN encryption */ #define S_FUNC_DCENC 0x64 /* DCR encryption */ #define S_FUNC_IPP 0x65 /* IP+ setting */ #define S_FUNC_TX_INHIBIT 0x66 /* TX inhibit setting */ #define S_FUNC_DPP 0x67 /* DPP setting */ /* * Set Power On/Off (C_SET_PWR) subcommands */ #define S_PWR_OFF 0x00 #define S_PWR_ON 0x01 #define S_PWR_STDBY 0x02 /* * Transmit control (C_CTL_PTT) subcommands */ #define S_PTT 0x00 #define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */ #define S_RD_TX_FREQ 0x03 /* Read transmit frequency */ /* * Band Edge control (C_CTL_EDGE) subcommands */ #define S_EDGE_RD_N 0x00 // Fixed band edge count #define S_EDGE_RD 0x01 // Fixed band edges #define S_EDGE_RD_NU 0x02 // User band edge count #define S_EDGE_RD_U 0x03 // User band edges /* * RIT/XIT control (C_CTL_RIT) subcommands */ #define S_RIT_FREQ 0x00 #define S_RIT 0x01 /* RIT 0 = OFF, 1 = ON */ #define S_XIT 0x02 /* XIT (delta TX) 0 = OFF, 1 = ON */ /* * Misc contents (C_CTL_MEM) subcommands applies to newer rigs. * * Beware the IC-7200 which is non-standard. */ #define S_MEM_CNTNT 0x00 /* Memory content 2 bigendian */ #define S_MEM_BAND_REG 0x01 /* band stacking register */ #define S_MEM_FILT_WDTH 0x03 /* current passband filter width */ #define S_MEM_PARM 0x05 /* rig parameters; extended parm # + param value: should be coded */ /* in the rig files because they are different for each rig */ #define S_MEM_DATA_MODE 0x06 /* data mode */ #define S_MEM_TX_PB 0x07 /* SSB tx passband */ #define S_MEM_FLTR_SHAPE 0x08 /* DSP filter shape 0=sharp 1=soft */ /* Icr75c */ #define S_MEM_CNTNT_SLCT 0x01 #define S_MEM_FLT_SLCT 0x01 #define S_MEM_MODE_SLCT 0x02 /* For IC-910H rig. */ #define S_MEM_RDWR_MEM 0x00 /* Read/write memory channel */ #define S_MEM_SATMEM 0x01 /* Satellite memory */ #define S_MEM_VOXGAIN 0x02 /* VOX gain level (0=0%, 255=100%) */ #define S_MEM_VOXDELAY 0x03 /* VOX delay (0=0.0 sec, 20=2.0 sec) */ #define S_MEM1_VOXDELAY 0x05 /* VOX delay (0=0.0 sec, 20=2.0 sec) */ #define S_MEM_ANTIVOX 0x04 /* anti VOX setting */ #define S_MEM_RIT 0x06 /* RIT (0=off, 1=on, 2=sub dial) */ #define S_MEM_SATMODE910 0x07 /* Satellite mode (on/off) */ #define S_MEM_BANDSCOPE 0x08 /* Simple bandscope (on/off) */ /* For IC9700 and IC9100 and likely future Icoms */ #define S_MEM_DUALMODE 0x59 /* Dualwatch mode (on/off) */ #define S_MEM_SATMODE 0x5a /* Satellite mode (on/off) */ /* IC-R8600 and others */ #define S_MEM_SKIP_SLCT_OFF 0x00 #define S_MEM_SKIP_SLCT_ON 0x10 #define S_MEM_PSKIP_SLCT_ON 0x20 #define S_MEM_DUP_OFF 0x00 #define S_MEM_DUP_MINUS 0x01 #define S_MEM_DUP_PLUS 0x02 #define S_MEM_TSTEP_OFF 0x00 #define S_MEM_TSTEP_ON 0x01 #define S_FUNC_IPPLUS 0x07 /* IP+ subcommand 0x1a 0x07 */ /* IC-R6 */ #define S_MEM_AFLT 0x00 /* AF LPF Off/On */ /* IC-R30 */ #define S_MEM_ANL 0x00 /* ANL Off/On */ #define S_MEM_EAR 0x01 /* Earphone mode Off/On */ #define S_MEM_REC 0x09 /* Recorder Off/On */ /* IC-F8101 */ #define S_MEM_PTT 0x37 /* PTT 0,1,2 for front/rear PTT */ /* * Tone control (C_SET_TONE) subcommands */ #define S_TONE_RPTR 0x00 /* Tone frequency setting for repeater receive */ #define S_TONE_SQL 0x01 /* Tone frequency setting for squelch */ #define S_TONE_DTCS 0x02 /* DTCS code and polarity for squelch */ #define S_TONE_P25NAC 0x03 /* P25 NAC */ #define S_TONE_DSCSQL 0x07 /* D-STAR CSQL */ #define S_TONE_DPCOM 0x08 /* dPMR COM ID */ #define S_TONE_DPCC 0x09 /* dPMR CC */ #define S_TONE_NXRAN 0x0A /* NXDN RAN */ #define S_TONE_DCUC 0x0B /* DCR UC */ #define S_TONE_DPSCK 0x0C /* dPMR scrambler key */ #define S_TONE_NXENK 0x0D /* NXDN encryption key */ #define S_TONE_DCENK 0x0E /* DCR encryption key */ /* * Transceiver ID (C_RD_TRXID) subcommands */ #define S_RD_TRXID 0x00 /* * Digital modes settings & status subcommands */ #define S_DIG_DSCALS 0x00 /* D-STAR Call sign */ #define S_DIG_DSMESS 0x01 /* D-STAR Message */ #define S_DIG_DSRSTS 0x02 /* D-STAR Rx status */ #define S_DIG_DSGPSD 0x03 /* D-STAR GPS data */ #define S_DIG_DSGPSM 0x04 /* D-STAR GPS message */ #define S_DIG_DSCSQL 0x05 /* D-STAR CSQL */ #define S_DIG_P25ID 0x06 /* P25 ID */ #define S_DIG_P25STS 0x07 /* P25 Rx status */ #define S_DIG_DPRXID 0x08 /* dPMR Rx ID */ #define S_DIG_DPRSTS 0x09 /* dPMR Rx status */ #define S_DIG_NXRXID 0x0A /* NXDN Rx ID */ #define S_DIG_NXRSTS 0x0B /* NXDN Rx status */ #define S_DIG_DCRXID 0x0C /* DCR Rx ID */ #define S_DVT_DSMYCS 0x00 /* D-STAR My CS */ #define S_DVT_DSTXCS 0x01 /* D-STAR Tx CS */ #define S_DVT_DSTXMS 0x02 /* D-STAR Tx Mess */ #define S_DSD_DSTXDT 0x00 /* D-STAR Tx Data */ /* * S_CTL_SCP Scope control & data subcommands */ #define S_SCP_DAT 0x00 /* Read data */ #define S_SCP_STS 0x10 /* On/Off status */ #define S_SCP_DOP 0x11 /* Data O/P Control */ #define S_SCP_MSS 0x12 /* Main/Sub setting */ #define S_SCP_SDS 0x13 /* Single/Dual scope setting */ #define S_SCP_MOD 0x14 /* Center/Fixed mode */ #define S_SCP_SPN 0x15 /* Span setting */ #define S_SCP_EDG 0x16 /* Edge setting */ #define S_SCP_HLD 0x17 /* Hold On/Off */ #define S_SCP_ATT 0x18 /* Attenuator */ #define S_SCP_REF 0x19 /* Reference level */ #define S_SCP_SWP 0x1a /* Sweep speed */ #define S_SCP_STX 0x1b /* Scope during Tx */ #define S_SCP_CFQ 0x1c /* Center frequency type */ #define S_SCP_VBW 0x1d /* Video Band Width (VBW) setting */ #define S_SCP_FEF 0x1e /* Fixed edge freqs */ #define S_SCP_RBW 0x1f /* Resolution Band Width (RBW) setting */ #define S_SCP_MKP 0x20 /* Marker position setting */ /* * C_CTL_MISC OptoScan extension */ #define S_OPTO_LOCAL 0x01 #define S_OPTO_REMOTE 0x02 #define S_OPTO_TAPE_ON 0x03 #define S_OPTO_TAPE_OFF 0x04 #define S_OPTO_RDSTAT 0x05 #define S_OPTO_RDCTCSS 0x06 #define S_OPTO_RDDCS 0x07 #define S_OPTO_RDDTMF 0x08 #define S_OPTO_RDID 0x09 #define S_OPTO_SPKRON 0x0a #define S_OPTO_SPKROFF 0x0b #define S_OPTO_5KSCON 0x0c #define S_OPTO_5KSCOFF 0x0d #define S_OPTO_NXT 0x0e #define S_OPTO_SCON 0x0f #define S_OPTO_SCOFF 0x10 /* * OmniVIPlus (Omni VI) extensions */ #define C_OMNI6_XMT 0x16 /* * S_MEM_MODE_SLCT Misc CI-V Mode settings */ #define S_PRM_BEEP 0x02 #define S_PRM_CWPITCH 0x10 #define S_PRM_LANG 0x15 #define S_PRM_BACKLT 0x21 #define S_PRM_SLEEP 0x32 #define S_PRM_SLPTM 0x33 #define S_PRM_TIME 0x27 /* * Tokens for Extra Level and Parameters common to multiple rigs. Use token # > 99. Defined here so they * will be available in ICOM name space. They have different internal commands primarily in dsp rigs. These * tokens are used ext_lvl and ext_parm functions in the individual rig files. * Extra parameters which are rig specific should be coded in the individual rig files and token #s < 100. */ #define TOKEN_BACKEND(t) (t) #define TOK_RTTY_FLTR TOKEN_BACKEND(100) #define TOK_SSBBASS TOKEN_BACKEND(101) #define TOK_SQLCTRL TOKEN_BACKEND(102) #define TOK_DRIVE_GAIN TOKEN_BACKEND(103) #define TOK_DIGI_SEL_FUNC TOKEN_BACKEND(104) #define TOK_DIGI_SEL_LEVEL TOKEN_BACKEND(105) #define TOK_DSTAR_CALL_SIGN TOKEN_BACKEND(120) #define TOK_DSTAR_MESSAGE TOKEN_BACKEND(121) #define TOK_DSTAR_STATUS TOKEN_BACKEND(122) #define TOK_DSTAR_GPS_DATA TOKEN_BACKEND(123) #define TOK_DSTAR_GPS_MESS TOKEN_BACKEND(124) #define TOK_DSTAR_DSQL TOKEN_BACKEND(125) #define TOK_DSTAR_MY_CS TOKEN_BACKEND(126) #define TOK_DSTAR_TX_CS TOKEN_BACKEND(127) #define TOK_DSTAR_TX_MESS TOKEN_BACKEND(128) #define TOK_DSTAR_TX_DATA TOKEN_BACKEND(129) #define TOK_DSTAR_CODE TOKEN_BACKEND(130) #define TOK_SCOPE_MSS TOKEN_BACKEND(140) #define TOK_SCOPE_SDS TOKEN_BACKEND(141) #define TOK_SCOPE_EDG TOKEN_BACKEND(142) #define TOK_SCOPE_STX TOKEN_BACKEND(143) #define TOK_SCOPE_CFQ TOKEN_BACKEND(144) #define TOK_SCOPE_VBW TOKEN_BACKEND(145) #define TOK_SCOPE_FEF TOKEN_BACKEND(146) #define TOK_SCOPE_RBW TOKEN_BACKEND(147) #define TOK_SCOPE_MKP TOKEN_BACKEND(148) #define TOK_IPP_FUNC TOKEN_BACKEND(149) #define TOK_TX_INHIBIT_FUNC TOKEN_BACKEND(150) #define TOK_DPP_FUNC TOKEN_BACKEND(151) #define TOK_ICPW2_FUNC TOKEN_BACKEND(152) /* * icom_ext_parm table subcommand modifiers */ #define SC_MOD_RD 0x01 /* Readable */ #define SC_MOD_WR 0x02 /* Writeable */ #define SC_MOD_RW 0x03 /* Read-write */ #define SC_MOD_RW12 0x07 /* Write +0x01, Read +0x02 */ /* * icom_ext_parm table data types */ #define CMD_DAT_WRD 0x00 /* literal single word type */ #define CMD_DAT_INT 0x01 /* bcd int type */ #define CMD_DAT_FLT 0x02 /* bcd float type */ #define CMD_DAT_LVL 0x03 /* bcd level type */ #define CMD_DAT_BOL 0x04 /* bcd boolean type */ #define CMD_DAT_STR 0x05 /* string type */ #define CMD_DAT_BUF 0x06 /* literal byte buffer type */ #define CMD_DAT_TIM 0x07 /* Time type HHMM<>seconds */ /* * Icom spectrum scope definitions */ #define SCOPE_MODE_CENTER 0x00 #define SCOPE_MODE_FIXED 0x01 #define SCOPE_MODE_SCROLL_C 0x02 #define SCOPE_MODE_SCROLL_F 0x03 #define SCOPE_SPEED_FAST 0x00 #define SCOPE_SPEED_MID 0x01 #define SCOPE_SPEED_SLOW 0x02 #define SCOPE_IN_RANGE 0x00 #define SCOPE_OUT_OF_RANGE 0x01 #endif /* _ICOM_DEFS_H */ hamlib-4.6.5/rigs/icom/frame.c0000664000175000017500000006352415056640443011617 /* * Hamlib CI-V backend - low level communication routines * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "cache.h" /* * Build a CI-V frame. * The whole frame is placed in frame[], * "re_id" is the transceiver's CI-V address, * "cmd" is the Command number, * "subcmd" is the Sub command number, set to -1 if not present in frame, * if the frame has no data, then the "data" pointer must be NULL, * and data_len==0. * "data_len" holds the Data area length pointed by the "data" pointer. * REM: if "data" is NULL, then "data_len" MUST be 0. * * NB: the frame array must be big enough to hold the frame. * The smallest frame is 6 bytes, the biggest is at least 13 bytes. */ int make_cmd_frame(unsigned char frame[], unsigned char re_id, unsigned char ctrl_id, unsigned char cmd, int subcmd, const unsigned char *data, int data_len) { int i = 0; #if 0 frame[i++] = PAD; /* give old rigs a chance to flush their rx buffers */ #endif frame[i++] = PR; /* Preamble code */ frame[i++] = PR; frame[i++] = re_id; frame[i++] = ctrl_id; frame[i++] = cmd; if (subcmd != -1) { #ifdef MULTIB_SUBCMD register int j; if ((j = subcmd & 0xff0000)) /* allows multi-byte subcmd for dsp rigs */ { frame[i++] = j >> 16; frame[i++] = (subcmd & 0xff00) >> 8; } else if ((j = subcmd & 0xff00)) { frame[i++] = j >> 8; } #endif frame[i++] = subcmd & 0xff; } if (data_len != 0) { memcpy(frame + i, data, data_len); i += data_len; } frame[i++] = FI; /* EOM code */ return (i); } int icom_frame_fix_preamble(int frame_len, unsigned char *frame) { if (frame[0] == PR) { // Sometimes the second preamble byte is missing -> TODO: Find out why! if (frame[1] != PR) { memmove(frame + 1, frame, frame_len); frame_len++; } } else { rig_debug(RIG_DEBUG_WARN, "%s: invalid Icom CI-V frame, no preamble found\n", __func__); return (-RIG_EPROTO); } return frame_len; } /* * icom_one_transaction * * We assume that rig!=NULL, STATE(rig)!= NULL, payload!=NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * payload can be NULL if payload_len == 0 * subcmd can be equal to -1 (no subcmd wanted) * if no answer is to be expected, data_len must be set to NULL to tell so * * return RIG_OK if transaction completed, * or a negative value otherwise indicating the error. */ int icom_one_transaction(RIG *rig, unsigned char cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len) { struct icom_priv_data *priv; const struct icom_priv_caps *priv_caps; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct timeval start_time, current_time, elapsed_time; // this buf needs to be large enough for 0xfe strings for power up // at 115,200 this is now at least 150 unsigned char buf[200]; unsigned char sendbuf[MAXFRAMELEN]; int frm_len, frm_data_len, retval; unsigned char ctrl_id; int collision_retry = 0; ENTERFUNC; memset(buf, 0, 200); memset(sendbuf, 0, MAXFRAMELEN); priv = (struct icom_priv_data *)rs->priv; priv_caps = (struct icom_priv_caps *)rig->caps->priv; ctrl_id = priv_caps->serial_full_duplex == 0 ? CTRLID : 0x80; // Should check return code and that write wrote cmd_len chars! set_transaction_active(rig); collision_retry: // The IC7100 cannot separate the CI-V port from the USB CI-V // We see async packets coming in so we'll try and do the flush // This also means the IC7100 will not support async packets anymore if (rig->caps->rig_model == RIG_MODEL_IC7100) { rig_flush(rp); } frm_len = make_cmd_frame(sendbuf, priv->re_civ_addr, ctrl_id, cmd, subcmd, payload, payload_len); if (data_len) { *data_len = 0; } retval = write_block(rp, sendbuf, frm_len); if (retval != RIG_OK) { set_transaction_inactive(rig); RETURNFUNC(retval); } if (!priv_caps->serial_full_duplex && !priv->serial_USB_echo_off) { /* * read what we just sent, because TX and RX are looped, * and discard it... * - if what we read is not what we sent, then it means * a collision on the CI-V bus occurred! * - if we get a timeout, then retry to send the frame, * up to rs->retry times. */ again1: retval = read_icom_frame(rp, buf, sizeof(buf)); if (retval == -RIG_ETIMEOUT || retval == 0) { /* Nothing received, CI-V interface is not echoing */ set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSERROR); } if (retval < 0) { set_transaction_inactive(rig); // Other error, return it RETURNFUNC(retval); } if (retval < 1) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } if (icom_is_async_frame(rig, frm_len, buf)) { icom_process_async_frame(rig, frm_len, buf); goto again1; } // if we get a reply that is not our cmd/subcmd we should just ignore it and retry the read. // this should somewhat allow splitting the COM port between two controllers if (cmd != buf[4]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd x%02x != buf x%02x so retry read\n", __func__, cmd, buf[4]); goto again1; } if (subcmd != -1 && subcmd != buf[5]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: subcmd x%02x != buf x%02x so retry read\n", __func__, subcmd, buf[5]); goto again1; } // we might have 0xfe string during rig wakeup rig_debug(RIG_DEBUG_TRACE, "%s: DEBUG retval=%d, frm_len=%d, cmd=0x%02x\n", __func__, retval, frm_len, cmd); if (retval != frm_len && cmd == C_SET_PWR) { rig_debug(RIG_DEBUG_TRACE, "%s: removing 0xfe power up echo, len=%d", __func__, frm_len); while (buf[2] == 0xfe) { memmove(buf, &buf[1], frm_len--); } dump_hex(buf, frm_len); } switch (buf[retval - 1]) { case COL: /* Collision */ // IC746 for example responds 0xfc when tuning is active so we will retry if (collision_retry++ < 20) { rig_debug(RIG_DEBUG_VERBOSE, "%s: collision retry#%d\n", __func__, collision_retry); hl_usleep(500 * 1000); // 500ms 20 times for ~15 second max before we back out for a retry if needed goto collision_retry; } set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; default: /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSERROR); } if (retval != frm_len) { /* Not the same length??? */ /* Problem on ci-v bus? */ /* Someone else got a packet in? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // first 2 bytes of everything are 0xfe so we won't test those // this allows some corruption of the 0xfe bytes which has been seen in the wild if (memcmp(&buf[2], &sendbuf[2], frm_len - 2) != 0) { /* Frames are different? */ /* Problem on ci-v bus? */ /* Someone else got a packet in? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } } /* * expect an answer? */ if (data_len == NULL) { set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } gettimeofday(&start_time, NULL); read_another_frame: /* * wait for ACK ... * FIXME: handle padding/collisions * ACKFRMLEN is the smallest frame we can expect from the rig */ priv->serial_USB_echo_off = 1; again2: buf[0] = 0; frm_len = read_icom_frame(rp, buf, sizeof(buf)); if (frm_len <= 0) { set_transaction_inactive(rig); RETURNFUNC(frm_len); } if (frm_len > 4 && memcmp(buf, sendbuf, frm_len) == 0) { priv->serial_USB_echo_off = 0; goto again2; } // https://github.com/Hamlib/Hamlib/issues/1575 // these types of async can interrupt the cmd we sent // if our host number changes must not be for us if (icom_is_async_frame(rig, frm_len, buf)) { icom_process_async_frame(rig, frm_len, buf); goto again2; } // IC-PW2 was sending fe fe 94 aa 1c 03 if (buf[3] == 0xaa || buf[2] == 0xaa) { goto again2; } if (sendbuf[3] != buf[2]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown async? read again\n", __func__); hl_usleep(100); rig_flush(rp); collision_retry++; if (collision_retry < 2) { goto collision_retry; } } #if 0 // this was causing rigctld to fail on IC706 and WSJT-X // This dynamic detection is therefore disabled for now if (memcmp(buf, sendbuf, frm_len) == 0 && priv->serial_USB_echo_off) { // Hmmm -- got an echo back when not expected so let's change priv->serial_USB_echo_off = 0; // And try again frm_len = read_icom_frame(rp, buf, sizeof(buf)); } #endif if (frm_len < 0) { set_transaction_inactive(rig); if (priv_caps->re_civ_addr != priv->re_civ_addr) { rig_debug(RIG_DEBUG_ERR, "%s: Icom timeout civ expected=%02x, used=%02x\n", __func__, priv_caps->re_civ_addr, priv->re_civ_addr); } // RIG_TIMEOUT: timeout getting response, return timeout // other error: return it RETURNFUNC(frm_len); } if (frm_len < 1) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } retval = icom_frame_fix_preamble(frm_len, buf); if (retval < 0) { set_transaction_inactive(rig); RETURNFUNC(retval); } frm_len = retval; if (frm_len < 1) { rig_debug(RIG_DEBUG_ERR, "Unexpected frame len=%d\n", frm_len); RETURNFUNC(-RIG_EPROTO); } switch (buf[frm_len - 1]) { case COL: set_transaction_inactive(rig); /* Collision */ RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; case NAK: set_transaction_inactive(rig); RETURNFUNC(-RIG_ERJCTED); default: set_transaction_inactive(rig); /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ RETURNFUNC(-RIG_EPROTO); } if (frm_len < ACKFRMLEN) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // if we send a bad command we will get back a NAK packet // e.g. fe fe e0 50 fa fd if (frm_len == 6 && NAK == buf[frm_len - 2]) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_TRACE, "%s: frm_len=%d, frm_len-1=%02x, frm_len-2=%02x\n", __func__, frm_len, buf[frm_len - 1], buf[frm_len - 2]); // has to be one of these two now or frame is corrupt if (FI != buf[frm_len - 1] && ACK != buf[frm_len - 1]) { set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSBUSY); } frm_data_len = frm_len - (ACKFRMLEN - 1); if (frm_data_len <= 0) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // TODO: Does ctrlid (detected by icom_is_async_frame) vary (seeing some code above using 0x80 for non-full-duplex)? if (icom_is_async_frame(rig, frm_len, buf)) { int elapsedms; icom_process_async_frame(rig, frm_len, buf); gettimeofday(¤t_time, NULL); timersub(¤t_time, &start_time, &elapsed_time); elapsedms = (int)(elapsed_time.tv_sec * 1000 + elapsed_time.tv_usec / 1000); if (elapsedms > rp->timeout) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ETIMEOUT); } goto read_another_frame; } set_transaction_inactive(rig); *data_len = frm_data_len; if (data != NULL) { memcpy(data, buf + 4, *data_len); } /* * TODO: check addresses in reply frame */ RETURNFUNC(RIG_OK); } /* * icom_transaction * * This function honors rigport.retry count. * * We assume that rig!=NULL, STATE(rig)!= NULL, payload!=NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * payload can be NULL if payload_len == 0 * subcmd can be equal to -1 (no subcmd wanted) * * return RIG_OK if transaction completed, * or a negative value otherwise indicating the error. */ int icom_transaction(RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len) { int retval, retry; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=0x%02x, subcmd=0x%02x, payload_len=%d\n", __func__, cmd, subcmd, payload_len); retry = RIGPORT(rig)->retry; do { retval = icom_one_transaction(rig, cmd, subcmd, payload, payload_len, data, data_len); // codes that make us return immediately if (retval == RIG_OK || retval == -RIG_ERJCTED || retval == -RIG_BUSERROR) { break; } rig_debug(RIG_DEBUG_WARN, "%s: retry=%d: %s\n", __func__, retry, rigerror(retval)); // On some serial errors we may need a bit of time hl_usleep(100 * 1000); // pause just a bit } while (retry-- > 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: failed: %s\n", __func__, rigerror(retval)); } RETURNFUNC(retval); } /* used in read_icom_frame as end of block */ static const char icom_block_end[2] = { FI, COL}; #define icom_block_end_length 2 /* * Read a whole CI-V frame (until 0xfd is encountered). * * TODO: strips padding/collisions * FIXME: check return codes/bytes read */ static int read_icom_frame_generic(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len, int direct) { int read = 0; int retries = 10; unsigned char *rx_ptr = (unsigned char *) rxbuffer; // zeroize the buffer so we can still check contents after timeouts memset(rx_ptr, 0, rxbuffer_len); /* * OK, now sometimes we may time out, e.g. the IC7000 can time out * during a PTT operation. So, we will ensure that the last thing we * read was a proper end marker - if not, we will try again. */ do { int i; if (direct) { i = read_string_direct(p, rx_ptr, MAXFRAMELEN - read, icom_block_end, icom_block_end_length, 0, 1); } else { i = read_string(p, rx_ptr, MAXFRAMELEN - read, icom_block_end, icom_block_end_length, 0, 1); } if (i < 0 && i != -RIG_BUSBUSY) /* die on errors */ { return (i); } if (i == 0) /* nothing read?*/ { if (--retries <= 0) /* Tried enough times? */ { return (read); } } /* OK, we got something. add it in and continue */ if (i > 0) { read += i; rx_ptr += i; } } while ((read < rxbuffer_len) && (rxbuffer[read - 1] != FI) && (rxbuffer[read - 1] != COL)); // Check that we have a valid frame preamble (which might be just a single preamble character) // Or an error code if (rxbuffer[0] != PR && rxbuffer[0] != COL) { return -RIG_EPROTO; } return (read); } int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len) { return read_icom_frame_generic(p, rxbuffer, rxbuffer_len, 0); } int read_icom_frame_direct(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len) { return read_icom_frame_generic(p, rxbuffer, rxbuffer_len, 1); } /* * convert mode and width as expressed by Hamlib frontend * to mode and passband data understandable by a CI-V rig * * if pd == -1, no passband data is to be sent * * return RIG_OK if everything's fine, negative value otherwise * * TODO: be more exhaustive * assumes rig!=NULL */ int rig2icom_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { unsigned char icmode; signed char icmode_ext; pbwidth_t width_tmp = width; const struct icom_priv_data *priv_data = (struct icom_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: mode=%d, width=%d\n", __func__, (int)mode, (int)width); icmode_ext = -1; if (width == RIG_PASSBAND_NOCHANGE) // then we read width so we can reuse it { rig_debug(RIG_DEBUG_TRACE, "%s: width==RIG_PASSBAND_NOCHANGE\n", __func__); rmode_t tmode; int ret = rig_get_mode(rig, vfo, &tmode, &width); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: Failed to get width for passband nochange err=%s\n", __func__, rigerror(ret)); } } switch (mode) { case RIG_MODE_AM: icmode = S_AM; break; case RIG_MODE_PKTAM: icmode = S_AM; break; case RIG_MODE_AMN: icmode = S_AMN; break; case RIG_MODE_AMS: icmode = S_AMS; break; case RIG_MODE_CW: icmode = S_CW; break; case RIG_MODE_CWR: icmode = S_CWR; break; case RIG_MODE_USB: icmode = S_USB; break; case RIG_MODE_PKTUSB: icmode = S_USB; if (rig->caps->rig_model == RIG_MODEL_IC7800) { icmode = S_PSK; } break; case RIG_MODE_LSB: icmode = S_LSB; break; case RIG_MODE_PKTLSB: icmode = S_LSB; if (rig->caps->rig_model == RIG_MODEL_IC7800) { icmode = S_PSKR; } break; case RIG_MODE_RTTY: icmode = S_RTTY; break; case RIG_MODE_RTTYR: icmode = S_RTTYR; break; case RIG_MODE_PSK: icmode = S_PSK; break; case RIG_MODE_PSKR: icmode = S_PSKR; break; case RIG_MODE_FM: icmode = S_FM; break; case RIG_MODE_PKTFM: icmode = S_FM; break; case RIG_MODE_FMN: icmode = S_FMN; break; case RIG_MODE_PKTFMN: icmode = S_FMN; break; case RIG_MODE_WFM: icmode = S_WFM; break; case RIG_MODE_P25: icmode = S_P25; break; case RIG_MODE_DSTAR: icmode = S_DSTAR; break; case RIG_MODE_DPMR: icmode = S_DPMR; break; case RIG_MODE_NXDNVN: icmode = S_NXDNVN; break; case RIG_MODE_NXDN_N: icmode = S_NXDN_N; break; case RIG_MODE_DCR: icmode = S_DCR; break; case RIG_MODE_DD: icmode = S_DD; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Hamlib mode %s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } if (width_tmp != RIG_PASSBAND_NOCHANGE) { rig_debug(RIG_DEBUG_TRACE, "%s: width_tmp=%ld\n", __func__, width_tmp); pbwidth_t medium_width = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { // Use rig default for "normal" passband icmode_ext = -1; } else if (width < medium_width) { icmode_ext = PD_NARROW_3; } else if (width == medium_width) { icmode_ext = PD_MEDIUM_3; } else { icmode_ext = PD_WIDE_3; } if (rig->caps->rig_model == RIG_MODEL_ICR7000) { if (mode == RIG_MODE_USB || mode == RIG_MODE_LSB) { icmode = S_R7000_SSB; icmode_ext = 0x00; } else if (mode == RIG_MODE_AM && icmode_ext == -1) { icmode_ext = PD_WIDE_3; /* default to Wide */ } } *pd = icmode_ext; } else { // filter should already be set elsewhere *pd = priv_data->filter; } *md = icmode; RETURNFUNC(RIG_OK); } /* * assumes rig!=NULL, mode!=NULL, width!=NULL */ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%02x, pd=%d\n", __func__, md, pd); // Some rigs return fixed with for FM mode if (RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) { if (md == S_FM) { *mode = RIG_MODE_FM; if (*width == 1) { *width = 15000; } else if (*width == 2) { *width = 10000; } else { *width = 7000; } return; } else if (md == S_WFM) { // For IC-705, *width will always be 1 // At least this works for IC-705 *mode = RIG_MODE_WFM; *width = 200000; return; } // If not FM nor SFM mode, // fall down this block for further processing } *width = RIG_PASSBAND_NORMAL; switch (md) { case S_AM: if (rig->caps->rig_model == RIG_MODEL_ICR30 && pd == 0x02) { *mode = RIG_MODE_AMN; } else { *mode = RIG_MODE_AM; } break; case S_AMS: *mode = RIG_MODE_AMS; break; case S_CW: *mode = RIG_MODE_CW; break; case S_CWR: *mode = RIG_MODE_CWR; break; case S_FM: if (rig->caps->rig_model == RIG_MODEL_ICR7000 && pd == 0x00) { *mode = RIG_MODE_USB; *width = rig_passband_normal(rig, RIG_MODE_USB); return; } else if (rig->caps->rig_model == RIG_MODEL_ICR30 && pd == 0x02) { *mode = RIG_MODE_FMN; } else { *mode = RIG_MODE_FM; } break; case S_WFM: *mode = RIG_MODE_WFM; break; case S_USB: *mode = RIG_MODE_USB; break; case S_LSB: *mode = RIG_MODE_LSB; break; case S_RTTY: *mode = RIG_MODE_RTTY; break; case S_RTTYR: *mode = RIG_MODE_RTTYR; break; case S_PSK: *mode = RIG_MODE_PSK; if (rig->caps->rig_model == RIG_MODEL_IC7800) { *mode = RIG_MODE_PKTUSB; } break; case S_PSKR: *mode = RIG_MODE_PSKR; if (rig->caps->rig_model == RIG_MODEL_IC7800) { *mode = RIG_MODE_PKTLSB; } break; case S_DSTAR: *mode = RIG_MODE_DSTAR; break; case S_P25: *mode = RIG_MODE_P25; break; case S_DPMR: *mode = RIG_MODE_DPMR; break; case S_NXDNVN: *mode = RIG_MODE_NXDNVN; break; case S_NXDN_N: *mode = RIG_MODE_NXDN_N; break; case S_DCR: *mode = RIG_MODE_DCR; break; case 0xff: *mode = RIG_MODE_NONE; break; /* blank mem channel */ default: rig_debug(RIG_DEBUG_ERR, "icom: Unsupported Icom mode %#.2x\n", md); *mode = RIG_MODE_NONE; } /* Most rigs return 1-wide, 2-narrow; or if it has 3 filters: 1-wide, 2-middle, 3-narrow. (Except for the 706 mkIIg 0-wide, 1-middle, 2-narrow.) For DSP rigs these are presets, which can be programmed for 30 - 41 bandwidths, depending on mode */ if (pd >= 0 && (rig->caps->rig_model == RIG_MODEL_IC706MKIIG || rig->caps->rig_model == RIG_MODEL_IC706 || rig->caps->rig_model == RIG_MODEL_IC706MKII)) { pd++; } switch (pd) { case 0x01: /* if no wide filter defined it's the default */ if (!(*width = rig_passband_wide(rig, *mode))) { *width = rig_passband_normal(rig, *mode); } break; case 0x02: if ((*width = rig_passband_wide(rig, *mode))) { *width = rig_passband_normal(rig, *mode); } else /* This really just depends on how you program the table. */ { *width = rig_passband_narrow(rig, *mode); } break; case 0x03: *width = rig_passband_narrow(rig, *mode); break; case -1: break; /* no passband data */ default: rig_debug(RIG_DEBUG_ERR, "icom: Unsupported Icom mode width %#.2x\n", pd); } } hamlib-4.6.5/rigs/icom/optoscan.c0000664000175000017500000005160415056640443012347 /* * Hamlib CI-V backend - OptoScan extensions * Copyright (c) 2000-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "optoscan.h" const struct confparams opto_ext_parms[] = { { TOK_TAPECNTL, "tapecntl", "Toggle Tape Switch", "Toggles built in tape switch", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_5KHZWIN, "5khzwin", "Toggle 5kHz Search Window", "Toggles 5kHz search window", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_SPEAKER, "speaker", "Toggle speaker audio", "Toggles speaker audio", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_AUDIO, "audio", "Audio present", "Audio present", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DTMFPEND, "dtmfpend", "DTMF Digit Pending", "DTMF Digit Pending", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DTMFOVRR, "dtmfovrr", "DTMF Buffer Overflow", "DTMF Buffer Overflow", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_CTCSSACT, "ctcssact", "CTCSS Tone Active", "CTCSS Tone Active", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DCSACT, "dcsact", "DCS Code Active", "DCS Code Active", NULL, RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; static int optoscan_get_status_block(RIG *rig, struct optostat *status_block); static int optoscan_send_freq(RIG *rig, vfo_t vfo, const pltstate_t *state); static int optoscan_RTS_toggle(RIG *rig); static int optoscan_start_timer(RIG *rig, pltstate_t *state); static int optoscan_wait_timer(RIG *rig, pltstate_t *state); /* * optoscan_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_open(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; pltstate_t *pltstate; unsigned char ackbuf[16]; int ack_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; pltstate = calloc(1, sizeof(pltstate_t)); if (!pltstate) { return -RIG_ENOMEM; } memset(pltstate, 0, sizeof(pltstate_t)); priv->pltstate = pltstate; /* select REMOTE control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_REMOTE, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { free(pltstate); return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_open: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); free(pltstate); return -RIG_ERJCTED; } return RIG_OK; } /* * optoscan_close * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_close(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char ackbuf[16]; int ack_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_LOCAL, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_close: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } free(priv->pltstate); return RIG_OK; } /* * optoscan_get_info * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ const char *optoscan_get_info(RIG *rig) { unsigned char ackbuf[16]; int ack_len, retval; static char info[64]; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDID, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return NULL; } if (ack_len != 7) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_info: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return NULL; } SNPRINTF(info, sizeof(info), "OptoScan%c%c%c, software version %d.%d, " "interface version %d.%d\n", ackbuf[2], ackbuf[3], ackbuf[4], ackbuf[5] >> 4, ackbuf[5] & 0xf, ackbuf[6] >> 4, ackbuf[6] & 0xf); return info; } /* * optoscan_get_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDCTCSS, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { return retval; } if (tone_len != 4) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_ctcss_tone: ack NG (%#.2x), " "len=%d\n", tonebuf[0], tone_len); return -RIG_ERJCTED; } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); rig_debug(RIG_DEBUG_ERR, "optoscan_get_ctcss_tone: *tone=%u\n", *tone); return RIG_OK; } /* * optoscan_get_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDCS, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { return retval; } if (tone_len != 4) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: ack NG (%#.2x), " "len=%d\n", tonebuf[0], tone_len); return -RIG_ERJCTED; } tone_len -= 2; *code = from_bcd_be(tonebuf + 2, tone_len * 2); rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: *code=%u\n", *code); return RIG_OK; } int optoscan_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { unsigned char dtmfbuf[MAXFRAMELEN], digit; int len, digitpos; const unsigned char xlate[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#' }; digitpos = 0; do { int retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDTMF, NULL, 0, dtmfbuf, &len); if (retval != RIG_OK) { return retval; } if (len != 3) { rig_debug(RIG_DEBUG_ERR, "optoscan_recv_dtmf: ack NG (%#.2x), len=%d\n", dtmfbuf[0], len); return -RIG_ERJCTED; } digit = dtmfbuf[2]; if (digit < 16) { digits[digitpos] = xlate[digit]; digitpos++; } } while ((digit != 0x99) && (digitpos < *length)); *length = digitpos; digits[digitpos] = 0; if (*length > 0) { rig_debug(RIG_DEBUG_ERR, "%s: %d digits - %s\n", __func__, *length, digits); } else { rig_debug(RIG_DEBUG_ERR, "%s: no digits to read.\n", __func__); } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int retval, subcode; memset(epbuf, 0, MAXFRAMELEN); memset(ackbuf, 0, MAXFRAMELEN); switch (token) { case TOK_TAPECNTL: if (val.i == 0) { subcode = S_OPTO_TAPE_OFF; } else { subcode = S_OPTO_TAPE_ON; } break; case TOK_5KHZWIN: if (val.i == 0) { subcode = S_OPTO_5KSCOFF; } else { subcode = S_OPTO_5KSCON; } break; case TOK_SPEAKER: if (val.i == 0) { subcode = S_OPTO_SPKROFF; } else { subcode = S_OPTO_SPKRON; } break; default: return -RIG_EINVAL; } retval = icom_transaction(rig, C_CTL_MISC, subcode, epbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int optoscan_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct optostat status_block; int retval; retval = optoscan_get_status_block(rig, &status_block); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_TAPECNTL: val->i = status_block.tape_enabled; break; case TOK_5KHZWIN: val->i = status_block.fivekhz_enabled; break; case TOK_SPEAKER: val->i = status_block.speaker_enabled; break; case TOK_AUDIO: val->i = status_block.audio_present; break; case TOK_DTMFPEND: val->i = status_block.DTMF_pending; break; case TOK_DTMFOVRR: val->i = status_block.DTMF_overrun; break; case TOK_CTCSSACT: val->i = status_block.CTCSS_active; break; case TOK_DCSACT: val->i = status_block.DCS_active; break; default: return -RIG_ENIMPL; } return RIG_OK; } /* * optoscan_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { unsigned char lvlbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int retval; memset(lvlbuf, 0, MAXFRAMELEN); /* * So far, levels of float type are in [0.0..1.0] range */ if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = val.f * 255; } else { icom_val = val.i; } switch (level) { case RIG_LEVEL_AF: lvl_cn = C_CTL_MISC; if (icom_val == 0) { lvl_sc = S_OPTO_SPKROFF; } else { lvl_sc = S_OPTO_SPKRON; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s", rig_strlevel(level)); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, lvlbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_set_level: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * optoscan_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int optoscan_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct optostat status_block; int lvl_len = 0; int icom_val; int retval; if (level != RIG_LEVEL_AF) { int lvl_cn, lvl_sc; /* Command Number, Subcommand */ unsigned char lvlbuf[MAXFRAMELEN]; int cmdhead; switch (level) { case RIG_LEVEL_RAWSTR: lvl_cn = C_RD_SQSM; lvl_sc = S_SML; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, NULL, 0, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (lvl_sc == -1) ? 1 : 2; lvl_len -= cmdhead; if (lvlbuf[0] != ACK && lvlbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_level: ack NG (%#.2x), " "len=%d\n", lvlbuf[0], lvl_len); return -RIG_ERJCTED; } /* * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ icom_val = from_bcd_be(lvlbuf + cmdhead, lvl_len * 2); } else /* level == RIG_LEVEL_AF */ { retval = optoscan_get_status_block(rig, &status_block); if (retval != RIG_OK) { return retval; } icom_val = 0; if (status_block.speaker_enabled == 1) { icom_val = 255; } } switch (level) { case RIG_LEVEL_RAWSTR: val->i = icom_val; break; default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float)icom_val / 255; } else { val->i = icom_val; } } rig_debug(RIG_DEBUG_TRACE, "optoscan_get_level: %d %d %d %f\n", lvl_len, icom_val, val->i, val->f); return RIG_OK; } /* OS456 Pipeline tuning algorithm: * Step 2: Send the next frequency and mode to the receiver using the * TRANSFER NEXT FREQUENCY/MODE command. * * Step 3: Change the state of the RTS interface signal to cause the * next frequency and mode to become the current frequency and * mode, and the receiver to begin settling. * * Step 4: While the receiver is still settling on the current * frequency and mode, send the next frequency and mode to the * receiver using the TRANSFER NEXT FREQUENCY/MODE command. * * Step 5: Wait for the receiver to finish settling. The total * settling time, including sending the next frequency and * mode, is 20 milliseconds (0.02 seconds). * * Step 6: Check the squelch status by reading the DCD interface * signal. If the squelch is open, scanning is stopped. * Otherwise, scanning continues. Optionally, the status of * the CTCSS/DCS/DTMF decoder can be checked, and the * appropriate action taken. * * Step 7: Continuously repeat steps 3 through 6 above. */ int optoscan_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { pltstate_t *state; pltune_cb_t cb; int rc, pin_state; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); if (scan != RIG_SCAN_PLT) { return -RIG_ENAVAIL; } rs = STATE(rig); cb = rig->callbacks.pltune; state = ((struct icom_priv_data *)rs->priv)->pltstate; if (state == NULL) { return -RIG_EINTERNAL; } if (state->freq == 0) /* pltstate_t is not initialized - perform setup */ { /* time for CIV command to be sent. this is subtracted from */ /* rcvr settle time */ state->usleep_time = (1000000 / (rp->parm.serial.rate)) * 13 * 9; rc = cb(rig, vfo, &(state->next_freq), &(state->next_mode), &(state->next_width), rig->callbacks.pltune_arg); if (rc == RIG_SCAN_STOP) { return RIG_OK; /* callback halted loop */ } /* Step 1 is implicit, since hamlib does this when it opens the device */ optoscan_send_freq(rig, vfo, state); /*Step 2*/ } rc = 0; while (rc != RIG_SCAN_STOP) { optoscan_RTS_toggle(rig); /*Step 3*/ state->freq = state->next_freq; state->mode = state->next_mode; optoscan_start_timer(rig, state); rc = cb(rig, vfo, &(state->next_freq), &(state->next_mode), &(state->next_width), rig->callbacks.pltune_arg); if (rc != RIG_SCAN_STOP) { optoscan_send_freq(rig, vfo, state); /*Step 4*/ } optoscan_wait_timer(rig, state); /*Step 5*/ ser_get_car(rp, &pin_state); if (pin_state) /*Step 6*/ { return RIG_OK; /* we've broken squelch - return(). caller can */ /* get current freq & mode out of state str */ } } /* exiting pipeline loop - force state init on next call */ state->freq = 0; return RIG_OK; } /* * Assumes rig!=NULL, status_block !=NULL */ static int optoscan_get_status_block(RIG *rig, struct optostat *status_block) { int retval, ack_len, expected_len; unsigned char ackbuf[MAXFRAMELEN]; memset(status_block, 0, sizeof(struct optostat)); retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDSTAT, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (rig->caps->rig_model) { case RIG_MODEL_OS456: expected_len = 4; break; case RIG_MODEL_OS535: expected_len = 5; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig model", __func__); return -RIG_ERJCTED; break; } if (ack_len != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } if (ackbuf[2] & 1) { status_block->remote_control = 1; } if (ackbuf[2] & 2) { status_block->DTMF_pending = 1; } if (ackbuf[2] & 4) { status_block->DTMF_overrun = 1; } if (ackbuf[2] & 16) { status_block->squelch_open = 1; } if (ackbuf[2] & 32) { status_block->CTCSS_active = 1; } if (ackbuf[2] & 64) { status_block->DCS_active = 1; } if (ackbuf[3] & 1) { status_block->tape_enabled = 1; } if (ackbuf[3] & 2) { status_block->speaker_enabled = 1; } if (ackbuf[3] & 4) { status_block->fivekhz_enabled = 1; } if (ackbuf[3] & 16) { status_block->audio_present = 1; } rig_debug(RIG_DEBUG_VERBOSE, "remote_control = %d\n", status_block->remote_control); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_pending = %d\n", status_block->DTMF_pending); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_overrun = %d\n", status_block->DTMF_overrun); rig_debug(RIG_DEBUG_VERBOSE, "squelch_open = %d\n", status_block->squelch_open); rig_debug(RIG_DEBUG_VERBOSE, "CTCSS_active = %d\n", status_block->CTCSS_active); rig_debug(RIG_DEBUG_VERBOSE, "DCS_active = %d\n", status_block->DCS_active); rig_debug(RIG_DEBUG_VERBOSE, "tape_enabled = %d\n", status_block->tape_enabled); rig_debug(RIG_DEBUG_VERBOSE, "speaker_enabled = %d\n", status_block->speaker_enabled); rig_debug(RIG_DEBUG_VERBOSE, "fivekhz_enabled = %d\n", status_block->fivekhz_enabled); rig_debug(RIG_DEBUG_VERBOSE, "audio_present = %d\n", status_block->audio_present); return RIG_OK; } static int optoscan_send_freq(RIG *rig, vfo_t vfo, const pltstate_t *state) { unsigned char buff[OPTO_BUFF_SIZE]; char md, pd; freq_t freq; rmode_t mode; freq = state->next_freq; mode = state->next_mode; memset(buff, 0, OPTO_BUFF_SIZE); to_bcd(buff, freq, 5 * 2); /* to_bcd requires nibble len */ rig2icom_mode(rig, vfo, mode, 0, (unsigned char *) &md, (signed char *) &pd); buff[5] = md; /* read echo'd chars only...there will be no ACK from this command * * Note: * It may have waited for pltstate->usleep_time before reading the echo'd * chars, but the read will be blocking anyway. --SF * */ return icom_transaction(rig, C_CTL_MISC, S_OPTO_NXT, buff, 6, NULL, NULL); } static int optoscan_RTS_toggle(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); int state = 0; ser_get_rts(rp, &state); ser_set_rts(rp, !state); return RIG_OK; } static int optoscan_start_timer(RIG *rig, pltstate_t *state) { gettimeofday(&(state->timer_start), NULL); return RIG_OK; } static int optoscan_wait_timer(RIG *rig, pltstate_t *state) { struct icom_priv_caps *priv_caps; int usec_diff; int settle_usec; priv_caps = (struct icom_priv_caps *)rig->caps->priv; settle_usec = priv_caps->settle_time * 1000; /*convert settle time (ms) to */ /* settle time (usec) */ gettimeofday(&(state->timer_current), NULL); usec_diff = (int)labs((state->timer_current.tv_usec) - (state->timer_start.tv_usec)); if (usec_diff < settle_usec) { hl_usleep(settle_usec - usec_diff); /* sleep balance of settle_time */ } return RIG_OK; } hamlib-4.6.5/rigs/icom/ic781.c0000664000175000017500000001507715056640443011360 /* * Hamlib CI-V backend - description of IC-781 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC781_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) /* * IC-781 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic781/specs.htm * * TODO: selected memory scan, delta-f scan, dual watch */ #define IC781_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define IC781_AM_TX_MODES (RIG_MODE_AM) #define IC781_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC781_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL|RIG_OP_XCHG) #define IC781_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC781_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic781_priv_caps = { 0x26, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic781_caps = { RIG_MODEL(RIG_MODEL_IC781), .model_name = "IC-781", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC781_VFO_OPS, .scan_ops = IC781_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC781_ALL_RX_MODES, -1, -1, IC781_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC781_OTHER_TX_MODES, W(10), W(150), IC781_VFO_ALL, IC781_ANTS), FRQ_RNG_HF(1, IC781_AM_TX_MODES, W(10), W(75), IC781_VFO_ALL, IC781_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC781_ALL_RX_MODES, -1, -1, IC781_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {kHz(1800), 1999999, IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, /* 150W class */ {kHz(1800), 1999999, IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, /* 75W class */ {kHz(3400), 4099999, IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(3400), 4099999, IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(9.9), MHz(1049999), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(9.9), MHz(1049999), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {kHz(17900), kHz(18499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(17900), kHz(18499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {kHz(24400), kHz(25099.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(24400), kHz(25099.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(27.9), MHz(30), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(27.9), MHz(30), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC781_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* narrow */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, /* narrow, with [CW250Hz] ON */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic781_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, /* TODO: more capabilities */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic785x.c0000664000175000017500000004375415056640443011557 /* * Hamlib CI-V backend - description of IC-785x and variations * Derived from ic7800.c by W9MDB -- needs testing * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "ic7300.h" #define IC785x_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC785x_1HZ_TS_MODES IC785x_ALL_RX_MODES #define IC785x_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC785x_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC785x_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD) #define IC785x_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_SPECTRUM_ATT|RIG_LEVEL_AGC_TIME) #define IC785x_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC785x_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE) #define IC785x_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC785x_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC785x_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-785x S-meter calibration data based on manual #define IC785x_STR_CAL { 3, \ { \ { 0, -54 }, /* S0 */ \ { 120, 0 }, /* S9 */ \ { 241, 60 } /* S9+60 */ \ } } #define IC785x_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC785x_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC785x_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC785x_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC785x_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC785x_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } extern int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); extern int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct cmdparams ic785x_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x04}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x76}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x96}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x09}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x55}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x87}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x52}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x54}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic785x_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_MKP, TOK_BACKEND_NONE }; /* * IC-785x rig capabilities. */ static struct icom_priv_caps ic785x_priv_caps = { 0x8e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 4, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 689, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 200, .signal_strength_min = -100, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic785x_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic785x_caps = { RIG_MODEL(RIG_MODEL_IC785x), .model_name = "IC-7850/7851", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC785x_FUNCS, .has_set_func = IC785x_FUNCS, .has_get_level = IC785x_LEVELS, .has_set_level = RIG_LEVEL_SET(IC785x_LEVELS), .has_get_parm = IC785x_PARMS, .has_set_parm = RIG_PARM_SET(IC785x_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic785x_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 12, 20, RIG_DBLST_END, }, .attenuator = { 3, 6, 9, 12, 15, 18, 21, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC785x_VFO_OPS, .scan_ops = IC785x_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC785x_ALL_RX_MODES, -1, -1, IC785x_VFOS, IC785x_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_6m(1, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_HF(1, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ FRQ_RNG_6m(1, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC785x_ALL_RX_MODES, -1, -1, IC785x_VFOS, IC785x_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_6m(2, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_HF(2, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ FRQ_RNG_6m(2, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC785x_1HZ_TS_MODES, 1}, {IC785x_ALL_RX_MODES, Hz(100)}, {IC785x_ALL_RX_MODES, kHz(1)}, {IC785x_ALL_RX_MODES, kHz(5)}, {IC785x_ALL_RX_MODES, kHz(9)}, {IC785x_ALL_RX_MODES, kHz(10)}, {IC785x_ALL_RX_MODES, kHz(12.5)}, {IC785x_ALL_RX_MODES, kHz(20)}, {IC785x_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC785x_STR_CAL, .swr_cal = IC785x_SWR_CAL, .alc_cal = IC785x_ALC_CAL, .rfpower_meter_cal = IC785x_RFPOWER_METER_CAL, .comp_meter_cal = IC785x_COMP_METER_CAL, .vd_meter_cal = IC785x_VD_METER_CAL, .id_meter_cal = IC785x_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .spectrum_attenuator = { 10, 20, 30, RIG_DBLST_END, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic785x_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = ic785x_set_level, .get_level = ic785x_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7300_set_clock, .get_clock = ic7300_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { return ic7800_set_level(rig, vfo, level, val); } int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return ic7800_get_level(rig, vfo, level, val); } hamlib-4.6.5/rigs/icom/ic751.c0000664000175000017500000002107315056640443011346 /* * Hamlib CI-V backend - description of IC-751 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" /* * FM is an option on the Icom IC-751, and built-in in the Icom IC-751A */ #define IC751_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* * 200W in all modes but AM (40W) */ #define IC751_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC751_AM_TX_MODES (RIG_MODE_AM) #define IC751_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC751_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC751_SCAN_OPS (RIG_SCAN_NONE) #define IC751_ANTS RIG_ANT_1 /* * S-Meter measurements * (Only the Piexx UX-14px rev.2 and up has an S-meter option.) * Values based on the readings of my IC-751A S-meter, i.e. not * actual signal strength. -- Lars, sm6rpz */ #define IC751_STR_CAL { 16, { \ { 3, -52 }, /* S0.5 */ \ { 12, -48 }, /* S1 */ \ { 33, -42 }, /* S2 */ \ { 45, -36 }, /* S3 */ \ { 60, -30 }, /* S4 */ \ { 73, -24 }, /* S5 */ \ { 86, -18 }, /* S6 */ \ { 100, -12 }, /* S7 */ \ { 115, -6 }, /* S8 */ \ { 129, 0 }, /* S9 */ \ { 160, 10 }, /* S9+10 */ \ { 186, 20 }, /* S9+20 */ \ { 208, 30 }, /* S9+30 */ \ { 226, 40 }, /* S9+40 */ \ { 241, 50 }, /* S9+50 */ \ { 255, 60 } /* S9+60 */ \ } } /* */ static const struct icom_priv_caps ic751_priv_caps = { 0x1c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic751_caps = { RIG_MODEL(RIG_MODEL_IC751), .model_name = "IC-751", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, /* Piexx UX-14px has a PTT option */ .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, /* Piexx UX-14px can use 9600 */ .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, /* Piexx UX-14px has an S-meter option */ .has_get_level = (RIG_LEVEL_RAWSTR | RIG_LEVEL_STRENGTH), .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC751_VFO_OPS, .scan_ops = IC751_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 32, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC751_ALL_RX_MODES, -1, -1, IC751_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(1.99999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC751_ALL_RX_MODES, -1, -1, IC751_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {MHz(1.8), MHz(1.99999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC751_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.3)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(250)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC751_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic751_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .get_level = icom_get_level, .set_ptt = icom_set_ptt,/* Piexx UX-14px has no get_ptt only set_ptt */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic718.c0000664000175000017500000001530115056640443011346 /* * Hamlib CI-V backend - description of IC-718 caps * Copyright (c) 2000-2010 by Stephane Fillod * Caps submitted by Chuck Gilkes WD0FCL/4 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #include "bandplan.h" #define IC718_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC718_1MHZ_TS_MODES (RIG_MODE_AM) #define IC718_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) /* tx doesn't have WFM. * 100W in all modes but AM (40W) */ #define IC718_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC718_AM_TX_MODES (RIG_MODE_AM) #define IC718_FUNC_ALL (RIG_FUNC_NR|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_ANF) #define IC718_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_MICGAIN|RIG_LEVEL_NR|RIG_LEVEL_CWPITCH|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RAWSTR|RIG_LEVEL_SQL) #define IC718_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC718_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC718_SCAN_OPS (RIG_SCAN_MEM) /* * TODO: check whether func and levels are stored in memory */ #define IC718_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ } #define IC718_STR_CAL UNKNOWN_IC_STR_CAL static const struct icom_priv_caps IC718_priv_caps = { 0x5e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic718_ts_sc_list }; struct rig_caps ic718_caps = { RIG_MODEL(RIG_MODEL_IC718), .model_name = "IC-718", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC718_FUNC_ALL, .has_set_func = IC718_FUNC_ALL, .has_get_level = IC718_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC718_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .str_cal = IC718_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC718_VFO_OPS, .scan_ops = IC718_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC718_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC718_MEM_CAP }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - 1, IC718_ALL_RX_MODES, -1, -1, IC718_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC718_OTHER_TX_MODES, W(5), W(100), IC718_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(1, IC718_AM_TX_MODES, W(2), W(40), IC718_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - 1, IC718_ALL_RX_MODES, -1, -1, IC718_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC718_OTHER_TX_MODES, W(5), W(100), IC718_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(2, IC718_AM_TX_MODES, W(2), W(40), IC718_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC718_1HZ_TS_MODES, 1}, {IC718_ALL_RX_MODES, 10}, {IC718_ALL_RX_MODES, 100}, {IC718_ALL_RX_MODES, kHz(1)}, {IC718_ALL_RX_MODES, kHz(5)}, {IC718_ALL_RX_MODES, kHz(9)}, {IC718_ALL_RX_MODES, kHz(10)}, {IC718_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.1)}, /* builtin */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* FL-52A */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, /* FL-53A */ {RIG_MODE_SSB, kHz(2.8)}, /* FL-96 */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.8)}, /* FL-222 */ {RIG_MODE_AM, kHz(6)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC718_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic737.c0000664000175000017500000001240515056640443011351 /* * Hamlib CI-V backend - description of IC-737 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-737 */ #define IC737_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC737_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC737_AM_TX_MODES (RIG_MODE_AM) #define IC737_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC737_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC737_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC737_ANTS (RIG_ANT_1|RIG_ANT_2) static const struct icom_priv_caps ic737_priv_caps = { 0x3c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list, .antack_len = 2, .ant_count = 2 }; struct rig_caps ic737_caps = { RIG_MODEL(RIG_MODEL_IC737), .model_name = "IC-737", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC737_VFO_OPS, .scan_ops = IC737_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM }, { 101, 101, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC737_ALL_RX_MODES, -1, -1, IC737_VFO_ALL, IC737_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC737_OTHER_TX_MODES, W(10), W(100), IC737_VFO_ALL, IC737_ANTS), FRQ_RNG_HF(1, IC737_AM_TX_MODES, W(10), W(40), IC737_VFO_ALL, IC737_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC737_ALL_RX_MODES, -1, -1, IC737_VFO_ALL, IC737_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC737_OTHER_TX_MODES, W(10), W(100), IC737_VFO_ALL, IC737_ANTS), FRQ_RNG_HF(2, IC737_AM_TX_MODES, W(10), W(40), IC737_VFO_ALL, IC737_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC737_ALL_RX_MODES, 10}, {IC737_ALL_RX_MODES, kHz(1)}, {IC737_ALL_RX_MODES, kHz(2)}, {IC737_ALL_RX_MODES, kHz(3)}, {IC737_ALL_RX_MODES, kHz(4)}, {IC737_ALL_RX_MODES, kHz(5)}, {IC737_ALL_RX_MODES, kHz(6)}, {IC737_ALL_RX_MODES, kHz(7)}, {IC737_ALL_RX_MODES, kHz(8)}, {IC737_ALL_RX_MODES, kHz(9)}, {IC737_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic737_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/delta2.c0000664000175000017500000001210415056640443011664 /* * Hamlib CI-V backend - description of the TenTenc DeltaII * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Delta II (aka TT 536) cloned after Omni VI. * Needs RS-232 Serial Level Converter Model 305 or equivalent. * * For changing CI-V address of the rig, see: * http://www.tentecwiki.org/doku.php?id=536addr */ /* Known problems: * * To Do: get the datasheet, and testing on real hardware!! */ #include #include "icom.h" #define DELTAII_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define DELTAII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DELTAII_ALL_RX_MODES (DELTAII_OTHER_TX_MODES|RIG_MODE_AM) #define DELTAII_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define DELTAII_STR_CAL { 0, { } } static const struct icom_priv_caps delta2_priv_caps = { 0x01, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list /* TODO: ts_sc_list */ }; struct rig_caps delta2_caps = { RIG_MODEL(RIG_MODEL_DELTAII), .model_name = "Delta II", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = DELTAII_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .str_cal = DELTAII_STR_CAL, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* TODO: 32 simplex, 16 duplex */ { 0, 47, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* These limits measured on Omni VI SN 1A10473 */ .rx_range_list2 = { {kHz(100), kHz(29999), DELTAII_ALL_RX_MODES, -1, -1, DELTAII_VFO_ALL}, RIG_FRNG_END, }, /* Note: There is no AM mode. */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(3500), MHz(4) - 1, DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(7), kHz(7300), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(10100), kHz(10150), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(14), kHz(14350), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(18068), kHz(18168), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(21), kHz(21450), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(24890), kHz(24990), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(28), kHz(29700), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {DELTAII_ALL_RX_MODES, Hz(10)}, // This radio has 10 Hz steps. RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& delta2_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // icom.c has no get_vfo .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic820h.c0000664000175000017500000001317715056640443011521 /* * Hamlib CI-V backend - description of IC-820H (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #define IC820H_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC820H_VFO_ALL (RIG_VFO_A|RIG_VFO_C|RIG_VFO_MEM) /* FIXME: What about MAIN/SUB mode? And satellite mode? */ #define IC820H_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC820H_SCAN_OPS (RIG_SCAN_MEM) /* FIXME: Manual talks about 3 modes: Programmed scan, Memory scan and * Mode select memory scan operation. How do i encode these? */ #define IC820H_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic820h_priv_caps = { 0x42, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic820h_caps = { RIG_MODEL(RIG_MODEL_IC820), .model_name = "IC-820H", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* Attenuator 15dB for each band. manual button */ .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ .targetable_vfo = 0, .vfo_ops = IC820H_VFO_OPS, .scan_ops = IC820H_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* FIXME: Each band has 80 channels (2*80) ?? */ { 1, 80, RIG_MTYPE_MEM }, { 81, 82, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(136), MHz(174), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, {MHz(430), MHz(450), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), RIG_MODE_SSB, W(6), W(35), IC820H_VFO_ALL}, {MHz(144), MHz(146), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC820H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_SSB, W(6), W(30), IC820H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC820H_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(136), MHz(174), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, {MHz(430), MHz(450), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, RIG_FRNG_END, }, /* * From manual: VHF UHF * USA 144.0-148.0 MHz 430.0-450.0 MHz * Europe 144.0-146.0 MHz 430.0-440.0 MHz * Australia 144.0-148.0 MHz 430.0-450.0 MHz * Sweden 144.0-146.0 MHz 432.0-438.0 MHz */ .tx_range_list2 = { {MHz(144), MHz(148), RIG_MODE_SSB, W(6), W(35), IC820H_VFO_ALL}, {MHz(144), MHz(148), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC820H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_SSB, W(6), W(30), IC820H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC820H_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */ {RIG_MODE_FM, kHz(15)}, /* builtin */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic820h_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7410.c0000664000175000017500000002502115056640443011422 /* * Hamlib CI-V backend - description of IC-7410 * Copyright (c) 2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "tones.h" #define IC7410_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7410_AM_TX_MODES (RIG_MODE_AM) #define IC7410_ALL_RX_MODES IC7410_OTHER_TX_MODES | IC7410_AM_TX_MODES #define IC7410_1HZ_TS_MODES IC7410_ALL_RX_MODES #define IC7410_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_TUNER) #define IC7410_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_AGC_TIME) #define IC7410_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7410_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7410_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7410_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7410_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Guess from IC7600 */ #define IC7410_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 124, 0 }, /* S9 */ \ { 246, 60 } /* S9+60dB */ \ } } #define IC7410_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7410_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7410_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } struct cmdparams ic7410_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 1, {0x75 }, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x75}, CMD_DAT_INT, 1 }, { {0} } }; /* * IC-7410 rig capabilities. */ static const struct icom_priv_caps ic7410_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .data_mode_supported = 1, }; struct rig_caps ic7410_caps = { RIG_MODEL(RIG_MODEL_IC7410), .model_name = "IC-7410", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7410_FUNCS, .has_set_func = IC7410_FUNCS, .has_get_level = IC7410_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7410_LEVELS), .has_get_parm = IC7410_PARMS, .has_set_parm = RIG_PARM_SET(IC7410_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7410_VFO_OPS, .scan_ops = IC7410_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7410_ALL_RX_MODES, -1, -1, IC7410_VFOS, IC7410_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_6m(1, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_HF(1, IC7410_AM_TX_MODES, W(1), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7410_AM_TX_MODES, W(1), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7410_ALL_RX_MODES, -1, -1, IC7410_VFOS, IC7410_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_6m(2, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_HF(2, IC7410_AM_TX_MODES, W(2), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7410_AM_TX_MODES, W(2), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7410_1HZ_TS_MODES, 1}, {IC7410_ALL_RX_MODES, Hz(100)}, {IC7410_ALL_RX_MODES, kHz(1)}, {IC7410_ALL_RX_MODES, kHz(5)}, {IC7410_ALL_RX_MODES, kHz(9)}, {IC7410_ALL_RX_MODES, kHz(10)}, {IC7410_ALL_RX_MODES, kHz(12.5)}, {IC7410_ALL_RX_MODES, kHz(20)}, {IC7410_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(350)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(8)}, /* TBC */ RIG_FLT_END, }, .str_cal = IC7410_STR_CAL, .swr_cal = IC7410_SWR_CAL, .alc_cal = IC7410_ALC_CAL, .rfpower_meter_cal = IC7410_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7410_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic821h.c0000664000175000017500000001566015056640443011521 /* * Hamlib CI-V backend - description of IC-821H (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "misc.h" #define IC821H_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC821H_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM|RIG_VFO_MAIN|RIG_VFO_SUB) /* FIXME: What about MAIN/SUB mode? And satellite mode? */ #define IC821H_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC821H_SCAN_OPS (RIG_SCAN_MEM) /* FIXME: Manual talks about 3 modes: Programmed scan, Memory scan and * Mode select memory scan operation. How do i encode these? */ #define IC821H_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic821h_priv_caps = { 0x4c, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; // split could be on VFOA/B or Main/Sub // If Main/Sub we assume we're doing satmode int ic821h_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval = -RIG_EINTERNAL; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, split=%d, tx_vfo=%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(tx_vfo)); if (tx_vfo == RIG_VFO_MAIN) { CACHE(rig)->satmode = split; // we emulate satmode of other rigs since we apparently can't query rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo==MAIN so assuming sat mode=%d\n", __func__, CACHE(rig)->satmode); STATE(rig)->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_SUB : RIG_VFO_MAIN; // the IC821 seems to be backwards in satmode -- setting Main select Sub and vice versa retval = rig_set_vfo(rig, RIG_VFO_SUB); } else if (tx_vfo == RIG_VFO_A) { retval = rig_set_vfo(rig, RIG_VFO_A); STATE(rig)->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_ERR, "%s: vfo=%s not handled for split mode\n", __func__, rig_strvfo(tx_vfo)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } struct rig_caps ic821h_caps = { RIG_MODEL(RIG_MODEL_IC821H), .model_name = "IC-821H", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* Attenuator 15dB for each band. manual button */ .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ .targetable_vfo = 0, .vfo_ops = IC821H_VFO_OPS, .scan_ops = IC821H_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* FIXME: Each band has 80 channels (2*80) */ { 1, 80, RIG_MTYPE_MEM }, { 81, 82, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(136), MHz(174), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, {MHz(430), MHz(450), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), RIG_MODE_SSB, W(6), W(35), IC821H_VFO_ALL}, {MHz(144), MHz(146), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC821H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_SSB, W(6), W(30), IC821H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC821H_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(136), MHz(174), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, {MHz(430), MHz(450), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, RIG_FRNG_END, }, /* * From manual: VHF UHF * USA 144.0-148.0 MHz 430.0-450.0 MHz * Europe 144.0-146.0 MHz 430.0-440.0 MHz * Australia 144.0-148.0 MHz 430.0-450.0 MHz * Sweden 144.0-146.0 MHz 432.0-438.0 MHz */ .tx_range_list2 = { {MHz(144), MHz(148), RIG_MODE_SSB, W(6), W(35), IC821H_VFO_ALL}, {MHz(144), MHz(148), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC821H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_SSB, W(6), W(30), IC821H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC821H_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* built-in */ {RIG_MODE_FM, kHz(15)}, /* built-in */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic821h_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = ic821h_set_split_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic761.c0000664000175000017500000001645615056640443011360 /* * Hamlib CI-V backend - description of IC-761 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC761_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC761_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC761_AM_TX_MODES (RIG_MODE_AM) #define IC761_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC761_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC761_SCAN_OPS (RIG_SCAN_NONE) #define IC761_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic761_priv_caps = { 0x1e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic761_caps = { RIG_MODEL(RIG_MODEL_IC761), .model_name = "IC-761", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC761_VFO_OPS, .scan_ops = IC761_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC761_ALL_RX_MODES, -1, -1, IC761_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(1.99999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC761_ALL_RX_MODES, -1, -1, IC761_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {MHz(1.8), MHz(1.99999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC761_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic761_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icr10.c0000664000175000017500000001043415056640443011433 /* * Hamlib CI-V backend - description of IC-R10 * Copyright (c) 2000-2004 by Stephane Fillod * Copyright (c) 2017 Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICR10_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR10_FUNC_ALL (RIG_FUNC_NONE) #define ICR10_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICR10_VFO_ALL (RIG_VFO_A) #define ICR10_VFO_OPS (RIG_OP_NONE) #define ICR10_SCAN_OPS (RIG_SCAN_NONE) #define ICR10_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 160, 60 } /* +60 */ \ } } static struct icom_priv_caps icr10_priv_caps = { 0x52, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icr10_caps = { RIG_MODEL(RIG_MODEL_ICR10), .model_name = "IC-R10", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR10_FUNC_ALL, .has_set_func = ICR10_FUNC_ALL, .has_get_level = ICR10_LEVEL_ALL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR10_VFO_OPS, .scan_ops = ICR10_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), GHz(1.3), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(823.9999), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, {MHz(849), MHz(868.9999), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, {MHz(894), GHz(1.3), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR10_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(4)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR10_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr10_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic703.c0000664000175000017500000001706215056640443011346 /* * Hamlib CI-V backend - description of IC-703 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "bandplan.h" #include "idx_builtin.h" #include "tones.h" #define IC703_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC703_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC703_AM_TX_MODES (RIG_MODE_AM) #define IC703_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_MON) #define IC703_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_METER|RIG_LEVEL_COMP|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_NR|RIG_LEVEL_IF|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT) #define IC703_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC703_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC703_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) #define IC703_ANTS (RIG_ANT_1) /* * IC703_REAL_STR_CAL is accurate measurements * IC703_STR_CAL is what the S-meter displays * * FIXME: calibration data cloned from IC706 */ #define IC703_STR_CAL { 17, \ { \ { 45, -60 }, \ { 46, -54 }, /* S0 */ \ { 54, -48 }, \ { 64, -42 }, \ { 76, -36 }, \ { 84, -30 }, \ { 94, -24 }, \ { 104, -18 }, \ { 113, -12 }, \ { 123, -6 }, \ { 133, 0 }, /* S9 */ \ { 144, 10 }, /* +10 */ \ { 156, 20 }, /* +20 */ \ { 170, 30 }, /* +30 */ \ { 181, 40 }, /* +40 */ \ { 192, 50 }, /* +50 */ \ { 204, 60 } /* +60 */ \ } } /* * ic703 rigs capabilities. */ static const struct icom_priv_caps ic703_priv_caps = { 0x68, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list }; struct rig_caps ic703_caps = { RIG_MODEL(RIG_MODEL_IC703), .model_name = "IC-703", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC703_FUNC_ALL, .has_set_func = IC703_FUNC_ALL, .has_get_level = IC703_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC703_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: 2 levels */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC703_VFO_OPS, .scan_ops = IC703_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 105, RIG_MTYPE_EDGE }, /* two by two */ { 106, 107, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC703_ALL_RX_MODES, -1, -1, IC703_VFO_ALL, IC703_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_6m(1, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_HF(1, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ FRQ_RNG_6m(1, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC703_ALL_RX_MODES, -1, -1, IC703_VFO_ALL, IC703_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_6m(2, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_HF(2, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ FRQ_RNG_6m(2, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC703_ALL_RX_MODES, 10}, {IC703_ALL_RX_MODES, 100}, {IC703_ALL_RX_MODES, kHz(1)}, {IC703_ALL_RX_MODES, kHz(5)}, {IC703_ALL_RX_MODES, kHz(9)}, {IC703_ALL_RX_MODES, kHz(10)}, {IC703_ALL_RX_MODES, 12500}, {IC703_ALL_RX_MODES, kHz(20)}, {IC703_ALL_RX_MODES, kHz(25)}, {IC703_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(9)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(9)}, /* narrow w/ builtin FL-94 */ RIG_FLT_END, }, .str_cal = IC703_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic703_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icr6.c0000664000175000017500000001216415056640443011362 /* * Hamlib CI-V backend - description of IC-R6 * Copyright (c) 2017 Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #include "tones.h" #define ICR6_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICR6_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_VSC|RIG_FUNC_CSQL|RIG_FUNC_AFLT|RIG_FUNC_DSQL) #define ICR6_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR6_VFO_ALL (RIG_VFO_A) #define ICR6_VFO_OPS (RIG_OP_NONE) #define ICR6_SCAN_OPS (RIG_SCAN_NONE) #define ICR6_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } static struct icom_priv_caps icr6_priv_caps = { 0x7e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list, /* wrong, but don't have set_ts anyway */ .antack_len = 2, .ant_count = 2 }; struct rig_caps icr6_caps = { RIG_MODEL(RIG_MODEL_ICR6), .model_name = "IC-R6", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR6_FUNC_ALL, .has_set_func = ICR6_FUNC_ALL, .has_get_level = ICR6_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR6_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR6_VFO_OPS, .scan_ops = ICR6_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = {RIG_CHAN_END,}, .rx_range_list1 = { /* Other countries but France */ {kHz(100), GHz(1.309995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(100), MHz(821.995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, {MHz(851), MHz(866.995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, {MHz(896), GHz(1.309995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR6_MODES, Hz(5000)}, {ICR6_MODES, Hz(6250)}, {ICR6_MODES, Hz(8330)}, // Air band only {ICR6_MODES, Hz(9000)}, // AM broadcast band only {ICR6_MODES, Hz(10000)}, {ICR6_MODES, Hz(12500)}, {ICR6_MODES, kHz(15)}, {ICR6_MODES, kHz(20)}, {ICR6_MODES, kHz(25)}, {ICR6_MODES, kHz(30)}, {ICR6_MODES, kHz(50)}, {ICR6_MODES, kHz(100)}, {ICR6_MODES, kHz(125)}, {ICR6_MODES, kHz(200)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR6_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr6_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .get_dcd = icom_get_dcd, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7300.c0000664000175000017500000025013715056640443011430 /* * Hamlib CI-V backend - description of IC-7300 and variations * Adapted by J.Watson from IC-7000 code (c) 2004 by Stephane Fillod * Adapted from IC-7200 (c) 2016 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "token.h" #include "frame.h" #include "icom.h" #include "icom_defs.h" #include "misc.h" #include "bandplan.h" #include "tones.h" #include "ic7300.h" static int ic7300_set_parm(RIG *rig, setting_t parm, value_t val); static int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val); int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int ic9700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic9700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int ic9700_set_vfo(RIG *rig, vfo_t vfo); #define IC7300_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define IC7300_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM) #define IC7300_NOT_TS_MODES (IC7300_ALL_RX_MODES &~IC7300_1HZ_TS_MODES) #define IC7300_OTHER_TX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7300_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7300_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SCOPE|RIG_FUNC_TUNER|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_SEND_MORSE|RIG_FUNC_SEND_VOICE_MEM|RIG_FUNC_OVF_STATUS) #define IC7300_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define IC7300_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) // RIG_PARM_BANDSELECT disabled until Icom can describe the return from 0x1a 0x01 //#define IC7300_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_BANDSELECT) #define IC7300_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_SCREENSAVER|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF) #define IC7300_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7300_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_VFO) #define IC7300_ANTS (RIG_ANT_1) /* ant-1 is Hf-6m */ /* * IC-7300 S-meter levels measured from live signals on multiple bands. Provides a good approximation. */ #define IC7300_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } #define IC7300_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7300_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7300_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7300_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7300_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC7300_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } /* * IC905 items that differ from IC7300 */ #define IC905_VFO_OPS (RIG_OP_CPY|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) /* * IC705 items that differ from IC7300 */ #define IC705_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_SCREENSAVER|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF|RIG_PARM_AFIF_WLAN) #define IC705_ALL_TX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR) #define IC705_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM|RIG_MODE_DSTAR|RIG_MODE_WFM) #define IC705_OTHER_TX_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR) #define IC705_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH) #define IC705_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 0.50f }, \ { 43, 1.00f }, \ { 65, 1.50f }, \ { 83, 2.00f }, \ { 95, 2.50f }, \ { 105, 3.00f }, \ { 114, 3.50f }, \ { 124, 4.00f }, \ { 143, 5.00f }, \ { 183, 7.50f }, \ { 213, 10.0f }, \ { 255, 12.0f } \ } } // flrig-2.0.05.93 #define IC705_COMP_METER_CAL { 12, \ { \ { 0, 0.0f }, \ { 11, 0.0f }, \ { 34, 3.0f }, \ { 58, 6.0f }, \ { 81, 9.0f }, \ { 104, 12.0f }, \ { 128, 15.0f }, \ { 151, 18.0f }, \ { 174, 21.0f }, \ { 197, 24.0f }, \ { 221, 27.0f }, \ { 244, 30.0f } \ } } // flrig-2.0.05.93 #define IC705_VD_METER_CAL { 2, \ { \ { 0, 0.0f }, \ { 241, 16.0f } \ } } // flrig-2.0.05.93 #define IC705_ID_METER_CAL { 2, \ { \ { 0, 0.0f }, \ { 241, 4.0f } \ } } /* * IC9700 items that differ from IC7300 */ #define IC9700_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) // RIG_PARM_BANDSELECT disabled until Icom can describe the return from 0x1a 0x01 //#define IC9700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_SCREENSAVER|RIG_PARM_BANDSELECT) #define IC9700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_SCREENSAVER|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF|RIG_PARM_AFIF_LAN|RIG_PARM_AFIF_ACC) #define IC9700_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_SCOPE|RIG_FUNC_SATMODE|RIG_FUNC_DUAL_WATCH|RIG_FUNC_AFC|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_SEND_MORSE|RIG_FUNC_SEND_VOICE_MEM|RIG_FUNC_OVF_STATUS) #define IC9700_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define IC9700_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC9700_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define IC9700_ALL_TX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) #define IC9700_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) #define IC9700_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } #define IC9700_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC9700_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC9700_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC9700_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 210, 25.5f } \ } } #define IC9700_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC9700_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 121, 10.0f }, \ { 241, 20.0f } \ } } struct cmdparams ic7300_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x23}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x81}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x89}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x95}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x59}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x59}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x71}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x02}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x60}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_BANDSELECT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_BAND_REG, SC_MOD_RW, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x64}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; struct cmdparams ic9700_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x29}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x52}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x67}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x80}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x05}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_ACC}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x00}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_LAN}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x10}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x30}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x27}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x92}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x06}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x27}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; struct cmdparams ic705_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x31}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x36}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x38}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x66}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x09}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_WLAN}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x14}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x59}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x31}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x78}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x13}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x55}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; int ic7300_ext_tokens[] = { TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_BACKEND_NONE, }; int ic9700_ext_tokens[] = { TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_MKP, TOK_BACKEND_NONE, }; int ic705_ext_tokens[] = { TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_BACKEND_NONE, }; /* * IC-7300 rig capabilities. */ static const struct icom_priv_caps IC7300_priv_caps = { 0x94, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic7300_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, // note this is handled by AGC time constant instead { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic7300_extcmds, /* Custom op parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1, .fm_filters = { 7000, 10000, 15000 } }; static const struct icom_priv_caps IC9700_priv_caps = { 0xA2, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic9700_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, // note this is handled by AGC time constant instead { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 144000000, .high_freq = 148000000, }, { .range_id = 2, .low_freq = 430000000, .high_freq = 450000000, }, { .range_id = 3, .low_freq = 1240000000, .high_freq = 1300000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic9700_extcmds, /* Custom op parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1, }; static const struct icom_priv_caps IC705_priv_caps = { 0xA4, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic705_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 14, .low_freq = 74800000, .high_freq = 108000000, }, { .range_id = 15, .low_freq = 108000000, .high_freq = 137000000, }, { .range_id = 16, .low_freq = 137000000, .high_freq = 200000000, }, { .range_id = 17, .low_freq = 400000000, .high_freq = 470000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic705_extcmds, /* Custom parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1, .fm_filters = { 7000, 10000, 15000 } }; static const struct icom_priv_caps IC905_priv_caps = { 0xAC, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic705_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 14, .low_freq = 74800000, .high_freq = 108000000, }, { .range_id = 15, .low_freq = 108000000, .high_freq = 137000000, }, { .range_id = 16, .low_freq = 137000000, .high_freq = 200000000, }, { .range_id = 17, .low_freq = 400000000, .high_freq = 470000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic705_extcmds, /* Custom parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7300_caps = { RIG_MODEL(RIG_MODEL_IC7300), .model_name = "IC-7300", .mfg_name = "Icom", .version = BACKEND_VER ".14", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC7300_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7300_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7300_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7300_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 1, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(74.8), IC7300_ALL_RX_MODES, -1, -1, IC7300_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_60m(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_4m(1, IC7300_OTHER_TX_MODES, W(2), W(50), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_HF(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_60m(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_4m(1, IC7300_AM_TX_MODES, W(1), W(12.5), IC7300_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(1)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC7300_RFPOWER_METER_CAL, .comp_meter_cal = IC7300_COMP_METER_CAL, .vd_meter_cal = IC7300_VD_METER_CAL, .id_meter_cal = IC7300_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7300_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic7300_set_parm, .get_parm = ic7300_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic7300_set_clock, .get_clock = ic7300_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic9700_caps = { RIG_MODEL(RIG_MODEL_IC9700), .model_name = "IC-9700", .mfg_name = "Icom", .version = BACKEND_VER ".20", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC9700_FUNCS, .has_set_func = IC9700_FUNCS, .has_get_level = IC9700_LEVELS, .has_set_level = RIG_LEVEL_SET(IC9700_LEVELS), .has_get_parm = IC9700_PARMS, .has_set_parm = RIG_PARM_SET(IC9700_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic9700_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC9700_VFO_OPS, .scan_ops = IC9700_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 3, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, // Hopefully any future changes in bandplans can be fixed with firmware updates // So we use the global REGION2 macros in here .rx_range_list1 = { // USA Version -- United States {MHz(144), MHz(148), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(148), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(144), MHz(148), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "USA"}, RIG_FRNG_END, }, .rx_range_list2 = { // EUR Version -- Europe {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, RIG_FRNG_END, }, .rx_range_list3 = { // ITR Version -- Italy {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, RIG_FRNG_END, }, .tx_range_list3 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, RIG_FRNG_END, }, .rx_range_list4 = { // TPE Version -- Taiwan ?? {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, RIG_FRNG_END, }, .tx_range_list4 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, RIG_FRNG_END, }, .rx_range_list5 = { // KOR Version -- Republic of Korea {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, RIG_FRNG_END, }, .tx_range_list5 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, RIG_FRNG_END, }, .tuning_steps = { {IC9700_ALL_RX_MODES, Hz(1)}, {IC9700_ALL_RX_MODES, Hz(10)}, {IC9700_ALL_RX_MODES, Hz(100)}, {IC9700_ALL_RX_MODES, Hz(500)}, {IC9700_ALL_RX_MODES, kHz(1)}, {IC9700_ALL_RX_MODES, kHz(5)}, {IC9700_ALL_RX_MODES, kHz(6.25)}, {IC9700_ALL_RX_MODES, kHz(10)}, {IC9700_ALL_RX_MODES, kHz(12.5)}, {IC9700_ALL_RX_MODES, kHz(20)}, {IC9700_ALL_RX_MODES, kHz(25)}, {IC9700_ALL_RX_MODES, kHz(50)}, {IC9700_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, RIG_FLT_END, }, .str_cal = IC9700_STR_CAL, .swr_cal = IC9700_SWR_CAL, .alc_cal = IC9700_ALC_CAL, .rfpower_meter_cal = IC9700_RFPOWER_METER_CAL, .comp_meter_cal = IC9700_COMP_METER_CAL, .vd_meter_cal = IC9700_VD_METER_CAL, .id_meter_cal = IC9700_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC9700_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // IC-9700 can indicate Main/Sub band selection, but not VFO A/B, so leave get_vfo not implemented // .get_vfo = icom_get_vfo, .set_vfo = ic9700_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .get_powerstat = icom_get_powerstat, .set_powerstat = icom_set_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic9700_set_clock, .get_clock = ic9700_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic705_caps = { RIG_MODEL(RIG_MODEL_IC705), .model_name = "IC-705", .mfg_name = "Icom", .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC705_LEVELS, .has_set_level = RIG_LEVEL_SET(IC705_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDWFM,BANDAIR,BAND70CM,BAND33CM,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, }, .ext_tokens = ic705_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7300_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(400), MHz(470), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1800), MHz(1.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(3.5), MHz(3.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(5.255), MHz(5.405), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(7.0), MHz(7.3), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(10.1), MHz(10.15), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(14.0), MHz(14.35), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(18.068), MHz(18.168), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(21.00), MHz(21.45), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(24.89), MHz(24.99), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(28.00), MHz(29.70), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(50.00), MHz(54.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(144.00), MHz(148.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(430.00), MHz(450.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(400), MHz(470), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(1810), MHz(1.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(3.5), MHz(3.8), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(7.0), MHz(7.2), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(10.1), MHz(10.15), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(14.0), MHz(14.35), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(18.068), MHz(18.168), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(21.00), MHz(21.45), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(24.89), MHz(24.99), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(28.00), MHz(29.70), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(50.00), MHz(52.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(144.00), MHz(146.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(430.00), MHz(440.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(100)}, {IC7300_ALL_RX_MODES, kHz(.5)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(6.25)}, {IC7300_ALL_RX_MODES, kHz(8.33)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, {IC7300_ALL_RX_MODES, kHz(50)}, {IC7300_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_WFM, kHz(200)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC705_RFPOWER_METER_CAL, .comp_meter_cal = IC705_COMP_METER_CAL, .vd_meter_cal = IC705_VD_METER_CAL, .id_meter_cal = IC705_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC705_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // powerstat is write only .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic905_caps = { RIG_MODEL(RIG_MODEL_IC905), .model_name = "IC-905", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 230400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC705_LEVELS, .has_set_level = RIG_LEVEL_SET(IC705_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC705_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM,BAND23CM,BAND13CM,BAND3CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic705_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC905_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(148), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(430), MHz(450), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(1240), MHz(1300), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(2300), MHz(2309.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(5650), MHz(5925), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(10000), MHz(10500), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(144), MHz(148), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(430), MHz(450), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(1240), MHz(1300), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(2300), MHz(2309.999999), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(2390.000001), MHz(2450), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(5650), MHz(5925), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(10000), MHz(10500), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(146), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(430), MHz(440), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(1240), MHz(1300), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(2300), MHz(2450), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(5650), MHz(5850), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(10000), MHz(10500), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list2 = { { MHz(144), MHz(148), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(430), MHz(450), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(1240), MHz(1300), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(2300), MHz(2309.999999), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(2390), MHz(2450), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(5650), MHz(5925), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(10000), MHz(10500), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(100)}, {IC7300_ALL_RX_MODES, kHz(.5)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(6.25)}, {IC7300_ALL_RX_MODES, kHz(8.33)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, {IC7300_ALL_RX_MODES, kHz(50)}, {IC7300_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC705_RFPOWER_METER_CAL, .comp_meter_cal = IC7300_COMP_METER_CAL, .vd_meter_cal = IC7300_VD_METER_CAL, .id_meter_cal = IC7300_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC905_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS, }; int ic7300_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_ANN: { int ann_mode = -1; int ann_lang = -1; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; case RIG_ANN_ENG: case RIG_ANN_JAP: ann_lang = (val.i == RIG_ANN_ENG) ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } if (ann_mode >= 0) { return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); } else if (ann_lang >= 0) { unsigned char prmbuf[MAXFRAMELEN]; prmbuf[0] = 0x1a; prmbuf[1] = 0x05; switch (rig->caps->rig_model) { case RIG_MODEL_IC7300: prmbuf[2] = 0x00; prmbuf[3] = 0x39; break; case RIG_MODEL_IC9700: prmbuf[2] = 0x01; prmbuf[3] = 0x77; break; case RIG_MODEL_IC705: prmbuf[2] = 0x00; prmbuf[3] = 0x53; break; default: return -RIG_ENIMPL; } prmbuf[4] = ann_lang; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 5, prmbuf, 0, 0); } rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } default: return icom_set_parm(rig, parm, val); } } int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val) { const unsigned char prmbuf[MAXFRAMELEN]; unsigned char resbuf[MAXFRAMELEN]; int prm_len = 0, res_len; int prm_cn = 0, prm_sc = 0; int icom_val = 0; int cmdhead; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { #if 0 case RIG_PARM_ANN: return -RIG_ENIMPL; // How can we implement this? #endif default: rig_debug(RIG_DEBUG_TRACE, "%s: using icom routine for PARM=%s\n", __func__, rig_strparm(parm)); return icom_get_parm(rig, parm, val); } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, resbuf, &res_len); if (retval != RIG_OK) { return retval; } cmdhead = 3; res_len -= cmdhead; if (resbuf[0] != ACK && resbuf[0] != prm_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } switch (parm) { #if 0 case RIG_PARM_ANN: rig_debug(RIG_DEBUG_WARN, "%s: not implemented\n", __func__); return -RIG_ENIMPL; #endif default: return icom_get_parm(rig, parm, val); } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } // if hour < 0 then only date will be set int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x94; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x95; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x96; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x94; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x95; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x96; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } // if hour < 0 then only date will be set int ic9700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x79; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x80; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x01; prmbuf[1] = 0x84; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic9700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x01; prmbuf[1] = 0x79; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x01; prmbuf[1] = 0x80; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x01; prmbuf[1] = 0x84; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } int ic9700_set_vfo(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; int vfo_is_main_or_sub = (vfo == RIG_VFO_MAIN) || (vfo == RIG_VFO_SUB); struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (cachep->satmode && !vfo_is_main_or_sub) { // Translate VFO A/B to Main/Sub in satellite mode if (vfo == RIG_VFO_A) { vfo = RIG_VFO_MAIN; } else if (vfo == RIG_VFO_B) { vfo = RIG_VFO_SUB; } else { rig_debug(RIG_DEBUG_ERR, "%s: Invalid VFO %s in satellite mode\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } } if (vfo == RIG_VFO_A) { retval = icom_transaction(rig, C_SET_VFO, S_VFOA, NULL, 0, ackbuf, &ack_len); } else if (vfo == RIG_VFO_B) { if (cachep->satmode) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } retval = icom_transaction(rig, C_SET_VFO, S_VFOB, NULL, 0, ackbuf, &ack_len); } else if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_MAIN_A || vfo == RIG_VFO_MAIN_B) { // First switch to Main receiver retval = icom_transaction(rig, C_SET_VFO, S_MAIN, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (cachep->satmode && vfo == RIG_VFO_MAIN_B) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_MAIN_A || vfo == RIG_VFO_MAIN_B) { int subcmd = vfo == RIG_VFO_MAIN_A ? S_VFOA : S_VFOB; retval = icom_transaction(rig, C_SET_VFO, subcmd, NULL, 0, ackbuf, &ack_len); } } else if (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B) { // First switch to Sub receiver retval = icom_transaction(rig, C_SET_VFO, S_SUB, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (cachep->satmode && vfo == RIG_VFO_SUB_B) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B) { HAMLIB_TRACE; int subcmd = vfo == RIG_VFO_SUB_A ? S_VFOA : S_VFOB; retval = icom_transaction(rig, C_SET_VFO, subcmd, NULL, 0, ackbuf, &ack_len); } } else if (vfo == RIG_VFO_MEM) { RETURNFUNC(icom_set_vfo(rig, vfo)); } else { // Unsupported VFO RETURNFUNC(-RIG_EINVAL); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } RETURNFUNC(retval); } hamlib-4.6.5/rigs/icom/ic970.c0000664000175000017500000001151715056640443011353 /* * Hamlib CI-V backend - description of IC-970 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #define IC970_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC970_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC970_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC970_STR_CAL { 0, { } } /* * FIXME: this appears to be the IC-970A/E * what about the IC-970H ? please give it a fix. --SF */ static const struct icom_priv_caps ic970_priv_caps = { 0x2e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic970_caps = { RIG_MODEL(RIG_MODEL_IC970), .model_name = "IC-970", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC970_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, { 102, 102, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), IC970_MODES, -1, -1, IC970_VFO_ALL}, {MHz(430), MHz(440), IC970_MODES, -1, -1, IC970_VFO_ALL}, /* 1200MHz band module is optional */ // {MHz(1240),MHz(1300),IC970_MODES,-1,-1,IC970_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, {MHz(430), MHz(440), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, // {MHz(1240),MHz(1300),IC970_MODES,W(1),W(10),IC970_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(150), IC970_MODES, -1, -1, IC970_VFO_ALL}, {MHz(430), MHz(450), IC970_MODES, -1, -1, IC970_VFO_ALL}, /* 1200MHz band module is optional */ // {MHz(1240),MHz(1300),IC970_MODES,-1,-1,IC970_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(150), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, {MHz(430), MHz(450), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, // {MHz(1240),MHz(1300),IC970_MODES,W(1),W(10),IC970_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC970_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, // {RIG_MODE_FM, Hz(500)}, /* optional CW NARROW FILTER */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic970_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7300.h0000664000175000017500000000055315056640443011430 #include "rig.h" extern int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); extern int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); hamlib-4.6.5/rigs/icom/icr20.c0000664000175000017500000001122715056640443011435 /* * Hamlib CI-V backend - description of IC-R20 * Copyright (c) 2004 by Stephane Fillod * Copyright (c) 2004 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICR20_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR20_FUNC_ALL (RIG_FUNC_NONE) #define ICR20_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICR20_VFO_ALL (RIG_VFO_A) #define ICR20_VFO_OPS (RIG_OP_NONE) #define ICR20_SCAN_OPS (RIG_SCAN_NONE) #define ICR20_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } static struct icom_priv_caps icr20_priv_caps = { 0x6c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icr20_caps = { RIG_MODEL(RIG_MODEL_ICR20), .model_name = "IC-R20", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR20_FUNC_ALL, .has_set_func = ICR20_FUNC_ALL, .has_get_level = ICR20_LEVEL_ALL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR20_VFO_OPS, .scan_ops = ICR20_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* Only through cloning mode OPC-1382 */ .chan_list = { { 1, 999, RIG_MTYPE_MEM }, /* TBC */ { 1000, 1199, RIG_MTYPE_MEM }, /* auto-write */ { 1200, 1249, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { /* Other countries but France */ {kHz(150), GHz(3.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(150), MHz(821.999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {MHz(851), MHz(866.999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {MHz(896), GHz(1.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {GHz(1.305), GHz(3.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR20_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.8)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR20_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr20_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, /* .set_vfo = icom_set_vfo, */ .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7200.c0000664000175000017500000002654015056640443011426 /* * Hamlib CI-V backend - description of IC-7200 and variations * Adapted by J.Watson from IC-7000 code (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * 26Mar09: Corrected tuning steps and added data modes. * 25Mar09: Initial release */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" /* AM Data mode needs adding - this would require one more mode 'RIG_MODE_PKTAM' to rig.h */ #define IC7200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define IC7200_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define IC7200_NOT_TS_MODES (IC7200_ALL_RX_MODES &~IC7200_1HZ_TS_MODES) #define IC7200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7200_AM_TX_MODES (RIG_MODE_AM) #define IC7200_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_ARO|RIG_FUNC_TUNER) #define IC7200_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_NB) #define IC7200_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7200_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7200_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7200_ANTS (RIG_ANT_1) /* ant-1 is Hf-6m */ #define IC7200_STR_CAL { 3, \ { \ { 0, -54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7200_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7200_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7200_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * IC-7200 rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps IC7200_priv_caps = { 0x76, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_SLOW, .icom_level = 2 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .x25x26_always = 0, .x25x26_possibly = 0, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7200_caps = { RIG_MODEL(RIG_MODEL_IC7200), .model_name = "IC-7200", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7200_FUNCS, .has_set_func = IC7200_FUNCS, .has_get_level = IC7200_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7200_LEVELS), .has_get_parm = IC7200_PARMS, .has_set_parm = RIG_PARM_SET(IC7200_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess */ .attenuator = { 20, RIG_DBLST_END, }, /* value taken from p.45 of manual*/ .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7200_VFO_OPS, .scan_ops = IC7200_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 1, .chan_desc_sz = 0, .chan_list = { { 1, 199, RIG_MTYPE_MEM }, { 200, 201, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7200_ALL_RX_MODES, -1, -1, IC7200_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_HF(1, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7200_ALL_RX_MODES, -1, -1, IC7200_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_HF(2, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC7200_1HZ_TS_MODES, 1}, {IC7200_NOT_TS_MODES, 10}, {IC7200_ALL_RX_MODES, Hz(100)}, {IC7200_ALL_RX_MODES, kHz(1)}, {IC7200_ALL_RX_MODES, kHz(5)}, {IC7200_ALL_RX_MODES, kHz(9)}, {IC7200_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC7200_STR_CAL, .swr_cal = IC7200_SWR_CAL, .alc_cal = IC7200_ALC_CAL, .rfpower_meter_cal = IC7200_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7200_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = ic7200_set_level, .get_level = ic7200_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { unsigned char cmdbuf[MAXFRAMELEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: cmdbuf[0] = 0x55; return icom_set_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmdbuf[MAXFRAMELEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: cmdbuf[0] = 0x55; return icom_get_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, val); default: return icom_get_level(rig, vfo, level, val); } } hamlib-4.6.5/rigs/icom/ic7100.c0000664000175000017500000004614615056640443011431 /* * Hamlib CI-V backend - description of IC-9100 (HF/VHF/UHF All-Mode Transceiver) * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" #include "bandplan.h" #include "token.h" #include "tones.h" #include "misc.h" #define IC7100_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM|\ RIG_MODE_DSTAR) #define IC7100_OTHER_TX_MODES ((IC7100_MODES) & ~(RIG_MODE_AM|RIG_MODE_PKTAM)) #define IC7100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7100_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7100_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG| \ RIG_OP_TUNE) #define IC7100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_VSC| \ RIG_FUNC_MN| \ RIG_FUNC_LOCK| \ RIG_FUNC_SCOPE| \ RIG_FUNC_TUNER) #define IC7100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_APF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SWR| \ RIG_LEVEL_ALC| \ RIG_LEVEL_RFPOWER_METER| \ RIG_LEVEL_RFPOWER_METER_WATTS| \ RIG_LEVEL_COMP_METER| \ RIG_LEVEL_VD_METER| \ RIG_LEVEL_ID_METER| \ RIG_LEVEL_MONITOR_GAIN| \ RIG_LEVEL_NB | \ RIG_LEVEL_AGC_TIME) //#define IC7100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_BANDSELECT) // BANDSELECT disabled unti we figure out Icom's ability #define IC7100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME) int ic7100_tokens[] = { TOK_DSTAR_CODE, TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_MY_CS, TOK_DSTAR_TX_CS, TOK_DSTAR_TX_MESS, TOK_BACKEND_NONE }; struct cmdparams ic7100_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x03}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x04}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x05}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x21}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x65}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; // IC-7100 S-meter calibration data based on manual #define IC7100_STR_CAL { 14, \ { \ { 0, -54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7100_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7100_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7100_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7100_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7100_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC7100_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } #define IC7100_HF_ANTS (RIG_ANT_1|RIG_ANT_2) /* * IC-7100 rig capabilities. */ static const struct icom_priv_caps ic7100_priv_caps = { 0x88, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7100_ts_sc_list, /* FIXME */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7100_extcmds, .antack_len = 2, .ant_count = 2, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7100_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x20; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x21; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x01; prmbuf[1] = 0x23; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7100_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x01; prmbuf[1] = 0x20; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x01; prmbuf[1] = 0x21; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x01; prmbuf[1] = 0x23; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7100_caps = { RIG_MODEL(RIG_MODEL_IC7100), .model_name = "IC-7100", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 700, .retry = 3, .has_get_func = IC7100_FUNC_ALL, .has_set_func = IC7100_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC7100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC7100_LEVEL_ALL), .has_get_parm = IC7100_PARM_ALL, .has_set_parm = IC7100_PARM_ALL, .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .ext_tokens = ic7100_tokens, .extlevels = icom_ext_levels, .extfuncs = icom_ext_funcs, .extparms = icom_ext_parms, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_KEYLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = {20, RIG_DBLST_END, }, .max_rit = kHz(9.999), .max_xit = kHz(9.999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7100_VFO_OPS, .scan_ops = IC7100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 9, /* TODO */ .chan_list = { /* TBC */ { 1, 396, RIG_MTYPE_MEM }, { 397, 400, RIG_MTYPE_CALL }, { 401, 424, RIG_MTYPE_EDGE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* Europe */ {kHz(30), MHz(60), IC7100_MODES, -1, -1, IC7100_VFO_ALL, IC7100_HF_ANTS}, {kHz(136), MHz(174), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), IC7100_VFO_ALL, IC7100_HF_ANTS), /* only HF */ FRQ_RNG_6m(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_2m(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(1, IC7100_OTHER_TX_MODES, W(2), W(75), IC7100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION1(IC7100_OTHER_TX_MODES, W(1), W(10), IC7100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(30), MHz(60), IC7100_MODES, -1, -1, IC7100_VFO_ALL, IC7100_HF_ANTS}, {kHz(136), MHz(174), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), IC7100_VFO_ALL, IC7100_HF_ANTS), /* only HF */ /* USA only, TBC: end of range and modes */ {MHz(5.255), MHz(5.405), IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS}, /* USA only */ {MHz(5.255), MHz(5.405), RIG_MODE_AM, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS}, /* USA only */ FRQ_RNG_6m(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_2m(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(2, IC7100_OTHER_TX_MODES, W(2), W(75), IC7100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION2(IC7100_OTHER_TX_MODES, W(1), W(10), IC7100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {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(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC7100_STR_CAL, .swr_cal = IC7100_SWR_CAL, .alc_cal = IC7100_ALC_CAL, .rfpower_meter_cal = IC7100_RFPOWER_METER_CAL, .comp_meter_cal = IC7100_COMP_METER_CAL, .vd_meter_cal = IC7100_VD_METER_CAL, .id_meter_cal = IC7100_ID_METER_CAL, .priv = (void *)& ic7100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, .get_mode = icom_get_mode, .set_mode = icom_set_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icom_get_func, .set_func = icom_set_func, .get_level = icom_get_level, .set_level = icom_set_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7100_set_clock, .get_clock = ic7100_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icf8101.c0000664000175000017500000003271115056640443011572 /* * Hamlib CI-V backend - description of IC-F8101 * Copyright (c) 2000-2010 by Stephane Fillod * Copyright (c) 2021 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" static int icf8101_rig_open(RIG *rig) { // turn on VFO mode icom_set_vfo(rig, RIG_VFO_A); return icom_rig_open(rig); } static int icf8101_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; int freq_len = 5; int ack_len; unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; vfo_t vfo_save = STATE(rig)->current_vfo; if (vfo != vfo_save) { rig_set_vfo(rig, vfo); } to_bcd(freqbuf, freq, freq_len * 2); retval = icom_transaction(rig, 0x1a, 0x35, freqbuf, freq_len, ackbuf, &ack_len); if (vfo != vfo_save) { rig_set_vfo(rig, vfo_save); } return retval; } static int icf8101_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char modebuf[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_LSB: modebuf[0] = 0x00; modebuf[1] = 0x00; break; case RIG_MODE_USB: modebuf[0] = 0x00; modebuf[1] = 0x01; break; case RIG_MODE_AM: modebuf[0] = 0x00; modebuf[1] = 0x02; break; case RIG_MODE_CW: modebuf[0] = 0x00; modebuf[1] = 0x03; break; case RIG_MODE_RTTY: modebuf[0] = 0x00; modebuf[1] = 0x04; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode of '%s\n", __func__, rig_strrmode(mode)); return (-RIG_EINVAL); } retval = icom_transaction(rig, 0x1A, 0x36, modebuf, 2, NULL, 0); return retval; } static int icf8101_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval = icom_get_mode(rig, vfo, mode, width); unsigned char modebuf[MAXFRAMELEN]; int modebuf_len; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (retval != RIG_OK) { return retval; } retval = icom_transaction(rig, 0x1A, 0x34, NULL, 0, modebuf, &modebuf_len); if (retval != RIG_OK) { return retval; } dump_hex(modebuf, modebuf_len); switch (modebuf[1]) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_AM; break; case 0x03: *mode = RIG_MODE_CW; break; case 0x04: *mode = RIG_MODE_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode response=0x%02x\n", __func__, modebuf[1]); } return retval; } /* * This function does the special bandwidth coding for IC-F8101 * (1 - normal, 2 - narrow) */ static int icf8101_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } #define ICF8101_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_RTTY) #define ICF8101_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define ICF8101_SCAN_OPS (RIG_SCAN_MEM) #define ICF8101_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC) #define ICF8101_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP) #define ICF8101_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ static const struct icom_priv_caps icf8101_priv_caps = { 0x8A, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ NULL, .r2i_mode = icf8101_r2i_mode }; int icf8101_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { default: return icom_set_func(rig, vfo, func, status); } } int icf8101_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { default: return icom_get_func(rig, vfo, func, status); } } int icf8101_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int icf8101_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, val); default: return icom_get_level(rig, vfo, level, val); } } int icf8101_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { return rig_set_freq(rig, RIG_VFO_B, tx_freq); } int icf8101_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { return rig_get_freq(rig, RIG_VFO_B, tx_freq); } int icf8101_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t mode, pbwidth_t width) { rig_set_freq(rig, RIG_VFO_B, tx_freq); return rig_set_mode(rig, RIG_VFO_B, mode, -1); } int icf8101_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *mode, pbwidth_t *width) { rig_get_freq(rig, RIG_VFO_B, tx_freq); return rig_get_mode(rig, RIG_VFO_B, mode, width); } int icf8101_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmdbuf[4]; int ack_len; unsigned char ackbuf[MAXFRAMELEN]; cmdbuf[0] = 0x03; cmdbuf[1] = 0x17; cmdbuf[2] = 0x00; cmdbuf[3] = split == RIG_SPLIT_ON; return icom_transaction(rig, 0x1a, 0x05, cmdbuf, sizeof(cmdbuf), ackbuf, &ack_len); } int icf8101_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; int ack_len; unsigned char ackbuf[MAXFRAMELEN]; unsigned char cmdbuf[2]; cmdbuf[0] = 0x03; cmdbuf[1] = 0x17; retval = icom_transaction(rig, 0x1a, 0x05, cmdbuf, sizeof(cmdbuf), ackbuf, &ack_len); if (retval == RIG_OK && ack_len >= 1) { dump_hex(ackbuf, ack_len); *split = ackbuf[0] == 1; *tx_vfo = *split ? RIG_VFO_B : RIG_VFO_A; } return retval; } int icf8101_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[2]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; switch (ptt) { case RIG_PTT_ON: pttbuf[0] = 0; pttbuf[1] = 1; break; case RIG_PTT_ON_MIC: pttbuf[0] = 0; pttbuf[1] = 1; break; case RIG_PTT_ON_DATA: pttbuf[0] = 0; pttbuf[1] = 2; break; case RIG_PTT_OFF: pttbuf[0] = 0; pttbuf[1] = 0; break; default: RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, C_CTL_MEM, S_MEM_PTT, pttbuf, 2, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes RETURNFUNC(-RIG_ETIMEOUT); } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(-RIG_ERJCTED); } RETURNFUNC(RIG_OK); } /* * icf8101_get_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icf8101_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { unsigned char pttbuf[MAXFRAMELEN]; int ptt_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_PTT, NULL, 0, pttbuf, &ptt_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * pttbuf should contain Cn,Sc,Data area */ ptt_len -= 2; if (ptt_len != 2) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ptt_len); RETURNFUNC(-RIG_ERJCTED); } if (pttbuf[3] == 0) { *ptt = RIG_PTT_OFF; } else if (pttbuf[3] == 1) { *ptt = RIG_PTT_ON_MIC; } else if (pttbuf[3] == 2) { *ptt = RIG_PTT_ON_DATA; } RETURNFUNC(RIG_OK); } struct rig_caps icf8101_caps = { RIG_MODEL(RIG_MODEL_ICF8101), .model_name = "IC-F8101", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICF8101_FUNC_ALL, .has_set_func = ICF8101_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = ICF8101_LEVEL_ALL | (RIG_LEVEL_RAWSTR), .has_set_level = ICF8101_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, }, .tuning_steps = { {ICF8101_MODES, 1}, }, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW, RIG_AGC_AUTO }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, // is it really 20dB? */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), /* there is RTTY shift */ .targetable_vfo = RIG_TARGETABLE_FREQ, .scan_ops = ICF8101_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 500, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(29.9999), ICF8101_MODES, -1, -1, ICF8101_VFO_ALL, RIG_ANT_CURR, "Other" }, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(1.6), MHz(29.9999), ICF8101_MODES, W(1), W(100), ICF8101_VFO_ALL, RIG_ANT_CURR, "Other"}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(29.9999), ICF8101_MODES, -1, -1, ICF8101_VFO_ALL, RIG_ANT_CURR, "AUS" }, RIG_FRNG_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY, kHz(3.0)}, /* builtin */ {RIG_MODE_AM, kHz(10)}, /* builtin */ RIG_FLT_END, }, .str_cal = ICF8101_STR_CAL, .priv = &icf8101_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icf8101_set_freq, .get_mode = icf8101_get_mode, .set_mode = icf8101_set_mode, .set_ptt = icf8101_set_ptt, .get_ptt = icf8101_get_ptt, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icf8101_get_func, .set_func = icf8101_set_func, .get_level = icf8101_get_level, .set_level = icf8101_set_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .rig_open = icf8101_rig_open, .rig_close = icom_rig_close, .set_split_freq = icf8101_set_split_freq, .get_split_freq = icf8101_get_split_freq, .set_split_vfo = icf8101_set_split_vfo, .get_split_vfo = icf8101_get_split_vfo, .set_split_freq_mode = icf8101_set_split_freq_mode, .get_split_freq_mode = icf8101_get_split_freq_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/TODO.icom0000664000175000017500000000012515056640443011763 hamlib - (C) 2008 Hamlib Group TODO.icom Test and verify each and every model! hamlib-4.6.5/rigs/icom/Android.mk0000664000175000017500000000152515056640443012263 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr6.c icr71.c icr72.c icr75.c icrx7.c \ id1.c id5100.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic7000.c ic7100.c ic7200.c ic7600.c ic7700.c \ icom.c frame.c optoscan.c x108g.c perseus.c id4100.c id51.c \ id31.c icr8600.c ic7300.c ic7610.c icr30.c ic785x.c LOCAL_MODULE := icom LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/icom/icom.c0000664000175000017500000101736215056640443011454 /* * Hamlib CI-V backend - main file * Copyright (c) 2000-2016 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * #include /* UNIX standard function definitions */ // cppcheck-suppress * #include #include #include #include #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "event.h" // we automatically determine availability of the 1A 03 command enum { ENUM_1A_03_UNK, ENUM_1A_03_YES, ENUM_1A_03_NO }; static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo); static int icom_set_default_vfo(RIG *rig); static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo); static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo, int *range_id); static void icom_set_x25x26_ability(RIG *rig, int status); static int icom_get_vfo_number_x25x26(RIG *rig, vfo_t vfo); const int cw_lookup [43][2] = { {0, 6}, {7, 7}, {12, 8}, {19, 9}, {25, 10}, {31, 11}, {37, 12}, {43, 13}, {49, 14}, {55, 15}, {61, 16}, {67, 17}, {73, 18}, {79, 19}, {84, 20}, {91, 21}, {97, 22}, {103, 23}, {108, 24}, {114, 25}, {121, 26}, {128, 27}, {134, 28}, {140, 29}, {144, 30}, {151, 31}, {156, 32}, {164, 33}, {169, 34}, {175, 35}, {182, 36}, {188, 37}, {192, 38}, {199, 39}, {203, 40}, {211, 41}, {215, 42}, {224, 43}, {229, 44}, {234, 45}, {239, 46}, {244, 47}, {250, 48} }; const cal_table_float_t icom_default_swr_cal = { 5, { {0, 1.0f}, {48, 1.5f}, {80, 2.0f}, {120, 3.0f}, {240, 6.0f} } }; const cal_table_float_t icom_default_alc_cal = { 2, { {0, 0.0f}, {120, 1.0f} } }; const cal_table_float_t icom_default_rfpower_meter_cal = { 13, { { 0, 0.0f }, { 21, 5.0f }, { 43, 10.0f }, { 65, 15.0f }, { 83, 20.0f }, { 95, 25.0f }, { 105, 30.0f }, { 114, 35.0f }, { 124, 40.0f }, { 143, 50.0f }, { 183, 75.0f }, { 213, 100.0f }, { 255, 120.0f } } }; const cal_table_float_t icom_default_comp_meter_cal = { 3, { {0, 0.0f}, {130, 15.0f}, {241, 30.0f} } }; const cal_table_float_t icom_default_vd_meter_cal = { 3, { {0, 0.0f}, {13, 10.0f}, {241, 16.0f} } }; const cal_table_float_t icom_default_id_meter_cal = { 4, { {0, 0.0f}, {97, 10.0f}, {146, 15.0f}, {241, 25.0f} } }; const struct ts_sc_list r8500_ts_sc_list[] = { {10, 0x00}, {50, 0x01}, {100, 0x02}, {kHz(1), 0x03}, {2500, 0x04}, {kHz(5), 0x05}, {kHz(9), 0x06}, {kHz(10), 0x07}, {12500, 0x08}, {kHz(20), 0x09}, {kHz(25), 0x10}, {kHz(100), 0x11}, {MHz(1), 0x12}, {0, 0x13}, /* programmable tuning step not supported */ {0, 0}, }; const struct ts_sc_list ic737_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(2), 0x02}, {kHz(3), 0x03}, {kHz(4), 0x04}, {kHz(5), 0x05}, {kHz(6), 0x06}, {kHz(7), 0x07}, {kHz(8), 0x08}, {kHz(9), 0x09}, {kHz(10), 0x10}, {0, 0}, }; const struct ts_sc_list r75_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {6250, 0x04}, {kHz(9), 0x05}, {kHz(10), 0x06}, {12500, 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(100), 0x10}, {MHz(1), 0x11}, {0, 0}, }; const struct ts_sc_list r7100_ts_sc_list[] = { {100, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x02}, {kHz(10), 0x03}, {12500, 0x04}, {kHz(20), 0x05}, {kHz(25), 0x06}, {kHz(100), 0x07}, {0, 0}, }; const struct ts_sc_list r9000_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {0, 0}, }; const struct ts_sc_list r9500_ts_sc_list[] = { {1, 0x00}, {10, 0x01}, {100, 0x02}, {kHz(1), 0x03}, {kHz(2.5), 0x04}, {kHz(5), 0x05}, {6250, 0x06}, {kHz(9), 0x07}, {kHz(10), 0x08}, {12500, 0x09}, {kHz(20), 0x10}, {kHz(25), 0x11}, {kHz(100), 0x12}, {MHz(1), 0x13}, {0, 0}, }; const struct ts_sc_list ic718_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x01}, {kHz(9), 0x01}, {kHz(10), 0x04}, {kHz(100), 0x05}, {0, 0}, }; const struct ts_sc_list ic756_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x02}, {kHz(9), 0x03}, {kHz(10), 0x04}, {0, 0}, }; const struct ts_sc_list ic756pro_ts_sc_list[] = { {10, 0x00}, /* 1 if step turned off */ {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {kHz(12.5), 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {0, 0}, }; const struct ts_sc_list ic706_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {0, 0}, }; const struct ts_sc_list ic7000_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {MHz(1), 0x10}, {0, 0}, }; const struct ts_sc_list ic7100_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(6.25), 0x04}, {kHz(9), 0x05}, {kHz(10), 0x06}, {kHz(12.5), 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(50), 0x0A}, {kHz(100), 0x0B}, {MHz(1), 0x0C}, {0, 0x00}, }; const struct ts_sc_list ic7200_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {0, 0}, }; const struct ts_sc_list ic7300_ts_sc_list[] = { {1, 0x00}, /* Manual says "Send/read the tuning step OFF" */ {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {kHz(12.5), 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {0, 0}, }; const struct ts_sc_list ic910_ts_sc_list[] = { {Hz(1), 0x00}, {Hz(10), 0x01}, {Hz(50), 0x02}, {Hz(100), 0x03}, {kHz(1), 0x04}, {kHz(5), 0x05}, {kHz(6.25), 0x06}, {kHz(10), 0x07}, {kHz(12.5), 0x08}, {kHz(20), 0x09}, {kHz(25), 0x10}, {kHz(100), 0x11}, {0, 0}, }; const struct ts_sc_list r8600_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(2.5), 0x03}, {3125, 0x04}, {kHz(5), 0x05}, {6250, 0x06}, {8330, 0x07}, {kHz(9), 0x08}, {kHz(10), 0x09}, {kHz(12.5), 0x10}, {kHz(20), 0x11}, {kHz(25), 0x12}, {kHz(100), 0x13}, {0, 0x14}, /* programmable tuning step not supported */ {0, 0}, }; const struct ts_sc_list ic705_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {500, 0x02}, {kHz(1), 0x03}, {kHz(5), 0x04}, {kHz(6.25), 0x05}, {kHz(8.33), 0x06}, {kHz(9), 0x07}, {kHz(10), 0x08}, {kHz(12.5), 0x09}, {kHz(20), 0x10}, {kHz(25), 0x11}, {kHz(50), 0x12}, {kHz(100), 0x13}, {0, 0}, }; const struct ts_sc_list ic9700_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {500, 0x02}, {kHz(1), 0x03}, {kHz(5), 0x04}, {kHz(6.25), 0x05}, {kHz(10), 0x06}, {kHz(12.5), 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(50), 0x10}, {kHz(100), 0x11}, {0, 0}, }; /* rtty filter list for some DSP rigs ie PRO */ #define RTTY_FIL_NB 5 const pbwidth_t rtty_fil[] = { Hz(250), Hz(300), Hz(350), Hz(500), kHz(1), 0, }; /* AGC Time value lookups */ const agc_time_t agc_level[] = // default { 0, 0.1, 0.2, 0.3, 0.5, 0.8, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0 }; const agc_time_t agc_level2[] = // AM Mode for 7300/9700/705 { 0, 0.3, 0.5, 0.8, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 }; struct icom_addr { rig_model_t model; unsigned char re_civ_addr; }; #define TOK_CIVADDR TOKEN_BACKEND(1) #define TOK_MODE731 TOKEN_BACKEND(2) #define TOK_NOXCHG TOKEN_BACKEND(3) #define TOK_TONE_ENABLE TOKEN_BACKEND(4) #define TOK_FILTER_USBD TOKEN_BACKEND(5) #define TOK_FILTER_USB TOKEN_BACKEND(6) #define TOK_FILTER_CW TOKEN_BACKEND(7) #define TOK_FILTER_FM TOKEN_BACKEND(8) const struct confparams icom_cfg_params[] = { { TOK_CIVADDR, "civaddr", "CI-V address", "Transceiver's CI-V address", "0", RIG_CONF_NUMERIC, {.n = {0, 0xff, 1}} }, { TOK_MODE731, "mode731", "CI-V 731 mode", "CI-V operating frequency " "data length, needed for IC731 and IC735", "0", RIG_CONF_CHECKBUTTON }, { TOK_NOXCHG, "no_xchg", "No VFO XCHG", "Don't Use VFO XCHG to set other VFO mode and Frequency", "0", RIG_CONF_CHECKBUTTON }, { TOK_TONE_ENABLE, "tone_enable", "Turn tone on", "Overcome a bug in IC-705 to enable tone after frequency change", "0", RIG_CONF_CHECKBUTTON }, { TOK_FILTER_USBD, "filter_usbd", "Filter to use USBD", "Filter to use for USBD/LSBD when setting mode", "1", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_USB, "filter_usb", "Filter to use USB", "Filter to use when for USB/LSB setting mode", "2", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_CW, "filter_cw", "Filter to use CW", "Filter to use for CW/CWR when setting mode", "3", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_FM, "filter_fm", "Filter to use FM", "Filter to use for FM/PKTFM when setting mode", "1", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, {RIG_CONF_END, NULL,} }; /* * Lookup table for icom_get_ext_func */ const struct confparams icom_ext_funcs[] = { { TOK_DIGI_SEL_FUNC, "digi_sel", "DIGI-SEL enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_IPP_FUNC, "IPP", "IP Plus", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_TX_INHIBIT_FUNC, "TX_INHIBIT", "TX Inhibit", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_DPP_FUNC, "DPP", "Digital Pre Distortion-SEL enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_ICPW2_FUNC, "ICPW2", "Icom PW2 enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_level */ const struct confparams icom_ext_levels[] = { { TOK_DIGI_SEL_LEVEL, "digi_sel_level", "DIGI-SEL level", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { TOK_SCOPE_MSS, "SPECTRUM_SELECT", "Spectrum Scope Main/Sub", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Main", "Sub", NULL } } } }, { TOK_SCOPE_SDS, "SPECTRUM_DUAL", "Spectrum Scope Single/Dual", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Single", "Dual", NULL } } } }, { TOK_SCOPE_EDG, "SPECTRUM_EDGE", "Spectrum Scope Edge", "Edge selection for fixed scope mode", "", RIG_CONF_COMBO, { .c = { .combostr = { "1", "2", "3", "4", NULL } } } }, { TOK_SCOPE_STX, "SPECTRUM_TX", "Spectrum Scope TX operation", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_SCOPE_CFQ, "SPECTRUM_CENTER", "Spectrum Scope Center Frequency Type", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Filter center", "Carrier point center", "Carrier point center (Abs. Freq.)", NULL } } } }, { TOK_SCOPE_VBW, "SPECTRUM_VBW", "Spectrum Scope VBW", "Video Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Wide", NULL } } } }, { TOK_SCOPE_RBW, "SPECTRUM_RBW", "Spectrum Scope RBW", "Resolution Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Wide", "Mid", "Narrow", NULL } } } }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_parm */ const struct confparams icom_ext_parms[] = { { TOK_DSTAR_DSQL, "dsdsql", "D-STAR CSQL Status", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_DSTAR_CALL_SIGN, "dscals", "D-STAR Call sign", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_MESSAGE, "dsrmes", "D-STAR Rx Message", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_STATUS, "dsstat", "D-STAR Rx Status", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_GPS_DATA, "dsgpsd", "D-STAR GPS Data", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_GPS_MESS, "dsgpsm", "D-STAR GPS Message", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_CODE, "dscode", "D-STAR CSQL Code", "", "", RIG_CONF_NUMERIC, {} }, { TOK_DSTAR_TX_DATA, "dstdat", "D-STAR Tx Data", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_MY_CS, "dsmycs", "D-STAR MY Call Sign", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_TX_CS, "dstxcs", "D-STAR Tx Call Sign", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_TX_MESS, "dstmes", "D-STAR Tx Message", "", "", RIG_CONF_STRING, {} }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_* & icom_set_ext_* functions */ const struct cmdparams icom_ext_cmd[] = { { {.t = TOK_DSTAR_DSQL}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW, 1, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DSTAR_CALL_SIGN}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCALS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 38 }, { {.t = TOK_DSTAR_MESSAGE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSMESS, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 32 }, { {.t = TOK_DSTAR_STATUS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSRSTS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 1 }, { {.t = TOK_DSTAR_GPS_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSD, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 52 }, { {.t = TOK_DSTAR_GPS_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSM, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 52 }, { {.t = TOK_DSTAR_CODE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW12, 2, {0}, CMD_DAT_FLT, 1 }, { {.t = TOK_DSTAR_TX_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DSD, S_DSD_DSTXDT, SC_MOD_RW, 1, {0}, CMD_DAT_BUF, 30 }, { {.t = TOK_DSTAR_MY_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSMYCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 12 }, { {.t = TOK_DSTAR_TX_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 24 }, { {.t = TOK_DSTAR_TX_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXMS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 20 }, { {.t = TOK_DRIVE_GAIN}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DRIVE, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 }, { {.t = TOK_DIGI_SEL_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_DIGISEL, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DIGI_SEL_LEVEL}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DIGI, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 }, { {.t = TOK_IPP_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_IPP, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_TX_INHIBIT_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_TX_INHIBIT, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DPP_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_DPP, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_ICPW2_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, 0x05, SC_MOD_RW, 2, {0x03, 0x10}, CMD_DAT_BOL, 1 }, { {0} } }; /* * Please, if the default CI-V address of your rig is listed as UNKNOWN_ADDR, * send the value to for inclusion. Thanks --SF */ static const struct icom_addr icom_addr_list[] = { {RIG_MODEL_IC703, 0x68}, {RIG_MODEL_IC706, 0x48}, {RIG_MODEL_IC706MKII, 0x4e}, {RIG_MODEL_IC706MKIIG, 0x58}, {RIG_MODEL_IC271, 0x20}, {RIG_MODEL_IC275, 0x10}, {RIG_MODEL_IC375, 0x12}, {RIG_MODEL_IC471, 0x22}, {RIG_MODEL_IC475, 0x14}, {RIG_MODEL_IC575, 0x16}, {RIG_MODEL_IC707, 0x3e}, {RIG_MODEL_IC725, 0x28}, {RIG_MODEL_IC726, 0x30}, {RIG_MODEL_IC728, 0x38}, {RIG_MODEL_IC729, 0x3a}, {RIG_MODEL_IC731, 0x02}, /* need confirmation */ {RIG_MODEL_IC735, 0x04}, {RIG_MODEL_IC736, 0x40}, {RIG_MODEL_IC7410, 0x80}, {RIG_MODEL_IC746, 0x56}, {RIG_MODEL_IC746PRO, 0x66}, {RIG_MODEL_IC737, 0x3c}, {RIG_MODEL_IC738, 0x44}, {RIG_MODEL_IC751, 0x1c}, {RIG_MODEL_IC751A, 0x1c}, {RIG_MODEL_IC756, 0x50}, {RIG_MODEL_IC756PRO, 0x5c}, {RIG_MODEL_IC756PROII, 0x64}, {RIG_MODEL_IC756PROIII, 0x6e}, {RIG_MODEL_IC7600, 0x7a}, {RIG_MODEL_IC761, 0x1e}, {RIG_MODEL_IC765, 0x2c}, {RIG_MODEL_IC775, 0x46}, {RIG_MODEL_IC7800, 0x6a}, {RIG_MODEL_IC785x, 0x8e}, {RIG_MODEL_IC781, 0x26}, {RIG_MODEL_IC820, 0x42}, {RIG_MODEL_IC821H, 0x4c}, {RIG_MODEL_IC910, 0x60}, {RIG_MODEL_IC9100, 0x7c}, {RIG_MODEL_IC9700, 0xa2}, {RIG_MODEL_IC970, 0x2e}, {RIG_MODEL_IC1271, 0x24}, {RIG_MODEL_IC1275, 0x18}, {RIG_MODEL_ICR10, 0x52}, {RIG_MODEL_ICR20, 0x6c}, {RIG_MODEL_ICR6, 0x7e}, {RIG_MODEL_ICR71, 0x1a}, {RIG_MODEL_ICR72, 0x32}, {RIG_MODEL_ICR75, 0x5a}, {RIG_MODEL_ICRX7, 0x78}, {RIG_MODEL_IC78, 0x62}, {RIG_MODEL_ICR7000, 0x08}, {RIG_MODEL_ICR7100, 0x34}, {RIG_MODEL_ICR8500, 0x4a}, {RIG_MODEL_ICR9000, 0x2a}, {RIG_MODEL_ICR9500, 0x72}, // {RIG_MODEL_MINISCOUT, 0x94}, // ic7300 took this one {RIG_MODEL_IC718, 0x5e}, {RIG_MODEL_OS535, 0x80}, /* same address as IC-7410 */ {RIG_MODEL_ICID1, 0x01}, {RIG_MODEL_IC7000, 0x70}, {RIG_MODEL_IC7100, 0x88}, {RIG_MODEL_IC7200, 0x76}, {RIG_MODEL_IC7300, 0x94}, {RIG_MODEL_IC7610, 0x98}, {RIG_MODEL_IC7700, 0x74}, {RIG_MODEL_IC7760, 0xB2}, {RIG_MODEL_PERSEUS, 0xE1}, {RIG_MODEL_X108G, 0x70}, {RIG_MODEL_X6100, 0x70}, {RIG_MODEL_ICR8600, 0x96}, {RIG_MODEL_ICR30, 0x9c}, {RIG_MODEL_NONE, 0}, }; /* * This is a generic icom_init function. * You might want to define yours, so you can customize it for your rig * * Basically, it sets up *priv * REM: serial port is already open (RIGPORT(rig)->fd) */ int icom_init(RIG *rig) { struct icom_priv_data *priv; struct icom_priv_caps *priv_caps; struct rig_caps *caps; struct rig_state *rs = STATE(rig); int i; ENTERFUNC; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (!caps->priv) { RETURNFUNC(-RIG_ECONF); } priv_caps = (struct icom_priv_caps *) caps->priv; rs->priv = (struct icom_priv_data *) calloc(1, sizeof(struct icom_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ RETURNFUNC(-RIG_ENOMEM); } priv = rs->priv; priv->spectrum_scope_count = 0; for (i = 0; caps->spectrum_scopes[i].name != NULL; i++) { priv->spectrum_scope_cache[i].spectrum_data = NULL; if (priv_caps->spectrum_scope_caps.spectrum_line_length < 1) { rig_debug(RIG_DEBUG_ERR, "%s: no spectrum scope line length defined\n", __func__); RETURNFUNC(-RIG_ECONF); } priv->spectrum_scope_cache[i].spectrum_data = calloc(1, priv_caps->spectrum_scope_caps.spectrum_line_length); if (!priv->spectrum_scope_cache[i].spectrum_data) { RETURNFUNC(-RIG_ENOMEM); } priv->spectrum_scope_count++; } /* TODO: CI-V address should be customizable */ /* * init the priv_data from static struct * + override with preferences */ priv->re_civ_addr = priv_caps->re_civ_addr; priv->civ_731_mode = priv_caps->civ_731_mode; priv->no_xchg = priv_caps->no_xchg; priv->serial_USB_echo_off = -1; // unknown at this point priv->x25cmdfails = 1; priv->x26cmdfails = 1; priv->x1cx03cmdfails = 0; // Reset 0x25/0x26 command detection for the rigs that may support it icom_set_x25x26_ability(rig, -1); RETURNFUNC(RIG_OK); } /* * ICOM Generic icom_cleanup routine * the serial port is closed by the frontend */ int icom_cleanup(RIG *rig) { struct icom_priv_data *priv; int i; ENTERFUNC; priv = STATE(rig)->priv; for (i = 0; rig->caps->spectrum_scopes[i].name != NULL; i++) { if (priv->spectrum_scope_cache[i].spectrum_data) { free(priv->spectrum_scope_cache[i].spectrum_data); priv->spectrum_scope_cache[i].spectrum_data = NULL; } } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /** * Returns 1 when USB ECHO is off * Returns 0 when USB ECHO is on * \return Returns < 0 when error occurs (e.g. timeout, nimple, navail) */ int icom_get_usb_echo_off(RIG *rig) { int retval; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; // Check for echo on first by assuming echo is off and checking the answer priv->serial_USB_echo_off = 1; retval = icom_transaction(rig, C_RD_FREQ, -1, NULL, 0, ackbuf, &ack_len); // if rig is not powered on we get no data and TIMEOUT if (ack_len == 0 && retval == -RIG_ETIMEOUT) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: ack_len=%d\n", __func__, ack_len); if (ack_len == 1) // then we got an echo of the cmd { unsigned char buf[16]; priv->serial_USB_echo_off = 0; // we should have a freq response so we'll read it and don't really care // flushing doesn't always work as it depends on timing retval = read_icom_frame(RIGPORT(rig), buf, sizeof(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo on detected, get freq retval=%d\n", __func__, retval); if (retval <= 0) { RETURNFUNC(-RIG_ETIMEOUT); } } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo off detected\n", __func__); } RETURNFUNC(priv->serial_USB_echo_off); } static int icom_check_ack(int ack_len, unsigned char *ackbuf) { if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes rig_debug(RIG_DEBUG_WARN, "%s: command timed out (%#.2x)\n", __func__, ackbuf[0]); return -RIG_ETIMEOUT; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not acknowledged (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } #if 0 // this causes the rig to go into VFO mode when it is in memory mode // we have to give up on determining active VFO for Icom rigs // figure out what VFO is current for rigs with 0x25 command static int icom_current_vfo_x25(RIG *rig, vfo_t *vfo) { int freq_offset = 0; freq_t freq_current, freq_other, freq_current_2; vfo_t vfo_current = RIG_VFO_NONE; vfo_t vfo_check = RIG_VFO_A; struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; if (priv->x25cmdfails > 0 && !priv_caps->x25x26_always) { return -RIG_ENAVAIL; } rig_get_freq(rig, RIG_VFO_CURR, &freq_current); rig_get_freq(rig, RIG_VFO_OTHER, &freq_other); if (freq_current == freq_other) { if (priv->vfo_flag != 0) { // we can't change freqs unless rig is idle and we don't know that // so we only check vfo once when freqs are equal rig_debug(RIG_DEBUG_TRACE, "%s: VFO already determined, returning current_vfo %s\n", __func__, rig_strvfo(rs->current_vfo)); *vfo = rs->current_vfo; return RIG_OK; } priv->vfo_flag = 1; freq_offset = 100; rig_set_freq(rig, RIG_VFO_CURR, freq_current + freq_offset); } if (rs->current_vfo == RIG_VFO_B) { vfo_check = RIG_VFO_B; } rig_set_vfo(rig, vfo_check); rig_get_freq(rig, RIG_VFO_CURR, &freq_current_2); if (freq_current_2 == freq_current + freq_offset) // then we are on the vfo_check { vfo_current = vfo_check; } else // the other VFO is the current one { rig_set_vfo(rig, vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); vfo_current = vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A; } if (freq_offset) // then we need to change freq_current back to original freq { rig_set_freq(rig, RIG_VFO_CURR, freq_current); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_current=%s\n", __func__, rig_strvfo(vfo_current)); *vfo = vfo_current; return RIG_OK; } #endif static int icom_current_vfo_to_vfo_with_band(RIG *rig, vfo_t *vfo_current) { int retval; vfo_t vfo_band; retval = icom_get_vfo(rig, &vfo_band); if (retval != RIG_OK) { return retval; } if (*vfo_current == RIG_VFO_B) { if (vfo_band == RIG_VFO_SUB) { *vfo_current = RIG_VFO_SUB_B; } else { *vfo_current = RIG_VFO_MAIN_B; } } else { if (vfo_band == RIG_VFO_SUB) { *vfo_current = RIG_VFO_SUB_A; } else { *vfo_current = RIG_VFO_MAIN_A; } } return retval; } // figure out what VFO is current static vfo_t icom_current_vfo(RIG *rig) { int retval; int freq_offset = 0; freq_t freq_current, freq_other, freq_current_2; vfo_t vfo_current = RIG_VFO_NONE; vfo_t vfo_check = RIG_VFO_A; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = rs->priv; #if 0 // Icom rigs with both Main/Sub receivers and A/B VFOs cannot use the 0x25 command to read Sub receiver frequency if (rs->targetable_vfo & RIG_TARGETABLE_FREQ && !VFO_HAS_MAIN_SUB_A_B_ONLY) { // these newer rigs get special treatment retval = icom_current_vfo_x25(rig, &vfo_current); if (VFO_HAS_MAIN_SUB_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode)) { vfo_current = (vfo_current == RIG_VFO_A) ? RIG_VFO_MAIN : RIG_VFO_SUB; } if (retval == RIG_OK) { return vfo_current; } } #endif if (cachep->ptt) { // don't do this if transmitting -- XCHG would mess it up return rs->current_vfo; } else if (!rig_has_vfo_op(rig, RIG_OP_XCHG)) { // for now we will just set vfoa and be done with it // will take more logic for rigs without XCHG rig_debug(RIG_DEBUG_TRACE, "%s: defaulting to VFOA as no XCHG or x25 available\n", __func__); rig_set_vfo(rig, RIG_VFO_A); return RIG_VFO_A; } rig_get_freq(rig, RIG_VFO_CURR, &freq_current); if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap\n", __func__); retval = icom_vfo_op(rig, vfo_current, RIG_OP_XCHG); if (retval != RIG_OK) { return rs->current_vfo; } } rig_get_freq(rig, RIG_VFO_CURR, &freq_other); if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap back\n", __func__); retval = icom_vfo_op(rig, vfo_current, RIG_OP_XCHG); if (retval != RIG_OK) { return rs->current_vfo; } } if (freq_current == freq_other) { if (priv->vfo_flag != 0) { // we can't change freqs unless rig is idle and we don't know that // so we only check vfo once when freqs are equal rig_debug(RIG_DEBUG_TRACE, "%s: vfo already determined...returning current_vfo", __func__); return rs->current_vfo; } priv->vfo_flag = 1; freq_offset = 100; rig_set_freq(rig, RIG_VFO_CURR, freq_current + freq_offset); } if (rs->current_vfo == RIG_VFO_B) { vfo_check = RIG_VFO_B; } rig_set_vfo(rig, vfo_check); rig_get_freq(rig, RIG_VFO_CURR, &freq_current_2); if (freq_current_2 == freq_current + freq_offset) { vfo_current = vfo_check; } else { rig_set_vfo(rig, vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); vfo_current = vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A; } if (freq_offset) // then we need to change freq_current back to original freq { rig_set_freq(rig, RIG_VFO_CURR, freq_current); } if (VFO_HAS_MAIN_SUB_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode)) { vfo_current = (vfo_current == RIG_VFO_A) ? RIG_VFO_MAIN : RIG_VFO_SUB; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && RIG_IS_IC9700) { // TODO: VFO op XCHG only exchanges Main/Sub, so Sub receiver VFO A/B selection cannot be determined this way retval = icom_current_vfo_to_vfo_with_band(rig, &vfo_current); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_current=%s\n", __func__, rig_strvfo(vfo_current)); if (vfo_current == RIG_VFO_NONE && rs->current_vfo != RIG_VFO_NONE) { vfo_current = rs->current_vfo; } return vfo_current; } // Some rigs, such as IC-9700, cannot execute 0x25/0x26 commands in satmode static void icom_satmode_fix(RIG *rig, int satmode) { if (RIG_IS_IC9700) { rig_debug(RIG_DEBUG_VERBOSE, "%s: toggling IC-9700 targetable for satmode=%d\n", __func__, satmode); // Modify the copy of targetable_vfo in rig_state only! if (satmode) { STATE(rig)->targetable_vfo = 0; } else { STATE(rig)->targetable_vfo = rig->caps->targetable_vfo; } } } /* * ICOM rig open routine * Detect echo state of USB serial port */ int icom_rig_open(RIG *rig) { int retval, retval_echo, value; int satmode = 0; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retry_flag = 1; short retry_save = rp->retry; ENTERFUNC; rp->retry = 0; priv->no_1a_03_cmd = ENUM_1A_03_UNK; rig_debug(RIG_DEBUG_VERBOSE, "%s: %s v%s\n", __func__, rig->caps->model_name, rig->caps->version); if (rs->auto_power_on && priv->poweron == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s asking for power on *****************************************\n", __func__); rig_set_powerstat(rig, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s asking for power on #2 =======================================\n", __func__); priv->poweron = 1; } retry_open: retval_echo = icom_get_usb_echo_off(rig); rig_debug(RIG_DEBUG_TRACE, "%s: echo status result=%d\n", __func__, retval_echo); if (retval_echo == 0 || retval_echo == 1) { retval = RIG_OK; } else if (retval_echo == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to determine Icom echo status -- is rig on and connected?\n", __func__); RETURNFUNC(retval_echo); } else { retval = retval_echo; } if (retval == RIG_OK) // then we know our echo status { // we need to know about dual watch for later use rs->dual_watch = 0; retval = rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, &value); if (retval == RIG_OK) { rs->dual_watch = value; } rig_debug(RIG_DEBUG_VERBOSE, "%s: dual_watch=%d\n", __func__, rs->dual_watch); rig_debug(RIG_DEBUG_TRACE, "%s: echo status known, getting frequency\n", __func__); rp->retry = 0; // rs->current_vfo = icom_current_vfo(rig); // some rigs like the IC7100 still echo when in standby // so asking for freq now should timeout if such a rig freq_t tfreq; retval = rig_get_freq(rig, RIG_VFO_CURR, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig error getting frequency retry=%d, err=%s\n", __func__, retry_flag, rigerror(retval)); } } else { rig_debug(RIG_DEBUG_TRACE, "%s: echo status unknown\n", __func__); } if (retval != RIG_OK && priv->poweron == 0 && rs->auto_power_on) { // maybe we need power on? rig_debug(RIG_DEBUG_VERBOSE, "%s trying power on\n", __func__); retval = abs(rig_set_powerstat(rig, 1)); // this is only a fatal error if powerstat is implemented // if not implemented than we're at an error here if (retval != RIG_OK) { rp->retry = retry_save; rig_debug(RIG_DEBUG_ERR, "%s: rig_set_powerstat failed: %s\n", __func__, rigerror(retval)); if (retval == RIG_ENIMPL || retval == RIG_ENAVAIL) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_powerstat not implemented for rig\n", __func__); RETURNFUNC(-RIG_ECONF); } RETURNFUNC(retval); } // Now that we're powered up let's try again retval_echo = icom_get_usb_echo_off(rig); if (retval_echo != 0 && retval_echo != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to determine USB echo status\n", __func__); rp->retry = retry_save; RETURNFUNC(retval_echo); } } else if (retval != RIG_OK) { // didn't ask for power on so let's retry one more time if (retry_flag) { retry_flag = 0; hl_usleep(500 * 1000); // 500ms pause goto retry_open; } rp->retry = retry_save; } priv->poweron = (retval == RIG_OK) ? 1 : 0; if (priv->poweron) { if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Getting satmode state updates RX/TX VFOs internally rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } //rs->current_vfo = icom_current_vfo(rig); } #if 0 // do not do this here -- needs to be done when ranges are requested instead as this is very slow icom_get_freq_range(rig); // try get to get rig range capability dynamically #endif rp->retry = retry_save; RETURNFUNC(RIG_OK); } /* * ICOM rig close routine */ int icom_rig_close(RIG *rig) { // Nothing to do yet struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; if (priv->poweron == 0) { RETURNFUNC(RIG_OK); } // nothing to do if (priv->poweron == 1 && rs->auto_power_off) { // maybe we need power off? rig_debug(RIG_DEBUG_VERBOSE, "%s trying power off\n", __func__); int retval = abs(rig_set_powerstat(rig, 0)); // this is only a fatal error if powerstat is implemented // if not implemented than we're at an error here if (retval != RIG_OK && retval != RIG_ENIMPL && retval != RIG_ENAVAIL) { rig_debug(RIG_DEBUG_WARN, "%s: unexpected retval here: %s\n", __func__, rigerror(retval)); rig_debug(RIG_DEBUG_WARN, "%s: rig_set_powerstat failed: =%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * Set default when vfo == RIG_VFO_NONE * Clients should be setting VFO as 1st things but some don't * So they will get defaults of Main/VFOA as the selected VFO * and we force that selection */ static int icom_set_default_vfo(RIG *rig) { int retval; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: called, curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); // we need to know if dual watch is on if (VFO_HAS_MAIN_SUB_A_B_ONLY) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN/VFOA\n", __func__); HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case if (retval != RIG_OK) { RETURNFUNC2(retval); } HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to Main in this case if (retval != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = RIG_VFO_MAIN; RETURNFUNC2(RIG_OK); } if (VFO_HAS_MAIN_SUB_ONLY) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN\n", __func__); HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case rs->current_vfo = RIG_VFO_MAIN; } else if (VFO_HAS_A_B) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as VFOA\n", __func__); HAMLIB_TRACE; retval = RIG_OK; if (rs->current_vfo != RIG_VFO_A) { retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to VFOA for all others rs->current_vfo = RIG_VFO_A; } } else { // we don't have any VFO selection rig_debug(RIG_DEBUG_TRACE, "%s: Unknown VFO setup so setting default as VFOA\n", __func__); rs->current_vfo = RIG_VFO_A; retval = RIG_OK; } if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now %s\n", __func__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } // return true if band is changing from last set_freq // Assumes rig is currently on the VFO being changed // This handles the case case Main/Sub cannot be on the same band int icom_band_changing(RIG *rig, freq_t test_freq) { freq_t curr_freq, freq1, freq2; int retval; ENTERFUNC2; // We should be sitting on the VFO we want to change so just get it's frequency retval = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_freq failed??\n", __func__); RETURNFUNC2(0); // I guess we need to say no change in this case } // Make our HF=0, 2M = 1, 70cm = 4, and 23cm=12 freq1 = floor(curr_freq / 1e8); freq2 = floor(test_freq / 1e8); rig_debug(RIG_DEBUG_TRACE, "%s: lastfreq=%.0f, thisfreq=%.0f\n", __func__, freq1, freq2); if (freq1 != freq2) { rig_debug(RIG_DEBUG_TRACE, "%s: Band change detected\n", __func__); RETURNFUNC2(1); } rig_debug(RIG_DEBUG_TRACE, "%s: Band change not detected\n", __func__); RETURNFUNC2(0); } static int icom_set_freq_x25(RIG *rig, vfo_t vfo, freq_t freq, int freq_len, unsigned char *freqbuf) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || (priv->x25cmdfails > 0 && !priv_caps->x25x26_always)) { return -RIG_ENAVAIL; } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_transaction(rig, C_SEND_SEL_FREQ, vfo_number, freqbuf, freq_len, ackbuf, &ack_len); if (priv->x25cmdfails < 0 || priv_caps->x25x26_always) { priv->x25cmdfails = (retval == RIG_OK) ? 0 : 1; } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { return retval; } return retval; } static int icom_get_freq_x25(RIG *rig, vfo_t vfo, int *ack_len, unsigned char *ackbuf, int *freqbuf_offset) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; // Rigs like IC-7600, IC-7700, IC-7800 and IC-7100 have new firmware that implements commands 0x25 and 0x26 // So if this succeeds we'll assume all such rigs are targetable freq & mode if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || (priv->x25cmdfails > 0 && !priv_caps->x25x26_always)) { return -RIG_ENAVAIL; } // Attempt to use the 0x25 command to get selected/unselected or Main/Sub VFO frequency directly // For the rigs that indicate selected/unselected VFO frequency, assume current_vfo is accurate to determine what "selected" means int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_transaction(rig, C_SEND_SEL_FREQ, vfo_number, NULL, 0, ackbuf, ack_len); if (retval == RIG_OK) { *freqbuf_offset = 2; } if (priv->x25cmdfails < 0 || priv_caps->x25x26_always) { priv->x25cmdfails = (retval == RIG_OK) ? 0 : 1; } return retval; } static int icom_get_tx_freq(RIG *rig, int *ack_len, unsigned char *ackbuf, int *freqbuf_offset) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; if (priv->x1cx03cmdfails > 0 && !priv_caps->x1cx03_always) { return -RIG_ENAVAIL; } retval = icom_transaction(rig, C_CTL_PTT, S_RD_TX_FREQ, NULL, 0, ackbuf, ack_len); if (retval == RIG_OK) { *freqbuf_offset = 2; } if (priv->x1cx03cmdfails < 0 || priv_caps->x1cx03_always) { priv->x1cx03cmdfails = (retval == RIG_OK) ? 0 : 1; } return retval; } /* * icom_set_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int freq_len, ack_len = sizeof(ackbuf), retval; int check_ack = 0; int cmd, subcmd = -1; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; freq_t curr_freq; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s=%" PRIfreq "\n", __func__, rig_strvfo(vfo), freq); // Icom 0x25 command can only manipulate VFO A/B *or* VFO Main/Sub frequencies. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver frequencies must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || force_vfo_swap) { // Switch to the desired VFO (if needed) if frequency is not targetable HAMLIB_TRACE; rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo_curr=%s\n", __func__, rig_strvfo(rs->current_vfo)); retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = rig_get_freq(rig, vfo, &curr_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } freq_len = priv->civ_731_mode ? 4 : 5; if (RIG_IS_IC905) { // > 5.85GHz is 6 bytes if (freq > 5.85e9) { freq_len = 6; } } to_bcd(freqbuf, freq, freq_len * 2); if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && !force_vfo_swap) { cmd = C_SEND_SEL_FREQ; subcmd = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_set_freq_x25(rig, vfo, freq, freq_len, freqbuf); } if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || retval == -RIG_ENAVAIL || force_vfo_swap) { cmd = C_SET_FREQ; subcmd = -1; #if 0 if (CACHE(rig)->ptt && (ICOM_IS_ID5100 || ICOM_IS_ID4100 || ICOM_IS_ID31 || ICOM_IS_ID51)) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): ID55100 0x00\n", __func__, __LINE__); // for these rigs 0x00 is setting the freq and 0x03 is just for reading cmd = 0x00; // temporary fix for ID5100 not giving ACK/NAK on 0x00 freq on E8 firmware retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_freq failed: %s\n", __func__, rigerror(retval)); return retval; } return RIG_OK; } else #endif { retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf, &ack_len); } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } check_ack = 1; } if (retval != RIG_OK) { // We might have a failed command if we're changing bands // For example, IC-9700 setting Sub=VHF when Main=VHF will fail // So we'll try a VFO swap and see if that helps things rig_debug(RIG_DEBUG_VERBOSE, "%s: special check for vfo swap\n", __func__); if (icom_band_changing(rig, freq)) { if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: vfo_op XCHG failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } // Try the command again retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf, &ack_len); // Swap back if we got an error otherwise we fall through for more processing if (retval != RIG_OK) { int retval2; rig_debug(RIG_DEBUG_ERR, "%s: 2nd set freq failed: %s\n", __func__, rigerror(retval)); retval2 = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval2 != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: 2nd vfo_op XCHG failed: %s\n", __func__, rigerror(retval2)); RETURNFUNC2(retval2); } RETURNFUNC2(retval); } check_ack = 1; } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set freq failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } if (check_ack && (retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } if (priv->tone_enable) { // IC-705 as of 2024-02-01 turn off TONE on freq change so we turn it back on if enabled rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(RIG_OK); } /* * icom_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL, Main=VFOA, Sub=VFOB * Note: old rig may return less than 4/5 bytes for get_freq */ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char freqbuf[MAXFRAMELEN]; int freq_len = sizeof(freqbuf); int freqbuf_offset = 1; int retval = RIG_OK; int civ_731_mode_save = 0; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); if (priv->serial_USB_echo_off == -1) { icom_get_usb_echo_off(rig); } if (vfo == RIG_VFO_MEM && (priv->civ_731_mode || RIG_IS_IC706)) { // Memory channels have always 5-byte frequency rig_debug(RIG_DEBUG_TRACE, "%s: VFO=MEM so turning off civ_731\n", __func__); civ_731_mode_save = 1; priv->civ_731_mode = 0; } // Pick the appropriate VFO when VFO_TX is requested if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: VFO_TX requested, vfo=%s\n", __func__, rig_strvfo(vfo)); // Attempt to read the transmit frequency directly to avoid VFO swapping retval = icom_get_tx_freq(rig, &freq_len, freqbuf, &freqbuf_offset); if (retval == RIG_OK) { *freq = from_bcd(&freqbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } // Fix VFO if the TX freq command is not available if (CACHE(rig)->split != RIG_SPLIT_OFF) { vfo = rs->tx_vfo; } else { vfo = rs->current_vfo; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); // Icom 0x25 command can only manipulate VFO A/B *or* VFO Main/Sub frequencies. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver frequencies must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && !force_vfo_swap) { retval = icom_get_freq_x25(rig, vfo, &freq_len, freqbuf, &freqbuf_offset); if (freq_len == 3 && freqbuf[2] == 0xff) { // then we are in VFO mode *freq = 0; return RIG_OK; } if (retval == RIG_OK) { // 0x25 cmd is 1 byte longer than 0x03 cmd freq_len--; } } // If the command 0x25 is not supported, swap VFO (if required) and read the frequency if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || retval == -RIG_ENAVAIL || force_vfo_swap) { freqbuf_offset = 1; HAMLIB_TRACE; retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } for (int i = 0; i < 2; ++i) { retval = icom_transaction(rig, C_RD_FREQ, -1, NULL, 0, freqbuf, &freq_len); HAMLIB_TRACE; if (freqbuf[4] == C_RD_FREQ) { break; } } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } if (retval != RIG_OK) { if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } /* * freqbuf should contain Cn,Data area */ freq_len--; /* * is it a blank mem channel ? */ if (freq_len == 1 && freqbuf[1] == 0xff) { *freq = RIG_FREQ_NONE; if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return RIG_OK; } if (freq_len == 3 && (ICOM_IS_ID5100 || ICOM_IS_ID4100 || ICOM_IS_ID31 || ICOM_IS_ID51)) { rig_debug(RIG_DEBUG_ERR, "%s: 3-byte ID5100/4100 length - turn off XONXOFF flow control\n", __func__); } else if (freq_len != 4 && freq_len != 5 && freq_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, freq_len); if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } if (freq_len == 1 && vfo == RIG_VFO_MEM) { *freq = 0; rig_debug(RIG_DEBUG_ERR, "%s: Rig is in MEM mode and MEM channel is empty\n", __func__); return -RIG_ETRUNC; } return -RIG_ENAVAIL; } if (freq_len != 3 && freq_len != 6 && freq_len != (priv->civ_731_mode ? 4 : 5)) { rig_debug(RIG_DEBUG_WARN, "%s: freq len (%d) differs from expected\n", __func__, freq_len); } *freq = from_bcd(freqbuf + freqbuf_offset, freq_len * 2); // 3-byte freq for ID5100 is in 10000Hz units so convert to Hz if (freq_len == 3) { *freq *= 10000; } if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s exit vfo=%s, curr_vfo=%s, freq=%g\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo), *freq); RETURNFUNC2(RIG_OK); } int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts) { unsigned char tsbuf[MAXFRAMELEN]; int ts_len, retval; retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, NULL, 0, tsbuf, &ts_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } /* * tsbuf nibbles should contain 10,1,1000,100 hz digits and 00=+, 01=- bit */ rig_debug(RIG_DEBUG_VERBOSE, "%s: ts_len=%d\n", __func__, ts_len); if (ts_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); RETURNFUNC2(-RIG_ERJCTED); } *ts = (shortfreq_t) from_bcd(tsbuf + 2, 4); if (tsbuf[4] != 0) { *ts *= -1; } RETURNFUNC2(RIG_OK); } // The Icom rigs have only one register for both RIT and Delta TX // you can turn one or both on -- but both end up just being in sync. static int icom_set_it_new(RIG *rig, vfo_t vfo, shortfreq_t ts, int set_xit) { unsigned char tsbuf[8]; unsigned char ackbuf[16]; int ack_len; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: ts=%d\n", __func__, (int) ts); to_bcd(tsbuf, abs((int) ts), 4); // set sign bit tsbuf[2] = (ts < 0) ? 1 : 0; retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, tsbuf, 3, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) { RETURNFUNC2(icom_set_it_new(rig, vfo, ts, 0)); } int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) { RETURNFUNC2(icom_set_it_new(rig, vfo, ts, 1)); } /* icom_get_dsp_flt returns the dsp filter width in hz or 0 if the command is not implemented or error. This allows the default parameters to be assigned from the get_mode routine if the command is not implemented. Assumes rig != null and the current mode is in mode. Has been tested for IC-746pro, Should work on the all dsp rigs ie pro models. The 746 documentation says it has the get_if_filter, but doesn't give any decoding information ? Please test. DSP filter setting ($1A$03), but not supported by every rig, and some models like IC910/Omni VI Plus have a different meaning for this subcommand */ int filtericom[] = { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600 }; pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode) { int retval, res_len = 0, rfstatus; unsigned char resbuf[MAXFRAMELEN]; value_t rfwidth; unsigned char fw_sub_cmd = RIG_IS_IC7200 ? 0x02 : S_MEM_FILT_WDTH; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); memset(resbuf, 0, sizeof(resbuf)); if (rig_has_get_func(rig, RIG_FUNC_RF) && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR))) { if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus) && (rfstatus)) { retval = rig_get_ext_parm(rig, TOK_RTTY_FLTR, &rfwidth); if (retval != RIG_OK || rfwidth.i >= RTTY_FIL_NB) { return (0); /* use default */ } else { return (rtty_fil[rfwidth.i]); } } } // TODO: Skip for Xiegu G90 too???? if (RIG_MODEL_X108G == rig->caps->rig_model || RIG_MODEL_X5105 == rig->caps->rig_model || RIG_MODEL_G90 == rig->caps->rig_model) { priv->no_1a_03_cmd = ENUM_1A_03_NO; } if (priv->no_1a_03_cmd == ENUM_1A_03_NO) { return (0); } retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, 0, 0, resbuf, &res_len); if (-RIG_ERJCTED == retval && !RIG_IS_IC7300) { if (priv->no_1a_03_cmd == ENUM_1A_03_UNK) { priv->no_1a_03_cmd = ENUM_1A_03_NO; /* do not keep asking */ return (RIG_OK); } else { rig_debug(RIG_DEBUG_ERR, "%s: 1a 03 cmd failed\n", __func__); return (retval); } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return (RIG_OK); /* use default */ } if (res_len == 3 && resbuf[0] == C_CTL_MEM) { int i; i = (int) from_bcd(resbuf + 2, 2); rig_debug(RIG_DEBUG_TRACE, "%s: i=%d, [0]=%02x, [1]=%02x, [2]=%02x, [3]=%02x\n", __func__, i, resbuf[0], resbuf[1], resbuf[2], resbuf[3]); if (mode & RIG_MODE_AM) { if (i > 49) { rig_debug(RIG_DEBUG_ERR, "%s: Expected max 49, got %d for filter\n", __func__, i); RETURNFUNC2(-RIG_EPROTO); } return ((i + 1) * 200); /* All Icoms that we know of */ } else if (mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: using filtericom width=%d\n", __func__, i); if (i > sizeof(filtericom) / sizeof(int)) { i = 40; } RETURNFUNC2(filtericom[i]); } } RETURNFUNC2(RIG_OK); } int icom_set_dsp_flt(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval, rfstatus; unsigned char ackbuf[MAXFRAMELEN]; unsigned char flt_ext; value_t rfwidth; int ack_len = sizeof(ackbuf), flt_idx; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; unsigned char fw_sub_cmd = RIG_IS_IC7200 ? 0x02 : S_MEM_FILT_WDTH; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s, width=%d\n", __func__, rig_strrmode(mode), (int)width); if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(RIG_OK); } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } // TODO: Rename RIG_FUNC_RF to RIG_FUNC_RTTYFLT ? AMBIGUOUS! if (rig_has_get_func(rig, RIG_FUNC_RF) && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR))) { if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus) && (rfstatus)) { int i; for (i = 0; i < RTTY_FIL_NB; i++) { if (rtty_fil[i] == width) { rfwidth.i = i; RETURNFUNC(rig_set_ext_parm(rig, TOK_RTTY_FLTR, rfwidth)); } } /* not found */ RETURNFUNC(-RIG_EINVAL); } } if (priv->no_1a_03_cmd == ENUM_1A_03_NO) { RETURNFUNC(RIG_OK); } // don't bother to try since it doesn't work if (mode & RIG_MODE_AM) { flt_idx = (width / 200) - 1; /* TBC: IC_7800? */ } else if (mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB)) { if (width == 0) { width = 1; } flt_idx = width <= 500 ? ((width + 49) / 50) - 1 : ((width + 99) / 100) + 4; if (flt_idx > 40) { flt_idx = 40; } } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(RIG_OK); } to_bcd(&flt_ext, flt_idx, 2); rig_debug(RIG_DEBUG_VERBOSE, "%s: flt_ext=%d, flt_idx=%d\n", __func__, flt_ext, flt_idx); retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, &flt_ext, 1, ackbuf, &ack_len); if (-RIG_ERJCTED == retval) { if (priv->no_1a_03_cmd == ENUM_1A_03_UNK) { priv->no_1a_03_cmd = ENUM_1A_03_NO; /* do not keep asking */ RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_ERR, "%s: 1A 03 %02x failed\n", __func__, flt_ext); RETURNFUNC(retval); } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(retval); } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_mode_without_data * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int icom_set_mode_without_data(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; const struct icom_priv_data *priv_data = (const struct icom_priv_data *) rs->priv; unsigned char ackbuf[MAXFRAMELEN]; unsigned char icmode; signed char icmode_ext; int ack_len = sizeof(ackbuf); int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, mode=%s, width=%d, current_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int) width, rig_strvfo(rs->current_vfo)); // We can assume here that mode is not targetable and that VFO swapping has been performed if (priv_caps->r2i_mode != NULL) { retval = priv_caps->r2i_mode(rig, vfo, mode, width, &icmode, &icmode_ext); } else { retval = rig2icom_mode(rig, vfo, mode, width, &icmode, &icmode_ext); } if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error on rig2icom_mode, result=%d\n", __func__, retval); RETURNFUNC2(retval); } if (width == RIG_PASSBAND_NOCHANGE) { icmode_ext = priv_data->filter; } rig_debug(RIG_DEBUG_VERBOSE, "%s: icmode=%d, icmode_ext=%d\n", __func__, icmode, icmode_ext); /* IC-375, IC-731, IC-726, IC-735, IC-910, IC-7000 don't support passband data */ /* IC-726 & IC-475A/E also limited support - only on CW */ /* TODO: G4WJS CW wide/narrow are possible with above two radios */ if (priv->civ_731_mode || RIG_IS_OS456 || RIG_IS_IC375 || RIG_IS_IC726 || RIG_IS_IC475 || RIG_IS_IC746 || RIG_IS_IC746PRO || RIG_IS_IC756 || RIG_IS_IC756PROII || RIG_IS_IC756PROIII || RIG_IS_IC910 || RIG_IS_IC7000) { icmode_ext = -1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: #2 icmode=%d, icmode_ext=%d\n", __func__, icmode, icmode_ext); retval = icom_transaction(rig, C_SET_MODE, icmode, (unsigned char *) &icmode_ext, (icmode_ext == -1 ? 0 : 1), ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } icom_set_dsp_flt(rig, vfo, mode, width); RETURNFUNC2(RIG_OK); } static int icom_get_mode_x26(RIG *rig, vfo_t vfo, int *mode_len, unsigned char *modebuf) { struct icom_priv_data *priv = STATE(rig)->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; if (priv->x26cmdfails > 0 && priv_caps->x25x26_always == 0) { rig_debug(RIG_DEBUG_WARN, "%s: x26cmdfails=%d, x25x26_always=%d\n", __func__, priv->x26cmdfails, priv_caps->x25x26_always); return -RIG_ENAVAIL; } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, vfo_number=%d\n", __func__, rig_strvfo(vfo), vfo_number); retval = icom_transaction(rig, C_SEND_SEL_MODE, vfo_number, NULL, 0, modebuf, mode_len); if (priv->x26cmdfails < 0 || priv_caps->x25x26_always) { priv->x26cmdfails = (retval == RIG_OK) ? 0 : 1; } if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: mode_len=%d, modebuf=%02x %02x %02x %02x %02x\n", __func__, *mode_len, modebuf[0], modebuf[1], modebuf[2], modebuf[3], modebuf[4]); priv->filter = modebuf[4]; return RIG_OK; } static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, rmode_t icom_mode, int datamode, int filter, pbwidth_t width) { struct icom_priv_data *priv = STATE(rig)->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; unsigned char buf[3]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int buf_len = 3; int mode_len; unsigned char mode_buf[5]; if (priv->x26cmdfails > 0 && !priv_caps->x25x26_always) { return -RIG_ENAVAIL; } icom_get_mode_x26(rig, vfo, &mode_len, mode_buf); buf[0] = icom_mode; buf[1] = datamode; // Skip filter selection, because at least IC-7300 has a bug defaulting to filter 2 when changing mode // Tested on IC-7300 and IC-9700 buf[2] = priv->filter; if (mode == RIG_MODE_FM || mode == RIG_MODE_WFM) { // we use the passed in filter for FM mode widths buf[2] = filter; } //rig_debug(RIG_DEBUG_TRACE, "%s: mode=%ld, filters usbd=%d, usb=%d, cw=%d\n", // __func__, mode, priv->filter_usbd, priv->filter_usb, priv->filter_cw); if (priv->filter_usbd > 0 && (mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter usbd=%d, width=%d\n", __func__, priv->filter_usbd, (int)width); buf[2] = priv->filter_usbd; if (width >= 1 && width <= 3) { buf[2] = width; } if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (priv->filter_usb > 0 && (mode == RIG_MODE_USB || mode == RIG_MODE_LSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter usb=%d\n", __func__, priv->filter_usb); buf[2] = priv->filter_usb; if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (priv->filter_cw > 0 && (mode == RIG_MODE_CW || mode == RIG_MODE_CWR)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter cw=%d\n", __func__, priv->filter_cw); buf[2] = priv->filter_cw; if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (mode == RIG_MODE_FM || mode == RIG_MODE_PKTFM) { rig_debug(RIG_DEBUG_TRACE, "%s: width=%d\n", __func__, (int)width); buf[2] = width; if (width > 10000) { buf[2] = 1; } else if (width > 7000) { buf[2] = 2; } else if (width > 3) { buf[2] = 3; } // Set "normal" bandwidth explicitly here // when width is zero or even less // (namely RIG_PASSBAND_NORMAL or RIG_PASSBAND_NOCHANGE) else if (width < 1) { buf[2] = 1; } if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (mode == RIG_MODE_WFM) { rig_debug(RIG_DEBUG_TRACE, "%s: wfm_width=%d\n", __func__, (int)width); // For IC-705, there's only one filter mode for WFM // So set always to 1 buf[2] = 1; if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, vfo_number=%d\n", __func__, rig_strvfo(vfo), vfo_number); // allow width of 1,2,3 to set explicit filter if (width >= 1 && width <= 3) { buf[2] = width; } retval = icom_transaction(rig, C_SEND_SEL_MODE, vfo_number, buf, buf_len, ackbuf, &ack_len); if (priv->x26cmdfails < 0 || priv_caps->x25x26_always) { priv->x26cmdfails = (retval == RIG_OK) ? 0 : 1; } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { return retval; } return RIG_OK; } /* * icom_set_mode */ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct rig_state *rs = STATE(rig); const struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; rmode_t base_mode; rmode_t current_mode; pbwidth_t current_width; int is_data_mode = 0; unsigned char dm_sub_cmd = RIG_IS_IC7200 ? 0x04 : S_MEM_DATA_MODE; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; ENTERFUNC; // Icom 0x26 command can only manipulate VFO A/B *or* VFO Main/Sub modes. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver modes must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!priv_caps->data_mode_supported) { // Use legacy command to set mode if data mode is not supported retval = icom_set_mode_without_data(rig, vfo, mode, width); if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC(retval); } // Do nothing if current mode and width is not changing // Reading mode also sets priv->filter to current filter choice retval = rig_get_mode(rig, vfo, ¤t_mode, ¤t_width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } switch (mode) { case RIG_MODE_PKTUSB: base_mode = RIG_MODE_USB; is_data_mode = 1; break; case RIG_MODE_PKTLSB: base_mode = RIG_MODE_LSB; is_data_mode = 1; break; case RIG_MODE_PKTFM: base_mode = RIG_MODE_FM; is_data_mode = 1; break; case RIG_MODE_PKTAM: base_mode = RIG_MODE_AM; is_data_mode = 1; break; default: base_mode = mode; break; } rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d, width=%d, current_vfo=%s\n", __func__, (int) base_mode, (int) width, rig_strvfo(rs->current_vfo)); // It is only necessary to change base mode if command 0x26 is not supported if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = icom_set_mode_without_data(rig, vfo, base_mode, width); } else { retval = RIG_OK; } if (retval == RIG_OK && (mode != current_mode || width != RIG_PASSBAND_NOCHANGE)) { unsigned char datamode[2]; unsigned char mode_icom; // Not used, we only need the width signed char width_icom; HAMLIB_TRACE; datamode[0] = is_data_mode ? 0x01 : 0x00; // Do not change the current filter datamode[1] = priv->filter; if (priv_caps->r2i_mode != NULL) { retval = priv_caps->r2i_mode(rig, vfo, mode, width, &mode_icom, &width_icom); } else { retval = rig2icom_mode(rig, vfo, mode, width, &mode_icom, &width_icom); } if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error on rig2icom_mode, result=%d\n", __func__, retval); RETURNFUNC(retval); } // Check if the filter width byte is needed if (priv_caps->mode_with_filter) { HAMLIB_TRACE; // allow 1,2,3 values to set filter number if (width >= 1 && width <= 3) { datamode[1] = width; } if (datamode[0] == 0) { datamode[1] = 0; } // the only good combo possible according to manual // we need to let FM mode widths through here with datamode[1] set to FM width // (This is not applicable to WFM) if ((priv_caps->fm_filters[0] != 0) && (mode == RIG_MODE_FM)) { // assumed fm_filters is ascending sequence -- see ic7300.c for example if (width >= 1 && width <= 3) { datamode[1] = width; } else if (width <= priv_caps->fm_filters[0]) { datamode[1] = 3; } else if (width <= priv_caps->fm_filters[1]) { datamode[1] = 2; } else { datamode[1] = 1; } if (width > 3) { rig_debug(RIG_DEBUG_WARN, "%s: IC7300 width set by 1,2,3 - adjustable width not implemented yet\n", __func__); } } rig_debug(RIG_DEBUG_TRACE, "%s(%d) mode_icom=%d, datamode=%d, filter=%d\n", __func__, __LINE__, mode_icom, datamode[0], datamode[1]); if (force_vfo_swap) { retval = -RIG_ENAVAIL; } else { if (datamode[0] == 0) { datamode[1] = 0; } // For IC-705, this is the only valid values for WFM if (RIG_IS_IC705 && (mode == RIG_MODE_WFM)) { datamode[0] = 0; datamode[1] = 1; } retval = icom_set_mode_x26(rig, vfo, mode, mode_icom, datamode[0], datamode[1], width); } if (retval != RIG_OK) { HAMLIB_TRACE; retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 2, ackbuf, &ack_len); } } else { HAMLIB_TRACE; retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 1, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } else { if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } } } } // no change and not setting filter number either if (width <= 3) { rig_debug(RIG_DEBUG_TRACE, "%s: setting filter=%d\n", __func__, (int)width); RETURNFUNC(RIG_OK); } if (((width != RIG_PASSBAND_NOCHANGE) && (width != current_width)) || (priv->filter_usbd > 0 || priv->filter_usb > 0 || priv->filter_cw > 0 || priv->filter_fm > 0)) { icom_set_dsp_flt(rig, vfo, mode, width); } else { rig_debug(RIG_DEBUG_TRACE, "%s: width not changing, keeping filter selection\n", __func__); } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } RETURNFUNC(retval); } /* * icom_get_mode_without_data * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL, width!=NULL * * TODO: IC-781 doesn't send filter width in wide filter mode, making the frame 1 byte short. */ static int icom_get_mode_without_data(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width, int force_vfo_swap) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv_data = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char modebuf[MAXFRAMELEN]; int mode_len; int retval; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); *width = 0; HAMLIB_TRACE; // Use command 0x26 to get selected/unselected or Main/Sub VFO mode, data mode and filter width // IC-7800 can set, but not read with 0x26 (although manual states otherwise?) if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && !RIG_IS_IC7800 && !force_vfo_swap) { retval = icom_get_mode_x26(rig, vfo, &mode_len, modebuf); if (retval == RIG_OK) { // mode_len=5, modebuf=26 01 01 01 01 // last 3 bytes are mode, datamode, filter (1-3) priv_data->datamode = modebuf[3]; *width = priv_data->filter = modebuf[4]; modebuf[1] = modebuf[2]; // copy mode to 2-byte format modebuf[2] = modebuf[4]; // copy filter to 2-byte format mode_len = 2; } else if (retval == -RIG_ENAVAIL) // In case it's been disabled { retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); } } else { retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); } if (--mode_len == 3) { // cppcheck-suppress redundantAssignment priv_data->filter = modebuf[2]; rig_debug(RIG_DEBUG_TRACE, "%s(%d): modebuf[0]=0x%02x, modebuf[1]=0x%02x, modebuf[2]=0x%02x, mode_len=%d, filter=%d\n", __func__, __LINE__, modebuf[0], modebuf[1], modebuf[2], mode_len, priv_data->filter); } else { priv_data->filter = 1; if (mode_len == 2) { priv_data->filter = modebuf[1]; } rig_debug(RIG_DEBUG_TRACE, "%s(%d): modebuf[0]=0x%02x, modebuf[1]=0x%02x, mode_len=%d\n", __func__, __LINE__, modebuf[0], modebuf[1], mode_len); } if (retval != RIG_OK) { RETURNFUNC2(retval); } /* * modebuf should contain Cn,Data area */ if (mode_len != 2 && mode_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, mode_len); RETURNFUNC2(-RIG_ERJCTED); } if (priv_caps->i2r_mode != NULL) { priv_caps->i2r_mode(rig, modebuf[1], mode_len == 2 ? modebuf[2] : -1, mode, width); } else { // we use width to pass in FM width for some rigs to i2r_mode icom2rig_mode(rig, modebuf[1], mode_len == 2 ? modebuf[2] : -1, mode, width); } if ((RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) && (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM || *mode == RIG_MODE_WFM)) { // we already have width from icom2rig_mode RETURNFUNC2(RIG_OK); } // The following rigs do not support querying filter width if ((RIG_IS_IC910) || (RIG_IS_OMNIVIP) || (RIG_IS_IC706) || (RIG_IS_IC706MKII) || (RIG_IS_IC706MKIIG) || (RIG_IS_IC756) || (RIG_IS_IC756PROII) || (RIG_IS_IC756PROIII) || (RIG_IS_ICR30)) { RETURNFUNC2(RIG_OK); } /** * Most rigs return 1-wide, 2-normal, 3-narrow * * For DSP rigs these are presets that can be programmed for 30 - 41 bandwidths, depending on mode. * * The DSP filter width can be read only for the selected VFO, so use cached width for other VFOs. */ pbwidth_t filter_width = 1; if (vfo == rs->current_vfo) { if (!((RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) && (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM))) // can't do this in FM mode { filter_width = icom_get_dsp_flt(rig, *mode); } } else { freq_t freq_cached; rmode_t mode_cached; pbwidth_t width_cached = 0; int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, &freq_cached, &cache_ms_freq, &mode_cached, &cache_ms_mode, &width_cached, &cache_ms_width); filter_width = width_cached; } *width = filter_width; if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 12000; // some default to 12000 if (RIG_IS_IC7300 || RIG_IS_IC9700 || RIG_IS_IC705) { if (priv_data->filter == 1) { *width = 15000; } else if (priv_data->filter == 2) { *width = 10000; } else if (priv_data->filter == 3) { *width = 7000; } } } else if (*mode == RIG_MODE_WFM) { // IC-705 only valid value if (RIG_IS_IC705) { *width = 200000; } } RETURNFUNC2(RIG_OK); } /* * icom_get_mode */ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char databuf[MAXFRAMELEN]; int data_len, retval; unsigned char dm_sub_cmd = RIG_IS_IC7200 ? 0x04 : S_MEM_DATA_MODE; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); // Icom 0x26 command can only manipulate VFO A/B *or* VFO Main/Sub modes. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver modes must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = icom_get_mode_without_data(rig, vfo, mode, width, force_vfo_swap); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d\n", __func__, (int) *mode); // Do not query data mode state for rigs that do not support them if (!priv_caps->data_mode_supported) { if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC2(retval); } switch (*mode) { case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_AM: case RIG_MODE_FM: // Check data mode state for the modes above if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && !force_vfo_swap) { // The data mode state is already read using command 0x26 for rigs with targetable mode // Fake the response in databuf databuf[2] = priv->datamode; data_len = 3; } else { retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, 0, 0, databuf, &data_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __func__, databuf[0], data_len); RETURNFUNC2(-RIG_ERJCTED); } } /* * databuf should contain Cn,Sc,D0[,D1] */ data_len -= 2; if (data_len < 1 || data_len > 2) { /* manual says 1 byte answer but at least IC756 ProIII sends 2 - second byte appears to be same as second byte from 04 command which is filter preset number, whatever it is we ignore it */ rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, data_len); RETURNFUNC2(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_VERBOSE, "%s databuf[2]=%d, mode=%d\n", __func__, (int)databuf[2], (int)*mode); // 0x01/0x02/0x03 -> data mode, 0x00 -> not data mode if (databuf[2]) { switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_AM: *mode = RIG_MODE_PKTAM; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; default: break; } } default: break; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC2(retval); } /* * icom_get_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Only some recent Icom rigs support reading the selected band (between Main/Sub). * Even then, they cannot distinguish between VFO A/B. * * Supported rigs so far: IC-7600 (firmware version 2.0+), IC-7610, IC-7800 (firmware version 3.1+), IC-785x * While IC-9700 supports the command too, it provides Main A/B and Sub A/B VFOs too, where A/B selection * cannot be detected. */ int icom_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; // TODO: Detect if the command is available for IC-7600 and IC-7800 // -> If not, return cached or -RIG_ENAVAIL? retval = icom_transaction(rig, C_SET_VFO, S_BAND_SEL, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error reading receiver/band selection: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (ackbuf[2] == 0) { *vfo = RIG_VFO_MAIN; } else { *vfo = RIG_VFO_SUB; } RETURNFUNC(RIG_OK); } /* * icom_set_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_vfo(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), icvfo, retval; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Main changed to %s\n", __func__, rig_strvfo(vfo)); } else if ((vfo == RIG_VFO_SUB) && (VFO_HAS_A_B_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode))) { // if rig doesn't have Main/Sub // or if rig has both Main/Sub and A/B -- e.g. 9700 // and we don't have split or satmode turned on // then we don't use Sub -- instead we use Main/VFOB vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Sub changed to %s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); vfo = RIG_VFO_A; if (VFO_HAS_A_B_ONLY && cachep->satmode) { vfo = RIG_VFO_B; } else if (VFO_HAS_MAIN_SUB_ONLY) { vfo = RIG_VFO_SUB; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode) { vfo = RIG_VFO_SUB; } } else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) && VFO_HAS_DUAL) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s, split=%d\n", __func__, __LINE__, rig_strvfo(vfo), cachep->split); // If we're being asked for A/Main but we are a MainA/MainB rig change it vfo = RIG_VFO_MAIN; if (cachep->split == RIG_SPLIT_ON && !cachep->satmode) { vfo = RIG_VFO_A; } // Seems the IC821H reverses Main/Sub when in satmode if (RIG_IS_IC821H && cachep->satmode) { vfo = RIG_VFO_SUB; } } else if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) && VFO_HAS_DUAL) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); // If we're being asked for B/Sub but we are a MainA/MainB rig change it vfo = RIG_VFO_SUB; // If we're in satmode for rigs like IC9700 we want the 2nd VFO if (cachep->satmode) { vfo = RIG_VFO_SUB_A; } else if (cachep->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } // Seems the IC821H reverses Main/Sub when in satmode if (RIG_IS_IC821H && cachep->satmode) { vfo = RIG_VFO_MAIN; } } else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B && VFO_HAS_MAIN_SUB) { // If we're being asked for A/B but we are a Main/Sub rig change it vfo_t vfo_old = vfo; vfo = vfo == RIG_VFO_A ? RIG_VFO_MAIN : RIG_VFO_SUB; rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO A/B?\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: Mapping %s=%s\n", __func__, rig_strvfo(vfo_old), rig_strvfo(vfo)); } if ((vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) && !VFO_HAS_MAIN_SUB) { rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO Main/Sub?\n", __func__); RETURNFUNC2(-RIG_EINVAL); } if (vfo != rs->current_vfo) { rig_debug(RIG_DEBUG_TRACE, "%s: VFO changing from %s to %s\n", __func__, rig_strvfo(rs->current_vfo), rig_strvfo(vfo)); cachep->freqCurr = 0; // reset current frequency so set_freq works 1st time } rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); switch (vfo) { case RIG_VFO_A: icvfo = S_VFOA; break; case RIG_VFO_B: icvfo = S_VFOB; break; case RIG_VFO_MAIN: icvfo = S_MAIN; // If not split or satmode then we must want VFOA if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode) { icvfo = S_VFOA; } rig_debug(RIG_DEBUG_TRACE, "%s: Main asked for, ended up with vfo=%s\n", __func__, icvfo == S_MAIN ? "Main" : "VFOA"); break; case RIG_VFO_SUB: icvfo = S_SUB; // If split is on these rigs can only split on Main/VFOB if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { icvfo = S_VFOB; } // If not split or satmode then we must want VFOB if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode) { icvfo = S_VFOB; } rig_debug(RIG_DEBUG_TRACE, "%s: Sub asked for, ended up with vfo=%s\n", __func__, icvfo == S_SUB ? "Sub" : "VFOB"); break; case RIG_VFO_TX: icvfo = (cachep->split != RIG_SPLIT_OFF) ? S_VFOB : S_VFOA; vfo = (cachep->split != RIG_SPLIT_OFF) ? RIG_VFO_B : RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX changing vfo to %s\n", __func__, rig_strvfo(vfo)); break; case RIG_VFO_VFO: retval = icom_transaction(rig, C_SET_VFO, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); case RIG_VFO_MEM: retval = icom_transaction(rig, C_SET_MEM, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); case RIG_VFO_MAIN_A: // we need to select Main before setting VFO case RIG_VFO_MAIN_B: rig_debug(RIG_DEBUG_VERBOSE, "%s: MainA/B logic\n", __func__); retval = icom_transaction(rig, C_SET_VFO, S_MAIN, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } icvfo = vfo == RIG_VFO_MAIN_A ? S_VFOA : S_VFOB; break; case RIG_VFO_SUB_A: // we need to select Sub before setting VFO case RIG_VFO_SUB_B: rig_debug(RIG_DEBUG_VERBOSE, "%s: SubA/B logic\n", __func__); retval = icom_transaction(rig, C_SET_VFO, S_SUB, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } // If SUB_A then we'll assume we're done and probably not in sat mode // If rig has SUB_B active this may be a problem if (vfo == RIG_VFO_SUB_A) { return RIG_OK; } icvfo = vfo == RIG_VFO_SUB_A ? S_VFOA : S_VFOB; break; case RIG_VFO_OTHER: switch (rs->current_vfo) { case RIG_VFO_CURR: break; // no change needed case RIG_VFO_A: vfo = RIG_VFO_B; icvfo = S_VFOB; break; case RIG_VFO_B: vfo = RIG_VFO_A; icvfo = S_VFOA; break; case RIG_VFO_MAIN: vfo = RIG_VFO_SUB; icvfo = S_SUB; break; case RIG_VFO_SUB: vfo = RIG_VFO_MAIN; icvfo = S_MAIN; break; case RIG_VFO_MAIN_A: vfo = RIG_VFO_MAIN_B; icvfo = S_MAIN; // TODO: Select also VFOB? break; case RIG_VFO_MAIN_B: vfo = RIG_VFO_MAIN_A; icvfo = S_MAIN; // TODO: Select also VFOA? break; case RIG_VFO_SUB_A: vfo = RIG_VFO_SUB_B; icvfo = S_SUB; // TODO: Select also VFOB? break; case RIG_VFO_SUB_B: vfo = RIG_VFO_SUB_A; icvfo = S_SUB; // TODO: Select also VFOA? break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown vfo '%s'\n", __func__, rig_strvfo(rs->current_vfo)); } default: if (priv->x25cmdfails == 0 || priv_caps->x25x26_always) rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); retval = icom_transaction(rig, C_SET_VFO, icvfo, NULL, 0, ackbuf, &ack_len); rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: line#%d curr_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } int icom_set_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t val) { ENTERFUNC; unsigned char cmdbuf[MAXFRAMELEN]; int cmdlen = 0; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = 0; if (!(par->submod & SC_MOD_WR)) { RETURNFUNC(-RIG_EINVAL); } if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12) { cmdbuf[0] = 0x01; cmdlen = 1; } else { cmdlen = par->sublen; memcpy(cmdbuf, par->subext, cmdlen); } int wrd = val.i; int i; switch (par->dattyp) { case CMD_DAT_WRD: for (i = 1; i <= par->datlen; i++) { cmdbuf[cmdlen + par->datlen - i] = wrd & 0xff; wrd >>= 8; } break; case CMD_DAT_BUF: memcpy(&cmdbuf[cmdlen], val.b.d, par->datlen); break; case CMD_DAT_INT: case CMD_DAT_BOL: to_bcd_be(&cmdbuf[cmdlen], val.i, (par->datlen * 2)); break; case CMD_DAT_FLT: to_bcd_be(&cmdbuf[cmdlen], (int) val.f, (par->datlen * 2)); break; case CMD_DAT_LVL: to_bcd_be(&cmdbuf[cmdlen], (int)(val.f * 255.0), (par->datlen * 2)); break; case CMD_DAT_TIM: // returned as seconds since midnight to_bcd_be(&cmdbuf[cmdlen], ((((int)val.i / 3600) * 100) + (((int)val.i / 60) % 60)), (par->datlen * 2)); break; default: break; } cmdlen += par->datlen; RETURNFUNC(icom_transaction(rig, par->command, par->subcmd, cmdbuf, cmdlen, ackbuf, &ack_len)); } int icom_get_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t *val) { ENTERFUNC; unsigned char ssc = 0x02; unsigned char resbuf[MAXFRAMELEN]; int reslen = sizeof(resbuf); int retval; if (!(par->submod & SC_MOD_RD)) { RETURNFUNC(-RIG_EINVAL); } if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12) { retval = icom_get_raw_buf(rig, par->command, par->subcmd, 1, &ssc, &reslen, resbuf); } else { retval = icom_get_raw_buf(rig, par->command, par->subcmd, par->sublen, (unsigned char *)par->subext, &reslen, resbuf); } if (retval != RIG_OK) { RETURNFUNC(retval); } switch (par->dattyp) { case CMD_DAT_WRD: { int wrd = 0; int i; for (i = 0; i < par->datlen; i++) { wrd = (wrd << 8) + resbuf[i]; } val->i = wrd; } break; case CMD_DAT_STR: if (strlen(val->s) < reslen) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(val->s, resbuf, reslen); val->s[reslen] = 0; break; case CMD_DAT_BUF: if (reslen > val->b.l) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(val->b.d, resbuf, reslen); val->b.l = reslen; break; case CMD_DAT_INT: val->i = from_bcd_be(resbuf, (reslen * 2)); break; case CMD_DAT_FLT: val->f = (float) from_bcd_be(resbuf, (reslen * 2)); break; case CMD_DAT_LVL: val->f = (float) from_bcd_be(resbuf, (reslen * 2)) / 255.0; break; case CMD_DAT_BOL: val->i = (from_bcd_be(resbuf, (reslen * 2)) == 0) ? 0 : 1; break; case CMD_DAT_TIM: val->i = (from_bcd_be(resbuf, 2) * 3600) + (from_bcd_be(&resbuf[1], 2) * 60); break; default: val->i = 0; break; } RETURNFUNC(RIG_OK); } /* * icom_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs = STATE(rig); unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int cmd_len, ack_len = sizeof(ackbuf); int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int i, retval; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; ENTERFUNC; const struct cmdparams *extcmds = priv_caps->extcmds; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val)); } } /* * Many levels of float type are in [0.0..1.0] range */ if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = val.f * 255; } else { icom_val = val.i; } /* convert values to 0 .. 255 range */ if (RIG_IS_ICR75) { switch (level) { case RIG_LEVEL_NR: icom_val = val.f * 240; break; case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: icom_val = (val.f / 10.0) + 128; if (icom_val > 255) { icom_val = 255; } break; default: break; } } switch (level) { int i; case RIG_LEVEL_KEYSPD: if (val.i < 6) { icom_val = 6; } else if (val.i > 48) { icom_val = 48; } for (i = 0; i < 43; ++i) { if (icom_val == cw_lookup[i][1]) { icom_val = cw_lookup[i][0]; rig_debug(RIG_DEBUG_ERR, "%s: found %d at i=%d\n", __func__, icom_val, i); break; } } break; case RIG_LEVEL_CWPITCH: if (val.i < 300) { icom_val = 300; } else if (val.i >= 900) { icom_val = 900; } icom_val = (int) lroundf(((float) icom_val - 300) * (255.0f / 600.0f)); break; default: break; } /* * Most of the time, the data field is a 3 digit BCD, * but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ cmd_len = 2; to_bcd_be(cmdbuf, (long long) icom_val, cmd_len * 2); switch (level) { case RIG_LEVEL_PREAMP: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_PAMP; cmd_len = 1; if (val.i == 0) { cmdbuf[0] = 0; /* 0=OFF */ break; } for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->preamp[i] == val.i) { break; } } if (i == HAMLIB_MAXDBLSTSIZ || rs->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp set_level %ddB\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = i + 1; /* 1=P.AMP1, 2=P.AMP2 */ break; case RIG_LEVEL_ATT: lvl_cn = C_CTL_ATT; /* attenuator level is dB, in BCD mode */ lvl_sc = (val.i / 10) << 4 | (val.i % 10); cmd_len = 0; break; case RIG_LEVEL_AF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_AF; break; case RIG_LEVEL_RF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RF; break; case RIG_LEVEL_SQL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_SQL; break; case RIG_LEVEL_IF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_IF; break; case RIG_LEVEL_APF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_APF; break; case RIG_LEVEL_NR: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; case RIG_LEVEL_NB: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NB; break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; break; case RIG_LEVEL_PBT_OUT: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTOUT; break; case RIG_LEVEL_CWPITCH: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; cmd_len = 3; cmdbuf[0] = S_PRM_CWPITCH; to_bcd_be(cmdbuf + 1, (long long) icom_val, 4); } break; case RIG_LEVEL_RFPOWER: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RFPOWER; break; case RIG_LEVEL_MICGAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MICGAIN; break; case RIG_LEVEL_KEYSPD: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; case RIG_LEVEL_COMP: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_COMP; break; case RIG_LEVEL_AGC_TIME: lvl_cn = C_CTL_MEM; lvl_sc = 0x04; cmd_len = 1; { icom_val = 0; const float *agcp = agc_level; if (rs->current_mode == RIG_MODE_AM) { agcp = agc_level2; } rig_debug(RIG_DEBUG_ERR, "%s: val.f=%f\n", __func__, val.f); for (i = 0; i <= 13; ++i) { if (agcp[i] <= val.f) { rig_debug(RIG_DEBUG_ERR, "%s: agcp=%f <= val.f=%f at %d\n", __func__, agcp[i], val.f, i); icom_val = i; } } cmdbuf[0] = icom_val; } break; case RIG_LEVEL_AGC: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_AGC; cmd_len = 1; if (priv_caps->agc_levels_present) { int found = 0; for (i = 0; i <= HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST; i++) { if (priv_caps->agc_levels[i].level == val.i) { cmdbuf[0] = priv_caps->agc_levels[i].icom_level; found = 1; break; } } if (!found) { RETURNFUNC(-RIG_EINVAL); } } else { // Legacy mapping that does not apply to all rigs switch (val.i) { case RIG_AGC_SLOW: cmdbuf[0] = D_AGC_SLOW; break; case RIG_AGC_MEDIUM: cmdbuf[0] = D_AGC_MID; break; case RIG_AGC_FAST: cmdbuf[0] = D_AGC_FAST; break; case RIG_AGC_SUPERFAST: cmdbuf[0] = D_AGC_SUPERFAST; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported LEVEL_AGC %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_BKINDL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BKINDL; break; case RIG_LEVEL_BALANCE: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BALANCE; break; case RIG_LEVEL_VOXGAIN: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_VOXGAIN; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_VOXGAIN; } break; case RIG_LEVEL_ANTIVOX: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_ANTIVOX; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_ANTIVOX; } break; case RIG_LEVEL_MONITOR_GAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MON; break; case RIG_LEVEL_SPECTRUM_MODE: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MOD; cmd_len = 2; switch (val.i) { case RIG_SPECTRUM_MODE_CENTER: icom_val = SCOPE_MODE_CENTER; break; case RIG_SPECTRUM_MODE_FIXED: icom_val = SCOPE_MODE_FIXED; break; case RIG_SPECTRUM_MODE_CENTER_SCROLL: icom_val = SCOPE_MODE_SCROLL_C; break; case RIG_SPECTRUM_MODE_FIXED_SCROLL: icom_val = SCOPE_MODE_SCROLL_F; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = icom_val; break; case RIG_LEVEL_SPECTRUM_SPAN: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SPN; cmd_len = 6; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); // Spectrum span is represented as a +/- value for Icom rigs to_bcd(cmdbuf + 1, val.i / 2, 5 * 2); break; case RIG_LEVEL_SPECTRUM_SPEED: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SWP; cmd_len = 2; if (val.i < 0) { val.i = 0; } else if (val.i > 2) { val.i = 2; } switch (val.i) { case 0: icom_val = SCOPE_SPEED_SLOW; break; case 1: icom_val = SCOPE_SPEED_MID; break; case 2: icom_val = SCOPE_SPEED_FAST; break; } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = icom_val; break; case RIG_LEVEL_SPECTRUM_REF: { float icom_db = (roundf(val.f * 2.0f) / 2.0f) * 100.0f; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_REF; cmd_len = 4; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); // Spectrum reference level is represented at 0.01dB accuracy, but needs to be rounded to nearest 0.5dB to_bcd_be(cmdbuf + 1, abs((int) icom_db), 2 * 2); // Sign cmdbuf[3] = (icom_db < 0) ? 1 : 0; break; } case RIG_LEVEL_SPECTRUM_EDGE_LOW: case RIG_LEVEL_SPECTRUM_EDGE_HIGH: { int range_id; value_t edge_number_value; value_t opposite_edge_value; setting_t level_opposite_edge = (level == RIG_LEVEL_SPECTRUM_EDGE_LOW) ? RIG_LEVEL_SPECTRUM_EDGE_HIGH : RIG_LEVEL_SPECTRUM_EDGE_LOW; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_FEF; cmd_len = 12; // Modify the frequency range currently active retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n", __func__); RETURNFUNC(retval); } // Modify the edge number currently active retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value); if (retval != RIG_OK) { RETURNFUNC(retval); } // Get the current opposite edge frequency retval = icom_get_level(rig, vfo, level_opposite_edge, &opposite_edge_value); if (retval != RIG_OK) { RETURNFUNC(retval); } to_bcd(cmdbuf, range_id, 1 * 2); to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2); if (level == RIG_LEVEL_SPECTRUM_EDGE_LOW) { to_bcd(cmdbuf + 2, val.i, 5 * 2); to_bcd(cmdbuf + 7, opposite_edge_value.i, 5 * 2); } else { to_bcd(cmdbuf + 2, opposite_edge_value.i, 5 * 2); to_bcd(cmdbuf + 7, val.i, 5 * 2); } break; } case RIG_LEVEL_SPECTRUM_ATT: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 2; for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) { if (rig->caps->spectrum_attenuator[i] == val.i) { break; } } if (val.i != 0 && (i == HAMLIB_MAXDBLSTSIZ || rig->caps->spectrum_attenuator[i] == 0)) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum attenuator level %ddB\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); to_bcd(cmdbuf + 1, val.i, 5 * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL * */ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs; unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN]; int cmd_len, resp_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int cmdhead; int retval; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; ENTERFUNC; const struct cmdparams *extcmds = priv_caps->extcmds; int i; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { //rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i); if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level) { RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val)); } } rig_debug(RIG_DEBUG_TRACE, "%s: no extcmd found\n", __func__); rs = STATE(rig); cmd_len = 0; switch (level) { case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: lvl_cn = C_RD_SQSM; lvl_sc = S_SML; break; case RIG_LEVEL_ALC: lvl_cn = C_RD_SQSM; lvl_sc = S_ALC; break; case RIG_LEVEL_SWR: lvl_cn = C_RD_SQSM; lvl_sc = S_SWR; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: lvl_cn = C_RD_SQSM; lvl_sc = S_RFML; break; case RIG_LEVEL_COMP_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_CMP; break; case RIG_LEVEL_VD_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_VD; break; case RIG_LEVEL_ID_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_ID; break; case RIG_LEVEL_PREAMP: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_PAMP; break; case RIG_LEVEL_ATT: lvl_cn = C_CTL_ATT; lvl_sc = -1; break; case RIG_LEVEL_AF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_AF; break; case RIG_LEVEL_RF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RF; break; case RIG_LEVEL_SQL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_SQL; break; case RIG_LEVEL_IF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_IF; break; case RIG_LEVEL_APF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_APF; break; case RIG_LEVEL_NR: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; case RIG_LEVEL_NB: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NB; break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; break; case RIG_LEVEL_PBT_OUT: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTOUT; break; case RIG_LEVEL_CWPITCH: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; cmd_len = 1; cmdbuf[0] = S_PRM_CWPITCH; } break; case RIG_LEVEL_RFPOWER: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RFPOWER; break; case RIG_LEVEL_MICGAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MICGAIN; break; case RIG_LEVEL_KEYSPD: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; case RIG_LEVEL_COMP: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_COMP; break; case RIG_LEVEL_AGC: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_AGC; break; case RIG_LEVEL_BKINDL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BKINDL; break; case RIG_LEVEL_BALANCE: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BALANCE; break; case RIG_LEVEL_VOXGAIN: /* IC-910H */ if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_VOXGAIN; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_VOXGAIN; } break; case RIG_LEVEL_ANTIVOX: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_ANTIVOX; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_ANTIVOX; } break; case RIG_LEVEL_MONITOR_GAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MON; break; case RIG_LEVEL_SPECTRUM_MODE: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MOD; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_SPAN: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SPN; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_SPEED: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SWP; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_REF: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_REF; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_EDGE_LOW: case RIG_LEVEL_SPECTRUM_EDGE_HIGH: { int range_id; value_t edge_number_value; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_FEF; cmd_len = 2; // Get the frequency range currently active retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n", __func__); RETURNFUNC(retval); } // Get the edge number currently active retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value); if (retval != RIG_OK) { RETURNFUNC(retval); } to_bcd(cmdbuf, range_id, 1 * 2); to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2); break; } case RIG_LEVEL_SPECTRUM_ATT: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_USB_AF: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 1; break; case RIG_LEVEL_AGC_TIME: lvl_cn = C_CTL_MEM; lvl_sc = 0x04; // IC-9700, 7300, 705 so far cmd_len = 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } /* use cmdbuf and cmd_len for 'set mode' subcommand */ retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf, &resp_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len; resp_len -= cmdhead; if (respbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, respbuf[0], resp_len); RETURNFUNC(-RIG_ERJCTED); } /* * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2); switch (level) { case RIG_LEVEL_STRENGTH: val->i = round(rig_raw2val(icom_val, &rig->caps->str_cal)); break; case RIG_LEVEL_RAWSTR: /* raw value */ val->i = icom_val; break; case RIG_LEVEL_AGC: if (priv_caps->agc_levels_present) { int found = 0; for (i = 0; i <= HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level >= 0; i++) { if (priv_caps->agc_levels[i].icom_level == icom_val) { val->i = priv_caps->agc_levels[i].level; found = 1; break; } } if (!found) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } } else { switch (icom_val) { case D_AGC_SLOW: val->i = RIG_AGC_SLOW; break; case D_AGC_MID: val->i = RIG_AGC_MEDIUM; break; case D_AGC_FAST: val->i = RIG_AGC_FAST; break; case D_AGC_SUPERFAST: val->i = RIG_AGC_SUPERFAST; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } } break; case RIG_LEVEL_ALC: if (rig->caps->alc_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_alc_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->alc_cal); } break; case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_swr_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->swr_cal); } break; case RIG_LEVEL_RFPOWER_METER: // rig table in Watts needs to be divided by 100 if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal) * 0.01; } else { val->f = rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal) * 0.01; } break; case RIG_LEVEL_RFPOWER_METER_WATTS: { freq_range_t range_list; // All Icom backends should be in Watts now if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal); rig_debug(RIG_DEBUG_TRACE, "%s: using rig table to convert %d to %.01f\n", __func__, icom_val, val->f); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal); rig_debug(RIG_DEBUG_TRACE, "%s: using default icom table to convert %d to %.01f\n", __func__, icom_val, val->f); } if (RIG_IS_IC9700 && CACHE(rig)->freqMainA >= 1e9) { val->f /= 10; // power scale is different for 10GHz } rig_get_range(&range_list, STATE(rig)->current_freq, STATE(rig)->current_mode); rig_debug(RIG_DEBUG_VERBOSE, "%s: maxpower=%d\n", __func__, range_list.high_power); break; } case RIG_LEVEL_COMP_METER: if (rig->caps->comp_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_comp_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->comp_meter_cal); } break; case RIG_LEVEL_VD_METER: if (rig->caps->vd_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_vd_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->vd_meter_cal); } break; case RIG_LEVEL_ID_METER: if (rig->caps->id_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_id_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->id_meter_cal); } break; case RIG_LEVEL_CWPITCH: val->i = (int) lroundf(300.0f + ((float) icom_val * 600.0f / 255.0f)); break; case RIG_LEVEL_KEYSPD: for (i = 0; i < 43; ++i) { int rigval = cw_lookup[i][0]; if (rigval >= icom_val) { icom_val = cw_lookup[i][1]; val->i = icom_val; break; } } if (i == 43) { rig_debug(RIG_DEBUG_ERR, "%s: did not find KEYSPD=%d\n", __func__, icom_val); } break; case RIG_LEVEL_PREAMP: if (icom_val == 0) { val->i = 0; break; } if (icom_val > HAMLIB_MAXDBLSTSIZ || rs->preamp[icom_val - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp get_level %ddB\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } val->i = rs->preamp[icom_val - 1]; break; case RIG_LEVEL_SPECTRUM_MODE: switch (icom_val) { case SCOPE_MODE_CENTER: val->i = RIG_SPECTRUM_MODE_CENTER; break; case SCOPE_MODE_FIXED: val->i = RIG_SPECTRUM_MODE_FIXED; break; case SCOPE_MODE_SCROLL_C: val->i = RIG_SPECTRUM_MODE_CENTER_SCROLL; break; case SCOPE_MODE_SCROLL_F: val->i = RIG_SPECTRUM_MODE_FIXED_SCROLL; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__, icom_val); RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_SPECTRUM_SPAN: icom_val = (int) from_bcd(respbuf + cmdhead, resp_len * 2); // Spectrum span is represented as a +/- value for Icom rigs val->i = icom_val * 2; break; case RIG_LEVEL_SPECTRUM_SPEED: switch (icom_val) { case SCOPE_SPEED_SLOW: val->i = 0; break; case SCOPE_SPEED_MID: val->i = 1; break; case SCOPE_SPEED_FAST: val->i = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum speed %d\n", __func__, icom_val); RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_SPECTRUM_REF: { unsigned char *icom_ref = respbuf + cmdhead; // Spectrum reference level is represented at 0.01dB accuracy, but is rounded to nearest 0.5dB float db = (float) from_bcd_be(icom_ref, 2 * 2) / 100.0f; // Sign if (icom_ref[2] != 0) { db = -db; } val->f = db; break; } case RIG_LEVEL_SPECTRUM_EDGE_LOW: val->i = (int) from_bcd(respbuf + cmdhead, 5 * 2); break; case RIG_LEVEL_SPECTRUM_EDGE_HIGH: val->i = (int) from_bcd(respbuf + cmdhead + 5, 5 * 2); break; case RIG_LEVEL_AGC_TIME: // some rigs have different level interpretaions for different modes if (rs->current_mode == RIG_MODE_AM) { val->f = agc_level2[icom_val]; } else { val->f = agc_level[icom_val]; } break; /* RIG_LEVEL_ATT/RIG_LEVEL_SPECTRUM_ATT: returned value is already an integer in dB (coded in BCD) */ default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float) icom_val / 255; } else { val->i = icom_val; } } /* convert values from 0 .. 255 range */ if (RIG_IS_ICR75) { switch (level) { case RIG_LEVEL_NR: val->f = (float) icom_val / 240; break; case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: if (icom_val == 255) { val->f = 1280.0; } else { val->f = (float)(icom_val - 128) * 10.0; } break; default: break; } } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len, icom_val, val->i, val->f); RETURNFUNC(RIG_OK); } int icom_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { const struct confparams *cfp = rig->caps->extlevels; unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int cmd_len, ack_len = sizeof(ackbuf); int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int i, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called: token=%ld int=%d float=%f\n", __func__, token, val.i, val.f); switch (token) { case TOK_SCOPE_MSS: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MSS; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_SDS: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SDS; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_STX: // TODO: Should be a func? if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_STX; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_CFQ: if (val.i < 0 || val.i > 2) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_CFQ; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_EDG: if (val.i < 0 || val.i > 3) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_EDG; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i + 1; break; case TOK_SCOPE_VBW: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_VBW; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i; break; case TOK_SCOPE_RBW: if (val.i < 0 || val.i > 2) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_RBW; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i; break; default: cfp = (cfp == NULL) ? icom_ext_levels : cfp; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_levels; i = 0; } else if (cfp[i].token == token) { RETURNFUNC2(icom_set_ext_cmd(rig, vfo, token, val)); } else { i++; } } rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_ext_level token: %ld\n", __func__, token); RETURNFUNC2(-RIG_EINVAL); } retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } int icom_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { const struct confparams *cfp = rig->caps->extlevels; unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN]; int cmd_len, resp_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int cmdhead; int retval; int i; ENTERFUNC; cmd_len = 0; lvl_sc = -1; switch (token) { case TOK_SCOPE_MSS: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MSS; break; case TOK_SCOPE_SDS: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SDS; break; case TOK_SCOPE_STX: // TODO: Should be a func? lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_STX; break; case TOK_SCOPE_CFQ: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_CFQ; break; case TOK_SCOPE_EDG: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_EDG; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case TOK_SCOPE_VBW: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_VBW; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case TOK_SCOPE_RBW: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_RBW; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; default: cfp = (cfp == NULL) ? icom_ext_levels : cfp; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_levels; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_get_ext_cmd(rig, vfo, token, val)); } else { i++; } } rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_ext_level token: %ld\n", __func__, token); RETURNFUNC(-RIG_EINVAL); } /* use cmdbuf and cmd_len for 'set mode' subcommand */ retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf, &resp_len); if (retval != RIG_OK) { RETURNFUNC(retval); } cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len; resp_len -= cmdhead; if (respbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, respbuf[0], resp_len); RETURNFUNC(-RIG_ERJCTED); } icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2); switch (token) { case TOK_SCOPE_EDG: val->i = icom_val - 1; break; default: val->i = icom_val; break; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len, icom_val, val->i, val->f); RETURNFUNC(RIG_OK); } int icom_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { ENTERFUNC; const struct confparams *cfp = rig->caps->extfuncs; cfp = (cfp == NULL) ? icom_ext_funcs : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_funcs; i = 0; } else if (cfp[i].token == token) { value_t value = { .i = status }; RETURNFUNC(icom_set_ext_cmd(rig, vfo, token, value)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { ENTERFUNC; const struct confparams *cfp = rig->caps->extfuncs; cfp = (cfp == NULL) ? icom_ext_funcs : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_funcs; i = 0; } else if (cfp[i].token == token) { value_t value; int result = icom_get_ext_cmd(rig, vfo, token, &value); if (result == RIG_OK) { *status = value.i; } RETURNFUNC(result); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { ENTERFUNC; const struct confparams *cfp = rig->caps->extparms; cfp = (cfp == NULL) ? icom_ext_parms : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_parms; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_set_ext_cmd(rig, RIG_VFO_NONE, token, val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { ENTERFUNC; const struct confparams *cfp = rig->caps->extparms; cfp = (cfp == NULL) ? icom_ext_parms : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_parms; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_get_ext_cmd(rig, RIG_VFO_NONE, token, val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int i; ENTERFUNC; for (i = 0; rig->caps->ext_tokens && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (rig->caps->ext_tokens[i] == token) { const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd; for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);) { if (cmd[i].id.t == 0) { cmd = icom_ext_cmd; i = 0; } else if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token) { RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } } RETURNFUNC(-RIG_EINVAL); } int icom_set_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int i; ENTERFUNC; for (i = 0; rig->caps->ext_tokens && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (rig->caps->ext_tokens[i] == token) { const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd; for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);) { if (cmd[i].id.t == 0) { cmd = icom_ext_cmd; i = 0; } else if (cmd->cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } } RETURNFUNC(-RIG_EINVAL); } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icom_priv_data *priv; struct rig_state *rs; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; switch (token) { case TOK_CIVADDR: if (val[0] == '0' && val[1] == 'x') { priv->re_civ_addr = strtol(val, (char **) NULL, 16); } else { priv->re_civ_addr = atoi(val); } break; case TOK_MODE731: priv->civ_731_mode = atoi(val) ? 1 : 0; break; case TOK_NOXCHG: priv->no_xchg = atoi(val) ? 1 : 0; break; case TOK_TONE_ENABLE: priv->tone_enable = atoi(val) ? 1 : 0; break; case TOK_FILTER_USBD: priv->filter_usbd = atoi(val); if (priv->filter_usbd > 3) { priv->filter_usbd = 3; } if (priv->filter_usbd < 1) { priv->filter_usbd = 1; } break; case TOK_FILTER_USB: priv->filter_usb = atoi(val); if (priv->filter_usb > 3) { priv->filter_usb = 3; } if (priv->filter_usb < 1) { priv->filter_usb = 1; } break; case TOK_FILTER_CW: priv->filter_cw = atoi(val); if (priv->filter_cw > 3) { priv->filter_cw = 3; } if (priv->filter_cw < 1) { priv->filter_cw = 1; } break; case TOK_FILTER_FM: priv->filter_fm = atoi(val); if (priv->filter_fm > 3) { priv->filter_fm = 3; } if (priv->filter_fm < 1) { priv->filter_fm = 1; } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int icom_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icom_priv_data *priv; struct rig_state *rs; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; switch (token) { case TOK_CIVADDR: SNPRINTF(val, val_len, "%d", priv->re_civ_addr); break; case TOK_MODE731: SNPRINTF(val, val_len, "%d", priv->civ_731_mode); break; case TOK_NOXCHG: SNPRINTF(val, val_len, "%d", priv->no_xchg); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int icom_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icom_get_conf2(rig, token, val, 128); } /* * icom_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[1]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; pttbuf[0] = ptt == RIG_PTT_ON ? 1 : 0; retval = icom_transaction(rig, C_CTL_PTT, S_PTT, pttbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icom_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { unsigned char pttbuf[MAXFRAMELEN]; int ptt_len, retval; int retry = 5; ENTERFUNC; do { retval = icom_transaction(rig, C_CTL_PTT, S_PTT, NULL, 0, pttbuf, &ptt_len); } while (--retry > 0 && retval != RIG_OK); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * pttbuf should contain Cn,Sc,Data area */ ptt_len -= 2; if (ptt_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ptt_len); RETURNFUNC(-RIG_ERJCTED); } *ptt = pttbuf[2] == 1 ? RIG_PTT_ON : RIG_PTT_OFF; RETURNFUNC(RIG_OK); } /* * icom_get_dcd * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icom_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char dcdbuf[MAXFRAMELEN]; int dcd_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_RD_SQSM, S_SQL, NULL, 0, dcdbuf, &dcd_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * dcdbuf should contain Cn,Data area */ dcd_len -= 2; if (dcd_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, dcd_len); RETURNFUNC(-RIG_ERJCTED); } /* * 0x00=sql closed, 0x01=sql open */ *dcd = dcdbuf[2] == 1 ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } /* * icom_set_rptr_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int rptr_sc; ENTERFUNC; switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rptr_sc = S_DUP_OFF; /* Simplex mode */ break; case RIG_RPT_SHIFT_MINUS: rptr_sc = S_DUP_M; /* Duplex - mode */ break; case RIG_RPT_SHIFT_PLUS: rptr_sc = S_DUP_P; /* Duplex + mode */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__, rptr_shift); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, C_CTL_SPLT, rptr_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_rptr_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rptr_shift!=NULL * will not work for IC-746 Pro * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF */ int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { unsigned char rptrbuf[MAXFRAMELEN]; int rptr_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0, rptrbuf, &rptr_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * rptrbuf should contain Cn,Sc */ rptr_len--; if (rptr_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, rptr_len); RETURNFUNC(-RIG_ERJCTED); } switch (rptrbuf[1]) { case S_DUP_OFF: case S_DUP_DD_RPS: *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */ break; case S_DUP_M: *rptr_shift = RIG_RPT_SHIFT_MINUS; /* Duplex - mode */ break; case S_DUP_P: *rptr_shift = RIG_RPT_SHIFT_PLUS; /* Duplex + mode */ break; // The same command indicates split state, which means simplex mode case S_SPLT_OFF: case S_SPLT_ON: *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__, rptrbuf[1]); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * icom_set_rptr_offs * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int offs_len; unsigned char offsbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; const struct icom_priv_caps *priv_caps; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN; /* * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF */ to_bcd(offsbuf, rptr_offs / 100, offs_len * 2); retval = icom_transaction(rig, C_SET_OFFS, -1, offsbuf, offs_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_rptr_offs * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rptr_offs!=NULL */ int icom_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int offs_len; unsigned char offsbuf[MAXFRAMELEN]; int buf_len, retval; const struct icom_priv_caps *priv_caps; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN; retval = icom_transaction(rig, C_RD_OFFS, -1, NULL, 0, offsbuf, &buf_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * offsbuf should contain Cn */ buf_len--; if (buf_len != offs_len) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, buf_len); RETURNFUNC(-RIG_ERJCTED); } /* * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF */ *rptr_offs = from_bcd(offsbuf + 1, buf_len * 2) * 100; RETURNFUNC(RIG_OK); } /* * Helper function to go back and forth split VFO */ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); ENTERFUNC; // Initialize TX VFO if not done yet if (rs->tx_vfo == RIG_VFO_NONE || rs->tx_vfo == RIG_VFO_CURR || rs->tx_vfo == RIG_VFO_TX) { if (cachep->split == RIG_SPLIT_OFF) { rs->tx_vfo = rs->current_vfo; } else { rs->tx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, cachep->split); } } if (VFO_HAS_A_B_ONLY) { if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_A_B_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else if (VFO_HAS_MAIN_SUB_ONLY) { if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_MAIN_SUB_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else if (VFO_HAS_MAIN_SUB_A_B_ONLY) { int satmode = 0; // e.g. IC-9700 split on Main/Sub does not work // only Main VFOA/B and SubRx/MainTx split works if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // don't care about retval here, only care about satmode=1 if (satmode) { *rx_vfo = RIG_VFO_MAIN; *tx_vfo = RIG_VFO_SUB; cachep->satmode = 1; } else if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; cachep->satmode = 0; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_MAIN_SUB_A_B_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO setup\n", __func__); RETURNFUNC(-RIG_ENAVAIL); } RETURNFUNC(RIG_OK); } /* * icom_set_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_freq works for this rig * * Assumes also that the current VFO is the rx VFO. */ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d, tx_vfo=%s\n", __func__, cachep->satmode, rig_strvfo(rs->tx_vfo)); if (vfo == RIG_VFO_TX) { if (cachep->satmode) { vfo = RIG_VFO_SUB; } else { vfo = rs->tx_vfo; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo is now %s\n", __func__, rig_strvfo(vfo)); if (rs->current_vfo == RIG_VFO_NONE || rs->current_vfo == RIG_VFO_CURR) { HAMLIB_TRACE; retval = icom_set_default_vfo(rig); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_default_vfo failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } // Use the command 0x25 if the rig supports it // This eliminates VFO swapping and improves split operations if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (priv->x25cmdfails <= 0 || priv_caps->x25x26_always)) { int satmode = 0; // Return value is not important, as only satmode=1 means anything if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // only worth trying if not in satmode if (satmode == 0) { int freq_len; short retry_save; unsigned char freqbuf[32]; freq_len = priv->civ_731_mode ? 4 : 5; to_bcd(freqbuf, tx_freq, freq_len * 2); retry_save = rp->retry; rp->retry = 1; retval = icom_set_freq_x25(rig, vfo, tx_freq, freq_len, freqbuf); rp->retry = retry_save; if (retval == RIG_OK) { if (priv->tone_enable) { rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(retval); } } } if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap/set/swap\n", __func__); if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: rx_vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo)); HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ)) { retval = rig_set_vfo(rig, tx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = rig_set_freq(rig, tx_vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (VFO_HAS_MAIN_SUB_A_B_ONLY) { // Then we return the VFO to the rx_vfo rig_debug(RIG_DEBUG_TRACE, "%s: SATMODE split_on=%d rig so setting vfo to %s\n", __func__, cachep->split, rig_strvfo(rx_vfo)); HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ)) { retval = rig_set_vfo(rig, rx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { HAMLIB_TRACE; RETURNFUNC2(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if (priv->tone_enable) { rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(retval); } /* * icom_get_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rx_freq!=NULL, tx_freq!=NULL * icom_set_vfo,icom_get_freq works for this rig */ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); if (RIG_IS_IC910) { ptt_t ptt; retval = rig_get_ptt(rig, RIG_VFO_CURR, &ptt); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (ptt) { int cache_ms_freq; rig_get_cache_freq(rig, vfo, tx_freq, &cache_ms_freq); rig_debug(RIG_DEBUG_TRACE, "%s: ptt is on so returning last known freq\n", __func__); RETURNFUNC2(RIG_OK); } } rig_debug(RIG_DEBUG_VERBOSE, "%s curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); if (rs->current_vfo == RIG_VFO_NONE) { HAMLIB_TRACE; icom_set_default_vfo(rig); } // Use the command 0x25 if the rig supports it // This eliminates VFO swapping and improves split operations // This does not work in satellite mode for the IC-9700 if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (priv->x25cmdfails <= 0 || priv_caps->x25x26_always)) { int satmode = 0; // Return value is not important, as only satmode=1 means anything if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } if (satmode == 0) { // Only worth trying if the rig is not in satmode short retry_save = rp->retry; int freqbuf_offset; rp->retry = 0; retval = icom_get_freq_x25(rig, vfo, &ack_len, ackbuf, &freqbuf_offset); rp->retry = retry_save; if (retval == RIG_OK) { *tx_freq = from_bcd(&ackbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); RETURNFUNC2(retval); } } else { // The rig is in satmode so attempt to get the TX frequency using another command int freqbuf_offset; retval = icom_get_tx_freq(rig, &ack_len, ackbuf, &freqbuf_offset); if (retval == RIG_OK) { *tx_freq = from_bcd(&ackbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); RETURNFUNC2(retval); } } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_get_freq(rig, tx_vfo, tx_freq))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { HAMLIB_TRACE; RETURNFUNC2(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } RETURNFUNC2(retval); } /* * icom_set_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_mode works for this rig */ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && rs->current_vfo != RIG_VFO_MEM) { RETURNFUNC(icom_set_mode(rig, vfo, tx_mode, tx_width)); } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, tx_vfo, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_get_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL * icom_set_vfo,icom_get_mode works for this rig */ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && rs->current_vfo != RIG_VFO_MEM) { RETURNFUNC(icom_get_mode(rig, vfo, tx_mode, tx_width)); } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_set_split_freq_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_mode works for this rig */ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int split_assumed = 0; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); // If the user is asking to set split on VFO_CURR we'll assume split mode // WSJT-X calls this function before turning on split mode if (vfo == RIG_VFO_CURR) { split_assumed = 1; } if (rs->current_vfo == RIG_VFO_NONE) { HAMLIB_TRACE; icom_set_default_vfo(rig); } if (rs->current_vfo != RIG_VFO_MEM) { if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (rs->targetable_vfo & RIG_TARGETABLE_MODE)) { retval = icom_set_freq(rig, vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(icom_set_mode(rig, vfo, tx_mode, tx_width)); } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B && (split_assumed || CACHE(rig)->split != RIG_SPLIT_OFF)) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } rig_debug(RIG_DEBUG_VERBOSE, "%s: before get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__, rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo)); if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC2(retval); } // WSJT-X calls this function before setting split // So in this case we have to force the tx_vfo if (split_assumed && vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: split_assumed so tx_vfo=%s\n", __func__, rig_strvfo(vfo)); tx_vfo = VFO_HAS_A_B_ONLY ? RIG_VFO_B : RIG_VFO_SUB; } rig_debug(RIG_DEBUG_VERBOSE, "%s: after get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__, rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo)); // if not asking for RIG_VFO_CURR we'll use the requested VFO in the function call as tx_vfo if (CACHE(rig)->split == RIG_SPLIT_OFF && vfo != RIG_VFO_CURR) { tx_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: split not on so using requested vfo=%s\n", __func__, rig_strvfo(tx_vfo)); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC2(retval); } if (VFO_HAS_A_B && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } RETURNFUNC2(retval); } /* * icom_get_split_freq_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL * icom_set_vfo,icom_get_mode works for this rig */ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if (rs->current_vfo != RIG_VFO_MEM) { if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (rs->targetable_vfo & RIG_TARGETABLE_MODE)) { retval = icom_get_freq(rig, vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(icom_get_mode(rig, vfo, tx_mode, tx_width)); } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_set_split * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int split_sc; /* For Icom which VFO is active for this call is not important * S VFOA 1 VFOB -- RX on VFOA, TX on VFOB * S VFOB 1 VFOA -- RX on VFOB, TX on VFOA * S Main 1 Sub -- RX on Main, TX on Sub * S Sub 1 Main -- RX on Sub, TX on Main */ rig_debug(RIG_DEBUG_VERBOSE, "%s called rx_vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rs->current_vfo)); // This should automatically switch between satmode on/off based on the requested split rx_vfo if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { int satmode = 0; // Check SATMODE status, because it affects commands related to split rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) && !cachep->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for Main/Sub VFO and satmode is OFF so turning satmode ON\n", __func__); retval = rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 1); // Split cannot be turned on in satmode, so return after enabling satmode RETURNFUNC2(retval); } else if ((tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B) && cachep->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for VFO A/B and satmode is ON so turning satmode OFF\n", __func__); rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 0); } else if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) && cachep->satmode && split == RIG_SPLIT_ON) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for Main/Sub VFO and rig is already in satmode so setting split on " "is redundant and will result in an error, returning OK\n", __func__); // Return OK as satmode is a split mode and gpredict wants to see the OK response here RETURNFUNC2(RIG_OK); } } if (rs->current_vfo != rx_vfo && rx_vfo != RIG_VFO_CURR) { // Icom split command requires switching to the RX VFO first retval = rig_set_vfo(rig, rx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } switch (split) { case RIG_SPLIT_OFF: split_sc = S_SPLT_OFF; break; case RIG_SPLIT_ON: split_sc = S_SPLT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__, split); RETURNFUNC2(-RIG_EINVAL); } if (priv_caps->dualwatch_split) { int wvfo = (tx_vfo & (RIG_VFO_A | RIG_VFO_MAIN)) ? S_SUB : S_MAIN; retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, split_sc); if (retval != RIG_OK) { RETURNFUNC2(retval); } retval = icom_transaction(rig, C_SET_VFO, wvfo, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } else { retval = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n", __func__, rig_strvfo(rs->current_vfo), rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split); RETURNFUNC2(RIG_OK); } /* * icom_get_split_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL, split!=NULL * * Does not appear to be supported by any mode? * \sa icom_mem_get_split_vfo() */ int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { unsigned char splitbuf[MAXFRAMELEN]; int split_len, retval, satmode = 0; struct rig_state *rs = STATE(rig); ENTERFUNC; retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0, splitbuf, &split_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: CTL_SPLT failed?\n", __func__); RETURNFUNC(retval); } /* * splitbuf should contain Cn,Sc */ split_len--; if (split_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, split_len); RETURNFUNC(-RIG_ERJCTED); } switch (splitbuf[1]) { case S_SPLT_OFF: *split = RIG_SPLIT_OFF; break; case S_SPLT_ON: *split = RIG_SPLIT_ON; break; // The same command indicates repeater shift state, which means that split is off case S_DUP_OFF: case S_DUP_M: case S_DUP_P: case S_DUP_DD_RPS: *split = RIG_SPLIT_OFF; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__, splitbuf[1]); RETURNFUNC(-RIG_EPROTO); } if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Check SATMODE status, because it affects commands related to split rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // Update cache early for icom_get_split_vfos() CACHE(rig)->split = *split; icom_get_split_vfos(rig, &rs->rx_vfo, &rs->tx_vfo); *tx_vfo = rs->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: rx_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * icom_mem_get_split_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL, split!=NULL */ int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; ENTERFUNC; /* this hacks works only when in memory mode * I have no clue how to detect split in regular VFO mode */ if (STATE(rig)->current_vfo != RIG_VFO_MEM || !rig_has_vfo_op(rig, RIG_OP_XCHG)) { *split = CACHE(rig)->split; // we set this but still return ENAVAIL RETURNFUNC(-RIG_ENAVAIL); } retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval == RIG_OK) { *split = RIG_SPLIT_ON; /* get it back to normal */ retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval != RIG_OK) { RETURNFUNC(retval); } } else if (retval == -RIG_ERJCTED) { *split = RIG_SPLIT_OFF; } else { /* this is really an error! */ RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_ts * Assumes rig!=NULL, rig->caps->priv!=NULL */ int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { const struct icom_priv_caps *priv_caps; unsigned char ackbuf[MAXFRAMELEN]; int i, ack_len = sizeof(ackbuf), retval; int ts_sc = 0; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (priv_caps->ts_sc_list[i].ts == ts) { ts_sc = priv_caps->ts_sc_list[i].sc; break; } } if (i >= HAMLIB_TSLSTSIZ) { RETURNFUNC(-RIG_EINVAL); /* not found, unsupported */ } retval = icom_transaction(rig, C_SET_TS, ts_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ts * Assumes rig!=NULL, rig->caps->priv!=NULL, ts!=NULL * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF Not available on 746pro */ int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { const struct icom_priv_caps *priv_caps; unsigned char tsbuf[MAXFRAMELEN]; int ts_len, i, retval; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; retval = icom_transaction(rig, C_SET_TS, -1, NULL, 0, tsbuf, &ts_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * tsbuf should contain Cn,Sc */ ts_len--; if (ts_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); RETURNFUNC(-RIG_ERJCTED); } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (priv_caps->ts_sc_list[i].sc == tsbuf[1]) { *ts = priv_caps->ts_sc_list[i].ts; break; } } if (i >= HAMLIB_TSLSTSIZ) { RETURNFUNC(-RIG_EPROTO); /* not found, unsupported */ } RETURNFUNC(RIG_OK); } /* * icom_set_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int fct_len, ack_len, retval; int fct_cn, fct_sc; /* Command Number, Subcommand */ struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; const struct icom_priv_caps *priv_caps = rig->caps->priv; const struct cmdparams *extcmds = priv_caps->extcmds; int i; value_t value = { .i = status }; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], value)); } } fctbuf[0] = status ? 0x01 : 0x00; fct_len = 1; switch (func) { case RIG_FUNC_NB: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NB; break; case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_COMP; break; case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VOX; break; case RIG_FUNC_TONE: /* repeater tone */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TONE; break; case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TSQL; break; case RIG_FUNC_SBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; if (status != 0) { fctbuf[0] = 0x01; } else { fctbuf[0] = 0x00; } break; case RIG_FUNC_FBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; if (status != 0) { fctbuf[0] = 0x02; } else { fctbuf[0] = 0x00; } break; case RIG_FUNC_ANF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_ANF; break; case RIG_FUNC_NR: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NR; break; case RIG_FUNC_APF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_APF; break; case RIG_FUNC_MON: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MON; break; case RIG_FUNC_MN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MN; break; case RIG_FUNC_RF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_RF; break; case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VSC; break; case RIG_FUNC_LOCK: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DIAL_LK; break; case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; case RIG_FUNC_SCOPE: fct_cn = C_CTL_SCP; fct_sc = S_SCP_STS; fctbuf[0] = status; fct_len = 1; break; case RIG_FUNC_SPECTRUM: fct_cn = C_CTL_SCP; fct_sc = S_SCP_DOP; fctbuf[0] = status; fct_len = 1; break; case RIG_FUNC_SPECTRUM_HOLD: fct_cn = C_CTL_SCP; fct_sc = S_SCP_HLD; fct_len = 2; fctbuf[0] = icom_get_spectrum_vfo(rig, vfo); fctbuf[1] = status; break; case RIG_FUNC_RESUME: /* IC-910H & IC-746-Pro */ fct_cn = C_CTL_SCAN; fct_sc = status ? S_SCAN_RSMON : S_SCAN_RSMOFF; fct_len = 0; break; case RIG_FUNC_CSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_CSQL; break; case RIG_FUNC_DSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DSSQL; if (status <= 2) { fctbuf[0] = status; } else { fctbuf[0] = 0; } break; case RIG_FUNC_AFLT: fct_cn = C_CTL_MEM; fct_sc = S_MEM_AFLT; break; case RIG_FUNC_ANL: fct_cn = C_CTL_MEM; fct_sc = S_MEM_ANL; break; case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ fct_cn = C_CTL_MEM; fct_sc = S_FUNC_IPPLUS; break; case RIG_FUNC_RIT: fct_cn = C_CTL_RIT; fct_sc = S_RIT; break; case RIG_FUNC_XIT: fct_cn = C_CTL_RIT; fct_sc = S_XIT; break; case RIG_FUNC_TUNER: fct_cn = C_CTL_PTT; fct_sc = S_ANT_TUN; break; case RIG_FUNC_DUAL_WATCH: if ((RIG_IS_IC9100) || (RIG_IS_IC9700) || (RIG_IS_ID5100)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; } else { fct_cn = C_SET_VFO; fct_sc = status ? S_DUAL_ON : S_DUAL_OFF; fct_len = 0; } break; case RIG_FUNC_SATMODE: if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; fct_sc = S_MEM_SATMODE910; } else { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_SATMODE; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (ack_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ack_len); RETURNFUNC(-RIG_EPROTO); } if (func == RIG_FUNC_SATMODE) { int satmode = status ? 1 : 0; if (satmode != CACHE(rig)->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): changed satmode=%d\n", __func__, __LINE__, satmode); // Reset x25cmdfails to current status, because it fails in SATMODE icom_set_x25x26_ability(rig, satmode ? 1 : -1); // Reset x1cx03cmdfails to test it again priv->x1cx03cmdfails = 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): satmode=%d\n", __func__, __LINE__, satmode); } CACHE(rig)->satmode = satmode; icom_satmode_fix(rig, satmode); // Turning satmode ON/OFF can change the TX/RX VFOs // Split is OFF always in satmode if (VFO_HAS_MAIN_SUB_A_B_ONLY) { vfo_t tx_vfo; split_t split; // Update split status (updates rig state/cache internally) retval = icom_get_split_vfo(rig, RIG_VFO_CURR, &split, &tx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } } } RETURNFUNC(RIG_OK); } /* * icom_get_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * FIXME: IC8500 and no-sc, any support? */ int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int fct_cn, fct_sc; /* Command Number, Subcommand */ unsigned char fctbuf[MAXFRAMELEN]; int fct_len = 0; const struct icom_priv_caps *priv_caps = rig->caps->priv; const struct cmdparams *extcmds = priv_caps->extcmds; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ENTERFUNC; value_t value; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { //rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i); if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func) { int result = icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], &value); if (result == RIG_OK) { *status = value.i; } RETURNFUNC(result); } } switch (func) { case RIG_FUNC_NB: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NB; break; case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_COMP; break; case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VOX; break; case RIG_FUNC_TONE: /* repeater tone */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TONE; break; case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TSQL; break; case RIG_FUNC_SBKIN: /* returns 1 for semi and 2 for full adjusted below */ case RIG_FUNC_FBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; break; case RIG_FUNC_ANF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_ANF; break; case RIG_FUNC_NR: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NR; break; case RIG_FUNC_APF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_APF; break; case RIG_FUNC_MON: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MON; break; case RIG_FUNC_MN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MN; break; case RIG_FUNC_RF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_RF; break; case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VSC; break; case RIG_FUNC_LOCK: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DIAL_LK; break; case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; case RIG_FUNC_SCOPE: fct_cn = C_CTL_SCP; fct_sc = S_SCP_STS; break; case RIG_FUNC_SPECTRUM: fct_cn = C_CTL_SCP; fct_sc = S_SCP_DOP; break; case RIG_FUNC_SPECTRUM_HOLD: fct_cn = C_CTL_SCP; fct_sc = S_SCP_HLD; fctbuf[0] = icom_get_spectrum_vfo(rig, vfo); fct_len = 1; break; case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ fct_cn = C_CTL_MEM; /* 1a */ fct_sc = S_FUNC_IPPLUS; break; case RIG_FUNC_CSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_CSQL; break; case RIG_FUNC_DSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DSSQL; break; case RIG_FUNC_AFLT: fct_cn = C_CTL_MEM; fct_sc = S_MEM_AFLT; break; case RIG_FUNC_ANL: fct_cn = C_CTL_MEM; fct_sc = S_MEM_ANL; break; case RIG_FUNC_RIT: fct_cn = C_CTL_RIT; fct_sc = S_RIT; break; case RIG_FUNC_XIT: fct_cn = C_CTL_RIT; fct_sc = S_XIT; break; case RIG_FUNC_TUNER: fct_cn = C_CTL_PTT; fct_sc = S_ANT_TUN; break; case RIG_FUNC_DUAL_WATCH: if ((RIG_IS_IC9100) || (RIG_IS_IC9700) || (RIG_IS_ID5100)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; } else { fct_cn = C_SET_VFO; fct_sc = S_DUAL; } break; case RIG_FUNC_SATMODE: if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; fct_sc = S_MEM_SATMODE910; } else { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_SATMODE; } break; case RIG_FUNC_OVF_STATUS: { fct_cn = C_RD_SQSM; fct_sc = S_OVF; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s\n", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (ack_len != (3 + fct_len)) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ack_len); RETURNFUNC(-RIG_EPROTO); } if (func == RIG_FUNC_FBKIN) { *status = ackbuf[2] == 2 ? 1 : 0; } else if (func == RIG_FUNC_SATMODE) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; int satmode = ackbuf[2 + fct_len]; *status = satmode; if (satmode != CACHE(rig)->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): changed satmode=%d\n", __func__, __LINE__, satmode); // Reset x25cmdfails to current status, because it fails in SATMODE icom_set_x25x26_ability(rig, satmode ? 1 : -1); // Reset x1cx03cmdfails to test it again priv->x1cx03cmdfails = 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): satmode=%d\n", __func__, __LINE__, satmode); } CACHE(rig)->satmode = satmode; icom_satmode_fix(rig, satmode); } else { *status = ackbuf[2 + fct_len]; } RETURNFUNC(RIG_OK); } /* * icom_set_parm * Assumes rig!=NULL * * NOTE: Most of the parm commands are rig-specific. * * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands. * * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_set_parm(RIG *rig, setting_t parm, value_t val) { ENTERFUNC; int i; const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *extcmds = priv->extcmds; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_PARM && extcmds[i].id.s == parm) { RETURNFUNC(icom_set_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&extcmds[i], val)); } } switch (parm) { case RIG_PARM_ANN: { int ann_mode; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported RIG_PARM_ANN %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0)); } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_parm %s\n", __func__, rig_strparm(parm)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } const char *icom_get_band(RIG *rig, int band) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); const char *s = rig_get_band_str(rig, band, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: %d=%s\n", __func__, band, s); return s; } /* * icom_get_parm * Assumes rig!=NULL * * NOTE: Most of the parm commands are rig-specific. * * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands. * * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_get_parm(RIG *rig, setting_t parm, value_t *val) { ENTERFUNC; const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds; int i; for (i = 0; cmd && cmd[i].id.s != 0; i++) { if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_PARM && cmd[i].id.s == parm) { int retval = icom_get_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&cmd[i], val); if (parm == RIG_PARM_BANDSELECT) { char *s = (char *)icom_get_band(rig, val->i); val->s = s; } RETURNFUNC(retval); } } switch (parm) { default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_parm %s", __func__, rig_strparm(parm)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* * icom_set_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Works for 746 pro and should work for 756 xx and 7800 */ int icom_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int tone_len, ack_len = sizeof(ackbuf), retval; ENTERFUNC; caps = rig->caps; if (caps->ctcss_list) { int i; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } } /* Sent as frequency in tenth of Hz */ tone_len = 3; to_bcd_be(tonebuf, tone, tone_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR, tonebuf, tone_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (tone_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, tonebuf[0], tone_len); RETURNFUNC(-RIG_ERJCTED); } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); if (!caps->ctcss_list) { RETURNFUNC(RIG_OK); } /* check this tone exists. That's better than nothing. */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == *tone) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_ctcss_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int tone_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } /* Sent as frequency in tenth of Hz */ tone_len = 3; to_bcd_be(tonebuf, tone, tone_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL, tonebuf, tone_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ctcss_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tone_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, tonebuf[0], tone_len); RETURNFUNC(-RIG_ERJCTED); } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); /* check this tone exists. That's better than nothing. */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == *tone) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int code_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { RETURNFUNC(-RIG_EINVAL); } /* DCS Polarity ignored, by setting code_len to 3 it's forced to 0 (= Tx:norm, Rx:norm). */ code_len = 3; to_bcd_be(codebuf, code, code_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, codebuf, code_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN]; int code_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0, codebuf, &code_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (code_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, codebuf[0], code_len); RETURNFUNC(-RIG_ERJCTED); } /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2 polarity is not decoded yet, hard to do without breaking ABI */ code_len -= 3; *code = from_bcd_be(codebuf + 3, code_len * 2); /* check this code exists. That's better than nothing. */ for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == *code) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_dcs_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int code_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { RETURNFUNC(-RIG_EINVAL); } /* DCS Polarity ignored, by setting code_len to 3 it's forced to 0 (= Tx:norm, Rx:norm). */ code_len = 3; to_bcd_be(codebuf, code, code_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, codebuf, code_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_dcs_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN]; int code_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0, codebuf, &code_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (code_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, codebuf[0], code_len); RETURNFUNC(-RIG_ERJCTED); } /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2 polarity is not decoded yet, hard to do without breaking ABI */ code_len -= 3; *code = from_bcd_be(codebuf + 3, code_len * 2); /* check this code exists. That's better than nothing. */ for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == *code) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_powerstat(RIG *rig, powerstat_t status) { unsigned char ackbuf[200]; int ack_len = sizeof(ackbuf), retval = RIG_OK; int pwr_sc; // so we'll do up to 150 for 115,200 int fe_max = 150; unsigned char fe_buf[fe_max]; // for FE's to power up int i; int retry; short retry_save, timeout_retry_save; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, (int) status); // eliminate retries to speed this up // especially important when rig is not turned on retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; rp->retry = 0; rp->timeout_retry = 0; switch (status) { case RIG_POWER_ON: // ic7300 manual says ~150 for 115,200 // we'll just send a few more to be sure for all speeds switch (rp->parm.serial.rate) { case 4800: fe_max = 7; break; case 9600: fe_max = 13; break; case 19200: fe_max = 25; break; case 38400: fe_max = 50; break; case 57600: fe_max = 75; break; case 115200: default: fe_max = 150; } memset(fe_buf, 0xfe, fe_max); // sending more than enough 0xfe's to wake up the rs232 write_block(rp, fe_buf, fe_max); // need to wait a bit for RigPI and others to queue the echo hl_usleep(400 * 1000); // we'll try 0x18 0x01 now -- should work on STBY rigs too pwr_sc = S_PWR_ON; fe_buf[0] = 0; priv->serial_USB_echo_off = 1; retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); float sec_wait = 5.5; // 5.5 worked for IC-9700 -- we default to worst-case-found if (RIG_IS_IC7300) { sec_wait = 3.8; } rig_debug(RIG_DEBUG_VERBOSE, "%s: waiting %g seconds for rig to wake up\n", __func__, sec_wait); hl_usleep(sec_wait * 1000 * 1000); // some are slow to start up -- may need to add more rigs // poweron == 0 means never powered -- == 2 means CAT turned off if (priv->poweron == 0 || priv->poweron == 2) { int echo_status = -1; for (i = 0; i < 10 && echo_status < 0; ++i) { echo_status = icom_get_usb_echo_off(rig); if (echo_status < 0) { hl_usleep(500 * 1000); } } if (echo_status >= 0) { priv->poweron = 1; } rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; return RIG_OK; } break; default: pwr_sc = S_PWR_OFF; fe_buf[0] = 0; retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); priv->poweron = 2; } i = 0; retry = 3; if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < retry; ++i) // up to 10 attempts { freq_t freq; // need to see if echo is on or not first // until such time as rig is awake we don't know retval = icom_get_usb_echo_off(rig); if (retval == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_WARN, "%s: get_usb_echo_off timeout...try#%d\n", __func__, i + 1); continue; } // Use get_freq as all rigs should respond to this retval = rig_get_freq(rig, RIG_VFO_CURR, &freq); if (retval == RIG_OK) { int satmode; if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Getting satmode state updates RX/TX VFOs internally rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } rs->current_vfo = icom_current_vfo(rig); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; RETURNFUNC2(retval); } else { rig_debug(RIG_DEBUG_TRACE, "%s: get_freq err=%s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait %d of %d for get_powerstat\n", __func__, i + 1, retry); } } rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; if (i == retry) { rig_debug(RIG_DEBUG_TRACE, "%s: Wait failed for get_powerstat\n", __func__); // close and re-open the rig // on linux the USB gets reset during power on rig_close(rig); sleep(1); rig_open(rig); retval = -RIG_ETIMEOUT; } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: retval != RIG_OK, =%s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } if (status == RIG_POWER_OFF && (ack_len != 1 || ackbuf[0] != ACK)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC2(-RIG_ERJCTED); } RETURNFUNC2(RIG_OK); } /* * icom_get_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_powerstat(RIG *rig, powerstat_t *status) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; *status = RIG_POWER_OFF; // default return until proven otherwise /* r75 has no way to get power status, so fake it */ if (RIG_IS_ICR75) { /* getting the mode doesn't work if a memory is blank */ /* so use one of the more innocuous 'set mode' commands instead */ int cmd_len = 1; unsigned char cmdbuf[MAXFRAMELEN]; cmdbuf[0] = S_PRM_TIME; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_MODE_SLCT, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = ((ack_len == 6) && (ackbuf[0] == C_CTL_MEM)) ? RIG_POWER_ON : RIG_POWER_OFF; } HAMLIB_TRACE; if (RIG_IS_IC2730 || RIG_IS_IC705 || RIG_IS_IC7100 || RIG_IS_IC7300 || RIG_IS_IC7600 || RIG_IS_IC7610 || RIG_IS_IC7700 || RIG_IS_IC7800 || RIG_IS_IC785X || RIG_IS_IC9700 || RIG_IS_IC905) { freq_t freq; hamlib_port_t *rp = RIGPORT(rig); short retry_save = rp->retry; short timeout_retry_save = rp->timeout_retry; HAMLIB_TRACE; rp->retry = 0; rp->timeout_retry = 0; retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: get freq failed, assuming power is off\n", __func__); } HAMLIB_TRACE; rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; // Assume power is OFF if get_freq fails *status = retval == RIG_OK ? RIG_POWER_ON : RIG_POWER_OFF; // Modify rig_state powerstat directly to reflect power ON/OFF status, but return the result of rig_get_freq, // because the error could indicate other connectivity issues too STATE(rig)->powerstat = *status; RETURNFUNC(retval); } else { retval = icom_transaction(rig, C_SET_PWR, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { // Assume power is OFF if getting power status fails // Modify rig_state powerstat directly to reflect power ON/OFF status, but return the result of rig_get_freq, // because the error could indicate other connectivity issues too rig_debug(RIG_DEBUG_WARN, "%s: get powerstat failed, assuming power is off\n", __func__); STATE(rig)->powerstat = RIG_POWER_OFF; RETURNFUNC(retval); } *status = ackbuf[1] == S_PWR_ON ? RIG_POWER_ON : RIG_POWER_OFF; } RETURNFUNC(RIG_OK); } /* * icom_set_mem * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char membuf[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int chan_len; ENTERFUNC; chan_len = ch < 100 ? 1 : 2; to_bcd_be(membuf, ch, chan_len * 2); retval = icom_transaction(rig, C_SET_MEM, -1, membuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_bank * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_bank(RIG *rig, vfo_t vfo, int bank) { unsigned char bankbuf[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; to_bcd_be(bankbuf, bank, BANK_NB_LEN * 2); retval = icom_transaction(rig, C_SET_MEM, S_BANK, bankbuf, CHAN_NB_LEN, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_ant * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { unsigned char antopt[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval, i_ant = 0; int antopt_len = 0; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d, antack_len=%d\n", __func__, ant, option.i, priv_caps->antack_len); // query the antennas once and find out how many we have if (ant >= rig_idx2setting(priv_caps->ant_count)) { RETURNFUNC2(-RIG_EINVAL); } if (ant > RIG_ANT_4) { RETURNFUNC2(-RIG_EDOM); } switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported ant %#x", __func__, ant); RETURNFUNC2(-RIG_EINVAL); } if (priv_caps->antack_len == 0) // we need to find out the antack_len { ant_t tmp_ant, ant_tx, ant_rx; int ant0 = 0; value_t tmp_option; retval = rig_get_ant(rig, vfo, ant0, &tmp_option, &tmp_ant, &ant_tx, &ant_rx); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_ant error: %s \n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } // Some rigs have 3-byte ant cmd so there is an option to be set too if (priv_caps->antack_len == 3) { if (option.i != 0 && option.i != 1) { rig_debug(RIG_DEBUG_ERR, "%s: option.i != 0 or 1, ==%d?\n", __func__, option.i); RETURNFUNC2(-RIG_EINVAL); } antopt_len = 1; antopt[0] = option.i; // we have to set the rx option by itself apparently rig_debug(RIG_DEBUG_TRACE, "%s: setting antopt=%d\n", __func__, antopt[0]); retval = icom_transaction(rig, C_CTL_ANT, i_ant, antopt, antopt_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d, antopt=0x%02x\n", __func__, priv_caps->antack_len, antopt_len, antopt[0]); } else if (priv_caps->antack_len == 2) { antopt_len = 0; rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__, priv_caps->antack_len, antopt_len); } else { rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__, priv_caps->antack_len, antopt_len); antopt_len = 0; rig_debug(RIG_DEBUG_ERR, "%s: rig does not have antenna select? antack_len=%d\n", __func__, priv_caps->antack_len); } rig_debug(RIG_DEBUG_TRACE, "%s: i_ant=%d, antopt=0x%02x, antopt_len=%d\n", __func__, i_ant, antopt[0], antopt_len); retval = icom_transaction(rig, C_CTL_ANT, i_ant, antopt, antopt_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * icom_get_ant * Assumes rig!=NULL, STATE(rig)->priv!=NULL * only meaningful for HF */ int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval = -RIG_EINTERNAL; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x\n", __func__, ant); if (ant != RIG_ANT_CURR) { ant = rig_setting2idx(ant); if (ant >= priv_caps->ant_count) { rig_debug(RIG_DEBUG_ERR, "%s: ant index=%u > ant_count=%d\n", __func__, ant, priv_caps->ant_count); RETURNFUNC2(-RIG_EINVAL); } } // Should be able to use just C_CTL_ANT for 1 or 2 antennas hopefully if (ant == RIG_ANT_CURR || priv_caps->ant_count <= 2) { retval = icom_transaction(rig, C_CTL_ANT, -1, NULL, 0, ackbuf, &ack_len); } else if (RIG_IS_IC785X) { unsigned char buf[2]; buf[0] = 0x03; buf[1] = 0x05 + ant; *ant_curr = ant; retval = icom_transaction(rig, C_CTL_MEM, 0x05, buf, sizeof(buf), ackbuf, &ack_len); if (retval == RIG_OK) { option->i = ackbuf[4]; RETURNFUNC2(RIG_OK); } } else { rig_debug(RIG_DEBUG_ERR, "%s: asking for non-current antenna and ant_count==0?\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to implement ant control for this rig?\n", __func__); RETURNFUNC2(-RIG_EINVAL); } if (retval != RIG_OK) { RETURNFUNC2(retval); } // ack_len should be either 2 or 3 // ant cmd format is one of // 0x12 0xaa // 0x12 0xaa 0xrr // Where aa is a zero-base antenna number and rr is a binary for rx only if ((ack_len != 2 && ack_len != 3) || ackbuf[0] != C_CTL_ANT || ackbuf[1] > 3) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d, ant=%d\n", __func__, ackbuf[0], ack_len, ackbuf[1]); RETURNFUNC2(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_ERR, "%s: ackbuf= 0x%02x 0x%02x 0x%02x\n", __func__, ackbuf[0], ackbuf[1], ackbuf[2]); *ant_curr = *ant_tx = *ant_rx = rig_idx2setting(ackbuf[1]); // Note: with IC756/IC-756Pro/IC-7800 and more, ackbuf[2] deals with [RX ANT] // Hopefully any ack_len=3 can fit in the option field if (ack_len == 3) { option->i = ackbuf[2]; *ant_rx = rig_idx2setting(ackbuf[2]); } RETURNFUNC2(RIG_OK); } /* * icom_vfo_op, Mem/VFO operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { unsigned char mvbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int mv_len = 0, ack_len = sizeof(ackbuf), retval; int mv_cn, mv_sc; int vfo_list; ENTERFUNC; switch (op) { case RIG_OP_CPY: mv_cn = C_SET_VFO; vfo_list = STATE(rig)->vfo_list; if ((vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) { mv_sc = S_BTOA; } else if ((vfo_list & (RIG_VFO_MAIN | RIG_VFO_SUB)) == (RIG_VFO_MAIN | RIG_VFO_SUB)) { mv_sc = S_SUBTOMAIN; } else { RETURNFUNC(-RIG_ENAVAIL); } break; case RIG_OP_XCHG: mv_cn = C_SET_VFO; mv_sc = S_XCHNG; break; case RIG_OP_FROM_VFO: mv_cn = C_WR_MEM; mv_sc = -1; break; case RIG_OP_TO_VFO: mv_cn = C_MEM2VFO; mv_sc = -1; break; case RIG_OP_MCL: mv_cn = C_CLR_MEM; mv_sc = -1; break; case RIG_OP_TUNE: mv_cn = C_CTL_PTT; mv_sc = S_ANT_TUN; mvbuf[0] = 2; mv_len = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mem/vfo op %#x", __func__, op); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, mv_cn, mv_sc, mvbuf, mv_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } // since we're messing with VFOs our cache may be invalid CACHE_RESET; if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes RETURNFUNC(-RIG_ETIMEOUT); } if (ack_len != 1 || ackbuf[0] != ACK) { if (op != RIG_OP_XCHG) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } RETURNFUNC(-RIG_ERJCTED); } RETURNFUNC(RIG_OK); } /* * icom_scan, scan operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { unsigned char scanbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int scan_len, ack_len = sizeof(ackbuf), retval; int scan_cn, scan_sc; vfo_t myvfo = vfo; ENTERFUNC; scan_len = 0; scan_cn = C_CTL_SCAN; // for current vfo just switch to VFO mode (we might be in MEM) if (myvfo == RIG_VFO_CURR) { myvfo = RIG_VFO_VFO; } switch (scan) { case RIG_SCAN_STOP: scan_sc = S_SCAN_STOP; break; case RIG_SCAN_VFO: case RIG_SCAN_MEM: HAMLIB_TRACE; retval = rig_set_vfo(rig, scan == RIG_SCAN_MEM ? RIG_VFO_MEM : myvfo); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Looks like all the IC-R* have this command, * but some old models don't have it. * Should be put in icom_priv_caps ? */ if (rig->caps->rig_type == RIG_TYPE_RECEIVER && scan == RIG_SCAN_MEM) { scan_sc = S_SCAN_MEM2; } else { scan_sc = S_SCAN_START; } break; case RIG_SCAN_SLCT: HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) { RETURNFUNC(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) { RETURNFUNC(retval); } HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { RETURNFUNC(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, "%s: unsupported scan %#x\n", __func__, scan); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, scan_cn, scan_sc, scanbuf, scan_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_send_morse * Assumes rig!=NULL, msg!=NULL */ int icom_send_morse(RIG *rig, vfo_t vfo, const char *msg) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int len; int retry = 20; ENTERFUNC; len = strlen(msg); if (len > 30) { len = 30; } rig_debug(RIG_DEBUG_TRACE, "%s: %s\n", __func__, msg); morse_retry: retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) msg, len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { if (retval == -RIG_ERJCTED) { if (len == 1 && --retry > 0) { // 50 retries should be around 200ms --plenty of time to clear out some characters hl_usleep(10 * 1000); goto morse_retry; } } RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_stop_morse * Assumes rig!=NULL, msg!=NULL */ int icom_stop_morse(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; unsigned char cmd[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; cmd[0] = 0xff; retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) cmd, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int icom_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const freq_range_t *range_list; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); range_list = rig_get_range(rig->caps->tx_range_list1, freq, mode); if (range_list == NULL) { *mwpower = power * 100000; // default to 100W if no range_list RETURNFUNC(RIG_OK); } rig_debug(RIG_DEBUG_VERBOSE, "%s: maxpower=%d\n", __func__, range_list->high_power); *mwpower = power * range_list->high_power; RETURNFUNC(RIG_OK); } int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = rig->caps->rig_model; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %" PRIfreq " Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); if (mwpower > 100000) { RETURNFUNC(-RIG_EINVAL); } switch (rig_id) { default: /* Default to a 100W radio */ *power = ((float) mwpower / 100000); break; } RETURNFUNC(RIG_OK); } #if defined(HAVE_PTHREAD) static int icom_parse_spectrum_frame(RIG *rig, size_t length, const unsigned char *frame_data) { struct rig_caps *caps = rig->caps; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) caps->priv; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; struct icom_spectrum_scope_cache *cache; int division = (int) from_bcd(frame_data + 1, 1 * 2); int max_division = (int) from_bcd(frame_data + 2, 1 * 2); size_t spectrum_data_length_in_frame; const unsigned char *spectrum_data_start_in_frame; ENTERFUNC; // The first byte indicates spectrum scope ID/VFO: 0 = Main, 1 = Sub int spectrum_id = frame_data[0]; if (spectrum_id >= priv->spectrum_scope_count) { rig_debug(RIG_DEBUG_ERR, "%s: invalid spectrum scope ID from CI-V frame: %d\n", __func__, spectrum_id); RETURNFUNC(-RIG_EPROTO); } cache = &priv->spectrum_scope_cache[spectrum_id]; if (division == 1) { int spectrum_scope_mode = frame_data[3]; int out_of_range = frame_data[14]; cache->spectrum_mode = RIG_SPECTRUM_MODE_NONE; switch (spectrum_scope_mode) { case SCOPE_MODE_CENTER: cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER; cache->spectrum_center_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2); cache->spectrum_span_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2) * 2; cache->spectrum_low_edge_freq = cache->spectrum_center_freq - cache->spectrum_span_freq / 2; cache->spectrum_high_edge_freq = cache->spectrum_center_freq + cache->spectrum_span_freq / 2; break; case SCOPE_MODE_FIXED: cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED; case SCOPE_MODE_SCROLL_C: if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE) { cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER_SCROLL; } case SCOPE_MODE_SCROLL_F: if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE) { cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED_SCROLL; } cache->spectrum_low_edge_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2); cache->spectrum_high_edge_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2); cache->spectrum_span_freq = (cache->spectrum_high_edge_freq - cache->spectrum_low_edge_freq); cache->spectrum_center_freq = cache->spectrum_high_edge_freq - cache->spectrum_span_freq / 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown Icom spectrum scope mode: %d\n", __func__, spectrum_scope_mode); RETURNFUNC(-RIG_EPROTO); } spectrum_data_length_in_frame = length - 15; spectrum_data_start_in_frame = frame_data + 15; memset(cache->spectrum_data, 0, priv_caps->spectrum_scope_caps.spectrum_line_length); cache->spectrum_data_length = 0; cache->spectrum_metadata_valid = 1; rig_debug(RIG_DEBUG_TRACE, "%s: Spectrum line start: id=%d division=%d max_division=%d mode=%d center=%.0f span=%.0f low_edge=%.0f high_edge=%.0f oor=%d data_length=%d\n", __func__, spectrum_id, division, max_division, spectrum_scope_mode, cache->spectrum_center_freq, cache->spectrum_span_freq, cache->spectrum_low_edge_freq, cache->spectrum_high_edge_freq, out_of_range, (int)spectrum_data_length_in_frame); } else { spectrum_data_length_in_frame = length - 3; spectrum_data_start_in_frame = frame_data + 3; } if (spectrum_data_length_in_frame > 0) { int frame_length = priv_caps->spectrum_scope_caps.single_frame_data_length; int data_frame_index = (max_division > 1) ? (division - 2) : (division - 1); int offset = data_frame_index * frame_length; if (offset + spectrum_data_length_in_frame > priv_caps->spectrum_scope_caps.spectrum_line_length) { rig_debug(RIG_DEBUG_ERR, "%s: too much spectrum scope data received: %d bytes > %d bytes expected\n", __func__, (int)(offset + spectrum_data_length_in_frame), priv_caps->spectrum_scope_caps.spectrum_line_length); RETURNFUNC(-RIG_EPROTO); } memcpy(cache->spectrum_data + offset, spectrum_data_start_in_frame, spectrum_data_length_in_frame); cache->spectrum_data_length = offset + spectrum_data_length_in_frame; } if (cache->spectrum_metadata_valid && division == max_division) { struct rig_spectrum_line spectrum_line = { .id = spectrum_id, .data_level_min = priv_caps->spectrum_scope_caps.data_level_min, .data_level_max = priv_caps->spectrum_scope_caps.data_level_max, .signal_strength_min = priv_caps->spectrum_scope_caps.signal_strength_min, .signal_strength_max = priv_caps->spectrum_scope_caps.signal_strength_max, .spectrum_mode = cache->spectrum_mode, .center_freq = cache->spectrum_center_freq, .span_freq = cache->spectrum_span_freq, .low_edge_freq = cache->spectrum_low_edge_freq, .high_edge_freq = cache->spectrum_high_edge_freq, .spectrum_data_length = cache->spectrum_data_length, .spectrum_data = cache->spectrum_data, }; #if defined(HAVE_PTHREAD) rig_fire_spectrum_event(rig, &spectrum_line); #endif cache->spectrum_metadata_valid = 0; } RETURNFUNC(RIG_OK); } #endif int icom_is_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame) { if (frame_length < ACKFRMLEN) { return 0; } /* Spectrum scope data is not CI-V transceive data, but handled the same way as it is pushed by the rig */ // IC-7100 sends 0xe1 for broadcast frame? return frame[2] == BCASTID || frame[2] == C_SND_MODE || (frame[2] == CTRLID && frame[4] == C_CTL_SCP && frame[5] == S_SCP_DAT); } int icom_process_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; rmode_t mode; pbwidth_t width; ENTERFUNC; /* * the first 2 bytes must be 0xfe * the 3rd one 0x00 since this is transceive mode * the 4th one the emitter * then the command number * the rest is data * and don't forget one byte at the end for the EOM */ if (frame[2] != BCASTID && frame[2] != CTRLID) { // just ignoring 0x01 for now // fe fe 01 94 1c 03 00 80 07 07 00 fd rig_debug(RIG_DEBUG_VERBOSE, "%s: Unknown/invalid destination - %#x\n", __func__, frame[2]); RETURNFUNC(RIG_OK); } switch (frame[4]) { case C_RD_FREQ: case C_SND_FREQ: { // TODO: The freq length might be less than 4 or 5 bytes on older rigs! // TODO: Disable cache timeout for frequency after first transceive packet once we figure out how to get active VFO reliably with transceive updates // TODO: rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_FREQ, HAMLIB_CACHE_ALWAYS); freq_t freq = (freq_t) from_bcd(frame + 5, (priv->civ_731_mode ? 4 : 5) * 2); #if defined(HAVE_PTHREAD) rig_fire_freq_event(rig, RIG_VFO_CURR, freq); #endif #if 0 if (rs->use_cached_freq != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): use_cached_freq turning on\n", __func__, __LINE__); rs->use_cached_freq = 0; } #endif break; } case C_SND_MODE: // TODO: Disable cache timeout for frequency after first transceive packet once we figure out how to get active VFO reliably with transceive updates // TODO: rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_MODE, HAMLIB_CACHE_ALWAYS); icom2rig_mode(rig, frame[5], frame[6], &mode, &width); #if defined(HAVE_PTHREAD) rig_fire_mode_event(rig, RIG_VFO_CURR, mode, width); #endif if (rs->use_cached_mode != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): use_cached_mode turning on\n", __func__, __LINE__); rs->use_cached_mode = 0; } break; #if defined(HAVE_PTHREAD) case C_CTL_SCP: if (frame[5] == S_SCP_DAT) { icom_parse_spectrum_frame(rig, frame_length - (6 + 1), frame + 6); } break; #endif default: rig_debug(RIG_DEBUG_VERBOSE, "%s: transceive cmd unsupported %#2.2x\n", __func__, frame[4]); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } /* * icom_decode is called by sa_sigio, when some asynchronous * data has been received from the rig */ int icom_decode_event(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char buf[MAXFRAMELEN]; int retval, frm_len; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; frm_len = read_icom_frame(RIGPORT(rig), buf, sizeof(buf)); if (frm_len == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: got a timeout before the first character\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (frm_len < 1) { RETURNFUNC(RIG_OK); } retval = icom_frame_fix_preamble(frm_len, buf); if (retval < 0) { RETURNFUNC(retval); } frm_len = retval; if (frm_len < 1) { rig_debug(RIG_DEBUG_ERR, "Unexpected frame len=%d\n", frm_len); RETURNFUNC(-RIG_EPROTO); } switch (buf[frm_len - 1]) { case COL: rig_debug(RIG_DEBUG_VERBOSE, "%s: saw a collision\n", __func__); /* Collision */ RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; default: /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ RETURNFUNC(-RIG_EPROTO); } if (!icom_is_async_frame(rig, frm_len, buf)) { rig_debug(RIG_DEBUG_WARN, "%s: CI-V %#x called for %#x!\n", __func__, priv->re_civ_addr, buf[2]); } RETURNFUNC(icom_process_async_frame(rig, frm_len, buf)); } int icom_read_frame_direct(RIG *rig, size_t buffer_length, const unsigned char *buffer) { return read_icom_frame_direct(RIGPORT(rig), buffer, buffer_length); } int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val) { unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int cmdbuflen = subcmdbuflen; int retval; ENTERFUNC; if (subcmdbuflen > 0) { if (subcmdbuf == NULL) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(cmdbuf, subcmdbuf, subcmdbuflen); } if (val_bytes > 0) { to_bcd_be(cmdbuf + subcmdbuflen, (long long) val, val_bytes * 2); cmdbuflen += val_bytes; } retval = icom_transaction(rig, cmd, subcmd, cmdbuf, cmdbuflen, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int cmdhead = subcmdbuflen; int retval; ENTERFUNC; retval = icom_transaction(rig, cmd, subcmd, subcmdbuf, subcmdbuflen, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } cmdhead += (subcmd == -1) ? 1 : 2; ack_len -= cmdhead; rig_debug(RIG_DEBUG_TRACE, "%s: ack_len=%d\n", __func__, ack_len); if (ack_len < 0) { RETURNFUNC(-RIG_EPROTO); } if (*reslen < ack_len || res == NULL) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(res, ackbuf + cmdhead, ack_len); *reslen = ack_len; RETURNFUNC(RIG_OK); } int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val) { unsigned char resbuf[MAXFRAMELEN]; int reslen = sizeof(resbuf); int retval; ENTERFUNC; retval = icom_get_raw_buf(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &reslen, resbuf); if (retval != RIG_OK) { RETURNFUNC(retval); } * val = from_bcd_be(resbuf, reslen * 2); rig_debug(RIG_DEBUG_TRACE, "%s: %d %d\n", __func__, reslen, *val); RETURNFUNC(RIG_OK); } int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val) { int icom_val; ENTERFUNC; if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = (int)(val.f * 255.0f); } else { icom_val = val.i; } RETURNFUNC(icom_set_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, val_bytes, icom_val)); } int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, value_t *val) { int icom_val; int retval; ENTERFUNC; retval = icom_get_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &icom_val); if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float) icom_val / 255.0f; } else { val->i = icom_val; } RETURNFUNC(RIG_OK); } int icom_stop_voice_mem(RIG *rig, vfo_t vfo) { return icom_send_voice_mem(rig, vfo, 0); } /* * icom_send_voice_mem * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char chbuf[1]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; to_bcd_be(chbuf, ch, 2); retval = icom_transaction(rig, C_SND_VOICE, 0, chbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_freq_range * Assumes rig!=NULL, STATE(rig)->priv!=NULL * Always returns RIG_OK */ int icom_get_freq_range(RIG *rig) { int nrange = 0; int i; int cmd, subcmd; int retval; unsigned char cmdbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); // struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; // int freq_len = priv->civ_731_mode ? 4 : 5; int freq_len = 5; cmd = C_CTL_EDGE; subcmd = 0; retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: rig does not have 0x1e command so skipping this check\n", __func__); RETURNFUNC2(RIG_OK); } rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf[0]=%02x, ackbuf[1]=%02x\n", __func__, ackbuf[0], ackbuf[1]); nrange = from_bcd(&ackbuf[2], 2); rig_debug(RIG_DEBUG_TRACE, "%s: nrange=%d\n", __func__, nrange); for (i = 1; i <= nrange; ++i) { cmd = C_CTL_EDGE; subcmd = 1; to_bcd(cmdbuf, i, 2); retval = icom_transaction(rig, cmd, subcmd, cmdbuf, 1, ackbuf, &ack_len); if (retval == RIG_OK) { freq_t freqlo, freqhi; rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf= %02x %02x %02x %02x...\n", __func__, ackbuf[0], ackbuf[1], ackbuf[2], ackbuf[3]); freqlo = from_bcd(&ackbuf[3], freq_len * 2); freqhi = from_bcd(&ackbuf[3 + freq_len + 1], freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__, i, freqlo, freqhi); } else { rig_debug(RIG_DEBUG_ERR, "%s: error from C_CTL_EDGE? err=%s\n", __func__, rigerror(retval)); } } // To be implemented // Automatically fill in the freq range for this rig if available rig_debug(RIG_DEBUG_TRACE, "%s: Hamlib ranges\n", __func__); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rig->caps->rx_range_list1[i]); i++) { rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__, i, (double)rig->caps->rx_range_list1[i].startf, (double)rig->caps->rx_range_list1[i].endf); } RETURNFUNC2(RIG_OK); } // Sets rig vfo && STATE(rig)->current_vfo to default VFOA, or current vfo, or the vfo requested static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo) { int retval; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(curr_vfo)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; RETURNFUNC2(RIG_OK); } if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Main=%s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_SUB && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Sub=%s\n", __func__, rig_strvfo(vfo)); } /* This method works also in memory mode(RIG_VFO_MEM) */ // first time we will set default to VFOA or Main as // So if you ask for frequency or such without setting VFO first you'll get Main/VFOA if (rs->current_vfo == RIG_VFO_NONE && vfo == RIG_VFO_CURR) { HAMLIB_TRACE; icom_set_default_vfo(rig); } // asking for vfo_curr so give it to them else if (rs->current_vfo != RIG_VFO_NONE && vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: using curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; } // only need to set vfo if it's changed else if (rs->current_vfo != vfo) { if (!(VFO_HAS_MAIN_SUB_A_B_ONLY && CACHE(rig)->split == RIG_SPLIT_OFF && !CACHE(rig)->satmode && vfo == RIG_VFO_SUB && rs->current_vfo == RIG_VFO_B)) { rig_debug(RIG_DEBUG_TRACE, "%s: setting new vfo=%s\n", __func__, rig_strvfo(vfo)); HAMLIB_TRACE; retval = rig_set_vfo(rig, vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now=%s\n", __func__, rig_strvfo(rs->current_vfo)); rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); } static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo) { if (STATE(rig)->targetable_vfo & RIG_TARGETABLE_SPECTRUM) { RETURNFUNC2(ICOM_GET_VFO_NUMBER(vfo)); } RETURNFUNC2(0); } static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo, int *range_id) { freq_t freq; rmode_t mode; pbwidth_t width; int cache_ms_freq, cache_ms_mode, cache_ms_width; int i, retval; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv; retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { RETURNFUNC2(retval); } // Get frequency if it is not cached or value is old if (freq == 0 || cache_ms_freq >= 1000) { retval = rig_get_freq(rig, vfo, &freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } } for (i = 0; i < ICOM_MAX_SPECTRUM_FREQ_RANGES; i++) { int id = priv_caps->spectrum_edge_frequency_ranges[i].range_id; if (id < 1) { break; } if (freq >= priv_caps->spectrum_edge_frequency_ranges[i].low_freq && freq < priv_caps->spectrum_edge_frequency_ranges[i].high_freq) { *range_id = id; RETURNFUNC2(RIG_OK); } } RETURNFUNC2(-RIG_EINVAL); } /* * init_icom is called by rig_probe_all (register.c) * * probe_icom reports all the devices on the CI-V bus. * * rig_model_t probeallrigs_icom(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(icom) { unsigned char buf[MAXFRAMELEN], civ_addr, civ_id; int frm_len, i; rig_model_t model = RIG_MODEL_NONE; int rates[] = { 19200, 9600, 300, 0 }; int rates_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port) { return (RIG_MODEL_NONE); } if (port->type.rig != RIG_PORT_SERIAL) { return (RIG_MODEL_NONE); } port->write_delay = port->post_write_delay = 0; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { int retval; port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 40; retval = serial_open(port); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } /* * try all possible addresses on the CI-V bus * FIXME: actually, old rigs do not support C_RD_TRXID cmd! * Try to be smart, and deduce model depending * on freq range, return address, and * available commands. */ for (civ_addr = 0x01; civ_addr <= 0x7f; civ_addr++) { frm_len = make_cmd_frame(buf, civ_addr, CTRLID, C_RD_TRXID, S_RD_TRXID, NULL, 0); rig_flush(port); write_block(port, buf, frm_len); /* read out the bytes we just sent * TODO: check this is what we expect */ read_icom_frame(port, buf, sizeof(buf)); /* this is the reply */ frm_len = read_icom_frame(port, buf, sizeof(buf)); /* timeout.. nobody's there */ if (frm_len <= 0) { continue; } if (buf[7] != FI && buf[5] != FI) { /* protocol error, unexpected reply. * is this a CI-V device? */ close(port->fd); return (RIG_MODEL_NONE); } else if (buf[4] == NAK) { /* * this is an Icom, but it does not support transceiver ID * try to guess from the return address */ civ_id = buf[3]; } else { civ_id = buf[6]; } for (i = 0; icom_addr_list[i].model != RIG_MODEL_NONE; i++) { if (icom_addr_list[i].re_civ_addr == civ_id) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found %#x at %#x\n", __func__, civ_id, buf[3]); model = icom_addr_list[i].model; if (cfunc) { (*cfunc)(port, model, data); } break; } } /* * not found in known table.... * update icom_addr_list[]! */ if (icom_addr_list[i].model == RIG_MODEL_NONE) rig_debug(RIG_DEBUG_WARN, "%s: found unknown device " "with CI-V ID %#x, please report to Hamlib " "developers.\n", __func__, civ_id); } /* * Try to identify OptoScan */ for (civ_addr = 0x80; civ_addr <= 0x8f; civ_addr++) { frm_len = make_cmd_frame(buf, civ_addr, CTRLID, C_CTL_MISC, S_OPTO_RDID, NULL, 0); rig_flush(port); write_block(port, buf, frm_len); /* read out the bytes we just sent * TODO: check this is what we expect */ read_icom_frame(port, buf, sizeof(buf)); /* this is the reply */ frm_len = read_icom_frame(port, buf, sizeof(buf)); /* timeout.. nobody's there */ if (frm_len <= 0) { continue; } /* wrong protocol? */ if (frm_len != 7 || buf[4] != C_CTL_MISC || buf[5] != S_OPTO_RDID) { continue; } rig_debug(RIG_DEBUG_VERBOSE, "%s: " "found OptoScan%c%c%c, software version %d.%d, " "interface version %d.%d, at %#x\n", __func__, buf[2], buf[3], buf[4], buf[5] >> 4, buf[5] & 0xf, buf[6] >> 4, buf[6] & 0xf, civ_addr); if (buf[6] == '5' && buf[7] == '3' && buf[8] == '5') { model = RIG_MODEL_OS535; } else if (buf[6] == '4' && buf[7] == '5' && buf[8] == '6') { model = RIG_MODEL_OS456; } else { continue; } if (cfunc) { (*cfunc)(port, model, data); } break; } close(port->fd); /* * Assumes all the rigs on the bus are running at same speed. * So if one at least has been found, none will be at lower speed. */ if (model != RIG_MODEL_NONE) { return (model); } } return (model); } static int icom_is_x25x26_potentially_supported(RIG *rig) { const struct icom_priv_caps *priv_caps = rig->caps->priv; // Handle rigs that will never support the 0x25 or 0x26 commands // The IC-751 doesn't even reject the command and has to time out if (priv_caps->x25x26_possibly || priv_caps->x25x26_always) { return 1; } return 0; } static void icom_set_x25x26_ability(RIG *rig, int status) { struct icom_priv_data *priv = STATE(rig)->priv; if (!icom_is_x25x26_potentially_supported(rig)) { // No change for rigs that don't support these commands anyway rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib thinks rig does not support x25/x26 command\n", __func__); return; } priv->x25cmdfails = status; priv->x26cmdfails = status; } /** * Resolves the VFO number for Icom commands 0x25 and 0x26 */ static int icom_get_vfo_number_x25x26(RIG *rig, vfo_t vfo) { int vfo_number = 0x00; struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); // Rigs with *only* Main/Sub VFOs can directly address VFOs: 0 = Main, 1 = Sub if (RIG_IS_IC7600 || RIG_IS_IC7610 || RIG_IS_IC7800 || RIG_IS_IC785X) { vfo_t actual_vfo = vfo_fixup(rig, vfo, cachep->split); if (actual_vfo == RIG_VFO_CURR) { actual_vfo = rs->current_vfo; } if (actual_vfo & (RIG_VFO_B | RIG_VFO_SUB)) { vfo_number = 0x01; } } else { // Other Icom rigs have: 0 = selected VFO, 1 = unselected VFO if (vfo == RIG_VFO_CURR) { vfo_number = 0x00; // selected VFO } else if (vfo == RIG_VFO_OTHER) { vfo_number = 0x01; // unselected VFO } else { vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B | RIG_VFO_OTHER; // Check if we are on the requested VFO already if (rs->current_vfo & vfo_unselected) { HAMLIB_TRACE; vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A | RIG_VFO_OTHER; } // Check if we are not on the unselected VFO if ((vfo & vfo_unselected) && !(rs->current_vfo & vfo_unselected)) { HAMLIB_TRACE; vfo_number = 0x01; // unselected VFO } // The split VFO is active when transmitting in split mode vfo_number = (cachep->split && cachep->ptt) ? !vfo_number : vfo_number; } } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): current_vfo=%s, vfo=%s -> vfo_number=%d\n", __func__, __LINE__, rig_strvfo(rs->current_vfo), rig_strvfo(vfo), vfo_number); return vfo_number; } /* * initrigs_icom is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icom) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ic703_caps); rig_register(&ic705_caps); rig_register(&ic706_caps); rig_register(&ic706mkii_caps); rig_register(&ic706mkiig_caps); rig_register(&ic718_caps); rig_register(&ic725_caps); rig_register(&ic726_caps); rig_register(&ic735_caps); rig_register(&ic736_caps); rig_register(&ic737_caps); rig_register(&ic738_caps); rig_register(&ic7410_caps); rig_register(&ic746_caps); rig_register(&ic746pro_caps); rig_register(&ic751_caps); rig_register(&ic761_caps); rig_register(&ic775_caps); rig_register(&ic756_caps); rig_register(&ic756pro_caps); rig_register(&ic756pro2_caps); rig_register(&ic756pro3_caps); rig_register(&ic7600_caps); rig_register(&ic765_caps); rig_register(&ic7700_caps); rig_register(&ic78_caps); rig_register(&ic7800_caps); rig_register(&ic785x_caps); rig_register(&ic7000_caps); rig_register(&ic7100_caps); rig_register(&ic7200_caps); rig_register(&ic7300_caps); rig_register(&ic7610_caps); rig_register(&ic7760_caps); rig_register(&ic781_caps); rig_register(&ic707_caps); rig_register(&ic728_caps); rig_register(&ic729_caps); rig_register(&ic820h_caps); rig_register(&ic821h_caps); rig_register(&ic905_caps); rig_register(&ic910_caps); rig_register(&ic9100_caps); rig_register(&ic970_caps); rig_register(&ic9700_caps); rig_register(&icrx7_caps); rig_register(&icr6_caps); rig_register(&icr10_caps); rig_register(&icr20_caps); rig_register(&icr30_caps); rig_register(&icr71_caps); rig_register(&icr72_caps); rig_register(&icr75_caps); rig_register(&icr7000_caps); rig_register(&icr7100_caps); rig_register(&icr8500_caps); rig_register(&icr8600_caps); rig_register(&icr9000_caps); rig_register(&icr9500_caps); rig_register(&ic271_caps); rig_register(&ic275_caps); rig_register(&ic375_caps); rig_register(&ic471_caps); rig_register(&ic475_caps); rig_register(&ic575_caps); rig_register(&ic1275_caps); rig_register(&icf8101_caps); rig_register(&os535_caps); rig_register(&os456_caps); rig_register(&omnivip_caps); rig_register(&delta2_caps); rig_register(&ic92d_caps); rig_register(&id1_caps); rig_register(&id31_caps); rig_register(&id51_caps); rig_register(&id4100_caps); rig_register(&id5100_caps); rig_register(&ic2730_caps); rig_register(&perseus_caps); rig_register(&x108g_caps); rig_register(&x6100_caps); rig_register(&g90_caps); rig_register(&x5105_caps); rig_register(&x6200_caps); return (RIG_OK); } hamlib-4.6.5/rigs/icom/icr71.c0000664000175000017500000001000715056640443011436 /* * Hamlib CI-V backend - description of IC-R71 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" /* FM optional */ #define ICR71_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define ICR71_FUNC_ALL (RIG_FUNC_NONE) #define ICR71_LEVEL_ALL (RIG_LEVEL_NONE) #define ICR71_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ICR71_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define ICR71_SCAN_OPS (RIG_SCAN_NONE) static struct icom_priv_caps icr71_priv_caps = { 0x1a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list /* none actually */ }; struct rig_caps icr71_caps = { RIG_MODEL(RIG_MODEL_ICR71), .model_name = "IC-R71", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR71_FUNC_ALL, .has_set_func = ICR71_FUNC_ALL, .has_get_level = ICR71_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR71_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR71_VFO_OPS, .scan_ops = ICR71_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), ICR71_MODES, -1, -1, ICR71_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), ICR71_MODES, -1, -1, ICR71_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR71_MODES, Hz(10)}, /* resolution */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, /* optional w/ IC-EX257 unit */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr71_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic475.c0000664000175000017500000001602615056640443011353 /* * Hamlib CI-V backend - description of IC-475 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC475_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC475_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC475_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * FIXME: this appears to be the IC-475A/E * what about the IC-475H ? please give it a fix. --SF */ static const struct icom_priv_caps ic475_priv_caps = { 0x14, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic475_caps = { RIG_MODEL(RIG_MODEL_IC475), .model_name = "IC-475", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC475_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC475_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic475_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic575_priv_caps = { 0x16, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic575_caps = { RIG_MODEL(RIG_MODEL_IC575), .model_name = "IC-575", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC475_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC475_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic575_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op }; hamlib-4.6.5/rigs/icom/Makefile.in0000664000175000017500000010466315056640452012426 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/icom ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_icom_la_LIBADD = am__objects_1 = icom.lo frame.lo ic706.lo icr8500.lo ic735.lo ic775.lo \ ic756.lo ic275.lo ic475.lo ic1275.lo ic820h.lo ic821h.lo \ icr7000.lo ic910.lo ic9100.lo ic970.lo ic725.lo ic737.lo \ ic718.lo os535.lo os456.lo omni.lo delta2.lo ic92d.lo ic736.lo \ ic738.lo ic7410.lo ic746.lo ic703.lo ic726.lo ic271.lo \ ic765.lo ic781.lo ic471.lo icr9000.lo icr9500.lo icr10.lo \ icr20.lo icr30.lo icr6.lo icr71.lo icr72.lo icr75.lo icrx7.lo \ icr8600.lo id1.lo id31.lo id51.lo id4100.lo id5100.lo \ perseus.lo ic2730.lo ic707.lo ic728.lo ic751.lo ic761.lo \ ic78.lo ic7800.lo ic785x.lo ic7000.lo ic7100.lo ic7200.lo \ ic7300.lo ic7600.lo ic7610.lo ic7700.lo ic7760.lo icf8101.lo \ optoscan.lo xiegu.lo am_libhamlib_icom_la_OBJECTS = $(am__objects_1) libhamlib_icom_la_OBJECTS = $(am_libhamlib_icom_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/delta2.Plo ./$(DEPDIR)/frame.Plo \ ./$(DEPDIR)/ic1275.Plo ./$(DEPDIR)/ic271.Plo \ ./$(DEPDIR)/ic2730.Plo ./$(DEPDIR)/ic275.Plo \ ./$(DEPDIR)/ic471.Plo ./$(DEPDIR)/ic475.Plo \ ./$(DEPDIR)/ic7000.Plo ./$(DEPDIR)/ic703.Plo \ ./$(DEPDIR)/ic706.Plo ./$(DEPDIR)/ic707.Plo \ ./$(DEPDIR)/ic7100.Plo ./$(DEPDIR)/ic718.Plo \ ./$(DEPDIR)/ic7200.Plo ./$(DEPDIR)/ic725.Plo \ ./$(DEPDIR)/ic726.Plo ./$(DEPDIR)/ic728.Plo \ ./$(DEPDIR)/ic7300.Plo ./$(DEPDIR)/ic735.Plo \ ./$(DEPDIR)/ic736.Plo ./$(DEPDIR)/ic737.Plo \ ./$(DEPDIR)/ic738.Plo ./$(DEPDIR)/ic7410.Plo \ ./$(DEPDIR)/ic746.Plo ./$(DEPDIR)/ic751.Plo \ ./$(DEPDIR)/ic756.Plo ./$(DEPDIR)/ic7600.Plo \ ./$(DEPDIR)/ic761.Plo ./$(DEPDIR)/ic7610.Plo \ ./$(DEPDIR)/ic765.Plo ./$(DEPDIR)/ic7700.Plo \ ./$(DEPDIR)/ic775.Plo ./$(DEPDIR)/ic7760.Plo \ ./$(DEPDIR)/ic78.Plo ./$(DEPDIR)/ic7800.Plo \ ./$(DEPDIR)/ic781.Plo ./$(DEPDIR)/ic785x.Plo \ ./$(DEPDIR)/ic820h.Plo ./$(DEPDIR)/ic821h.Plo \ ./$(DEPDIR)/ic910.Plo ./$(DEPDIR)/ic9100.Plo \ ./$(DEPDIR)/ic92d.Plo ./$(DEPDIR)/ic970.Plo \ ./$(DEPDIR)/icf8101.Plo ./$(DEPDIR)/icom.Plo \ ./$(DEPDIR)/icr10.Plo ./$(DEPDIR)/icr20.Plo \ ./$(DEPDIR)/icr30.Plo ./$(DEPDIR)/icr6.Plo \ ./$(DEPDIR)/icr7000.Plo ./$(DEPDIR)/icr71.Plo \ ./$(DEPDIR)/icr72.Plo ./$(DEPDIR)/icr75.Plo \ ./$(DEPDIR)/icr8500.Plo ./$(DEPDIR)/icr8600.Plo \ ./$(DEPDIR)/icr9000.Plo ./$(DEPDIR)/icr9500.Plo \ ./$(DEPDIR)/icrx7.Plo ./$(DEPDIR)/id1.Plo ./$(DEPDIR)/id31.Plo \ ./$(DEPDIR)/id4100.Plo ./$(DEPDIR)/id51.Plo \ ./$(DEPDIR)/id5100.Plo ./$(DEPDIR)/omni.Plo \ ./$(DEPDIR)/optoscan.Plo ./$(DEPDIR)/os456.Plo \ ./$(DEPDIR)/os535.Plo ./$(DEPDIR)/perseus.Plo \ ./$(DEPDIR)/xiegu.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_icom_la_SOURCES) DIST_SOURCES = $(libhamlib_icom_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ICOMSRC = icom.c icom.h icom_defs.h frame.c frame.h ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr30.c icr6.c icr71.c icr72.c icr75.c icrx7.c icr8600.c \ id1.c id31.c id51.c id4100.c id5100.c perseus.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic785x.c \ ic7000.c ic7100.c ic7200.c ic7300.c ic7600.c ic7610.c ic7700.c ic7760.c icf8101.c \ ic7300.h optoscan.c optoscan.h xiegu.c level_gran_icom.h noinst_LTLIBRARIES = libhamlib-icom.la libhamlib_icom_la_SOURCES = $(ICOMSRC) EXTRA_DIST = README.icom TODO.icom Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/icom/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/icom/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-icom.la: $(libhamlib_icom_la_OBJECTS) $(libhamlib_icom_la_DEPENDENCIES) $(EXTRA_libhamlib_icom_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_icom_la_OBJECTS) $(libhamlib_icom_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delta2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic1275.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic271.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic2730.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic275.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic471.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic475.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic703.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic706.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic707.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic718.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic725.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic726.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic728.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7300.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic735.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic736.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic737.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic738.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7410.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic746.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic751.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic756.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic761.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7610.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic765.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic775.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7760.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic78.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7800.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic781.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic785x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic820h.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic821h.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic910.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic9100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic92d.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic970.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icf8101.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr20.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr30.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr6.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr7000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr71.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr72.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr75.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr8500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr8600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr9000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr9500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icrx7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id31.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id4100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id51.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id5100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omni.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optoscan.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os456.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os535.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perseus.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiegu.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/delta2.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f ./$(DEPDIR)/ic1275.Plo -rm -f ./$(DEPDIR)/ic271.Plo -rm -f ./$(DEPDIR)/ic2730.Plo -rm -f ./$(DEPDIR)/ic275.Plo -rm -f ./$(DEPDIR)/ic471.Plo -rm -f ./$(DEPDIR)/ic475.Plo -rm -f ./$(DEPDIR)/ic7000.Plo -rm -f ./$(DEPDIR)/ic703.Plo -rm -f ./$(DEPDIR)/ic706.Plo -rm -f ./$(DEPDIR)/ic707.Plo -rm -f ./$(DEPDIR)/ic7100.Plo -rm -f ./$(DEPDIR)/ic718.Plo -rm -f ./$(DEPDIR)/ic7200.Plo -rm -f ./$(DEPDIR)/ic725.Plo -rm -f ./$(DEPDIR)/ic726.Plo -rm -f ./$(DEPDIR)/ic728.Plo -rm -f ./$(DEPDIR)/ic7300.Plo -rm -f ./$(DEPDIR)/ic735.Plo -rm -f ./$(DEPDIR)/ic736.Plo -rm -f ./$(DEPDIR)/ic737.Plo -rm -f ./$(DEPDIR)/ic738.Plo -rm -f ./$(DEPDIR)/ic7410.Plo -rm -f ./$(DEPDIR)/ic746.Plo -rm -f ./$(DEPDIR)/ic751.Plo -rm -f ./$(DEPDIR)/ic756.Plo -rm -f ./$(DEPDIR)/ic7600.Plo -rm -f ./$(DEPDIR)/ic761.Plo -rm -f ./$(DEPDIR)/ic7610.Plo -rm -f ./$(DEPDIR)/ic765.Plo -rm -f ./$(DEPDIR)/ic7700.Plo -rm -f ./$(DEPDIR)/ic775.Plo -rm -f ./$(DEPDIR)/ic7760.Plo -rm -f ./$(DEPDIR)/ic78.Plo -rm -f ./$(DEPDIR)/ic7800.Plo -rm -f ./$(DEPDIR)/ic781.Plo -rm -f ./$(DEPDIR)/ic785x.Plo -rm -f ./$(DEPDIR)/ic820h.Plo -rm -f ./$(DEPDIR)/ic821h.Plo -rm -f ./$(DEPDIR)/ic910.Plo -rm -f ./$(DEPDIR)/ic9100.Plo -rm -f ./$(DEPDIR)/ic92d.Plo -rm -f ./$(DEPDIR)/ic970.Plo -rm -f ./$(DEPDIR)/icf8101.Plo -rm -f ./$(DEPDIR)/icom.Plo -rm -f ./$(DEPDIR)/icr10.Plo -rm -f ./$(DEPDIR)/icr20.Plo -rm -f ./$(DEPDIR)/icr30.Plo -rm -f ./$(DEPDIR)/icr6.Plo -rm -f ./$(DEPDIR)/icr7000.Plo -rm -f ./$(DEPDIR)/icr71.Plo -rm -f ./$(DEPDIR)/icr72.Plo -rm -f ./$(DEPDIR)/icr75.Plo -rm -f ./$(DEPDIR)/icr8500.Plo -rm -f ./$(DEPDIR)/icr8600.Plo -rm -f ./$(DEPDIR)/icr9000.Plo -rm -f ./$(DEPDIR)/icr9500.Plo -rm -f ./$(DEPDIR)/icrx7.Plo -rm -f ./$(DEPDIR)/id1.Plo -rm -f ./$(DEPDIR)/id31.Plo -rm -f ./$(DEPDIR)/id4100.Plo -rm -f ./$(DEPDIR)/id51.Plo -rm -f ./$(DEPDIR)/id5100.Plo -rm -f ./$(DEPDIR)/omni.Plo -rm -f ./$(DEPDIR)/optoscan.Plo -rm -f ./$(DEPDIR)/os456.Plo -rm -f ./$(DEPDIR)/os535.Plo -rm -f ./$(DEPDIR)/perseus.Plo -rm -f ./$(DEPDIR)/xiegu.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/delta2.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f ./$(DEPDIR)/ic1275.Plo -rm -f ./$(DEPDIR)/ic271.Plo -rm -f ./$(DEPDIR)/ic2730.Plo -rm -f ./$(DEPDIR)/ic275.Plo -rm -f ./$(DEPDIR)/ic471.Plo -rm -f ./$(DEPDIR)/ic475.Plo -rm -f ./$(DEPDIR)/ic7000.Plo -rm -f ./$(DEPDIR)/ic703.Plo -rm -f ./$(DEPDIR)/ic706.Plo -rm -f ./$(DEPDIR)/ic707.Plo -rm -f ./$(DEPDIR)/ic7100.Plo -rm -f ./$(DEPDIR)/ic718.Plo -rm -f ./$(DEPDIR)/ic7200.Plo -rm -f ./$(DEPDIR)/ic725.Plo -rm -f ./$(DEPDIR)/ic726.Plo -rm -f ./$(DEPDIR)/ic728.Plo -rm -f ./$(DEPDIR)/ic7300.Plo -rm -f ./$(DEPDIR)/ic735.Plo -rm -f ./$(DEPDIR)/ic736.Plo -rm -f ./$(DEPDIR)/ic737.Plo -rm -f ./$(DEPDIR)/ic738.Plo -rm -f ./$(DEPDIR)/ic7410.Plo -rm -f ./$(DEPDIR)/ic746.Plo -rm -f ./$(DEPDIR)/ic751.Plo -rm -f ./$(DEPDIR)/ic756.Plo -rm -f ./$(DEPDIR)/ic7600.Plo -rm -f ./$(DEPDIR)/ic761.Plo -rm -f ./$(DEPDIR)/ic7610.Plo -rm -f ./$(DEPDIR)/ic765.Plo -rm -f ./$(DEPDIR)/ic7700.Plo -rm -f ./$(DEPDIR)/ic775.Plo -rm -f ./$(DEPDIR)/ic7760.Plo -rm -f ./$(DEPDIR)/ic78.Plo -rm -f ./$(DEPDIR)/ic7800.Plo -rm -f ./$(DEPDIR)/ic781.Plo -rm -f ./$(DEPDIR)/ic785x.Plo -rm -f ./$(DEPDIR)/ic820h.Plo -rm -f ./$(DEPDIR)/ic821h.Plo -rm -f ./$(DEPDIR)/ic910.Plo -rm -f ./$(DEPDIR)/ic9100.Plo -rm -f ./$(DEPDIR)/ic92d.Plo -rm -f ./$(DEPDIR)/ic970.Plo -rm -f ./$(DEPDIR)/icf8101.Plo -rm -f ./$(DEPDIR)/icom.Plo -rm -f ./$(DEPDIR)/icr10.Plo -rm -f ./$(DEPDIR)/icr20.Plo -rm -f ./$(DEPDIR)/icr30.Plo -rm -f ./$(DEPDIR)/icr6.Plo -rm -f ./$(DEPDIR)/icr7000.Plo -rm -f ./$(DEPDIR)/icr71.Plo -rm -f ./$(DEPDIR)/icr72.Plo -rm -f ./$(DEPDIR)/icr75.Plo -rm -f ./$(DEPDIR)/icr8500.Plo -rm -f ./$(DEPDIR)/icr8600.Plo -rm -f ./$(DEPDIR)/icr9000.Plo -rm -f ./$(DEPDIR)/icr9500.Plo -rm -f ./$(DEPDIR)/icrx7.Plo -rm -f ./$(DEPDIR)/id1.Plo -rm -f ./$(DEPDIR)/id31.Plo -rm -f ./$(DEPDIR)/id4100.Plo -rm -f ./$(DEPDIR)/id51.Plo -rm -f ./$(DEPDIR)/id5100.Plo -rm -f ./$(DEPDIR)/omni.Plo -rm -f ./$(DEPDIR)/optoscan.Plo -rm -f ./$(DEPDIR)/os456.Plo -rm -f ./$(DEPDIR)/os535.Plo -rm -f ./$(DEPDIR)/perseus.Plo -rm -f ./$(DEPDIR)/xiegu.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/icom/icr9000.c0000664000175000017500000001317415056640443011607 /* * Hamlib CI-V backend - IC-R9000 descriptions * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #define ICR9000_MODES (RIG_MODE_AM|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_WFM) #define ICR9000_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) #define ICR9000_FUNCS (RIG_FUNC_VSC) #define ICR9000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define ICR9000_PARMS (RIG_PARM_ANN) #define ICR9000_SCAN_OPS (RIG_SCAN_MEM) /* TBC */ #define ICR9000_ANTS (RIG_ANT_1|RIG_ANT_2) /* selectable by CI-V ? */ #define ICR9000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT, \ } /* TODO: S-Meter measurements */ #define ICR9000_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icr9000_priv_caps = { 0x2a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r9000_ts_sc_list, .antack_len = 2, .ant_count = 2 }; /* * ICR9000A rig capabilities. */ struct rig_caps icr9000_caps = { RIG_MODEL(RIG_MODEL_ICR9000), .model_name = "IC-R9000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR9000_FUNCS, .has_set_func = ICR9000_FUNCS, .has_get_level = ICR9000_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR9000_LEVELS), .has_get_parm = ICR9000_PARMS, .has_set_parm = RIG_PARM_SET(ICR9000_PARMS), .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 10, 20, 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR9000_OPS, .scan_ops = ICR9000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 999, RIG_MTYPE_MEM, ICR9000_MEM_CAP }, /* TBC */ { 1000, 1009, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* 2 by 2 */ { 1010, 1019, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(1999.8), ICR9000_MODES, -1, -1, RIG_VFO_A, ICR9000_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(1999.8), ICR9000_MODES, -1, -1, RIG_VFO_A, ICR9000_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR9000_MODES, 10}, /* resolution */ {ICR9000_MODES, 100}, {ICR9000_MODES, kHz(1)}, {ICR9000_MODES, kHz(5)}, {ICR9000_MODES, kHz(9)}, {ICR9000_MODES, kHz(10)}, {ICR9000_MODES, 12500}, {ICR9000_MODES, kHz(20)}, {ICR9000_MODES, kHz(25)}, {ICR9000_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR9000_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr9000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, #ifdef XXREMOVEDXX .set_parm = icom_set_parm, .get_parm = icom_get_parm, #endif .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic726.c0000664000175000017500000001245115056640443011350 /* * Hamlib CI-V backend - description of IC-726 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC726_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-726 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic726/specs.htm * */ #define IC726_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC726_AM_TX_MODES (RIG_MODE_AM) #define IC726_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC726_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC726_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC726_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic726_priv_caps = { 0x30, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic726_caps = { RIG_MODEL(RIG_MODEL_IC726), .model_name = "IC-726", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC726_VFO_OPS, .scan_ops = IC726_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, {MHz(50), MHz(54), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC726_OTHER_TX_MODES, W(10), W(100), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_HF(1, IC726_AM_TX_MODES, W(10), W(40), IC726_VFO_ALL, IC726_ANTS), /* AM class */ FRQ_RNG_6m(1, IC726_OTHER_TX_MODES, W(1), W(10), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_6m(1, IC726_AM_TX_MODES, W(1), W(4), IC726_VFO_ALL, IC726_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, {MHz(50), MHz(54), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC726_OTHER_TX_MODES, W(10), W(100), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_HF(2, IC726_AM_TX_MODES, W(10), W(40), IC726_VFO_ALL, IC726_ANTS), /* AM class */ FRQ_RNG_6m(2, IC726_OTHER_TX_MODES, W(1), W(10), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_6m(2, IC726_AM_TX_MODES, W(1), W(4), IC726_VFO_ALL, IC726_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC726_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic726_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7610.c0000664000175000017500000005237315056640443011436 /* * Hamlib CI-V backend - description of IC-7610 * Stolen from IC7610.c by Michael Black W9MDB * Copyright (c) 2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7610_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7610_1HZ_TS_MODES IC7610_ALL_RX_MODES #define IC7610_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7610_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7610_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_OVF_STATUS) #define IC7610_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_AGC_TIME) #define IC7610_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7610_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7610_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7610_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7610_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Measurement by Roeland, PA3MET */ #define IC7610_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ } } #define IC7610_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7610_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7610_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7610_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7610_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 10.0f }, \ { 211, 16.0f } \ } } #define IC7610_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 77, 10.0f }, \ { 165, 20.0f }, \ { 241, 30.0f } \ } } struct cmdparams ic7610_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x24}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x41}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x59}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x92}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x12}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x70}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x82}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x31}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7610_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_RBW, TOK_SCOPE_MKP, TOK_IPP_FUNC, TOK_TX_INHIBIT_FUNC, TOK_DPP_FUNC, TOK_ICPW2_FUNC, TOK_BACKEND_NONE }; /* * IC-7610 rig capabilities. */ static const struct icom_priv_caps ic7610_priv_caps = { 0x98, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 689, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 200, .signal_strength_min = -100, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic7610_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7610_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x58; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x62; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7610_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x62; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7610_caps = { RIG_MODEL(RIG_MODEL_IC7610), .model_name = "IC-7610", .mfg_name = "Icom", .version = BACKEND_VER ".15", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7610_FUNCS, .has_set_func = IC7610_FUNCS, .has_get_level = IC7610_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7610_LEVELS), .has_get_parm = IC7610_PARMS, .has_set_parm = RIG_PARM_SET(IC7610_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7610_ext_tokens, .extfuncs = icom_ext_funcs, .extlevels = icom_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 12, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC7610_VFO_OPS, .scan_ops = IC7610_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7610_ALL_RX_MODES, -1, -1, IC7610_VFOS, IC7610_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_6m(1, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_HF(1, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7610_ALL_RX_MODES, -1, -1, IC7610_VFOS, IC7610_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_6m(2, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_HF(2, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7610_1HZ_TS_MODES, 1}, {IC7610_ALL_RX_MODES, Hz(100)}, {IC7610_ALL_RX_MODES, kHz(1)}, {IC7610_ALL_RX_MODES, kHz(5)}, {IC7610_ALL_RX_MODES, kHz(9)}, {IC7610_ALL_RX_MODES, kHz(10)}, {IC7610_ALL_RX_MODES, kHz(12.5)}, {IC7610_ALL_RX_MODES, kHz(20)}, {IC7610_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7610_STR_CAL, .swr_cal = IC7610_SWR_CAL, .alc_cal = IC7610_ALC_CAL, .rfpower_meter_cal = IC7610_RFPOWER_METER_CAL, .comp_meter_cal = IC7610_COMP_METER_CAL, .vd_meter_cal = IC7610_VD_METER_CAL, .id_meter_cal = IC7610_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7610_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic7610_set_clock, .get_clock = ic7610_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic1275.c0000664000175000017500000001020615056640443011424 /* * Hamlib CI-V backend - description of IC-1275 and variations * Copyright (c) 2000-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC1275_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC1275_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC1275_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) static const struct icom_priv_caps ic1275_priv_caps = { 0x18, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic1275_caps = { RIG_MODEL(RIG_MODEL_IC1275), .model_name = "IC-1275", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC1275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(1240), MHz(1300), IC1275_MODES, -1, -1, IC1275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1240), MHz(1300), IC1275_MODES, W(1), W(10), IC1275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(1240), MHz(1300), IC1275_MODES, -1, -1, IC1275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(1240), MHz(1300), IC1275_MODES, W(1), W(10), IC1275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC1275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_CW, Hz(500)}, /* optional FL-83 CW narrow filter */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic1275_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic735.c0000664000175000017500000001332315056640443011347 /* * Hamlib CI-V backend - description of IC-735 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "bandplan.h" #define IC735_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC735_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC735_AM_TX_MODES (RIG_MODE_AM) #define IC735_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC735_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC735_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic735_priv_caps = { 0x04, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic735_caps = { RIG_MODEL(RIG_MODEL_IC735), .model_name = "IC-735", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC735_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 10, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 11, 12, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC735_ALL_RX_MODES, -1, -1, IC735_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC735_OTHER_TX_MODES, W(10), W(100), IC735_VFO_ALL, IC735_ANTS), FRQ_RNG_HF(1, IC735_AM_TX_MODES, W(10), W(40), IC735_VFO_ALL, IC735_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC735_ALL_RX_MODES, -1, -1, IC735_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(7), kHz(7300), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(7), kHz(7300), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(10100), kHz(10150), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(10100), kHz(10150), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(14), kHz(14350), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(14), kHz(14350), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(18068), kHz(18168), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(18068), kHz(18168), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(21), kHz(21450), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(21), kHz(21450), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(24890), kHz(24990), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(24890), kHz(24990), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(28), kHz(29700), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(28), kHz(29700), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC735_ALL_RX_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic735_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7760.c0000664000175000017500000003722715056640443011445 /* * Hamlib CI-V backend - description of IC-7760 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Stre #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7760_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PSK|RIG_MODE_PSKR) #define IC7760_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7760_ALL_RX_MODES IC7760_OTHER_TX_MODES | IC7760_AM_TX_MODES #define IC7760_1HZ_TS_MODES IC7760_ALL_RX_MODES #define IC7760_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) #define IC7760_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7760_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7760_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7760_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7760_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7760_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7760 calibration data based on manual #define IC7760_STR_CAL { 3, \ { \ { 0,-54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7760_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7760_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7760_RFPOWER_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 143, 100.0f }, \ { 212, 200.0f }, \ { 255, 250.0f }, \ } } #define IC7760_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7760_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7760_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } struct cmdparams ic7760_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x82}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7760_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7760 rig capabilities. */ static const struct icom_priv_caps ic7760_priv_caps = { 0xb2, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 4, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7760_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7760_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x02; prmbuf[1] = 0x05; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x02; prmbuf[1] = 0x06; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x02; prmbuf[1] = 0x04; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7760_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x61; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } static int ic7760_rig_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: enter\n", __func__); return icom_rig_open(rig); } struct rig_caps ic7760_caps = { RIG_MODEL(RIG_MODEL_IC7760), .model_name = "IC-7760", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, // the manual does not show serial speeds .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7760_FUNCS, .has_set_func = IC7760_FUNCS, .has_get_level = IC7760_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7760_LEVELS), .has_get_parm = IC7760_PARMS, .has_set_parm = RIG_PARM_SET(IC7760_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7760_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, // ?? 7700 can have a different mode on VFOB but requires VFO swap .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7760_VFO_OPS, .scan_ops = IC7760_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7760_ALL_RX_MODES, -1, -1, IC7760_VFOS, IC7760_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_6m(1, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_HF(1, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7760_ALL_RX_MODES, -1, -1, IC7760_VFOS, IC7760_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_6m(2, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_HF(2, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7760_AM_TX_MODES, W(.251), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7760_1HZ_TS_MODES, 1}, {IC7760_ALL_RX_MODES, Hz(100)}, {IC7760_ALL_RX_MODES, kHz(1)}, {IC7760_ALL_RX_MODES, kHz(5)}, {IC7760_ALL_RX_MODES, kHz(9)}, {IC7760_ALL_RX_MODES, kHz(10)}, {IC7760_ALL_RX_MODES, kHz(12.5)}, {IC7760_ALL_RX_MODES, kHz(20)}, {IC7760_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7760_STR_CAL, .swr_cal = IC7760_SWR_CAL, .alc_cal = IC7760_ALC_CAL, .rfpower_meter_cal = IC7760_RFPOWER_METER_CAL, .comp_meter_cal = IC7760_COMP_METER_CAL, .vd_meter_cal = IC7760_VD_METER_CAL, .id_meter_cal = IC7760_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7760_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = ic7760_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7760_set_clock, .get_clock = ic7760_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/xiegu.c0000664000175000017500000013707215056640443011646 /* * Hamlib CI-V backend - description of Xiegu X108G and variations * Adapted from IC-7000 code 2017 by Michael Black W9MDB * As of this date there is no CAT manual for this rig * The X108G is supposed to emulate the IC-7000 but there are a few * differences as of 2017-02-11 in the return data from the rig * It's quite possible they may fix all these eventually * If they do the functions below can go back to the icom routines * #1 the response to PTT * #2 the inability to set_dsp_mode * #3 setting split which impacts 3 routines * * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #define X108G_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM|RIG_MODE_FMN|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_NOT_TS_MODES (X108G_ALL_RX_MODES &~X108G_1HZ_TS_MODES) #define X108G_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_AM_TX_MODES (RIG_MODE_AM) #define X108G_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) #define X108G_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define X108G_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define X108G_PARMS (RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define X108G_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define X108G_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define X108G_ANTS (RIG_ANT_1|RIG_ANT_2) /* ant-1 is Hf-6m, ant-2 is 2m-70cm */ /* * Measurement by Mark, WA0TOP * * s/n 0503103. * Preamp off, ATT off, mode AM, f=10 MHz */ #define X108G_STR_CAL { 14, \ { \ { 0, -54 }, /* first one is made up */ \ { 5, -29 }, \ { 15, -27 }, \ { 43, -22 }, \ { 68, -17 }, \ { 92, -12 }, \ { 120, -6 }, \ { 141, 2 }, \ { 162, 13 }, \ { 182, 25 }, \ { 202, 38 }, \ { 222, 47 }, \ { 241, 57 }, \ { 255, 63 } \ } } /* * * X108G channel caps. */ #define X108G_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = X108G_FUNCS, \ .levels = RIG_LEVEL_SET(X108G_LEVELS), \ } /* * Prototypes */ static int x108g_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int x108g_rig_open(RIG *rig) { int retval; ENTERFUNC; retval = icom_rig_open(rig); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_open failed with %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int xiegu_rig_open(RIG *rig) { int retval; unsigned char id[4]; int id_len = 2; int cmd = 0x19; int subcmd = 0x00; unsigned short iid; retval = icom_rig_open(rig); if (retval != RIG_OK) { return retval; } retval = icom_transaction(rig, cmd, subcmd, NULL, 0, id, &id_len); if (retval == RIG_OK) { dump_hex(id, id_len); iid = (int)id[1]; if (id_len > 2) { iid = (iid << 8) + id[2]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu Radio ID=0x%04x\n", __func__, iid); switch (iid) { case 0x0070: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G90"); break; case 0x0090: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G90S"); break; case 0x0106: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G106/G106C"); break; case 0x6100: case 0x00a4: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "X6100/X6200"); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "Unknown"); break; } } return retval; } /* * taken from IC-7000 rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static struct icom_priv_caps x108g_priv_caps = { 0x70, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, }; struct rig_caps x108g_caps = { RIG_MODEL(RIG_MODEL_X108G), .model_name = "X108G", .mfg_name = "Xiegu", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .targetable_vfo = 0, .vfo_ops = X108G_VFO_OPS, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x108g_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = x108g_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = x108g_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = x108g_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = x108g_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps x6100_priv_caps = { 0xa4, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 0, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps x6100_caps = { RIG_MODEL(RIG_MODEL_X6100), .model_name = "X6100", .mfg_name = "Xiegu", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 3, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x6100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, // testing with X6100 showed it rejected the 0x0f 0x01 command .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps x6200_caps = { RIG_MODEL(RIG_MODEL_X6200), .model_name = "X6200", .mfg_name = "Xiegu", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 3, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x6100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, // testing with X6100 showed it rejected the 0x0f 0x01 command .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps g90_priv_caps = { 0xa4, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .x25x26_always = 0, .x25x26_possibly = 1, // Firmware G90 v20240504.8 doesn't work well -- see https://github.com/Hamlib/Hamlib/issues/1547 .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 0, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps g90_caps = { RIG_MODEL(RIG_MODEL_G90), .model_name = "G90", .mfg_name = "Xiegu", .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 19200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& g90_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps x5105_caps = { RIG_MODEL(RIG_MODEL_X5105), .model_name = "X5105", .mfg_name = "Xiegu", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .targetable_vfo = 0, .vfo_ops = X108G_VFO_OPS, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x108g_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = NULL, .get_split_vfo = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * x108g_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL * The response from the x108g isn't quite right at this time * Eventually they may fix their firmware and we can use the icom_set_split_vfo */ int x108g_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[1]; int ack_len = sizeof(ackbuf), retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); pttbuf[0] = ptt == RIG_PTT_ON ? 1 : 0; retval = icom_transaction(rig, C_CTL_PTT, S_PTT, pttbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } /* X108G doesn't quite follow ICOM protocol -- returns 0x1c instead of 0xfb */ if (ackbuf[0] != 0xfb && (ack_len != 3 || ackbuf[0] != 0x1c)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d, ptt=%d\n", __func__, ackbuf[0], ack_len, ptt); return -RIG_ERJCTED; } return RIG_OK; } /* * The response from the x108g isn't quite right at this time * Eventually they may fix their firmware and we can use the icom_set_split_vfo * x108g_set_split * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), rc; int split_sc; struct rig_cache *cachep = CACHE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_OFF: split_sc = S_SPLT_OFF; break; case RIG_SPLIT_ON: split_sc = S_SPLT_ON; if (cachep->split == RIG_SPLIT_OFF) { /* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) { if (RIG_OK != (rc = icom_set_vfo(rig, RIG_VFO_A))) { return rc; } } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported split %d", __func__, split); return -RIG_EINVAL; } if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0, ackbuf, &ack_len))) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) // instead of len=1 & ACK { rig_debug(RIG_DEBUG_ERR, "x108g_set_split: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } cachep->split = split; return RIG_OK; } /* * x108g_set_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * * Assumes also that the current VFO is the rx VFO. */ static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int rc; vfo_t rx_vfo, tx_vfo; struct icom_priv_data *priv; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct icom_priv_data *)rs->priv; /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } if (RIG_OK != (rc = icom_set_freq(rig, RIG_VFO_CURR, tx_freq))) { return rc; } if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } return rc; } /* In the case of rigs with an A/B VFO arrangement we assume the current VFO is VFO A and the split Tx VFO is always VFO B. These assumptions allow us to deal with the lack of VFO and split queries */ /* broken if user changes split on rig :( */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) { rig_debug(RIG_DEBUG_ERR, "x108g_set_split_freq: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } if (RIG_OK != (rc = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) { return rc; } if (RIG_OK != (rc = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } } return rc; } /* * x108g_set_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, */ static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int rc; vfo_t rx_vfo, tx_vfo; struct icom_priv_data *priv; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct icom_priv_data *)rs->priv; /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { return rc; } if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } return rc; } /* In the case of rigs with an A/B VFO arrangement we assume the current VFO is VFO A and the split Tx VFO is always VFO B. These assumptions allow us to deal with the lack of VFO and split queries */ /* broken if user changes split on rig :( */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) { rig_debug(RIG_DEBUG_ERR, "x108g_set_split_mode: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } if (RIG_OK != (rc = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) { return rc; } if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } } return rc; } hamlib-4.6.5/rigs/icom/icr8600.c0000664000175000017500000002700115056640443011606 /* * Hamlib CI-V backend - description of IC-R8600 * Copyright (c) 2000-2004 by Stephane Fillod * Copyright (c) 2018 by Ekki Plicht * Copyright (c) 2019 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "token.h" #include "tones.h" #include "icom.h" #include "icom_defs.h" #define ICR8600_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_RTTY|\ RIG_MODE_FM|RIG_MODE_WFM|RIG_MODE_CWR|RIG_MODE_RTTYR|RIG_MODE_SAM|RIG_MODE_SAL|\ RIG_MODE_SAH|RIG_MODE_P25|RIG_MODE_DSTAR|RIG_MODE_DPMR|RIG_MODE_NXDNVN|\ RIG_MODE_NXDN_N|RIG_MODE_DCR) #define ICR8600_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MN|RIG_FUNC_AFC|\ RIG_FUNC_NR|RIG_FUNC_AIP|RIG_FUNC_LOCK|RIG_FUNC_VSC|RIG_FUNC_RESUME|RIG_FUNC_TSQL|\ RIG_FUNC_CSQL|RIG_FUNC_DSQL|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_OVF_STATUS) #define ICR8600_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|\ RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|\ RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|\ RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define ICR8600_PARM_ALL (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_KEYLIGHT) #define ICR8600_VFO_ALL (RIG_VFO_VFO|RIG_VFO_MEM) #define ICR8600_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR8600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|\ RIG_SCAN_PRIO|RIG_SCAN_PRIO|RIG_SCAN_DELTA|RIG_SCAN_STOP) #define ICR8600_ANTS_HF (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define ICR8600_ANTS_VHF (RIG_ANT_1) #define ICR8600_STR_CAL { 2, {\ { 0, -60 }, \ { 255, 60 }, \ } } struct cmdparams icr8600_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x38}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x15}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x16}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x32}, CMD_DAT_TIM, 2 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x92}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x40}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x81}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_NONE} } }; int icr8600_tokens[] = { TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_SCOPE_CFQ, TOK_SCOPE_VBW, TOK_BACKEND_NONE }; #define ICR8600_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ .flags = 1, \ } static struct icom_priv_caps icr8600_priv_caps = { 0x96, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8600_ts_sc_list, /* list of tuning steps */ .antack_len = 2, .ant_count = 3, .offs_len = 4, /* Repeater offset is 4 bytes */ .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -100, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 0, .high_freq = 3000000000, }, }, .extcmds = icr8600_extcmds /* Custom ext_cmd parameters */ }; struct rig_caps icr8600_caps = { RIG_MODEL(RIG_MODEL_ICR8600), .model_name = "IC-R8600", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_func = ICR8600_FUNC_ALL, .has_set_func = ICR8600_FUNC_ALL, .has_get_level = ICR8600_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR8600_LEVEL_ALL), .has_get_parm = ICR8600_PARM_ALL, .has_set_parm = RIG_PARM_SET(ICR8600_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = {.i = 0}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_TIME] = { .min = { .i = 0 }, .max = { .i = 86399} } }, .ext_tokens = icr8600_tokens, .extlevels = icom_ext_levels, .extfuncs = icom_ext_funcs, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* 20 on HF, 14 on VHF, UHF, same setting */ .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = ICR8600_VFO_OPS, .scan_ops = ICR8600_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 100, .chan_desc_sz = 16, .chan_list = { { 0, 99, RIG_MTYPE_MEM, ICR8600_MEM_CAP }, { 0, 99, RIG_MTYPE_EDGE, ICR8600_MEM_CAP }, /* to be extended */ RIG_CHAN_END, }, .rx_range_list1 = { { kHz(10), MHz(3000), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_VHF }, { kHz(10), MHz(30), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_HF }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { kHz(10), MHz(3000), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_VHF }, { kHz(10), MHz(30), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_HF }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR8600_MODES, Hz(100)}, {ICR8600_MODES, kHz(1)}, {ICR8600_MODES, kHz(2.5)}, {ICR8600_MODES, kHz(3.125)}, {ICR8600_MODES, kHz(5)}, {ICR8600_MODES, kHz(6.25)}, {ICR8600_MODES, kHz(8.33)}, {ICR8600_MODES, kHz(9)}, {ICR8600_MODES, kHz(10)}, {ICR8600_MODES, kHz(12.5)}, {ICR8600_MODES, kHz(20)}, {ICR8600_MODES, kHz(25)}, {ICR8600_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(15)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ICR8600_STR_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .priv = (void *)& icr8600_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_bank = icom_set_bank, .get_rptr_offs = icom_get_rptr_offs, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_shift = icom_set_rptr_shift, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/omni.c0000664000175000017500000002125315056640443011460 /* * Hamlib CI-V backend - description of the TenTenc OMNI VI * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Improvements by Martin Ewing, AA6E, 3/2008 * This backend should support either the Ten-Tec Omni VI Plus (564) or the * Omni VI (563). Tested on an Omni VI. */ /* Known problems: * * To Do: * Implement vfo split, FSK mode */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include #define OMNIVIP_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define OMNIVIP_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define OMNIVIP_ALL_RX_MODES (OMNIVIP_OTHER_TX_MODES) #define OMNIVIP_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define OMNIVIP_STR_CAL { 0, { } } static int omni6_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int omni6_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int omni6_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static struct icom_priv_caps omnivip_priv_caps = { 0x04, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL /* TODO */ }; struct rig_caps omnivip_caps = { RIG_MODEL(RIG_MODEL_OMNIVIP), .model_name = "Omni VI Plus", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Allow program controlled PTT .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9980), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = OMNIVIP_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* These limits measured on Omni VI SN 1A10473 */ .rx_range_list2 = { {kHz(1770), kHz(2330), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(3471), kHz(4030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(6821), kHz(7338), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(9971), kHz(10530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(13971), kHz(14530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(17971), kHz(18530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(20971), kHz(21530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(24471), kHz(25030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(27971), kHz(30030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, RIG_FRNG_END, }, /* Note: There is no AM mode. */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(3500), MHz(4) - 1, OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(7), kHz(7300), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(10100), kHz(10150), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(14), kHz(14350), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(18068), kHz(18168), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(21), kHz(21450), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(24890), kHz(24990), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(28), kHz(29700), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {OMNIVIP_ALL_RX_MODES, Hz(10)}, // This radio has 10 Hz steps. RIG_TS_END, }, /* mode/filter list, remember: order matters! * Possible XTAL filters: 2.4, 1.8, 0.5, 0.25 kHz - may not all be * present. FM filter is 15 kHz. * We are not supporting the 'FSK' (RTTY) mode at this time. */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& omnivip_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // icom.c has no get_vfo .set_rit = omni6_set_rit, .get_rit = omni6_get_rit, // icom.c has no get_rit .set_xit = omni6_set_rit, // xit=rit for this rig .get_xit = omni6_get_rit, // (front panel controlled) .set_ptt = omni6_set_ptt, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * omni6_set_ptt based on icom_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int omni6_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval, sc; sc = ptt == RIG_PTT_ON ? 0x1 : 0x2; /* * Ignore ACK/NAK on this command, because in CW mode, the Omni VI * does not send an ACK. */ retval = icom_transaction(rig, C_OMNI6_XMT, sc, NULL, 0, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * These 'rit' commands actually deal with an offset frequency. The operator * must select rit on/off or xit on/off manually to apply this offset. * Omni VI's rit uses 9's complement for negative freq, and freqs are in units * of 10 Hz. on the Omni. * Note that Omni VI rejects rit > 9980, but takes rit >= -9990. So the * rit limit should be +/- 9.98 kHz. */ int omni6_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int freq_len, ack_len = sizeof(ackbuf), retval; shortfreq_t rit10; rit10 = rit / 10; // 10 Hz resolution for Omni if (rit10 < 0) { rit10 += 10000L; } // 9's compl. freq_len = 2; to_bcd(freqbuf, rit10, 2 * freq_len); retval = icom_transaction(rig, C_SET_OFFS, -1, freqbuf, freq_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "omni6_set_rit: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Note: icom.c does not provide a get_rit method. It would have been * wrong for the Omni VI, anyway, so we implement it here. */ int omni6_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { unsigned char buffer[MAXFRAMELEN]; int buffer_len, retval; shortfreq_t my_rit; retval = icom_transaction(rig, C_RD_OFFS, -1, NULL, 0, buffer, & buffer_len); if (retval != RIG_OK) { return retval; } if (buffer_len != 3) { rig_debug(RIG_DEBUG_ERR, "omni6_get_rit: wrong length response (%d)\n", buffer_len); return -RIG_ERJCTED; } my_rit = 10 * from_bcd(buffer, 2 * buffer_len); if (my_rit > 10000L) { my_rit -= 100000L; } // 9's compl for negatives *rit = my_rit; return RIG_OK; } hamlib-4.6.5/rigs/icom/README.icom0000664000175000017500000000301615056640443012155 hamlib - Copyright (C) 2008 The Hamlib Group File: README.icom Notes on Icom backends 2008-03, AA6E: Tested and extended omni.c for Ten-Tec Omni VI and Omni VI Plus It is now at least "beta" level. 2008-07, AA6E: Tests with IC-756PROIII at ARRL. Added AF, RF, SQL levels, COMP, BALANCE. Note: communications do not seem completely reliable for baud rates > 9600. VOX-related commands are implemented for the '910H but are wrong for the '756 and other models. They should be reimplemented in a more general way. 2008-10, DL1JBE: Tested IC-275H and IC-475H at local clubstation. Offered functions do work as expected in most cases. Only problem: Bandwidth in Get_Mode is reported always as 0. Besides this backend seems to be stable -> Changing State to RIG_STATUS_BETA. 2020-02, W9MDB: Antenna count and ack length for existing Icom's with antenna settings Model #Ant ack length 7100 2 2 737 2 2 7410 2 2 746 2 2 746 2 2 756 2 2 756 2 2 756 2 2 756 2 2 7600 2 3 7610 2 3 7700 4 3 7800 4 3 785x 4 3 9100 2 2 icr30 2 2 icr6 2 2 icr75 2 2 icr8600 3 2 icr9000 2 2 icr9500 3 2 2020-09, G0GJV Attempting to support RIT. I asked ICOM technical support "I am doing some work on the Hamlib amateur radio control library, and in particular looking at control of RIT via CI-V on the Icom IC-9100 Is my reading of the manual correct - on this (and most older Icom rigs) - there is no RIT/XIT control available?" and received the answer "Hi Mike, Yes that's right Thanks Virgil" So I've removed the erroneous icom_set_rit function.hamlib-4.6.5/rigs/icom/icr75.c0000664000175000017500000004335115056640443011452 /* * Hamlib CI-V backend - description of IC-R75 * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "misc.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" /* * IC-R75 * * TODO: * $1A command: * - set_parm, set_trn, IF filter setting, etc. */ #define ICR75_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_AMS) #define ICR75_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_NR) #define ICR75_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR75_PARM_ALL (RIG_PARM_ANN|RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME) #define ICR75_VFO_ALL (RIG_VFO_VFO|RIG_VFO_MEM) #define ICR75_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR75_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO) #define ICR75_ANTS (RIG_ANT_1|RIG_ANT_2) #define ICR75_STR_CAL { 17, { \ { 0, -60 }, \ { 37, -54 }, \ { 52, -48 }, \ { 61, -42 }, \ { 72, -36 }, \ { 86, -30 }, \ { 95, -24 }, \ { 109, -18 }, \ { 124, -12 }, \ { 128, -6 }, \ { 146, 0 }, \ { 166, 10 }, \ { 186, 20 }, \ { 199, 30 }, \ { 225, 40 }, \ { 233, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define ICR75_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ .flags = 1, \ } static int icr75_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int icr75_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int icr75_set_parm(RIG *rig, setting_t parm, value_t val); static int icr75_get_parm(RIG *rig, setting_t parm, value_t *val); static struct icom_priv_caps icr75_priv_caps = { 0x5a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r75_ts_sc_list, .antack_len = 2, .ant_count = 2 }; struct rig_caps icr75_caps = { RIG_MODEL(RIG_MODEL_ICR75), .model_name = "IC-R75", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_func = ICR75_FUNC_ALL, .has_set_func = ICR75_FUNC_ALL, .has_get_level = ICR75_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR75_LEVEL_ALL), .has_get_parm = ICR75_PARM_ALL, .has_set_parm = RIG_PARM_SET(ICR75_PARM_ALL), .level_gran = { #define NO_LVL_PBT_IN #define NO_LVL_PBT_OUT #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_PBT_IN] = { .min = { .f = -1280 }, .max = { .f = +1280 }, .step = { .f = 15 } }, [LVL_PBT_OUT] = { .min = { .f = -1280 }, .max = { .f = +1280 }, .step = { .f = 15 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 10 } }, #undef NO_LVL_PBT_IN #undef NO_LVL_PBT_OUT #undef NO_LVL_CWPITCH }, .parm_gran = { [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, [PARM_TIME] = { .min = { .i = 0 }, .max = { .i = 86399} }, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR75_VFO_OPS, .scan_ops = ICR75_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 1, 99, RIG_MTYPE_MEM, ICR75_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, ICR75_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), ICR75_MODES, -1, -1, ICR75_VFO_ALL, ICR75_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), ICR75_MODES, -1, -1, ICR75_VFO_ALL, ICR75_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR75_MODES, Hz(10)}, {ICR75_MODES, Hz(100)}, {ICR75_MODES, kHz(1)}, {ICR75_MODES, kHz(5)}, {ICR75_MODES, kHz(6.25)}, {ICR75_MODES, kHz(9)}, {ICR75_MODES, kHz(10)}, {ICR75_MODES, kHz(12.5)}, {ICR75_MODES, kHz(20)}, {ICR75_MODES, kHz(25)}, {ICR75_MODES, kHz(100)}, {ICR75_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(15)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ICR75_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr75_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icr75_set_parm, .get_parm = icr75_get_parm, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .set_channel = icr75_set_channel, .get_channel = icr75_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * icr75_set_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * TODO: still a WIP --SF */ int icr75_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int chan_len, freq_len, ack_len, retval; unsigned char icmode; signed char icmode_ext; int err; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chanbuf[2] = S_MEM_CNTNT_SLCT; freq_len = priv->civ_731_mode ? 4 : 5; /* * to_bcd requires nibble len */ to_bcd(chanbuf + 3, chan->freq, freq_len * 2); chan_len = 2 + freq_len + 1; err = rig2icom_mode(rig, vfo, chan->mode, chan->width, &icmode, &icmode_ext); if (err != RIG_OK) { return err; } chanbuf[chan_len++] = icmode; chanbuf[chan_len++] = icmode_ext; to_bcd_be(chanbuf + chan_len++, chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i, 2); to_bcd_be(chanbuf + chan_len++, chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i, 2); to_bcd_be(chanbuf + chan_len++, chan->ant, 2); memset(chanbuf + chan_len, 0, 8); SNPRINTF((char *)(chanbuf + chan_len), 9, "%.8s", chan->channel_desc); chan_len += 8; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * icr75_get_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * TODO: still a WIP --SF */ int icr75_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[24]; int chan_len, freq_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; freq_len = priv->civ_731_mode ? 4 : 5; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_SQL)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_NR)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_IN)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_OUT)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_CWPITCH)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); /* * freqbuf should contain Cn,Data area */ if ((chan_len != freq_len + 18) && (chan_len != 5)) { rig_debug(RIG_DEBUG_ERR, "icr75_get_channel: wrong frame len=%d\n", chan_len); return -RIG_ERJCTED; } /* do this only if not a blank channel */ if (chan_len != 5) { /* * from_bcd requires nibble len */ chan->flags = RIG_CHFLAG_NONE; chan->freq = from_bcd(chanbuf + 5, freq_len * 2); chan_len = 4 + freq_len + 1; icom2rig_mode(rig, chanbuf[chan_len], chanbuf[chan_len + 1], &chan->mode, &chan->width); chan_len += 2; if (from_bcd_be(chanbuf + chan_len++, 2) != 0) { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 20; } if (from_bcd_be(chanbuf + chan_len++, 2) != 0) { chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 20; } chan->ant = from_bcd_be(chanbuf + chan_len++, 2); strncpy(chan->channel_desc, (char *)(chanbuf + chan_len), 8); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int icr75_set_parm(RIG *rig, setting_t parm, value_t val) { unsigned char prmbuf[MAXFRAMELEN]; int min, hr, sec; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_ANN: { int ann_mode = -1; int ann_lang = -1; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; case RIG_ANN_ENG: case RIG_ANN_JAP: ann_lang = (val.i == RIG_ANN_ENG) ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } if (ann_mode >= 0) { return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); } else if (ann_lang >= 0) { prmbuf[0] = S_PRM_LANG; prmbuf[1] = ann_lang; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); } rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } case RIG_PARM_APO: prmbuf[0] = S_PRM_SLPTM; hr = (int)((float) val.i / 60.0f); min = val.i - (hr * 60); to_bcd_be(prmbuf + 1, (long long) hr, 2); to_bcd_be(prmbuf + 2, (long long) min, 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); case RIG_PARM_BACKLIGHT: prmbuf[0] = S_PRM_BACKLT; to_bcd_be(prmbuf + 1, (long long)(val.f * 255.0f), 2 * 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); case RIG_PARM_BEEP: prmbuf[0] = S_PRM_BEEP; prmbuf[1] = val.i ? 1 : 0; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); case RIG_PARM_TIME: hr = (int)((float) val.i / 3600.0); min = (int)((float)(val.i - (hr * 3600)) / 60.0); sec = (val.i - (hr * 3600) - (min * 60)); prmbuf[0] = S_PRM_TIME; to_bcd_be(prmbuf + 1, (long long) hr, 2); to_bcd_be(prmbuf + 2, (long long) min, 2); to_bcd_be(prmbuf + 3, (long long) sec, 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 4, prmbuf, 0, 0); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %s\n", rig_strparm(parm)); return -RIG_EINVAL; } } int icr75_get_parm(RIG *rig, setting_t parm, value_t *val) { unsigned char prmbuf[MAXFRAMELEN], resbuf[MAXFRAMELEN]; int prm_len, res_len; int prm_cn, prm_sc; int icom_val = 0; int cmdhead; int retval; int min, hr, sec; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_APO: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_SLPTM; break; case RIG_PARM_BACKLIGHT: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_BACKLT; break; case RIG_PARM_BEEP: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_BEEP; break; case RIG_PARM_TIME: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_TIME; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_parm %s", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, resbuf, &res_len); if (retval != RIG_OK) { return retval; } cmdhead = 3; res_len -= cmdhead; if (resbuf[0] != ACK && resbuf[0] != prm_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } switch (parm) { case RIG_PARM_APO: hr = from_bcd_be(resbuf + cmdhead, 2); min = from_bcd_be(resbuf + cmdhead + 1, 2); icom_val = (hr * 60) + min; val->i = icom_val; break; case RIG_PARM_TIME: hr = from_bcd_be(resbuf + cmdhead, 2); min = from_bcd_be(resbuf + cmdhead + 1, 2); sec = from_bcd_be(resbuf + cmdhead + 2, 2); icom_val = (hr * 3600) + (min * 60) + sec; val->i = icom_val; break; case RIG_PARM_BACKLIGHT: icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); val->f = (float) icom_val / 255.0; break; case RIG_PARM_BEEP: icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); val->i = icom_val; break; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } hamlib-4.6.5/rigs/icom/ic7600.c0000664000175000017500000004172715056640443011436 /* * Hamlib CI-V backend - description of IC-7600 * Copyright (c) 2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "token.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #include "tones.h" #define IC7600_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7600_1HZ_TS_MODES IC7600_ALL_RX_MODES #define IC7600_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7600_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7600_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) #define IC7600_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7600_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7600_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT) #define IC7600_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7600_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Measurement by Roeland, PA3MET */ #define IC7600_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ } } #define IC7600_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7600_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7600_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7600_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7600_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 152, 10.0f }, \ { 181, 13.0f }, \ { 212, 16.0f } \ } } #define IC7600_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 241, 25.0f } \ } } struct cmdparams ic7600_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x59}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x38}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x54}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x67}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x37}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7600_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_BACKEND_NONE }; /* * IC-7600 rig capabilities. */ static const struct icom_priv_caps ic7600_priv_caps = { 0x7a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7600_extcmds, /* Custom op parameters */ .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7600_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x53; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x54; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x56; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7600_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x53; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x54; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x56; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7600_caps = { RIG_MODEL(RIG_MODEL_IC7600), .model_name = "IC-7600", .mfg_name = "Icom", .version = BACKEND_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7600_FUNCS, .has_set_func = IC7600_FUNCS, .has_get_level = IC7600_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7600_LEVELS), .has_get_parm = IC7600_PARMS, .has_set_parm = RIG_PARM_SET(IC7600_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_KEYLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7600_ext_tokens, .extfuncs = icom_ext_funcs, .extlevels = icom_ext_levels, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 16, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7600_VFO_OPS, .scan_ops = IC7600_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7600_ALL_RX_MODES, -1, -1, IC7600_VFOS, IC7600_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_6m(1, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_HF(1, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7600_ALL_RX_MODES, -1, -1, IC7600_VFOS, IC7600_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_6m(2, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_HF(2, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7600_1HZ_TS_MODES, 1}, {IC7600_ALL_RX_MODES, Hz(100)}, {IC7600_ALL_RX_MODES, kHz(1)}, {IC7600_ALL_RX_MODES, kHz(5)}, {IC7600_ALL_RX_MODES, kHz(9)}, {IC7600_ALL_RX_MODES, kHz(10)}, {IC7600_ALL_RX_MODES, kHz(12.5)}, {IC7600_ALL_RX_MODES, kHz(20)}, {IC7600_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7600_STR_CAL, .swr_cal = IC7600_SWR_CAL, .alc_cal = IC7600_ALC_CAL, .rfpower_meter_cal = IC7600_RFPOWER_METER_CAL, .comp_meter_cal = IC7600_COMP_METER_CAL, .vd_meter_cal = IC7600_VD_METER_CAL, .id_meter_cal = IC7600_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7600_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .wait_morse = rig_wait_morse, .set_clock = ic7600_set_clock, .get_clock = ic7600_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/optoscan.h0000664000175000017500000000424215056640443012350 /* * Hamlib CI-V backend - main header * Copyright (c) 2000-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _OPTOSCAN_H #define _OPTOSCAN_H 1 #include #include "icom_defs.h" #define TOK_TAPECNTL TOKEN_BACKEND(1) #define TOK_5KHZWIN TOKEN_BACKEND(2) #define TOK_SPEAKER TOKEN_BACKEND(3) #define TOK_AUDIO TOKEN_BACKEND(4) #define TOK_DTMFPEND TOKEN_BACKEND(5) #define TOK_DTMFOVRR TOKEN_BACKEND(6) #define TOK_CTCSSACT TOKEN_BACKEND(7) #define TOK_DCSACT TOKEN_BACKEND(8) #define OPTO_BUFF_SIZE 64 int optoscan_open(RIG *rig); int optoscan_close(RIG *rig); const char* optoscan_get_info(RIG *rig); int optoscan_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int optoscan_get_dcs_code(RIG * rig, vfo_t vfo, tone_t *code); int optoscan_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length); int optoscan_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int optoscan_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int optoscan_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int optoscan_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int optoscan_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); struct optostat { int remote_control; int DTMF_pending; int DTMF_overrun; int squelch_open; int CTCSS_active; int DCS_active; int tape_enabled; int speaker_enabled; int fivekhz_enabled; int audio_present; }; #endif /* _OPTOSCAN_H */ hamlib-4.6.5/rigs/icom/ic92d.c0000664000175000017500000001645015056640443011433 /* * Hamlib CI-V backend - description of IC-E92D/IC-92AD and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "frame.h" #include "icom_defs.h" #include "tones.h" /* TODO: DV (GMSK 4.8 kbps voice) */ #define IC92D_MODES (RIG_MODE_FM) #define IC92D_MODES_TX (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define IC92D_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_MON|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_AFC) #define IC92D_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define IC92D_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define IC92D_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC92D_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC92D_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* * FIXME: real measurement */ #define IC92D_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ #define IC92D_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .funcs = IC92D_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC92D_LEVEL_ALL), \ } static const char *ic92d_get_info(RIG *rig); /* FIXME: tuning step sub-commands */ const struct ts_sc_list ic92d_ts_sc_list[] = { { kHz(5), 0x00 }, { kHz(6.25), 0x01 }, { kHz(8.33), 0x02 }, { kHz(9), 0x03 }, { kHz(10), 0x04 }, { kHz(12.5), 0x05 }, { kHz(15), 0x06 }, { kHz(20), 0x07 }, { kHz(25), 0x08 }, { kHz(30), 0x09 }, { kHz(50), 0x0a }, { kHz(100), 0x0b }, { kHz(125), 0x0c }, { kHz(200), 0x0d }, { 0, 0 }, }; /* */ static const struct icom_priv_caps ic92d_priv_caps = { 0x01, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic92d_ts_sc_list, .serial_full_duplex = 1 }; struct rig_caps ic92d_caps = { RIG_MODEL(RIG_MODEL_IC92D), .model_name = "IC-92D", /* IC-E92D/IC-92AD */ .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 38400, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC92D_FUNC_ALL, .has_set_func = IC92D_FUNC_ALL, .has_get_level = IC92D_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC92D_LEVEL_ALL), .has_get_parm = IC92D_PARM_ALL, .has_set_parm = IC92D_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC92D_VFO_OPS, .scan_ops = IC92D_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 26, .chan_desc_sz = 8, /* The IC-E92D has a total 1304 memory channels with 26 memory banks. * The VFO A has 800 regular channels, 50 scan edges and 2 call channels, * while the VFO B has 400 regular, 50 scan edges and 2 call channels. */ .chan_list = { { 1, 1200, RIG_MTYPE_MEM, IC92D_MEM_CAP }, { 1201, 1300, RIG_MTYPE_EDGE, IC92D_MEM_CAP }, { 1301, 1304, RIG_MTYPE_CALL, IC92D_MEM_CAP }, RIG_CHAN_END, }, /* IC-E92D */ .rx_range_list1 = { {kHz(495), MHz(999.99), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, RIG_VFO_A}, {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV {MHz(350), MHz(470), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, {MHz(430), MHz(440) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, RIG_FRNG_END, }, /* IC-92AD */ .rx_range_list2 = { {kHz(495), MHz(999.99), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, RIG_VFO_A}, {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV {MHz(350), MHz(470), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, {MHz(430), MHz(440) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC92D_MODES, kHz(5)}, {IC92D_MODES, kHz(6.25)}, {IC92D_MODES, kHz(8.33)}, {IC92D_MODES, kHz(9)}, {IC92D_MODES, kHz(10)}, {IC92D_MODES, 12500}, {IC92D_MODES, kHz(15)}, {IC92D_MODES, kHz(20)}, {IC92D_MODES, kHz(25)}, {IC92D_MODES, kHz(50)}, {IC92D_MODES, kHz(100)}, {IC92D_MODES, kHz(125)}, {IC92D_MODES, kHz(200)}, RIG_TS_END, }, /* FIXME: mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(9)}, /* N-FM & AM */ {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = IC92D_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic92d_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .get_info = ic92d_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; const char *ic92d_get_info(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char ackbuf[16]; int ack_len, retval; static char info[64]; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; // 018019fd priv->re_civ_addr = 0x01; retval = icom_transaction(rig, C_RD_TRXID, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return NULL; } if (ack_len <= 3) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return NULL; } SNPRINTF(info, sizeof(info), "ID %02x%02x%02x\n", ackbuf[1], ackbuf[2], ackbuf[3]); return info; } hamlib-4.6.5/rigs/icom/ic471.c0000664000175000017500000001027715056640443011351 /* * Hamlib CI-V backend - description of IC-471 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC471_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC471_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC471_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC471_STR_CAL { 0, { } } /* * IC-471 A/E * IC-471 H is high power (75W) * specs: http://www.qsl.net/sm7vhs/radio/icom/ic471/specs.htm * * Please report testing / patches. Some capabilities may be missing too. --sf */ static const struct icom_priv_caps ic471_priv_caps = { 0x22, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic471_caps = { RIG_MODEL(RIG_MODEL_IC471), .model_name = "IC-471", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC471_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 38, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC471_MODES, -1, -1, IC471_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC471_MODES, W(2.5), W(25), IC471_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC471_MODES, -1, -1, IC471_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC471_MODES, W(2.5), W(25), IC471_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC471_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic471_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic2730.c0000664000175000017500000001457115056640443011432 /* * Hamlib CI-V backend - description of IC-2730 and variations * Copyright (c) 2015 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define IC2730_MODES (RIG_MODE_FM) #define IC2730_ALL_RX_MODES (RIG_MODE_AM|IC2730_MODES) #define IC2730_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define IC2730_SCAN_OPS RIG_SCAN_NONE #define IC2730_VFO_OPS RIG_OP_NONE #define IC2730_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_VOX) #define IC2730_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define IC2730_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define IC2730_STR_CAL UNKNOWN_IC_STR_CAL static const struct icom_priv_caps ic2730_priv_caps = { 0x90, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps ic2730_caps = { RIG_MODEL(RIG_MODEL_IC2730), .model_name = "IC-2730", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC2730_FUNC_ALL, .has_set_func = IC2730_FUNC_ALL, .has_get_level = IC2730_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC2730_LEVEL_ALL), .has_get_parm = IC2730_PARM_ALL, .has_set_parm = IC2730_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC2730_VFO_OPS, .scan_ops = IC2730_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, {MHz(375), MHz(550), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC2730_MODES, W(5), W(25), IC2730_VFO_ALL}, {MHz(430), MHz(440), IC2730_MODES, W(5), W(25), IC2730_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, {MHz(375), MHz(550), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC2730_MODES, W(5), W(50), IC2730_VFO_ALL}, {MHz(430), MHz(450), IC2730_MODES, W(5), W(50), IC2730_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {IC2730_ALL_RX_MODES, kHz(5)}, {IC2730_ALL_RX_MODES, kHz(6.25)}, // The 8.33 kHz step is not selectable, depending on the operating band or mode. {IC2730_ALL_RX_MODES, kHz(8.33)}, {IC2730_ALL_RX_MODES, kHz(10)}, {IC2730_ALL_RX_MODES, 12500}, {IC2730_ALL_RX_MODES, kHz(15)}, {IC2730_ALL_RX_MODES, kHz(20)}, {IC2730_ALL_RX_MODES, kHz(25)}, {IC2730_ALL_RX_MODES, kHz(30)}, {IC2730_ALL_RX_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = IC2730_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic2730_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic78.c0000664000175000017500000001260015056640443011264 /* * Hamlib CI-V backend - description of IC-78 * Copyright (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "icom.h" #include "bandplan.h" #include "idx_builtin.h" #define IC78_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC78_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC78_AM_TX_MODES (RIG_MODE_AM) #define IC78_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP) #define IC78_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_SQL) #define IC78_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC78_VFO_OPS (RIG_OP_NONE) #define IC78_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) #define IC78_ANTS (RIG_ANT_1) /* * IC78_STR_CAL is what the S-meter displays * * FIXME: real measures! */ #define IC78_STR_CAL { 2, \ { \ { 0, -60 }, \ { 255, 60 } \ } } /* * ic78 rigs capabilities. */ static const struct icom_priv_caps ic78_priv_caps = { 0x62, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list }; struct rig_caps ic78_caps = { RIG_MODEL(RIG_MODEL_IC78), .model_name = "IC-78", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC78_FUNC_ALL, .has_set_func = IC78_FUNC_ALL, .has_get_level = IC78_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC78_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC78_VFO_OPS, .scan_ops = IC78_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 100, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - 1, IC78_ALL_RX_MODES, -1, -1, IC78_VFO_ALL, IC78_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC78_OTHER_TX_MODES, W(2), W(100), IC78_VFO_ALL, IC78_ANTS), FRQ_RNG_HF(1, IC78_AM_TX_MODES, W(2), W(40), IC78_VFO_ALL, IC78_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - 1, IC78_ALL_RX_MODES, -1, -1, IC78_VFO_ALL, IC78_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC78_OTHER_TX_MODES, W(2), W(100), IC78_VFO_ALL, IC78_ANTS), FRQ_RNG_HF(2, IC78_AM_TX_MODES, W(2), W(40), IC78_VFO_ALL, IC78_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC78_ALL_RX_MODES, 10}, {IC78_ALL_RX_MODES, 100}, {IC78_ALL_RX_MODES, kHz(1)}, {IC78_ALL_RX_MODES, kHz(5)}, {IC78_ALL_RX_MODES, kHz(9)}, {IC78_ALL_RX_MODES, kHz(10)}, {IC78_ALL_RX_MODES, 12500}, {IC78_ALL_RX_MODES, kHz(20)}, {IC78_ALL_RX_MODES, kHz(25)}, {IC78_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .str_cal = IC78_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic78_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic271.c0000664000175000017500000001030715056640443011341 /* * Hamlib CI-V backend - description of IC-271 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC271_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC271_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC271_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * IC-271 A/E * IC-271 H is high power (75W) * * Independent transmit/receive * * specs: http://www.qsl.net/sm7vhs/radio/icom/Ic271/specs.htm * * Please report testing / patches. Some capabilities may be missing too. --sf */ static const struct icom_priv_caps ic271_priv_caps = { 0x20, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic271_caps = { RIG_MODEL(RIG_MODEL_IC271), .model_name = "IC-271", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC271_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 32, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), IC271_MODES, -1, -1, IC271_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC271_MODES, W(2.5), W(25), IC271_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(143.8), MHz(148.2), IC271_MODES, -1, -1, IC271_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC271_MODES, W(2.5), W(25), IC271_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC271_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic271_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/icr72.c0000664000175000017500000001134015056640443011440 /* * Hamlib CI-V backend - description of IC-R72 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define ICR72_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define ICR72_FUNC_ALL (RIG_FUNC_NONE) #define ICR72_LEVEL_ALL (RIG_LEVEL_NONE) #define ICR72_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL) #define ICR72_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ICR71_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR72_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) static struct icom_priv_caps icr72_priv_caps = { 0x32, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps icr72_caps = { RIG_MODEL(RIG_MODEL_ICR72), .model_name = "IC-R72", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR72_FUNC_ALL, .has_set_func = ICR72_FUNC_ALL, .has_get_level = ICR72_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR72_LEVEL_ALL), .has_get_parm = RIG_PARM_ANN, .has_set_parm = RIG_PARM_ANN, .level_gran = {}, /* granularity */ .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR72_VFO_OPS, .scan_ops = ICR72_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), ICR72_MODES, -1, -1, ICR72_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), ICR72_MODES, -1, -1, ICR72_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR72_MODES, Hz(10)}, {ICR72_MODES, kHz(1)}, {ICR72_MODES, kHz(2)}, {ICR72_MODES, kHz(3)}, {ICR72_MODES, kHz(4)}, {ICR72_MODES, kHz(5)}, {ICR72_MODES, kHz(6)}, {ICR72_MODES, kHz(7)}, {ICR72_MODES, kHz(8)}, {ICR72_MODES, kHz(9)}, {ICR72_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr72_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .get_level = icom_get_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic7000.c0000664000175000017500000003270515056640443011424 /* * Hamlib CI-V backend - description of IC-7000 and variations * Adapted from IC-7800 code 2006 by Kent Hill * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "tones.h" #define IC7000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_WFM) #define IC7000_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7000_NOT_TS_MODES (IC7000_ALL_RX_MODES &~IC7000_1HZ_TS_MODES) #define IC7000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC7000_AM_TX_MODES (RIG_MODE_AM) #define IC7000_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) #define IC7000_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7000_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7000_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7000_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7000_ANTS (RIG_ANT_1|RIG_ANT_2) /* ant-1 is Hf-6m, ant-2 is 2m-70cm */ /* * Measurement by Mark, WA0TOP * * s/n 0503103. * Preamp off, ATT off, mode AM, f=10 MHz */ #define IC7000_STR_CAL { 14, \ { \ { 0, -54 }, /* first one is made up */ \ { 5, -29 }, \ { 15, -27 }, \ { 43, -22 }, \ { 68, -17 }, \ { 92, -12 }, \ { 120, -6 }, \ { 141, 2 }, \ { 162, 13 }, \ { 182, 25 }, \ { 202, 38 }, \ { 222, 47 }, \ { 241, 57 }, \ { 255, 63 } \ } } #define IC7000_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7000_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7000_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7000_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } /* * * IC7000 channel caps. */ #define IC7000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = IC7000_FUNCS, \ .levels = RIG_LEVEL_SET(IC7000_LEVELS), \ } struct cmdparams ic7000_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x17}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x41}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_NONE} } }; /* * This function does the special bandwidth coding for IC-7000 */ static int ic7000_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } // CAT section of manual says: nn = 0 -40 > bw = 50Hz > 3600Hz // Tested by Ian G3VPX 20201029 // 0 - 9 > bw 50Hz to 500Hz in 50Hz steps // 10 - 40 > bw 600Hz to 3600Hz in 100Hz steps if (width != RIG_PASSBAND_NOCHANGE) { if (width <= 500) { *pd = width / 50 - 1; } else if (width <= 3600) { *pd = width / 100 + 4; } else { *pd = 40; } } return RIG_OK; } /* * IC-7000 rig capabilities. */ static const struct icom_priv_caps IC7000_priv_caps = { 0x70, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7000_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7000_extcmds, .r2i_mode = ic7000_r2i_mode }; struct rig_caps ic7000_caps = { RIG_MODEL(RIG_MODEL_IC7000), .model_name = "IC-7000", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7000_FUNCS, .has_set_func = IC7000_FUNCS, .has_get_level = IC7000_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7000_LEVELS), .has_get_parm = IC7000_PARMS, .has_set_parm = RIG_PARM_SET(IC7000_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_APO] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess */ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7000_VFO_OPS, .scan_ops = IC7000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC7000_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, IC7000_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, IC7000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, {MHz(400), MHz(470), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, IC7000_OTHER_TX_MODES, W(2), W(50), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, IC7000_OTHER_TX_MODES, W(2), W(35), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, IC7000_AM_TX_MODES, W(2), W(20), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, IC7000_OTHER_TX_MODES, W(2), W(14), IC7000_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, {MHz(400), MHz(470), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, IC7000_OTHER_TX_MODES, W(2), W(50), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, IC7000_OTHER_TX_MODES, W(2), W(35), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, IC7000_AM_TX_MODES, W(2), W(20), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, IC7000_OTHER_TX_MODES, W(2), W(14), IC7000_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {IC7000_1HZ_TS_MODES, 1}, {IC7000_NOT_TS_MODES, 10}, {IC7000_ALL_RX_MODES, Hz(100)}, {IC7000_ALL_RX_MODES, kHz(1)}, {IC7000_ALL_RX_MODES, kHz(5)}, {IC7000_ALL_RX_MODES, kHz(9)}, {IC7000_ALL_RX_MODES, kHz(10)}, {IC7000_ALL_RX_MODES, kHz(12.5)}, {IC7000_ALL_RX_MODES, kHz(20)}, {IC7000_ALL_RX_MODES, kHz(25)}, {IC7000_ALL_RX_MODES, kHz(100)}, {IC7000_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = IC7000_STR_CAL, .swr_cal = IC7000_SWR_CAL, .alc_cal = IC7000_ALC_CAL, .rfpower_meter_cal = IC7000_RFPOWER_METER_CAL, .comp_meter_cal = IC7000_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/id31.c0000664000175000017500000001365615056640443011266 /* * Hamlib CI-V backend - description of ID-31 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 11 of ID-31A_E_CD_ENG_1.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP" for rig control. * */ #define ID31_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID31_ALL_RX_MODES (RIG_MODE_AM|ID31_MODES) #define ID31_VFO_ALL (RIG_VFO_MAIN) #define ID31_SCAN_OPS RIG_SCAN_NONE #define ID31_VFO_OPS RIG_OP_NONE #define ID31_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID31_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID31_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define ID31_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id31_priv_caps = { 0xA0, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id31_caps = { RIG_MODEL(RIG_MODEL_ID31), .model_name = "ID-31", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID31_FUNC_ALL, .has_set_func = ID31_FUNC_ALL, .has_get_level = ID31_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID31_LEVEL_ALL), .has_get_parm = ID31_PARM_ALL, .has_set_parm = ID31_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID31_VFO_OPS, .scan_ops = ID31_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(440), MHz(450), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID31_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id31_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // not capable .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic707.c0000664000175000017500000001174615056640443011355 /* * Hamlib CI-V backend - description of IC-707 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC707_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-707 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic707/specs.htm * */ #define IC707_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC707_AM_TX_MODES (RIG_MODE_AM) #define IC707_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC707_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC707_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_STOP) #define IC707_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic707_priv_caps = { 0x3e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic707_caps = { RIG_MODEL(RIG_MODEL_IC707), .model_name = "IC-707", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC707_VFO_OPS, .scan_ops = IC707_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 25, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 26, 30, RIG_MTYPE_SPLIT, IC_MIN_MEM_CAP }, /* split ? */ { 31, 32, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC707_ALL_RX_MODES, -1, -1, IC707_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC707_OTHER_TX_MODES, W(5), W(100), IC707_VFO_ALL, IC707_ANTS), FRQ_RNG_HF(1, IC707_AM_TX_MODES, W(5), W(25), IC707_VFO_ALL, IC707_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC707_ALL_RX_MODES, -1, -1, IC707_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC707_OTHER_TX_MODES, W(5), W(100), IC707_VFO_ALL, IC707_ANTS), FRQ_RNG_HF(2, IC707_AM_TX_MODES, W(5), W(25), IC707_VFO_ALL, IC707_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC707_ALL_RX_MODES, 10}, {IC707_ALL_RX_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic707_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_ts = icom_set_ts, // .get_ts = icom_get_ts, // apparently does not have this .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/perseus.c0000664000175000017500000001270115056640443012202 /* * Hamlib CI-V backend - Perseus description * Copyright (c) 2016 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "frame.h" /* TODO: $09 DRM, $0a USER */ #define PERSEUS_MODES (RIG_MODE_AM|RIG_MODE_SAM|RIG_MODE_SSB| \ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR| \ RIG_MODE_FM) #define PERSEUS_FUNCS (RIG_FUNC_NONE) /* TODO (not standard) : * RIG_LEVEL_AGC|RIG_LEVEL_NB|RIG_LEVEL_ANR|RIG_LEVEL_ANR|RIG_LEVEL_AF|RIG_LEVEL_ANF */ #define PERSEUS_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define PERSEUS_PARMS (RIG_PARM_NONE) /* S-Meter calibration, according to the Reference Manual */ #define PERSEUS_STR_CAL { 2, \ { \ { 0, -67 }, /* -140 dBm */ \ { 255, 103 }, /* +30 dBm */ \ } } static int perseus_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); static void perseus_i2r_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); static struct icom_priv_caps perseus_priv_caps = { 0xE1, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ .r2i_mode = perseus_r2i_mode, .i2r_mode = perseus_i2r_mode, }; /* * PERSEUS rigs capabilities. * * PERSEUS Receiver CAT Interface Reference Manual (Revision EN03) : * http://microtelecom.it/perseus/PERSEUS_CI-V_Interface-EN03.pdf */ struct rig_caps perseus_caps = { RIG_MODEL(RIG_MODEL_PERSEUS), .model_name = "Perseus", .mfg_name = "Microtelecom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = PERSEUS_FUNCS, .has_set_func = PERSEUS_FUNCS, .has_get_level = PERSEUS_LEVELS, .has_set_level = RIG_LEVEL_SET(PERSEUS_LEVELS), .has_get_parm = PERSEUS_PARMS, .has_set_parm = PERSEUS_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(30), PERSEUS_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), PERSEUS_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {PERSEUS_MODES, 100}, /* resolution */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = PERSEUS_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& perseus_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_level = icom_set_level, .get_level = icom_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * This function does the special bandwidth coding for the Perseus * * NB: the filter width will be ignored. */ static int perseus_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err == 0 && mode == RIG_MODE_SAM) { *md = 0x06; } return err; } static void perseus_i2r_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width) { icom2rig_mode(rig, md, pd, mode, width); if (md == 0x06) { *mode = RIG_MODE_SAM; } } hamlib-4.6.5/rigs/icom/ic7700.c0000664000175000017500000003734215056640443011435 /* * Hamlib CI-V backend - description of IC-7700 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Stre #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7700_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PSK|RIG_MODE_PSKR) #define IC7700_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7700_ALL_RX_MODES IC7700_OTHER_TX_MODES | IC7700_AM_TX_MODES #define IC7700_1HZ_TS_MODES IC7700_ALL_RX_MODES #define IC7700_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) #define IC7700_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7700_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7700_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7700_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7700_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7700 S-meter calibration data based on manual #define IC7700_STR_CAL { 3, \ { \ { 0,-54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7700_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7700_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7700_RFPOWER_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 143, 100.0f }, \ { 212, 200.0f }, \ { 255, 250.0f }, \ } } #define IC7700_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7700_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7700_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } struct cmdparams ic7700_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x82}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7700_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7700 rig capabilities. */ static const struct icom_priv_caps ic7700_priv_caps = { 0x74, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 3, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7700_extcmds, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x58; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x61; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x61; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } static int ic7700_rig_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: enter\n", __func__); struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; priv->x26cmdfails = priv->x25cmdfails = 1; return icom_rig_open(rig); } struct rig_caps ic7700_caps = { RIG_MODEL(RIG_MODEL_IC7700), .model_name = "IC-7700", .mfg_name = "Icom", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7700_FUNCS, .has_set_func = IC7700_FUNCS, .has_get_level = IC7700_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7700_LEVELS), .has_get_parm = IC7700_PARMS, .has_set_parm = RIG_PARM_SET(IC7700_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7700_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, // 7700 can have a different mode on VFOB but requires VFO swap .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7700_VFO_OPS, .scan_ops = IC7700_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7700_ALL_RX_MODES, -1, -1, IC7700_VFOS, IC7700_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_6m(1, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_HF(1, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7700_ALL_RX_MODES, -1, -1, IC7700_VFOS, IC7700_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_6m(2, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_HF(2, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7700_1HZ_TS_MODES, 1}, {IC7700_ALL_RX_MODES, Hz(100)}, {IC7700_ALL_RX_MODES, kHz(1)}, {IC7700_ALL_RX_MODES, kHz(5)}, {IC7700_ALL_RX_MODES, kHz(9)}, {IC7700_ALL_RX_MODES, kHz(10)}, {IC7700_ALL_RX_MODES, kHz(12.5)}, {IC7700_ALL_RX_MODES, kHz(20)}, {IC7700_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7700_STR_CAL, .swr_cal = IC7700_SWR_CAL, .alc_cal = IC7700_ALC_CAL, .rfpower_meter_cal = IC7700_RFPOWER_METER_CAL, .comp_meter_cal = IC7700_COMP_METER_CAL, .vd_meter_cal = IC7700_VD_METER_CAL, .id_meter_cal = IC7700_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7700_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = ic7700_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7700_set_clock, .get_clock = ic7700_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic756.c0000664000175000017500000011105715056640443011355 /* * Hamlib CI-V backend - description of IC-756 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "bandplan.h" #include "tones.h" #define IC756_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756_1HZ_TS_MODES IC756_ALL_RX_MODES #define IC756_FUNC_SET (RIG_FUNC_DUAL_WATCH) /* * 100W in all modes but AM (40W) */ #define IC756_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756_AM_TX_MODES (RIG_MODE_AM) #define IC756PRO_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_RF|RIG_FUNC_ANF) #define IC756PRO_FUNC_SET (IC756PRO_FUNC_ALL|RIG_FUNC_DUAL_WATCH) #define IC756PRO_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_COMP) /* Note that RIG_LEVEL_VOXGAIN and RIG_LEVEL_ANTIVOX are incorrectly handled in icom.c for * this model. */ #define IC756_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC756_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC756_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC756_ANTS (RIG_ANT_1|RIG_ANT_2) struct cmdparams ic756pro_cmdparms[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x20}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x09}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x16}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x60}, CMD_DAT_INT, 1 }, { {0} } }; #define IC756PRO_STR_CAL { 16, \ { \ { 0, -60 }, \ { 14, -52 }, \ { 29, -44 }, \ { 44, -36 }, \ { 60, -28 }, \ { 75, -20 }, \ { 91, -12 }, \ { 107, -4 }, \ { 124, 4 }, \ { 141, 12 }, \ { 158, 20 }, \ { 175, 28 }, \ { 192, 36 }, \ { 210, 44 }, \ { 228, 52 }, \ { 247 ,60 } \ } } /* * This function deals with the older type radios with only 2 filter widths * (0 - normal, 1 - narrow) */ static int r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } if (PD_WIDE_3 == *pd) { *pd = PD_MEDIUM_2; } else if (*pd > PD_WIDE_3) { (*pd)--; } return RIG_OK; } /* * IC-756 rig capabilities. */ static const struct icom_priv_caps ic756_priv_caps = { 0x50, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756_ts_sc_list, .antack_len = 3, .ant_count = 2, .r2i_mode = r2i_mode, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, }; struct rig_caps ic756_caps = { RIG_MODEL(RIG_MODEL_IC756), .model_name = "IC-756", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = IC756_FUNC_SET, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756_1HZ_TS_MODES, 1}, {IC756_ALL_RX_MODES, kHz(1)}, {IC756_ALL_RX_MODES, kHz(5)}, {IC756_ALL_RX_MODES, kHz(9)}, {IC756_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-756pro rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro_priv_caps = { 0x5c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -2 }, }, }; struct rig_caps ic756pro_caps = { RIG_MODEL(RIG_MODEL_IC756PRO), .model_name = "IC-756PRO", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, .has_set_func = IC756PRO_FUNC_SET, .has_get_level = IC756PRO_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756_1HZ_TS_MODES, 1}, {IC756_ALL_RX_MODES, kHz(1)}, {IC756_ALL_RX_MODES, kHz(5)}, {IC756_ALL_RX_MODES, kHz(9)}, {IC756_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-756proII rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro2_priv_caps = { 0x64, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic756pro_cmdparms, /* Custom op parameters */ .data_mode_supported = 1 }; /* * These TOKEN_BACKEND's are on a different name space than conf's */ #define TOK_MEMNAME TOKEN_BACKEND(1) #define TOK_MYCALL TOKEN_BACKEND(2) static const struct confparams ic756pro2_ext_parms[] = { { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", NULL, RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_MEMNAME, "showmem", "Show mem name", "Show memory name", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_SQLCTRL, "sqlctrl", "RF/Sql control", "set RF/Squelch control", NULL, RIG_CONF_COMBO, { .c = {{ "Auto", "Sql", "RF+Sql", NULL }} } }, { TOK_MYCALL, "mycall", "Callsign", "My call sign", NULL, RIG_CONF_STRING, { } }, { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", "350", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } }, { RIG_CONF_END, NULL, } }; /* * NUMERIC: val.f * COMBO: val.i, starting from 0 * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ /*IC-756Pro Rig parameters Only available in this namespace*/ #define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ #define S_MEM_SBASS 0x501 /* SSB TX tone bass level */ #define S_MEM_NAME 0x514 /* send/read memory name */ #define S_MEM_MYCALL 0x515 #define S_MEM_BEEP 0x520 /* Button confirmation */ #define S_MEM_SQL_CTL 0x522 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ #define S_MEM_QSPLT 0x524 /* enable quick split mode */ #define S_MEM_TRCV 0x532 /* CI-V transceive mode */ #define S_MEM_LANG 0x536 /* 0=English 1=Japanese for voice announcer */ #define S_MEM_SCN_SPD 0x556 /* 0 = low; 1 = high */ #define S_MEM_RTTY_FL_PB 0x561 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ #define S_MEM_RTTY_TWNPK 0x562 /* rtty twin peak filter off/on */ static int ic756pro2_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int ic756pro2_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); #define IC756PROII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_1HZ_TS_MODES IC756PROII_ALL_RX_MODES #define IC756PROII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_AM_TX_MODES (RIG_MODE_AM) #define IC756PROII_LEVEL_ALL (IC756PRO_LEVEL_ALL|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AGC_TIME) #define IC756PROII_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT|RIG_PARM_TIME) struct rig_caps ic756pro2_caps = { RIG_MODEL(RIG_MODEL_IC756PROII), .model_name = "IC-756PROII", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, .has_set_func = IC756PRO_FUNC_SET, .has_get_level = IC756PROII_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PROII_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .extparms = ic756pro2_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756PROII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756PROII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756PROII_1HZ_TS_MODES, 1}, {IC756PROII_ALL_RX_MODES, kHz(1)}, {IC756PROII_ALL_RX_MODES, kHz(5)}, {IC756PROII_ALL_RX_MODES, kHz(9)}, {IC756PROII_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro2_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ic756pro2_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; ep_len = 0; /* 0 implies BCD data */ val_len = 1; switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; icom_val = val.i ? 1 : 0; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_len = strlen(val.cs); if (ep_len > 10) { return -RIG_EINVAL; } ep_sc = S_MEM_MYCALL; memcpy(epbuf, val.cs, ep_len); break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ if (val.i < 0 || val.i > 4) { return -RIG_EINVAL; } ep_sc = S_MEM_RTTY_FL_PB; icom_val = val.i; break; default: return -RIG_EINVAL; } if (ep_len == 0) { to_bcd_be(epbuf, (long long)icom_val, val_len * 2); ep_len += val_len; } retval = icom_transaction(rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ static int ic756pro2_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { const struct confparams *cfp; unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val = 0; int cmdhead; int retval; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_sc = S_MEM_MYCALL; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ ep_sc = S_MEM_RTTY_FL_PB; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_ext_parm %s", rig_strparm(token)); return -RIG_EINVAL; } retval = icom_transaction(rig, ep_cmd, ep_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (ep_sc == -1) ? 1 : S_MEM_SC_LEN + 1; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != ep_cmd) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } cfp = rig_ext_lookup_tok(rig, token); switch (cfp->type) { case RIG_CONF_STRING: memcpy(val->s, resbuf, res_len); break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: val->i = from_bcd_be(resbuf + cmdhead, res_len * 2); break; case RIG_CONF_NUMERIC: val->f = from_bcd_be(resbuf + cmdhead, res_len * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * IC-756proIII rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro3_priv_caps = { 0x6e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic756pro_cmdparms, /* Custom op parameters */ .data_mode_supported = 1 }; #define IC756PROIII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_1HZ_TS_MODES IC756PROIII_ALL_RX_MODES #define IC756PROIII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_AM_TX_MODES (RIG_MODE_AM) #define IC756PROIII_LEVEL_ALL (IC756PROII_LEVEL_ALL|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_NB) /* * TODO: check whether all func and levels are stored in memory * * No memory split support. * .rptr_offs = 1, to be done for FM special mode * * Channel description should be possible through: 0x1a 0x00 * c.f. http://www.plicht.de/ekki/civ/civ-p4305-756pro.html */ #define IC756PROIII_MEM_CAP { \ .ant = 1, \ .tuning_step = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = IC756PRO_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), \ } #define IC756PROIII_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC756PROIII_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC756PROIII_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC756PROIII_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } struct rig_caps ic756pro3_caps = { RIG_MODEL(RIG_MODEL_IC756PROIII), .model_name = "IC-756PROIII", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL | RIG_FUNC_TUNER, .has_set_func = IC756PRO_FUNC_SET | RIG_FUNC_TUNER, .has_get_level = IC756PROIII_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PROIII_LEVEL_ALL), .has_get_parm = IC756PROII_PARMS, .has_set_parm = RIG_PARM_SET(IC756PROII_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .extparms = ic756pro2_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC values */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS | RIG_OP_TUNE, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 10, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC756PROIII_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC756PROIII_MEM_CAP }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756PROIII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL, IC756_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756PROIII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL, IC756_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756PROIII_1HZ_TS_MODES, 1}, {IC756PROIII_1HZ_TS_MODES, 100}, {IC756PROIII_ALL_RX_MODES, kHz(1)}, {IC756PROIII_ALL_RX_MODES, kHz(5)}, {IC756PROIII_ALL_RX_MODES, kHz(9)}, {IC756PROIII_ALL_RX_MODES, kHz(10)}, {IC756PROIII_ALL_RX_MODES, kHz(12.5)}, {IC756PROIII_ALL_RX_MODES, kHz(20)}, {IC756PROIII_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(3.6)}, /* wide */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(50)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, /* almost any filter */ RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .swr_cal = IC756PROIII_SWR_CAL, .alc_cal = IC756PROIII_ALC_CAL, .rfpower_meter_cal = IC756PROIII_RFPOWER_METER_CAL, .comp_meter_cal = IC756PROIII_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro3_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic738.c0000664000175000017500000001307015056640443011351 /* * Hamlib CI-V backend - description of IC-738 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-738, like the IC-736 but without 6m */ #define IC738_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC738_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC738_AM_TX_MODES (RIG_MODE_AM) #define IC738_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC738_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC738_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC738_ANTS 0 /* TODO: declare both antenna connectors? */ #define IC738_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic738_priv_caps = { 0x44, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic738_caps = { RIG_MODEL(RIG_MODEL_IC738), .model_name = "IC-738", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC738_VFO_OPS, .scan_ops = IC738_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 89, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 90, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* FIXME: split */ { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, {MHz(50), MHz(54), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC738_OTHER_TX_MODES, W(5), W(100), IC738_VFO_ALL, IC738_ANTS), FRQ_RNG_HF(1, IC738_AM_TX_MODES, W(4), W(40), IC738_VFO_ALL, IC738_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, {MHz(50), MHz(54), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC738_OTHER_TX_MODES, W(5), W(100), IC738_VFO_ALL, IC738_ANTS), FRQ_RNG_HF(2, IC738_AM_TX_MODES, W(4), W(40), IC738_VFO_ALL, IC738_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { /* TBC */ {IC738_ALL_RX_MODES, 10}, {IC738_ALL_RX_MODES, kHz(1)}, {IC738_ALL_RX_MODES, kHz(2)}, {IC738_ALL_RX_MODES, kHz(3)}, {IC738_ALL_RX_MODES, kHz(4)}, {IC738_ALL_RX_MODES, kHz(5)}, {IC738_ALL_RX_MODES, kHz(6)}, {IC738_ALL_RX_MODES, kHz(7)}, {IC738_ALL_RX_MODES, kHz(8)}, {IC738_ALL_RX_MODES, kHz(9)}, {IC738_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic738_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic728.c0000664000175000017500000002020715056640443011350 /* * Hamlib CI-V backend - description of IC-728 * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC728_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-728 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic728/specs.htm * */ #define IC728_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC728_AM_TX_MODES (RIG_MODE_AM) #define IC728_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC728_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC728_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC728_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic728_priv_caps = { 0x38, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic728_caps = { RIG_MODEL(RIG_MODEL_IC728), .model_name = "IC-728", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC728_VFO_OPS, .scan_ops = IC728_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(1, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(2, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC728_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic728_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic729_priv_caps = { 0x3a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic729_caps = { RIG_MODEL(RIG_MODEL_IC729), .model_name = "IC-729", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC728_VFO_OPS, .scan_ops = IC728_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(1, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(2, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC728_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic729_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/id4100.c0000664000175000017500000001470615056640443011424 /* * Hamlib CI-V backend - description of ID-4100 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 10 of ID-4100A_E_ENG_PU_0.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP2" for rig control. * * TODO: * - DV mode * - GPS support * - Single/dual watch (RIG_LEVEL_BALANCE) */ #define ID4100_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID4100_ALL_RX_MODES (RIG_MODE_AM|ID4100_MODES) #define ID4100_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ID4100_SCAN_OPS RIG_SCAN_NONE #define ID4100_VFO_OPS RIG_OP_NONE #define ID4100_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID4100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID4100_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define ID4100_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id4100_priv_caps = { 0x9A, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id4100_caps = { RIG_MODEL(RIG_MODEL_ID4100), .model_name = "ID-4100", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID4100_FUNC_ALL, .has_set_func = ID4100_FUNC_ALL, .has_get_level = ID4100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID4100_LEVEL_ALL), .has_get_parm = ID4100_PARM_ALL, .has_set_parm = ID4100_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID4100_VFO_OPS, .scan_ops = ID4100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, {MHz(375), MHz(550), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID4100_MODES, W(5), W(25), ID4100_VFO_ALL}, {MHz(430), MHz(440), ID4100_MODES, W(5), W(25), ID4100_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, {MHz(375), MHz(550), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID4100_MODES, W(5), W(50), ID4100_VFO_ALL}, {MHz(430), MHz(450), ID4100_MODES, W(5), W(50), ID4100_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID4100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id4100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, //.set_powerstat = icom_set_powerstat, // ID-4100 does cannot query power .get_powerstat = icom_get_powerstat, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic9100.c0000664000175000017500000002613615056640443011430 /* * Hamlib CI-V backend - description of IC-9100 (HF/VHF/UHF All-Mode Transceiver) * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "icom.h" #include "icom_defs.h" #include "idx_builtin.h" #include "bandplan.h" #include "tones.h" #define IC9100_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define IC9100_OTHER_TX_MODES ((IC9100_MODES) & ~RIG_MODE_AM) #define IC9100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define IC9100_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC9100_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG| \ RIG_OP_TUNE) #define IC9100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_SATMODE| \ RIG_FUNC_DUAL_WATCH| \ RIG_FUNC_VSC| \ RIG_FUNC_MN| \ RIG_FUNC_LOCK| \ RIG_FUNC_SCOPE) #define IC9100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_APF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_MONITOR_GAIN| \ RIG_LEVEL_AGC_TIME) #define IC9100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC9100_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ #define IC9100_HF_ANTS (RIG_ANT_1|RIG_ANT_2) struct cmdparams ic9100_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x27}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x02}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; static const struct icom_priv_caps ic9100_priv_caps = { 0x7c, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ ic910_ts_sc_list, /* FIXME */ .antack_len = 2, .ant_count = 2, .extcmds = ic9100_extcmds, .x25x26_always = 0, .x25x26_possibly = 0, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // borrow this as they behave the same extern int ic9700_set_vfo(RIG *rig, vfo_t vfo); struct rig_caps ic9100_caps = { RIG_MODEL(RIG_MODEL_IC9100), .model_name = "IC-9100", .mfg_name = "Icom", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC9100_FUNC_ALL, .has_set_func = IC9100_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC9100_LEVEL_ALL | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR, .has_set_level = IC9100_LEVEL_ALL, .has_get_parm = IC9100_PARM_ALL, .has_set_parm = IC9100_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = {20, RIG_DBLST_END, }, .attenuator = {20, RIG_DBLST_END, }, .max_rit = kHz(9.999), .max_xit = kHz(9.999), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC9100_VFO_OPS, .scan_ops = IC9100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 9, /* TODO */ .chan_list = { /* TBC */ { 1, 396, RIG_MTYPE_MEM }, { 397, 400, RIG_MTYPE_CALL }, { 401, 424, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { /* Europe */ {kHz(30), MHz(60), IC9100_MODES, -1, -1, IC9100_VFO_ALL, IC9100_HF_ANTS}, {kHz(136), MHz(174), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), IC9100_VFO_ALL, IC9100_HF_ANTS), /* only HF */ FRQ_RNG_6m(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_2m(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(1, IC9100_OTHER_TX_MODES, W(2), W(75), IC9100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION1(IC9100_OTHER_TX_MODES, W(1), W(10), IC9100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(30), MHz(60), IC9100_MODES, -1, -1, IC9100_VFO_ALL, IC9100_HF_ANTS}, {kHz(136), MHz(174), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), IC9100_VFO_ALL, IC9100_HF_ANTS), /* only HF */ /* USA only, TBC: end of range and modes */ {MHz(5.255), MHz(5.405), IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS}, /* USA only */ {MHz(5.255), MHz(5.405), RIG_MODE_AM, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS}, /* USA only */ FRQ_RNG_6m(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_2m(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(2, IC9100_OTHER_TX_MODES, W(2), W(75), IC9100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION2(IC9100_OTHER_TX_MODES, W(1), W(10), IC9100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {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(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, /* builtin */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_FM, kHz(15)}, /* builtin */ {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* builtin */ RIG_FLT_END, }, .str_cal = IC9100_STR_CAL, .priv = (void *)& ic9100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, .get_mode = icom_get_mode, .set_mode = icom_set_mode, .set_vfo = ic9700_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icom_get_func, .set_func = icom_set_func, .get_level = icom_get_level, .set_level = icom_set_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/ic910.c0000664000175000017500000002605515056640443011350 /* * Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" #include "tones.h" /* * It seems some IC910 out there have weird firmware. Uncomment the following * if your modes are wrong, and please report to hamlib-developer maillist * with firmware number. That'd be interesting to have a word from Icom * on this subject, and if firmware updates are possible. */ #ifdef HAVE_WEIRD_IC910_MODES static int ic910_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { /* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */ if (mode == RIG_MODE_FM) { mode = RIG_MODE_RTTY; } return icom_set_mode(rig, vfo, mode, width); } static int ic910_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { /* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */ int retval = icom_get_mode(rig, vfo, mode, width); if (*mode == RIG_MODE_RTTY) { *mode = RIG_MODE_FM; } return retval; } #endif /* HAVE_WEIRD_IC910_MODES */ /* * This function does the special bandwidth coding for IC-910 * (1 - normal, 2 - narrow) */ static int ic910_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } #define IC910_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC910_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC910_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define IC910_SCAN_OPS (RIG_SCAN_MEM) #define IC910_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG) #define IC910_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_SATMODE| \ RIG_FUNC_SCOPE) #define IC910_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP) #define IC910_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ static const struct icom_priv_caps ic910_priv_caps = { 0x60, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ ic910_ts_sc_list, .r2i_mode = ic910_r2i_mode }; int ic910_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_SCOPE: return icom_set_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, 1, status ? 1 : 0); case RIG_FUNC_SATMODE: return icom_set_raw(rig, C_CTL_MEM, S_MEM_SATMODE910, 0, NULL, 1, status ? 1 : 0); default: return icom_set_func(rig, vfo, func, status); } } int ic910_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { case RIG_FUNC_SCOPE: return icom_get_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, status); case RIG_FUNC_SATMODE: return icom_get_raw(rig, C_CTL_MEM, S_MEM_SATMODE910, 0, NULL, status); default: return icom_get_func(rig, vfo, func, status); } } int ic910_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int ic910_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, val); default: return icom_get_level(rig, vfo, level, val); } } extern int ic9700_set_vfo(RIG *rig, vfo_t vfo); struct rig_caps ic910_caps = { RIG_MODEL(RIG_MODEL_IC910), .model_name = "IC-910", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC910_FUNC_ALL, .has_set_func = IC910_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC910_LEVEL_ALL | (RIG_LEVEL_RAWSTR), .has_set_level = IC910_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ // .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = IC910_VFO_OPS, .scan_ops = IC910_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 105, RIG_MTYPE_EDGE }, { 106, 106, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { /* USA */ {MHz(144), MHz(148), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(430), MHz(450), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(148), IC910_MODES, W(5), W(100), IC910_VFO_ALL}, {MHz(430), MHz(450), IC910_MODES, W(5), W(75), IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { /* Europe */ {MHz(144), MHz(146), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(430), MHz(440), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(146), IC910_MODES, W(5), W(100), IC910_VFO_ALL}, {MHz(430), MHz(440), IC910_MODES, W(5), W(75), IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {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(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */ {RIG_MODE_CW, Hz(600)}, /* with optional FL-132/Fl133 CW filters */ {RIG_MODE_FM, kHz(15)}, /* builtin */ {RIG_MODE_FM, kHz(6)}, /* builtin */ RIG_FLT_END, }, .str_cal = IC910_STR_CAL, .priv = &ic910_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, #ifdef HAVE_WEIRD_IC910_MODES .get_mode = ic910_get_mode, .set_mode = ic910_set_mode, #else .get_mode = icom_get_mode, .set_mode = icom_set_mode, #endif .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_vfo = ic9700_set_vfo, // .get_vfo = icom_get_vfo, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = ic910_get_func, .set_func = ic910_set_func, .get_level = ic910_get_level, .set_level = ic910_set_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/icom/Makefile.am0000664000175000017500000000146715056640443012413 ICOMSRC = icom.c icom.h icom_defs.h frame.c frame.h ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr30.c icr6.c icr71.c icr72.c icr75.c icrx7.c icr8600.c \ id1.c id31.c id51.c id4100.c id5100.c perseus.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic785x.c \ ic7000.c ic7100.c ic7200.c ic7300.c ic7600.c ic7610.c ic7700.c ic7760.c icf8101.c \ ic7300.h optoscan.c optoscan.h xiegu.c level_gran_icom.h noinst_LTLIBRARIES = libhamlib-icom.la libhamlib_icom_la_SOURCES = $(ICOMSRC) EXTRA_DIST = README.icom TODO.icom Android.mk hamlib-4.6.5/rigs/icom/ic746.c0000664000175000017500000011765715056640443011370 /* * Hamlib CI-V backend - description of IC-746 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "misc.h" #include "tones.h" /* * IC-746 and IC-746pro * * TODO: * - advanced scanning functions * - set_ctcss_tone/ctcss_sql * - set keyer? * - test all that stuff.. */ #define IC746_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC746_1HZ_TS_MODES IC746_ALL_RX_MODES /* * 100W in all modes but AM (40W) * deleted rig_mode_tx_modes */ #define IC746_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC746_AM_TX_MODES (RIG_MODE_AM) #define IC746_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_RF|RIG_FUNC_ANF|RIG_FUNC_APF|RIG_FUNC_RESUME|RIG_FUNC_ARO) #define IC746_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_APF|RIG_LEVEL_AGC_TIME|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define IC746_GET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define IC746_SET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_ANN) #define IC746_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC746_ANTS (RIG_ANT_1|RIG_ANT_2) #define IC746_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC746_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PROG|RIG_SCAN_DELTA) #define IC746_STR_CAL { 16, \ { \ { 0, -60 }, \ { 10, -55 }, \ { 27, -49 }, \ { 45, -42 }, \ { 60, -35 }, \ { 76, -28 }, \ { 89, -21 }, \ { 100, -14 }, \ { 110, -7 }, \ { 120, 0 }, \ { 125, 10 }, \ { 129, 20 }, \ { 133, 30 }, \ { 138, 40 }, \ { 142, 50 }, \ { 146, 60 } \ } } #define IC746PRO_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ .rptr_shift = 1,\ .ctcss_tone = 1,\ .ctcss_sql = 1, \ .dcs_code = 1, \ .flags = 1, \ .channel_desc = 1, \ } /* Memory channel buffer structure for IC-746 pro and ? Note requires an ack_buff of 64 bytes and data length is 46. */ typedef struct { unsigned char freq[5]; /* little endian frequency */ unsigned char mode; signed char pb; /* passband or filter selection*/ unsigned char data; /* data port 0=off 1=on */ unsigned char dup; /* duplex, tone, tonesql and DTCS Values in hex are "or"ed together 00 = Simplex 10 = -DUP 20 = +DUP 01 = ctcss tone on 02 = tone_sql on 03 = DTCS on */ unsigned char tone[3]; /* ctcss tone bigendian first byte fixed 00 */ unsigned char tone_sql[3]; /* tone squelch frequency as tone */ struct { unsigned char code[2]; /* DTCS code bigendian */ } dcs; } channel_str_t; typedef struct { char chan_flag; /* split 0x10 = on; scan select 0x01 = on */ channel_str_t rx; channel_str_t tx; char name[9]; /*name 9 ascii no null terminator */ } mem_buf_t; #define MAX_MEM_BUF_LEN sizeof(mem_buf_t) /* IC-746 Pro has a 3 "band-stacking registers" defined for each hamband and general coverage. These are updated and rotated when band is changed from front panel. The most recent is rolled down and the oldest discarded. The structure of the register is roughly half a memory buffer. */ typedef channel_str_t band_stack_reg_t; static int ic746_set_parm(RIG *rig, setting_t parm, value_t val); static int ic746_get_parm(RIG *rig, setting_t parm, value_t *val); static int ic746pro_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ic746pro_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ic746pro_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int ic746pro_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); /* * IC-746 rig capabilities. */ static const struct icom_priv_caps ic746_priv_caps = { 0x56, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, }; struct rig_caps ic746_caps = { RIG_MODEL(RIG_MODEL_IC746), .model_name = "IC-746", .mfg_name = "Icom", .version = BACKEND_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC746_FUNC_ALL, .has_set_func = IC746_FUNC_ALL, .has_get_level = IC746_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC746_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_ANN, .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC746_VFO_OPS, .scan_ops = IC746_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, /* most it2 rigs have 108-174 coverage*/ .rx_range_list2 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC746_1HZ_TS_MODES, 1}, {IC746_ALL_RX_MODES, 100}, {IC746_ALL_RX_MODES, kHz(1)}, {IC746_ALL_RX_MODES, kHz(5)}, {IC746_ALL_RX_MODES, kHz(9)}, {IC746_ALL_RX_MODES, kHz(10)}, {IC746_ALL_RX_MODES, kHz(12.5)}, {IC746_ALL_RX_MODES, kHz(20)}, {IC746_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTYR | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC746_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic746_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic746_set_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* IC-746Pro Rig parameters Only available in this namespace. This is a partial list */ #define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ #define S_MEM_LCD_CONT 0x501 /* LCD Contrast 0-256/0-100% */ #define S_MEM_BKLIT 0x502 /* Backlight 0-256/0-100% */ #define S_MEM_BEEP 0x506 /* Button confirmation */ #define S_MEM_SQL_CTL 0x508 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ #define S_MEM_QSPLT 0x511 /* enable quick split mode */ /* values -9.999 MHz to + 9.999 Mhz */ #define S_MEM_SPLT_OFST 0x512 /* default split offset 4 bytes little endian last byte sign*/ #define S_MEM_SPLT_LOCK 0x513 /* split lock set */ /* values 0.000 MHz to + 9.999 Mhz */ #define S_MEM_HF_DUP_OFST 0x514 /* default HF band duplex offset 3 byte little endian */ #define S_MEM_6M_DUP_OFST 0x515 /* default 50 mHz duplex offset 3 byte little endian */ #define S_MEM_2M_DUP_OFST 0x516 /* default 144 MHz duplex offset 3 byte little endian */ #define S_MEM_AUTO_RPTR 0x518 /* auto repeater set 0=OFF; 1=ON-1; 2=ON-2 */ #define S_MEM_LANG 0x523 /* 0=English 1=Japanese for voice announcer */ #define S_MEM_TRCV 0x536 /* CI-V transceive mode */ #define S_MEM_CMP_LVL 0x538 /* speech compressor level 0-10 */ #define S_MEM_SBASS 0x539 /* SSB TX tone bass level */ #define S_MEM_RTTY_FL_PB 0x562 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ #define S_MEM_RTTY_TWNPK 0x563 /* rtty twin peak filter off/on */ #define S_MEM_SCN_SPD 0x570 /* 0 = low; 1 = high */ #define S_MEM_NB_LVL 0x572 /* NB level 0-255 */ #define S_MEM_VOX_GN_LVL 0x573 /* vox gain */ #define S_MEM_AVOX_GN_LVL 0x574 /* anti-vox gain */ #define S_MEM_VOX_DEL_LVL 0x575 /* vox delay 0=0 - 20=2.0 sec */ static const struct confparams ic746pro_ext_parms[] = { { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", NULL, RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_SQLCTRL, "sqlctrl", "RF/Sql control", "set RF/Squelch control", NULL, RIG_CONF_COMBO, { .c = {{ "Auto", "Sql", "RF+Sql", NULL }} } }, { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", "350", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } }, { RIG_CONF_END, NULL, } }; /* * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ /* * IC-746pro rig capabilities. */ static const struct icom_priv_caps ic746pro_priv_caps = { 0x66, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = -1, .icom_level = 0 }, }, }; struct rig_caps ic746pro_caps = { RIG_MODEL(RIG_MODEL_IC746PRO), .model_name = "IC-746PRO", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC746_FUNC_ALL | RIG_FUNC_TUNER | RIG_FUNC_VSC, .has_set_func = IC746_FUNC_ALL | RIG_FUNC_TUNER | RIG_FUNC_VSC, .has_get_level = IC746_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC746_LEVEL_ALL), .has_get_parm = IC746_GET_PARM, .has_set_parm = IC746_SET_PARM, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .extparms = ic746pro_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC746_VFO_OPS | RIG_OP_TUNE, .scan_ops = IC746_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 9, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC746PRO_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC746PRO_MEM_CAP }, /* two by two */ { 102, 102, RIG_MTYPE_CALL, IC746PRO_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(144), MHz(146), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, /* most it2 rigs have 108-174 coverage*/ .rx_range_list2 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC746_1HZ_TS_MODES, 1}, {IC746_ALL_RX_MODES, 100}, {IC746_ALL_RX_MODES, kHz(1)}, {IC746_ALL_RX_MODES, kHz(5)}, {IC746_ALL_RX_MODES, kHz(9)}, {IC746_ALL_RX_MODES, kHz(10)}, {IC746_ALL_RX_MODES, kHz(12.5)}, {IC746_ALL_RX_MODES, kHz(20)}, {IC746_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! It might be better to rewrite and just put all filter widths for 1 mode together in 1 record. Remember these are defaults, with dsp rigs you can change them to anything you want (except rtty filter modes). */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, /* There are 5 rtty filters when rtty filter mode is set (default condition) { 1k, 500, 350, 300, 250 }. These are fixed. If rtty filter mode is unset there are 3 general IF filters { 2.4k, 500, 250 are the defaults }. These can be changed. There is a "twin-peak" filter mode as well. It boosts the 2125 and 2295 receive frequency response. The S_FUNC_RF (rtty filter) turns the rtty filter mode on and off. */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* RTTY & "normal" IF Filters */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, /* RTTY & "narrow" IF Filters */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, /* "wide" IF filter */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1)}, /*RTTY mode Filter*/ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(350)}, /*"Default " rtty mode filter*/ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, /* RTTY mode Filter */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC746_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic746pro_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic746_set_parm, .get_parm = ic746_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic746pro_set_ext_parm, .get_ext_parm = ic746pro_get_ext_parm, .get_channel = ic746pro_get_channel, .set_channel = ic746pro_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ic746pro_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; ep_len = 0; /* 0 implies BCD data */ val_len = 1; switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ if (val.i < 0 || val.i > 4) { return -RIG_EINVAL; } ep_sc = S_MEM_RTTY_FL_PB; icom_val = val.i; break; default: return -RIG_EINVAL; } if (ep_len == 0) { to_bcd_be(epbuf, (long long)icom_val, val_len * 2); ep_len += val_len; } retval = icom_transaction(rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ static int ic746pro_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { const struct confparams *cfp; unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val = 0; int cmdhead; int retval; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ ep_sc = S_MEM_RTTY_FL_PB; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_ext_parm %s", rig_strparm(token)); return -RIG_EINVAL; } retval = icom_transaction(rig, ep_cmd, ep_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (ep_sc == -1) ? 1 : S_MEM_SC_LEN + 1; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != ep_cmd) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } cfp = rig_ext_lookup_tok(rig, token); switch (cfp->type) { case RIG_CONF_STRING: memcpy(val->s, resbuf, res_len); break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: val->i = from_bcd_be(resbuf + cmdhead, res_len * 2); break; case RIG_CONF_NUMERIC: val->f = from_bcd_be(resbuf + cmdhead, res_len * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * icom_set_parm * Assumes rig!=NULL * These are very much rig specific and should probably be in rig files. These are for IC-746Pro. * The 746 has no parameters. */ int ic746_set_parm(RIG *rig, setting_t parm, value_t val) { unsigned char prmbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, prm_len; int prm_cn, prm_sc; int retval, icom_val; prm_cn = C_CTL_MEM; /* Most parm are 0x05xx */ prm_sc = S_MEM_PARM; switch (parm) { case RIG_PARM_ANN: if ((val.i == RIG_ANN_FREQ) || (val.i == RIG_ANN_RXMODE)) { prm_cn = C_CTL_ANN; prm_sc = val.i; prm_len = 0; } else { if ((val.i == RIG_ANN_ENG) || (val.i == RIG_ANN_JAP)) { prm_cn = C_CTL_MEM; prm_sc = S_MEM_LANG; prm_len = 1; prmbuf[0] = (val.i == RIG_ANN_ENG ? 0 : 1); } else { rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm_ann %d\n", val.i); return -RIG_EINVAL; } } break; case RIG_PARM_BACKLIGHT: prm_sc = S_MEM_BKLIT; prm_len = 2; icom_val = val.f * 255 ; to_bcd_be(prmbuf + 1, (long long)icom_val, 4); break; case RIG_PARM_BEEP: prm_sc = S_MEM_BEEP; prm_len = 1; prmbuf[1] = val.i; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %s\n", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1) { rig_debug(RIG_DEBUG_ERR, "icom_set_parm: wrong frame len=%d\n", ack_len); return -RIG_EPROTO; } return RIG_OK; } /* * icom_get_parm * Assumes rig!=NULL */ int ic746_get_parm(RIG *rig, setting_t parm, value_t *val) { unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val; int prm_cn, prm_sc; int cmdhead; int retval; prm_cn = C_CTL_MEM; switch (parm) { case RIG_PARM_BACKLIGHT: prm_sc = S_MEM_BKLIT; break; case RIG_PARM_BEEP: prm_sc = S_MEM_BEEP; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_parm %s", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (prm_sc == -1) ? 1 : 3; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != prm_cn) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); if (RIG_PARM_IS_FLOAT(parm)) { val->f = (float)icom_val / 255; } else { val->i = icom_val; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * ic746pro_get_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * * If memory is empty it will return RIG_OK,but every thing will be null. Where do we boundary check? */ int ic746pro_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[MAXFRAMELEN]; int chan_len, freq_len, retval, data_len; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; freq_len = priv->civ_731_mode ? 4 : 5; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->tx_vfo = RIG_VFO_NONE; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_SQL)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_NR)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_IN)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_OUT)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_CWPITCH)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); /* * chanbuf should contain Cn,Sc, Chan #, Data area */ // Do we get chan_len==1 || chan_len==5 on empty memory? // The IC746Pro returns 1a 00 00 01 ff on a blank channel // So this logic should apply to any Icom with chan_len==5 hopefully if (chan_len == 5 && chanbuf[4] == 0xff) { rig_debug(RIG_DEBUG_TRACE, "%s: chan %d is empty\n", __func__, chan->channel_num); return RIG_OK; } if ((chan_len != freq_len * 2 + 40) && (chan_len != 1)) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, chan_len); return -RIG_ERJCTED; } /* do this only if not a blank channel */ if (chan_len != 1) { int band; int sc; unsigned char databuf[32]; mem_buf_t *membuf; membuf = (mem_buf_t *)(chanbuf + 4); chan->split = (membuf->chan_flag & 0x10) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; chan->flags = (membuf->chan_flag & 0x01) ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; rig_debug(RIG_DEBUG_TRACE, "%s: chan->flags=0x%02x\n", __func__, chan->flags); /* data mode on */ rig_debug(RIG_DEBUG_TRACE, "%s: membuf->rx.data=0x%02x\n", __func__, membuf->rx.data); if (membuf->rx.data) { chan->flags |= RIG_CHFLAG_DATA; } /* * from_bcd requires nibble len */ chan->freq = from_bcd(membuf->rx.freq, freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: chan->freq=%f\n", __func__, chan->freq); icom2rig_mode(rig, membuf->rx.mode, membuf->rx.pb, &chan->mode, &chan->width); chan->rptr_shift = (rptr_shift_t)(membuf->rx.dup >> 8); rig_debug(RIG_DEBUG_TRACE, "%s: chan->rptr_shift=%d\n", __func__, chan->rptr_shift); /* offset is default for the band & is not stored in channel memory. The following retrieves the system default for the band */ band = (int) chan->freq / 1000000; /* hf, 2m or 6 m */ if (band < 50) { sc = S_MEM_HF_DUP_OFST; } else if (band < 108) { sc = S_MEM_6M_DUP_OFST; } else { sc = S_MEM_2M_DUP_OFST; } retval = icom_transaction(rig, C_CTL_MEM, sc, NULL, 0, databuf, &data_len); if (retval != RIG_OK) { return retval; } chan->rptr_offs = from_bcd(databuf + 3, 6) * 100; rig_debug(RIG_DEBUG_TRACE, "%s: chan->rptr_offs=%d\n", __func__, (int)chan->rptr_offs); chan->ctcss_tone = from_bcd_be(membuf->rx.tone, 6); rig_debug(RIG_DEBUG_TRACE, "%s: chan->ctcss_tone=%u\n", __func__, chan->ctcss_tone); chan->ctcss_sql = from_bcd_be(membuf->rx.tone_sql, 6); rig_debug(RIG_DEBUG_TRACE, "%s: chan->ctcss_sql=%u\n", __func__, chan->ctcss_sql); chan->dcs_code = from_bcd_be(membuf->rx.dcs.code, 4); rig_debug(RIG_DEBUG_TRACE, "%s: chan->dcs_code=%u\n", __func__, chan->dcs_code); /* The dcs information include in the channel includes polarity information for both tx and receive. Both directions are enabled when in dcs mode */ chan->tx_freq = from_bcd(membuf->tx.freq, freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: chan->tx_freq=%f\n", __func__, chan->tx_freq); icom2rig_mode(rig, membuf->tx.mode, membuf->tx.pb, &chan->tx_mode, &chan->tx_width); strncpy(chan->channel_desc, membuf->name, 9); chan->channel_desc[9] = '\0'; /* add null terminator */ rig_debug(RIG_DEBUG_TRACE, "%s: chan->channel_desc=%s\n", __func__, chan->channel_desc); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * ic746pro_set_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL */ int ic746pro_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; mem_buf_t membuf = {0}; unsigned char chanbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int chan_len, ack_len, freq_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; freq_len = priv->civ_731_mode ? 4 : 5; // set memory channel to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; // if good value, we change the memory otherwise clear if (chan->freq != 0 || chan->mode != 0) { if (chan->split == RIG_SPLIT_ON) { membuf.chan_flag |= 0x10; } else { membuf.chan_flag |= (chan->flags & RIG_CHFLAG_SKIP) ? 0x01 : 0x00; } // RX to_bcd(membuf.rx.freq, chan->freq, freq_len * 2); retval = rig2icom_mode(rig, vfo, chan->mode, chan->width, &membuf.rx.mode, &membuf.rx.pb); if (retval != RIG_OK) { return retval; } if (membuf.rx.pb == -1) { membuf.rx.pb = PD_MEDIUM_3; } membuf.rx.data = (chan->flags & RIG_CHFLAG_DATA) ? 1 : 0; membuf.rx.dup = chan->rptr_shift; // not empty otherwise the call fail if (chan->ctcss_tone == 0) { to_bcd_be(membuf.rx.tone, 885, 6); } else { to_bcd_be(membuf.rx.tone, chan->ctcss_tone, 6); } if (chan->ctcss_sql == 0) { to_bcd_be(membuf.rx.tone_sql, 885, 6); } else { to_bcd_be(membuf.rx.tone_sql, chan->ctcss_sql, 6); } if (chan->dcs_code == 0) { to_bcd_be(membuf.rx.dcs.code, 23, 4); } else { to_bcd_be(membuf.rx.dcs.code, chan->dcs_code, 4); } // TX to_bcd(membuf.tx.freq, chan->tx_freq, freq_len * 2); retval = rig2icom_mode(rig, vfo, chan->tx_mode, chan->tx_width, &membuf.tx.mode, &membuf.tx.pb); if (retval != RIG_OK) { return retval; } if (membuf.tx.pb == -1) { membuf.tx.pb = PD_MEDIUM_3; } membuf.tx.data = (chan->flags & RIG_CHFLAG_DATA) ? 1 : 0; membuf.tx.dup = chan->rptr_shift; // not empty otherwise the call fail if (chan->ctcss_tone == 0) { to_bcd_be(membuf.tx.tone, 885, 6); } else { to_bcd_be(membuf.tx.tone, chan->ctcss_tone, 6); } if (chan->ctcss_sql == 0) { to_bcd_be(membuf.tx.tone_sql, 885, 6); } else { to_bcd_be(membuf.tx.tone_sql, chan->ctcss_sql, 6); } if (chan->dcs_code == 0) { to_bcd_be(membuf.tx.dcs.code, 23, 4); } else { to_bcd_be(membuf.tx.dcs.code, chan->dcs_code, 4); } // set description memcpy(membuf.name, chan->channel_desc, sizeof(membuf.name)); memcpy(chanbuf + chan_len, &membuf, sizeof(mem_buf_t)); chan_len += sizeof(mem_buf_t); retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } else { retval = icom_transaction(rig, C_SET_MEM, -1, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } retval = icom_transaction(rig, C_CLR_MEM, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } return RIG_OK; } hamlib-4.6.5/rigs/icom/ic7800.c0000664000175000017500000004347315056640443011440 /* * Hamlib CI-V backend - description of IC-7800 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "frame.h" #include "misc.h" #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "ic7300.h" int ic7800_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic7800_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); #define IC7800_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7800_1HZ_TS_MODES IC7800_ALL_RX_MODES #define IC7800_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7800_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7800_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) #define IC7800_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7800_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7800_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7800_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7800_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7800_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7800 S-meter calibration data based on manual #define IC7800_STR_CAL { 3, \ { \ { 0, -54 }, /* S0 */ \ { 120, 0 }, /* S9 */ \ { 241, 60 } /* S9+60 */ \ } } #define IC7800_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7800_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7800_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7800_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7800_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7800_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct cmdparams ic7800_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x83}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7800_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7800 rig capabilities. */ static const struct icom_priv_caps ic7800_priv_caps = { 0x6a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 3, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7800_extcmds, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7800_caps = { RIG_MODEL(RIG_MODEL_IC7800), .model_name = "IC-7800", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7800_FUNCS, .has_set_func = IC7800_FUNCS, .has_get_level = IC7800_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7800_LEVELS), .has_get_parm = IC7800_PARMS, .has_set_parm = RIG_PARM_SET(IC7800_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7800_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 16, RIG_DBLST_END, }, .attenuator = { 3, 6, 9, 12, 15, 18, 21, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7800_VFO_OPS, .scan_ops = IC7800_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7800_ALL_RX_MODES, -1, -1, IC7800_VFOS, IC7800_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_6m(1, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_HF(1, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7800_ALL_RX_MODES, -1, -1, IC7800_VFOS, IC7800_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_6m(2, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_HF(2, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7800_1HZ_TS_MODES, 1}, {IC7800_ALL_RX_MODES, Hz(100)}, {IC7800_ALL_RX_MODES, kHz(1)}, {IC7800_ALL_RX_MODES, kHz(5)}, {IC7800_ALL_RX_MODES, kHz(9)}, {IC7800_ALL_RX_MODES, kHz(10)}, {IC7800_ALL_RX_MODES, kHz(12.5)}, {IC7800_ALL_RX_MODES, kHz(20)}, {IC7800_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7800_STR_CAL, .swr_cal = IC7800_SWR_CAL, .alc_cal = IC7800_ALC_CAL, .rfpower_meter_cal = IC7800_RFPOWER_METER_CAL, .comp_meter_cal = IC7800_COMP_METER_CAL, .vd_meter_cal = IC7800_VD_METER_CAL, .id_meter_cal = IC7800_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7800_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = ic7800_set_level, .get_level = ic7800_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7800_set_clock, .get_clock = ic7800_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-7800 has 0x11 command using index instead of backend's real dB value * * c.f. http://www.plicht.de/ekki/civ/civ-p42.html */ int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: if (val.i != 0) { /* Convert dB to index */ int i; for (i = 0; i < 7; i++) { if (val.i == STATE(rig)->attenuator[i]) { val.i = i + 1; break; } } /* TODO: Should fail when not found? */ } return icom_set_level(rig, vfo, level, val); default: return icom_set_level(rig, vfo, level, val); } } /* * IC-7800 has 0x11 command using index instead of backend's real dB value */ int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: retval = icom_get_level(rig, vfo, level, val); if (retval != RIG_OK) { return retval; } /* Convert index to dB * Rem: ATT index 0 means attenuator Off */ if (val->i > 0 && val->i <= 7) { val->i = STATE(rig)->attenuator[val->i - 1]; } break; default: return icom_get_level(rig, vfo, level, val); } return RIG_OK; } // if hour < 0 then only date will be set int ic7800_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x60; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x62; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7800_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x59; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x60; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x62; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } hamlib-4.6.5/rigs/icom/ic275.c0000664000175000017500000001611315056640443011346 /* * Hamlib CI-V backend - description of IC-275 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC275_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC275_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC275_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * FIXME: this appears to be the IC-275A/E * what about the IC-275H ? please give it a fix. --SF */ static const struct icom_priv_caps ic275_priv_caps = { 0x10, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; static const struct icom_priv_caps ic375_priv_caps = { 0x12, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic275_caps = { RIG_MODEL(RIG_MODEL_IC275), .model_name = "IC-275", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic275_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic375_caps = { RIG_MODEL(RIG_MODEL_IC375), .model_name = "IC-375", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic375_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/barrett/0000775000175000017500000000000015056640476011151 5hamlib-4.6.5/rigs/barrett/4100.c0000664000175000017500000002164715056640443011625 /* * Hamlib Barrett 4100 backend - main file * Derived from 4050 backend * Copyright (c) 2017-2024 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "barrett.h" #define MAXCMDLEN 32 //#define BARRETT4100 VFOS (RIG_VFO_A|RIG_VFO_MEM) // VFO_MEM eventually? #define BARRETT4100 VFOS (RIG_VFO_A) #define BARRETT4100_MODES (RIG_MODE_CW | RIG_MODE_SSB) // Levels eventually //#define BARRETT4100_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH) // Functions eventually //#define BARRETT4100_FUNCTIONS (RIG_FUNC_TUNER) extern int barret950_get_freq(RIG *rig, vfo_t vfo, freq_t freq); /* * barrett4100_get_info */ static const char *barrett4100_get_info(RIG *rig) { static char *response; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction2(rig, "M:MIB GM", 64, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "MIB GM: %s\n", response); } retval = barrett_transaction2(rig, "M:FF GM", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "M:MIB GM: %s\n", response); } retval = barrett_transaction2(rig, "M:FF BWA", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "FF BWA: %s\n", response); } retval = barrett_transaction2(rig, "M:FF GRFA", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "M:FF GRFA: %s\n", response); } return response; } static int barrett4100_open(RIG *rig) { int retval; char *response; ENTERFUNC; retval = barrett_transaction2(rig, "M:REMOTE SENTER2,1", 3, &response); rig_debug(RIG_DEBUG_ERR, "%s: back from REMOTE SENTER2: got %d\n", __func__, retval); if (response[0] != 's') { rig_debug(RIG_DEBUG_ERR, "%s: REMOTE SENTER2 error: got %s\n", __func__, response); } //barrett4100_get_info(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: success, ret=%d\n", __func__, retval); RETURNFUNC(RIG_OK); } static int barrett4100_close(RIG *rig) { char *response; int retval = barrett_transaction2(rig, "M:REMOTE SENTER0", 18, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } return rig_close(rig); } int barrett4100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char *response; int retval = barrett_transaction2(rig, "M:FF SRF%.0f GRF", freq, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); freq_t freq2 = 0; int n = sscanf(response, "s gRF%lf", &freq2); if (n == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gRF\n", __func__); } } retval = barrett_transaction2(rig, "M:FF STF%.0f GTF", freq, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); freq_t freq2 = 0; int n = sscanf(response, "s gTF%lf", &freq2); if (n == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gTF\n", __func__); } } return retval; } int barrett4100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *response; int retval = barrett_transaction2(rig, "M:FF GRF", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { int n = sscanf(response, "gRF%lf", freq); //int n = sscanf(response, "gRFA1,%*d,%lf,%*d", freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s(%d): unable to parse freq from '%s'\n", __func__, __LINE__, response); return -RIG_EPROTO; } } return retval; } int barrett4100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char *response; int retval = barrett_transaction2(rig, "M:FF SRPTT%d GRPTT", ptt, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, response); return retval; } int barrett4100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char *response; int retval = barrett_transaction2(rig, "M:FF GRPTT", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, response); return retval; } struct rig_caps barrett4100_caps = { RIG_MODEL(RIG_MODEL_BARRETT_4100), .model_name = "4100", .mfg_name = "Rhode&Schwarz", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, // do no promote until somebody confirms it works ok -- nobody to test it .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NETWORK, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, // .has_get_func = BARRETT4100_FUNCTIONS, // .has_set_func = BARRETT4100_FUNCTIONS, // .has_get_level = BARRETT4100_LEVELS, .has_set_level = RIG_LEVEL_AGC, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(10), .endf = MHz(30), .modes = BARRETT4100_MODES, .low_power = -1, .high_power = -1, BARRETT4100_MODES, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT4100_MODES, 1}, {BARRETT4100_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .rig_open = barrett4100_open, .rig_close = barrett4100_close, .set_freq = barrett4100_set_freq, .get_freq = barrett4100_get_freq, // .set_mode = barrett_set_mode, // .get_mode = barrett_get_mode, // .set_level = barrett_set_level, // .get_level = barrett_get_level, .get_info = barrett4100_get_info, .set_ptt = barrett4100_set_ptt, .get_ptt = barrett4100_get_ptt, // .set_split_freq = barrett_set_split_freq, // .set_split_vfo = barrett_set_split_vfo, // .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/barrett/barrett.h0000664000175000017500000000603115056640443012677 /* * Hamlib Barrett backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _BARRETT_H #define _BARRETT_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20240422" #define EOM "\x0d" #define TRUE 1 #define FALSE 0 // For the current implemented command set 64 is long enough // This will need a lot more room for some channel commands like IDFA which return all channels // But that would 9999*41 or 406KB so didn't do that right now #define BARRETT_DATA_LEN 64 // RET_LEN is # of max channels times the per-channel response length #define BARRETT_RET_LEN 24*1000 extern struct rig_caps barrett_caps; extern struct rig_caps barrett950_caps; extern struct rig_caps barrett4050_caps; extern struct rig_caps barrett4100_caps; struct barrett_priv_data { char cmd_str[BARRETT_DATA_LEN]; /* command string buffer */ char ret_data[BARRETT_RET_LEN]; /* returned data--max value, most are less */ char split; /* split on/off */ int channel_base; /* base channel for 0-9 10-channel assignment if needed */ }; extern int barrett_transaction(RIG *rig, char *cmd, int expected, char **result); extern int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result); extern int barrett_init(RIG *rig); extern int barrett_cleanup(RIG *rig); extern int barrett_open(RIG *rig); extern int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int barrett_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); extern int barrett_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int barrett_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int barrett_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); extern int barrett_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); extern int barrett_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); extern int barrett_set_split_vfo(RIG *rig, vfo_t rxvfo, split_t split, vfo_t txvfo); extern int barrett_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); extern int barrett_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern int barrett_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); #endif /* _BARRETT_H */ hamlib-4.6.5/rigs/barrett/950.c0000664000175000017500000001675415056640443011561 /* * Hamlib Barrett 950 backend - main file * Copyright (c) 2017-2020 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT950_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT950_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT950_LEVELS (RIG_LEVEL_NONE) int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int barrett950_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *barrett950_get_info(RIG *rig); // 10 band channel from 441 to 450 #define CHANNEL_BASE 441 struct chan_map_s { float lo, hi; int chan_offset; }; // Our 10 bands static struct chan_map_s chan_map[] = { { 0, 3.5, 0}, { 3.5, 5.3, 1}, { 5.3, 7.0, 2}, { 7.0, 10.1, 3}, { 10.1, 14.0, 4}, { 14.0, 18.068, 5}, { 18.068, 21.0, 6}, { 21.0, 24.89, 7}, { 24.89, 28.0, 8}, { 28.0, 30.0, 9} }; struct rig_caps barrett950_caps = { RIG_MODEL(RIG_MODEL_BARRETT_950), .model_name = "950", .mfg_name = "Barrett", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .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_XONXOFF, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = BARRETT950_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT950_MODES, .low_power = -1, .high_power = -1, BARRETT950_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT950_MODES, 1}, {BARRETT950_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .set_freq = barrett950_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, .get_level = barrett950_get_level, .get_info = barrett950_get_info, .set_ptt = barrett_set_ptt, .get_ptt = NULL, .set_split_freq = barrett_set_split_freq, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * barrett950_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; int i; int chan = -1; freq_t freq_rx, freq_tx; freq_t freq_MHz; char *response = NULL; const struct barrett_priv_data *priv = STATE(rig)->priv; //struct barrett_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); // 950 can only set freq via memory channel // So we make a 10-channel memory from 441-450 by band // And we don't care about VFO -- we set TX=RX to avoid doing split freq changes // Trying to minimize writes to EEPROM // What band is being requested? freq_MHz = freq / 1e6; for (i = 0; i < 10; ++i) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Mhz=%lg, lo=%lg, hi=%lg\n", __func__, freq_MHz, chan_map[i].lo, chan_map[i].hi); if (freq_MHz >= chan_map[i].lo && freq_MHz <= chan_map[i].hi) { int channel_base = priv->channel_base; chan = channel_base + chan_map[i].chan_offset; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using chan %d for freq %.0f \n", __func__, chan, freq); // Set the channel SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "XC%04d", chan); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } // Read the current channel for the requested freq to see if it needs changing SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "IDC%04d", chan); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } if (strstr(response, "E5")) { freq_rx = freq_tx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: new channel being programmed\n", __func__); } else if (sscanf(response, "%4d%8lf%8lf", &chan, &freq_rx, &freq_tx) != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse chan/freq from %s\n", __func__, response); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: got chan %d, freq_rx=%.0f, freq_tx=%.0f", __func__, chan, freq_rx, freq_tx); if (freq_rx == freq && freq_tx == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no freq change needed\n", __func__); return RIG_OK; } // New freq so let's update the channel // We do not support split mode -- too many writes to EEPROM to support it SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "PC%04dR%08.0lfT%08.0lf", chan, freq, freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval != RIG_OK || strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * barrett950_get_level */ int barrett950_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return -RIG_ENIMPL; } /* * barrett950_get_info */ const char *barrett950_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IV", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Software Version %s\n", response); } return response; } hamlib-4.6.5/rigs/barrett/barrett.c0000664000175000017500000005706515056640443012707 /* * Hamlib Barrett backend - main file * Copyright (c) 2017 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT_LEVELS (RIG_LEVEL_STRENGTH) DECLARE_INITRIG_BACKEND(barrett) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&barrett_caps); rig_register(&barrett950_caps); rig_register(&barrett4050_caps); rig_register(&barrett4100_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } void barrett_flush(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); int timesave = STATE(rig)->timeout; STATE(rig)->timeout = 0; rig_flush(rp); STATE(rig)->timeout = timesave; } // this version is for 4100 int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; struct barrett_priv_data *priv = STATE(rig)->priv; int retval; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%c%s%s", 0x0a, cmd, EOM); barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in write_block\n", __func__, __LINE__); return retval; } retval = read_block(RIGPORT(rig), (unsigned char *) priv->ret_data, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %d bytes read\n", __func__, __LINE__, retval); if (priv->ret_data[0] == 0x13) // we'll return from the 1st good char { *result = &(priv->ret_data[1]); } else // some commands like IAL don't give XOFF but XON is there -- is this a bug? { *result = &(priv->ret_data[0]); } return retval; } int barrett_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; char *p; char xon; char xoff; hamlib_port_t *rp = RIGPORT(rig); struct barrett_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); if (rig->caps->rig_model == RIG_MODEL_BARRETT_4100) { } else { SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%s", cmd, EOM); } barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } if (expected == 0) { // response format is 0x11,data...,0x0d,0x0a,0x13 retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x11", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: resultlen=%d\n", __func__, (int)strlen(priv->ret_data)); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_string\n", __func__, __LINE__); return retval; } } else { retval = read_block(rp, (unsigned char *) priv->ret_data, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } } p = priv->ret_data; xon = p[0]; xoff = p[strlen(p) - 1]; if (xon == 0x13 && xoff == 0x11) { //rig_debug(RIG_DEBUG_TRACE, "%s: removing xoff char\n", __func__); p[strlen(p) - 1] = 0; } else { rig_debug(RIG_DEBUG_WARN, "%s: expected XOFF=0x13 as first and XON=0x11 as last byte, got %02x/%02x\n", __func__, xon, xoff); } //rig_debug(RIG_DEBUG_ERR, "%s: removing xon char\n", __func__); // Remove the XON char if there p = memchr(priv->ret_data, 0x11, strlen(priv->ret_data)); if (p) { *p = 0; } if (result != NULL) { int n = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting result\n", __func__); if (priv->ret_data[0] == 0x13) // we'll return from the 1st good char { *result = &(priv->ret_data[1]); } else // some commands like IAL don't give XOFF but XON is there -- is this a bug? { *result = &(priv->ret_data[0]); } // See how many CR's we have for (p = *result; *p; ++p) { if (*p == 0x0d) { ++n; } } // if only 1 CR then we'll truncate string // Several commands can return multiline strings and we'll leave them alone if (n == 1) { char *dummy; strtok_r(*result, "\r", &dummy); } //rig_debug(RIG_DEBUG_VERBOSE, "%s: returning result=%s\n", __func__, // *result); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int barrett_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct barrett_priv_data *)calloc(1, sizeof(struct barrett_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } /* * barrett_cleanup * */ int barrett_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * barrett_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int barrett_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; if (vfo == RIG_VFO_B) // We treat the TX VFO as VFO_B and RX VFO as VFO_A { retval = barrett_transaction(rig, "IT", 0, &response); } else { retval = barrett_transaction(rig, "IR", 0, &response); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "%lg", freq); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } // TC command does not work on 4050 -- not implemented as of 2022-01-12 /* * barrett_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int barrett_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; const struct barrett_priv_data *priv = STATE(rig)->priv; freq_t tfreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); retval = rig_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq failed: %s\n", __func__, strerror(retval)); return retval; } if (tfreq == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq not changing\n", __func__); return RIG_OK; } // If we are not explicitly asking for VFO_B then we'll set the receive side also if (vfo != RIG_VFO_B) { char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TR%08.0f", freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } //dump_hex((unsigned char *)response, strlen(response)); if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } } if (priv->split == 0 || vfo == RIG_VFO_B) // if we aren't in split mode we have to set the TX VFO too { char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TC9999T%08.0f", freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } } return RIG_OK; } /* * barrett_set_ptt * Assumes rig!=NULL */ int barrett_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); // we need a little extra time before we assert PTT // testing with rigctld worked, but from WSJT-X did not // WSJT-X is just a little faster without the network timing hl_usleep(100 * 1000); SNPRINTF(cmd_buf, sizeof(cmd_buf), "XP%d", ptt); response = NULL; retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd:IP result=%s\n", __func__, response); return RIG_OK; } /* * barrett_get_ptt * Assumes rig!=NULL */ int barrett_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; char c; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = barrett_transaction(rig, "IP", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } c = response[0]; if (c == '1' || c == '0') { *ptt = c - '0'; } else { rig_debug(RIG_DEBUG_ERR, "%s: error response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * barrett_set_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ int barrett_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], ttmode; int retval; rmode_t tmode; pbwidth_t twidth; //struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = rig_get_mode(rig, vfo, &tmode, &twidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed %s\n", __func__, strerror(retval)); } if (tmode == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already mode %s so not changing\n", __func__, rig_strrmode(mode)); return RIG_OK; } switch (mode) { case RIG_MODE_USB: ttmode = 'U'; break; case RIG_MODE_LSB: ttmode = 'L'; break; case RIG_MODE_CW: ttmode = 'C'; break; case RIG_MODE_AM: ttmode = 'A'; break; case RIG_MODE_RTTY: ttmode = 'F'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TB%c" EOM, ttmode); retval = barrett_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } /* * barrett_get_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ int barrett_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = barrett_transaction(rig, "IB", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } //dump_hex((unsigned char *)result,strlen(result)); switch (result[1]) { case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'A': *mode = RIG_MODE_AM; break; case 'F': *mode = RIG_MODE_RTTY; break; case 'C': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode='%c%c'\n", __func__, result[0], result[1]); return -RIG_EPROTO; } *width = 3000; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } #if 0 int barrett_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } #endif /* * barrett_set_split_freq */ int barrett_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { // The 2050 only has one RX and one TX VFO -- it's not treated as VFOA/VFOB char cmd_buf[MAXCMDLEN]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), tx_freq); SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TT%08.0f" EOM, tx_freq); retval = barrett_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } int barrett_set_split_vfo(RIG *rig, vfo_t rxvfo, split_t split, vfo_t txvfo) { struct barrett_priv_data *priv; priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(rxvfo), rig_strvfo(txvfo), split); priv->split = split; return RIG_OK; } int barrett_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { struct barrett_priv_data *priv; priv = STATE(rig)->priv; *split = priv->split; *txvfo = RIG_VFO_B; // constant rig_debug(RIG_DEBUG_VERBOSE, "%s called rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(rxvfo), rig_strvfo(*txvfo), *split); return RIG_OK; } /* * barrett_get_level */ int barrett_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval = 0; char *response = NULL; switch (level) { int strength; int n; case RIG_LEVEL_STRENGTH: retval = barrett_transaction(rig, "IAL", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } n = sscanf(response, "%2d", &strength); if (n == 1) { val->i = strength; } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse STRENGTH from %s\n", __func__, response); return -RIG_EPROTO; } break; case RIG_LEVEL_AGC: retval = barrett_transaction(rig, "IGA", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (response[0] == 'H') // then AGC hang is on { val->i = 1; } else { val->i = 0; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s val=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level), response); return RIG_OK; } int barrett_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd_buf[MAXCMDLEN]; hamlib_port_t *rp = RIGPORT(rig); int retval; switch (level) { case RIG_LEVEL_AGC: sprintf(cmd_buf, "EG%c%s", val.i == 0 ? 'N' : 'H', EOM); break; default: return -RIG_ENIMPL; } barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } return RIG_OK; } /* * barrett_get_info */ const char *barrett_get_info(RIG *rig) { char *response = NULL; char *series; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IDR", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: IDR command failed: %s\n", __func__, strerror(retval)); series = "unknown"; } else { series = strdup(response); } retval = barrett_transaction(rig, "IDS", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: IDS command failed: %s\n", __func__, strerror(retval)); response = "unknown"; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Barrett series %s, serial# %s\n", __func__, series, response); retval = barrett_transaction(rig, "IV", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: IV failed result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Barrett software Version %s\n", response); } return response; } int barrett_open(RIG *rig) { ENTERFUNC; barrett_get_info(rig); RETURNFUNC(RIG_OK); } struct rig_caps barrett_caps = { RIG_MODEL(RIG_MODEL_BARRETT_2050), .model_name = "2050", .mfg_name = "Barrett", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .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_XONXOFF, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = BARRETT_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT_MODES, .low_power = -1, .high_power = -1, BARRETT_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT_MODES, 1}, {BARRETT_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, // .extlevels = dummy_ext_levels, // .extparms = dummy_ext_parms, // .cfgparams = dummy_cfg_params, .rig_init = barrett_init, .rig_open = barrett_open, .rig_cleanup = barrett_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = barrett_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, // .set_powerstat = dummy_set_powerstat, // .get_powerstat = dummy_get_powerstat, // .set_level = dummy_set_level, .get_level = barrett_get_level, // .set_func = dummy_set_func, // .get_func = dummy_get_func, // .set_parm = dummy_set_parm, // .get_parm = dummy_get_parm, // .set_ext_level = dummy_set_ext_level, // .get_ext_level = dummy_get_ext_level, // .set_ext_parm = dummy_set_ext_parm, // .get_ext_parm = dummy_get_ext_parm, .get_info = barrett_get_info, .set_ptt = barrett_set_ptt, .get_ptt = barrett_get_ptt, // .get_dcd = dummy_get_dcd, // .set_rptr_shift = dummy_set_rptr_shift, // .get_rptr_shift = dummy_get_rptr_shift, // .set_rptr_offs = dummy_set_rptr_offs, // .get_rptr_offs = dummy_get_rptr_offs, // .set_ctcss_tone = dummy_set_ctcss_tone, // .get_ctcss_tone = dummy_get_ctcss_tone, // .set_dcs_code = dummy_set_dcs_code, // .get_dcs_code = dummy_get_dcs_code, // .set_ctcss_sql = dummy_set_ctcss_sql, // .get_ctcss_sql = dummy_get_ctcss_sql, // .set_dcs_sql = dummy_set_dcs_sql, // .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = barrett_set_split_freq, // .get_split_freq = dummy_get_split_freq, // .set_split_mode = dummy_set_split_mode, // .get_split_mode = dummy_get_split_mode, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, // .set_rit = dummy_set_rit, // .get_rit = dummy_get_rit, // .set_xit = dummy_set_xit, // .get_xit = dummy_get_xit, // .set_ts = dummy_set_ts, // .get_ts = dummy_get_ts, // .set_ant = dummy_set_ant, // .get_ant = dummy_get_ant, // .set_bank = dummy_set_bank, // .set_mem = dummy_set_mem, // .get_mem = dummy_get_mem, // .vfo_op = dummy_vfo_op, // .scan = dummy_scan, // .send_dtmf = dummy_send_dtmf, // .recv_dtmf = dummy_recv_dtmf, // .send_morse = dummy_send_morse, // .set_channel = dummy_set_channel, // .get_channel = dummy_get_channel, // .set_trn = dummy_set_trn, // .get_trn = dummy_get_trn, // .power2mW = dummy_power2mW, // .mW2power = dummy_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/barrett/4050.c0000664000175000017500000001202415056640443011616 /* * Hamlib Barrett 4050 backend - main file * Copyright (c) 2017-2022 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT4050_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT4050_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT4050_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH) #define BARRETT4050_FUNCTIONS (RIG_FUNC_TUNER) extern int barret950_get_freq(RIG *rig, vfo_t vfo, freq_t freq); /* * barrett4050_get_info */ static const char *barrett4050_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IV", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Software Version %s\n", response); } return response; } static int barrett4050_open(RIG *rig) { int retval; char *response; struct barrett_priv_data *priv = STATE(rig)->priv; ENTERFUNC; barrett4050_get_info(rig); retval = barrett_transaction(rig, "IDC9999", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: channel 9999 info=%s\n", __func__, response); priv->channel_base = 9990; } retval = barrett_transaction(rig, "XC9999", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } retval = barrett_transaction(rig, "IC", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } RETURNFUNC(RIG_OK); } struct rig_caps barrett4050_caps = { RIG_MODEL(RIG_MODEL_BARRETT_4050), .model_name = "4050", .mfg_name = "Barrett", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = BARRETT4050_FUNCTIONS, .has_set_func = BARRETT4050_FUNCTIONS, .has_get_level = BARRETT4050_LEVELS, .has_set_level = RIG_LEVEL_AGC, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT4050_MODES, .low_power = -1, .high_power = -1, BARRETT4050_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT4050_MODES, 1}, {BARRETT4050_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .rig_open = barrett4050_open, // Barrett said eeprom is good for 1M writes so channelized should be OK for a long time // TC command was not implemented as of 2022-01-12 which would be better .set_freq = barrett950_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, .set_level = barrett_set_level, .get_level = barrett_get_level, .get_info = barrett4050_get_info, .set_ptt = barrett_set_ptt, .get_ptt = barrett_get_ptt, .set_split_freq = barrett_set_split_freq, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/barrett/Android.mk0000664000175000017500000000041415056640443012773 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := barrett.c barrett.h 950.c LOCAL_MODULE := barrett LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/barrett/Makefile.in0000664000175000017500000005351015056640452013134 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/barrett ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_barrett_la_LIBADD = am__objects_1 = barrett.lo 950.lo 4050.lo 4100.lo am_libhamlib_barrett_la_OBJECTS = $(am__objects_1) libhamlib_barrett_la_OBJECTS = $(am_libhamlib_barrett_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/4050.Plo ./$(DEPDIR)/4100.Plo \ ./$(DEPDIR)/950.Plo ./$(DEPDIR)/barrett.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_barrett_la_SOURCES) DIST_SOURCES = $(libhamlib_barrett_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BARRETTSRC = barrett.c barrett.h 950.c 4050.c 4100.c noinst_LTLIBRARIES = libhamlib-barrett.la libhamlib_barrett_la_SOURCES = $(BARRETTSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/barrett/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/barrett/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-barrett.la: $(libhamlib_barrett_la_OBJECTS) $(libhamlib_barrett_la_DEPENDENCIES) $(EXTRA_libhamlib_barrett_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_barrett_la_OBJECTS) $(libhamlib_barrett_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4050.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrett.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/4050.Plo -rm -f ./$(DEPDIR)/4100.Plo -rm -f ./$(DEPDIR)/950.Plo -rm -f ./$(DEPDIR)/barrett.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/4050.Plo -rm -f ./$(DEPDIR)/4100.Plo -rm -f ./$(DEPDIR)/950.Plo -rm -f ./$(DEPDIR)/barrett.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/barrett/Makefile.am0000664000175000017500000000024615056640443013121 BARRETTSRC = barrett.c barrett.h 950.c 4050.c 4100.c noinst_LTLIBRARIES = libhamlib-barrett.la libhamlib_barrett_la_SOURCES = $(BARRETTSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/alinco/0000775000175000017500000000000015056640475010752 5hamlib-4.6.5/rigs/alinco/dx77.c0000664000175000017500000010534615056640443011633 /* * Hamlib Alinco backend - DX77 description * Copyright (c) 2001-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include #include "idx_builtin.h" #include "alinco.h" #include #include "tones.h" #include /* * modes in use by the "2G" command */ #define MD_LSB '0' #define MD_USB '1' #define MD_CWL '2' #define MD_CWU '3' #define MD_AM '4' #define MD_FM '5' /* Line Feed */ #define EOM "\x0d" #define LF "\x0a" #define CMD_TXFREQ "0A" /* Transmit frequency */ #define CMD_RXFREQ "0B" /* Receive frequency */ #define CMD_VFO "1A" #define CMD_MEMMD "1B" /* Memory mode */ #define CMD_CHAN "1D" /* Channel Display */ #define CMD_UPDWN "2A" /* UP/DOWN */ #define CMD_MON "2B" /* Check Transmit Frequency */ #define CMD_PWR "2C" /* Transmit Output Power */ #define CMD_SCAN "2D" /* Scanning */ #define CMD_PRIO "2E" /* Priority */ #define CMD_SPLT "2F" /* Split */ #define CMD_MODE "2G" /* Mode */ #define CMD_RFGAIN "2H" /* RF Gain */ #define CMD_AGC "2I" #define CMD_FLTER "2J" /* Filter */ #define CMD_NB "2K" #define CMD_CTCSS "2L" #define CMD_TUNE "2M" #define CMD_SELECT "2N" #define CMD_MCALL "2V" /* Memory Channel Call Up */ #define CMD_SDATA "2W" /* Set Data */ /* Data Output Commands */ #define CMD_SMETER "3A" /* S-meter read */ #define CMD_PTT "3B" /* PTT status read */ #define CMD_SQL "3C" /* Squelch status */ #define CMD_RIT "3D" /* RIT status */ #define CMD_RMEM "3E" /* Current Memory-channel Number read */ #define CMD_RMV "3G" /* Memory/VFO -mode read */ #define CMD_RDATA "3H" /* Current Data read */ #define CMD_RSPLT "3I" /* Split read */ #define CMD_RPOWER "3J" /* Transmitter Output read */ #define CMD_RSELECT "3K" /* SELECT Position read */ #define DX77_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DX77_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DX77_AM_TX_MODES RIG_MODE_AM #define DX77_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TONE) #define DX77_LEVEL_ALL (RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|RIG_LEVEL_BKINDL|RIG_LEVEL_CWPITCH) #define DX77_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define DX77_VFO (RIG_VFO_A|RIG_VFO_B) /* 90 is S9 */ #define DX77_STR_CAL { 13, { \ { 0, -60 }, \ { 28, -48 }, \ { 36, -42 }, \ { 42, -36 }, \ { 50, -30 }, \ { 58, -24 }, \ { 66, -18 }, \ { 74, -12 }, \ { 82, -6 }, \ { 90, 0 }, \ { 132, 20 }, \ { 174, 40 }, \ { 216, 60 }, \ } } int dx77_set_vfo(RIG *rig, vfo_t vfo); int dx77_get_vfo(RIG *rig, vfo_t *vfo); int dx77_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int dx77_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int dx77_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int dx77_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int dx77_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int dx77_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int dx77_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int dx77_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int dx77_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int dx77_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int dx77_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int dx77_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int dx77_set_parm(RIG *rig, setting_t parm, value_t val); int dx77_get_parm(RIG *rig, setting_t parm, value_t *val); int dx77_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int dx77_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); int dx77_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int dx77_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int dx77_set_mem(RIG *rig, vfo_t vfo, int ch); int dx77_get_mem(RIG *rig, vfo_t vfo, int *ch); /* * dx77 rig capabilities. * * protocol is documented at * http://www.alinco.com/pdf.files/DX77-77_SOFTWARE_MANUAL.pdf * * This backend was a pleasure to develop. Documentation is clear, * and the protocol logical. I'm wondering is the rig's good too. --SF * * TODO: * - get_parm/set_parm and some LEVELs left (Set Data "2W" command). * - tuner * - up/down * - scan */ struct rig_caps dx77_caps = { RIG_MODEL(RIG_MODEL_DX77), .model_name = "DX-77", .mfg_name = "Alinco", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .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 = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DX77_FUNC, .has_set_func = DX77_FUNC | RIG_FUNC_MON | RIG_FUNC_COMP, .has_get_level = DX77_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DX77_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(DX77_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = kHz(1), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(500), .endf = MHz(30), .modes = DX77_OTHER_TX_MODES, .low_power = -1, .high_power = -1, RIG_VFO_A, RIG_ANT_NONE }, { .startf = kHz(500), .endf = MHz(30), .modes = DX77_AM_TX_MODES, .low_power = -1, .high_power = -1, RIG_VFO_A, RIG_ANT_NONE }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { {kHz(500), MHz(30), DX77_ALL_MODES, -1, -1, DX77_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(1800), MHz(2) - 100, DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(3500), MHz(4) - 100, DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(3500), MHz(4) - 100, DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(7), kHz(7300), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(7), kHz(7300), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(10100), kHz(10150), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(10100), kHz(10150), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(14), kHz(14350), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(14), kHz(14350), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(18068), kHz(18168), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(18068), kHz(18168), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(21), kHz(21450), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(21), kHz(21450), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(24890), kHz(24990), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(24890), kHz(24990), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(28), kHz(29700), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(28), kHz(29700), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, RIG_FRNG_END, }, .tuning_steps = { {DX77_ALL_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_CW, kHz(0.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_AM, kHz(2.7)}, RIG_FLT_END, }, .str_cal = DX77_STR_CAL, .set_freq = dx77_set_freq, .get_freq = dx77_get_freq, .set_mode = dx77_set_mode, .get_mode = dx77_get_mode, .set_vfo = dx77_set_vfo, .get_vfo = dx77_get_vfo, .set_split_vfo = dx77_set_split_vfo, .get_split_vfo = dx77_get_split_vfo, .set_split_freq = dx77_set_split_freq, .get_split_freq = dx77_get_split_freq, .set_ctcss_tone = dx77_set_ctcss_tone, .get_rit = dx77_get_rit, .get_ptt = dx77_get_ptt, .get_dcd = dx77_get_dcd, .set_func = dx77_set_func, .get_func = dx77_get_func, .set_parm = dx77_set_parm, .set_level = dx77_set_level, .get_level = dx77_get_level, .set_mem = dx77_set_mem, .get_mem = dx77_get_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * dx77_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int dx77_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char echobuf[BUFSZ + 1]; if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: null argument for cmd?\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF * TODO: check whether cmd and echobuf match (optional) */ retval = read_string(rp, (unsigned char *) echobuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } if (((data == NULL) && (data_len > 0)) || ((data != NULL) && (data_len == 0))) { rig_debug(RIG_DEBUG_ERR, "%s: data and datalen not both NULL??\n", __func__); return -RIG_EINTERNAL; } /* no data expected, check for OK returned */ if (data == NULL) { retval = read_string(rp, (unsigned char *) echobuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } if (retval > 2) { retval -= 2; } echobuf[retval] = 0; if (strcmp(echobuf, "OK") == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } *data_len = retval; /* strip CR/LF from string */ data[0] = 0; if (*data_len > 2) { *data_len -= 2; data[*data_len] = 0; } return RIG_OK; } /* * dx77_set_vfo * Assumes rig!=NULL */ int dx77_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[BUFSZ]; char vfo_num; switch (vfo) { case RIG_VFO_A: vfo_num = '1'; break; case RIG_VFO_B: vfo_num = '2'; break; case RIG_VFO_MEM: return dx77_transaction(rig, AL CMD_MEMMD "0" EOM, strlen(AL CMD_MEMMD "0" EOM), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "dx77_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_VFO "%c" EOM, vfo_num); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_vfo * Assumes rig!=NULL, !vfo */ int dx77_get_vfo(RIG *rig, vfo_t *vfo) { char vfobuf[BUFSZ]; int vfo_len, retval; retval = dx77_transaction(rig, AL CMD_RMV EOM, strlen(AL CMD_RMV EOM), vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } if (vfo_len != 4) { rig_debug(RIG_DEBUG_ERR, "dx77_get_vfo: wrong answer %s, " "len=%d\n", vfobuf, vfo_len); return -RIG_ERJCTED; } vfobuf[vfo_len] = '\0'; if (!strcmp(vfobuf, "VFOA")) { *vfo = RIG_VFO_A; } else if (!strcmp(vfobuf, "VFOB")) { *vfo = RIG_VFO_B; } else if (!strcmp(vfobuf, "MEMO")) { *vfo = RIG_VFO_MEM; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_vfo: unsupported VFO %s\n", vfobuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_freq * Assumes rig!=NULL */ int dx77_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* max 10 digits */ if (freq >= GHz(10)) { return -RIG_EINVAL; } /* at least 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), AL CMD_RXFREQ "%06"PRIll EOM, (int64_t)freq); return dx77_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * where databuf points to a 26 char long buffer */ static int current_data_read(RIG *rig, char *databuf) { int data_len, retval; retval = dx77_transaction(rig, AL CMD_RDATA EOM, strlen(AL CMD_RDATA EOM), databuf, &data_len); if (retval != RIG_OK) { return retval; } if (data_len != 26) { rig_debug(RIG_DEBUG_ERR, "dx77_current_data_read: wrong answer %s, len=%d\n", databuf, data_len); return -RIG_ERJCTED; } return RIG_OK; } /* * dx77_get_freq * Assumes rig!=NULL, freq!=NULL */ int dx77_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ]; retval = current_data_read(rig, freqbuf); if (retval != RIG_OK) { return retval; } /* extract RX freq */ freqbuf[16] = '\0'; sscanf(freqbuf + 6, "%"SCNfreq, freq); return RIG_OK; } /* * dx77_set_mode * Assumes rig!=NULL */ int dx77_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int wide_filter, retval; char amode; switch (mode) { /* FIXME: MD_CWL or MD_CWU? */ case RIG_MODE_CW: amode = MD_CWU; break; case RIG_MODE_USB: amode = MD_USB; break; case RIG_MODE_LSB: amode = MD_LSB; break; case RIG_MODE_FM: amode = MD_FM; break; case RIG_MODE_AM: amode = MD_AM; break; default: rig_debug(RIG_DEBUG_ERR, "dx77_set_mode: unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), AL CMD_MODE "%c" EOM, amode); retval = dx77_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } /* * TODO: please DX77 owners, check this, I'm not sure * which passband is default! */ if (width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { wide_filter = 0; } else { wide_filter = 1; } SNPRINTF(mdbuf, sizeof(mdbuf), AL CMD_FLTER "%02d" EOM, wide_filter); retval = dx77_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * dx77_get_mode * Assumes rig!=NULL, mode!=NULL */ int dx77_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int settings; char modebuf[BUFSZ]; retval = current_data_read(rig, modebuf); if (retval != RIG_OK) { return retval; } /* FIXME: CWL&CWU: what are they? CW & CWR? */ switch (modebuf[3]) { case MD_CWL: case MD_CWU: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "dx77_get_mode: unknown mode %c%c\n", modebuf[2], modebuf[3]); return -RIG_EINVAL; } modebuf[2] = '\0'; settings = strtol(modebuf, (char **)NULL, 16); /* * TODO: please DX77 owners, check this, I'm not sure * which passband is default! */ if (settings & 0x02) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * dx77_set_split * Assumes rig!=NULL */ int dx77_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SPLT "%d" EOM, split == RIG_SPLIT_ON ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_split * Assumes rig!=NULL, split!=NULL */ int dx77_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int splt_len, retval; char spltbuf[BUFSZ]; retval = dx77_transaction(rig, AL CMD_RSPLT EOM, strlen(AL CMD_RSPLT EOM), spltbuf, &splt_len); if (retval != RIG_OK) { return retval; } if (splt_len != 2) { rig_debug(RIG_DEBUG_ERR, "dx77_get_split: wrong answer %s, len=%d\n", spltbuf, splt_len); return -RIG_ERJCTED; } spltbuf[splt_len] = '\0'; if (!strcmp(spltbuf, "OF")) { *split = RIG_SPLIT_OFF; } else if (!strcmp(spltbuf, "ON")) { *split = RIG_SPLIT_ON; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_split: unsupported SPLIT %s\n", spltbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_split_freq * Assumes rig!=NULL */ int dx77_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { char freqbuf[BUFSZ]; int retval; /* max 10 digits */ if (tx_freq >= GHz(10)) { return -RIG_EINVAL; } /* at least 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), AL CMD_TXFREQ "%06"PRIll EOM, (int64_t)tx_freq); retval = dx77_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * dx77_get_split_freq * Assumes rig!=NULL, rx_freq!=NULL, tx_freq!=NULL */ int dx77_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; char freqbuf[BUFSZ]; retval = current_data_read(rig, freqbuf); if (retval != RIG_OK) { return retval; } /* extract TX freq first, as RX kills freqbuf[16] */ freqbuf[26] = '\0'; sscanf(freqbuf + 16, "%"SCNfreq, tx_freq); return RIG_OK; } /* * dx77_get_rit * Assumes rig!=NULL, split!=NULL */ int dx77_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int rit_len, retval; char ritbuf[BUFSZ]; /* read in Hertz unit */ retval = dx77_transaction(rig, AL CMD_RIT "0" EOM, strlen(AL CMD_RIT "0" EOM), ritbuf, &rit_len); if (retval != RIG_OK) { return retval; } if (rit_len != 8) /* || (ritbuf[0] != '+' && ritbuf[0] != '-')) { */ { rig_debug(RIG_DEBUG_ERR, "dx77_get_rit: wrong answer %s, len=%d\n", ritbuf, rit_len); return -RIG_ERJCTED; } ritbuf[rit_len] = '\0'; ritbuf[0] = ' '; ritbuf[1] = ' '; ritbuf[2] = ' '; *rit = atoi(ritbuf); return RIG_OK; } /* * dx77_set_func * Assumes rig!=NULL */ int dx77_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_TONE: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_CTCSS "%02d" EOM, status ? 51 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_FAGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_AGC "%02d" EOM, status ? 1 : 2); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_NB: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_NB "%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_COMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "C%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_MON: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_MON "%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_get_func * Assumes rig!=NULL, status!=NULL */ int dx77_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int settings; char funcbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_TONE: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x08) ? 1 : 0; break; case RIG_FUNC_FAGC: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x01) ? 1 : 0; break; case RIG_FUNC_NB: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x04) ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int dx77_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int lvl; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_PREAMP: switch (val.i) { case 0: lvl = 0; break; case 10: lvl = 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported Preamp %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_RFGAIN "%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_ATT: switch (val.i) { case 0: lvl = 0; break; case 10: lvl = 11; break; case 20: lvl = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported Att %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_RFGAIN "%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_PWR "%1d" EOM, val.f < 0.5 ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_KEYSPD: if (val.i < 6) { lvl = 31; } else if (val.i < 20) { lvl = val.i + 25; } else if (val.i <= 50) { lvl = val.i - 20; } else { lvl = 30; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "P%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_CWPITCH: lvl = 4; if (val.i < 426) { lvl = 5; } else if (val.i >= 426 && val.i <= 475) { lvl = 6; } else if (val.i >= 476 && val.i <= 525) { lvl = 7; } else if (val.i >= 526 && val.i <= 575) { lvl = 8; } else if (val.i >= 576 && val.i <= 625) { lvl = 9; } else if (val.i >= 626 && val.i <= 675) { lvl = 10; } else if (val.i >= 676 && val.i <= 725) { lvl = 11; } else if (val.i >= 726 && val.i <= 775) { lvl = 12; } else if (val.i >= 776 && val.i <= 825) { lvl = 0; } else if (val.i >= 826 && val.i <= 875) { lvl = 1; } else if (val.i >= 876 && val.i <= 925) { lvl = 2; } else if (val.i >= 926 && val.i <= 975) { lvl = 3; } else if (val.i >= 976 && val.i <= 1025) { lvl = 4; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "M%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_get_level * Assumes rig!=NULL, val!=NULL */ int dx77_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char lvlbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ retval = dx77_transaction(rig, AL CMD_SMETER "1" EOM, strlen(AL CMD_SMETER "1" EOM), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "dx77_get_level: wrong answer len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[6] = '\0'; val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_PREAMP: retval = current_data_read(rig, lvlbuf); if (retval != RIG_OK) { return retval; } switch (lvlbuf[5]) { case '2': case '3': case '0': val->i = 0; break; case '1': val->i = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n", lvlbuf[4], lvlbuf[5]); } break; case RIG_LEVEL_ATT: retval = current_data_read(rig, lvlbuf); if (retval != RIG_OK) { return retval; } switch (lvlbuf[5]) { case '1': case '0': val->i = 0; break; case '2': val->i = 20; break; case '3': val->i = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n", lvlbuf[4], lvlbuf[5]); } break; case RIG_LEVEL_RFPOWER: retval = dx77_transaction(rig, AL CMD_RPOWER EOM, strlen(AL CMD_RPOWER EOM), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 1) { rig_debug(RIG_DEBUG_ERR, "dx77_get_level: wrong answer len=%d\n", lvl_len); return -RIG_ERJCTED; } /* H or L */ val->f = lvlbuf[0] == 'H' ? 1.0 : 0.0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_parm */ int dx77_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_BEEP: rig_debug(RIG_DEBUG_ERR, "val is %d\n", val.i); SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "A%d" EOM, val.i ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_BACKLIGHT: rig_debug(RIG_DEBUG_ERR, "val is %0f\n", val.f); SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "O%d" EOM, (int)(val.f * 5)); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %d\n", (int)parm); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_ctcss_tone * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int dx77_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; unsigned char tonebuf[BUFSZ]; int i; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } SNPRINTF((char *) tonebuf, sizeof(tonebuf), AL CMD_CTCSS "%02d" EOM, i + 1); return dx77_transaction(rig, (char *) tonebuf, strlen((char *)tonebuf), NULL, NULL); } /* * dx77_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int dx77_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[BUFSZ]; int ptt_len, retval; retval = dx77_transaction(rig, AL CMD_PTT EOM, strlen(AL CMD_PTT EOM), pttbuf, &ptt_len); if (retval != RIG_OK) { return retval; } if (ptt_len != 3 && ptt_len != 4) { rig_debug(RIG_DEBUG_ERR, "dx77_get_ptt: wrong answer %s, len=%d\n", pttbuf, ptt_len); return -RIG_ERJCTED; } pttbuf[ptt_len] = '\0'; if (!strcmp(pttbuf, "SEND")) { *ptt = RIG_PTT_OFF; } else if (!strcmp(pttbuf, "REV")) { *ptt = RIG_PTT_ON; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_ptt: unknown PTT %s\n", pttbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_get_dcd * Assumes rig!=NULL, dcd!=NULL */ int dx77_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int dcd_len, retval; retval = dx77_transaction(rig, AL CMD_SQL EOM, strlen(AL CMD_SQL EOM), dcdbuf, &dcd_len); if (retval != RIG_OK) { return retval; } if (dcd_len != 4 && dcd_len != 5) { rig_debug(RIG_DEBUG_ERR, "dx77_get_dcd: wrong answer %s, len=%d\n", dcdbuf, dcd_len); return -RIG_ERJCTED; } dcdbuf[dcd_len] = '\0'; if (!strcmp(dcdbuf, "OPEN")) { *dcd = RIG_DCD_ON; } else if (!strcmp(dcdbuf, "CLOSE")) { *dcd = RIG_DCD_OFF; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_dcd: unknown SQL %s\n", dcdbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_mem * Assumes rig!=NULL * FIXME: check we're in memory mode first */ int dx77_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; if (ch < 0 || ch > 99) { return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_MCALL "%02d" EOM, ch); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_mem * Assumes rig!=NULL, !vfo */ int dx77_get_mem(RIG *rig, vfo_t vfo, int *ch) { char membuf[BUFSZ]; int mem_len, retval; retval = dx77_transaction(rig, AL CMD_RMEM EOM, strlen(AL CMD_RMEM EOM), membuf, &mem_len); if (retval != RIG_OK) { return retval; } if (mem_len != 2) { rig_debug(RIG_DEBUG_ERR, "dx77_get_mem: wrong answer %s, len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } membuf[mem_len] = '\0'; *ch = atoi(membuf); if (*ch < 0 || *ch > 99) { rig_debug(RIG_DEBUG_ERR, "dx77_get_mem: unknown mem %s\n", membuf); return -RIG_EPROTO; } return RIG_OK; } hamlib-4.6.5/rigs/alinco/alinco.c0000664000175000017500000000217315056640443012301 /* * Hamlib Alinco backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "alinco.h" /* * initrigs_alinco is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(alinco) { rig_register(&dx77_caps); rig_register(&dxsr8_caps); return RIG_OK; } /* * Function definitions below */ hamlib-4.6.5/rigs/alinco/Android.mk0000664000175000017500000000041115056640442012571 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dx77.c alinco.c dxsr8.c LOCAL_MODULE := alinco LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/alinco/Makefile.in0000664000175000017500000005320215056640452012734 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/alinco ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_alinco_la_LIBADD = am__objects_1 = dx77.lo dxsr8.lo alinco.lo am_libhamlib_alinco_la_OBJECTS = $(am__objects_1) libhamlib_alinco_la_OBJECTS = $(am_libhamlib_alinco_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/alinco.Plo ./$(DEPDIR)/dx77.Plo \ ./$(DEPDIR)/dxsr8.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_alinco_la_SOURCES) DIST_SOURCES = $(libhamlib_alinco_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ALINCOSRC = dx77.c dxsr8.c alinco.c alinco.h noinst_LTLIBRARIES = libhamlib-alinco.la libhamlib_alinco_la_SOURCES = $(ALINCOSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/alinco/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/alinco/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-alinco.la: $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_DEPENDENCIES) $(EXTRA_libhamlib_alinco_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alinco.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dx77.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dxsr8.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/alinco.Plo -rm -f ./$(DEPDIR)/dx77.Plo -rm -f ./$(DEPDIR)/dxsr8.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/alinco.Plo -rm -f ./$(DEPDIR)/dx77.Plo -rm -f ./$(DEPDIR)/dxsr8.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/alinco/alinco.h0000664000175000017500000000210415056640443012300 /* * Hamlib Alinco backend - main header * Copyright (c) 2001-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ALINCO_H #define _ALINCO_H 1 #include #define BACKEND_VER "20200323" extern struct rig_caps dx77_caps; extern struct rig_caps dxsr8_caps; #define BUFSZ 32 #define AL "AL" #endif /* _ALINCO_H */ hamlib-4.6.5/rigs/alinco/dxsr8.c0000664000175000017500000005063315056640443012110 /* * Hamlib Alinco backend - DXSR8 description * Copyright (c) 2020 by Wes Bustraan (W8WJB) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include "tones.h" #include #include #include #include "idx_builtin.h" #include "alinco.h" #define DXSR8_ALL_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_AM|RIG_MODE_FM) #define DXSR8_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DXSR8_AM_TX_MODES RIG_MODE_AM #define DXSR8_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB) #define DXSR8_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_RF) #define DXSR8_PARM_ALL RIG_PARM_NONE #define DXSR8_VFO RIG_VFO_A /* Line Feed */ #define EOM "\r\n" #define LF "\n" #define MD_USB 0 #define MD_LSB 1 #define MD_CWU 2 #define MD_CWL 3 #define MD_AM 4 #define MD_FM 5 int dxsr8_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int dxsr8_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int dxsr8_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int dxsr8_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int dxsr8_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int dxsr8_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int dxsr8_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int dxsr8_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int dxsr8_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int dxsr8_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); /* * DX-SR8 rig capabilities. * * thanks to * https://yo5ptd.wordpress.com/2017/02/12/alinco-dx-sr8/ * for a partially documented protocol */ struct rig_caps dxsr8_caps = { RIG_MODEL(RIG_MODEL_DXSR8), .model_name = "DX-SR8", .mfg_name = "Alinco", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .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 = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DXSR8_FUNC, .has_set_func = DXSR8_FUNC, .has_get_level = DXSR8_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DXSR8_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = kHz(1.5), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM }, { 0, 199, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(135), MHz(30), DXSR8_ALL_MODES, -1, -1, DXSR8_VFO, 0, "DX-SR8T"}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1800), MHz(2) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(1800), MHz(2) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(3500), MHz(4) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(3500), MHz(4) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {5330500, 5330500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5346500, 5346500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5366500, 5366500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5371500, 5371500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5403500, 5403500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(7), kHz(7300), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(7), kHz(7300), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(10100), kHz(10150), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(10100), kHz(10150), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(14), kHz(14350), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(14), kHz(14350), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(18068), kHz(18168), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(18068), kHz(18168), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(21), kHz(21450), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(21), kHz(21450), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(24890), kHz(24990), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(24890), kHz(24990), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(28), kHz(29700), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(28), kHz(29700), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(135), MHz(30), DXSR8_ALL_MODES, -1, -1, DXSR8_VFO, 0, "DX-SR8E"}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(1800), MHz(2) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(3500), MHz(4) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(3500), MHz(4) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(6900), kHz(7500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(6900), kHz(7500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(9900), kHz(10500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(9900), kHz(10500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(13900), kHz(14500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(13900), kHz(14500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(17900), kHz(18500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(17900), kHz(18500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(20900), kHz(21500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(20900), kHz(21500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(24400), kHz(25099), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(24400), kHz(25099), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {MHz(28), MHz(30), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {MHz(28), MHz(30), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, RIG_FRNG_END, }, .tuning_steps = { {DXSR8_ALL_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(9)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .set_freq = dxsr8_set_freq, // AL~RW_RXF14212000 .get_freq = dxsr8_get_freq, // AL~RR_RXF .set_mode = dxsr8_set_mode, // AL~RW_RFM00, AL~RW_NAR00 .get_mode = dxsr8_get_mode, // AL~RR_RFM, AL~RR_NAR .get_ptt = dxsr8_get_ptt, // AL~RR_PTT .set_ptt = dxsr8_set_ptt, // AL~RW_PTT00 .set_func = dxsr8_set_func, // AL~RW_AGC00, AL~RW_NZB00 .get_func = dxsr8_get_func, // AL~RR_AGC, AL~RR_NZB .set_level = dxsr8_set_level, // AL~RW_RFG00, AL~RW_PWR00 .get_level = dxsr8_get_level, // AL~RR_RFG, AL~RR_PWR .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * dxsr8_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int dxsr8_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char replybuf[BUFSZ + 1]; int reply_len; if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: null argument for cmd?\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF * TODO: check whether cmd and echobuf match (optional) */ retval = read_string(rp, (unsigned char *) replybuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } retval = read_string(rp, (unsigned char *) replybuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } /* no data expected, check for OK returned */ if (data == NULL) { if (retval > 2) { retval -= 2; } replybuf[retval] = 0; if (strcmp(replybuf, "OK") == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } // strip CR/LF from string reply_len = strcspn(replybuf, "\r\n"); replybuf[reply_len] = 0; strcpy(data, replybuf); *data_len = reply_len; return RIG_OK; } /** * dxsr8_read_num * Convenience function to read a numeric value from the radio */ int dxsr8_read_num(RIG *rig, const char *cmd, int *reply_num) { int retval; int reply_len; char replybuf[10]; retval = dxsr8_transaction(rig, cmd, strlen(cmd), replybuf, &reply_len); if (retval != RIG_OK) { return retval; } *reply_num = atoi(replybuf); return RIG_OK; } /* * dxsr8_set_freq * Assumes rig!=NULL */ int dxsr8_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd[BUFSZ]; /* max 10 digits */ if (freq >= GHz(10)) { return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RXF%08"PRIll EOM, (int64_t)freq); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); } /* * dxsr8_get_freq * Assumes rig!=NULL, freq!=NULL */ int dxsr8_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval, data_len; const char cmd[] = AL "~RR_RXF" EOM; char freqbuf[BUFSZ]; retval = dxsr8_transaction(rig, cmd, strlen(cmd), freqbuf, &data_len); if (retval != RIG_OK) { return retval; } /* extract RX freq */ num_sscanf(freqbuf, "%"SCNfreq, freq); return RIG_OK; } /* * dxsr8_set_mode * Assumes rig!=NULL */ int dxsr8_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int wide_filter, retval; int amode; switch (mode) { case RIG_MODE_CW: amode = MD_CWU; break; case RIG_MODE_CWR: amode = MD_CWL; break; case RIG_MODE_USB: amode = MD_USB; break; case RIG_MODE_LSB: amode = MD_LSB; break; case RIG_MODE_FM: amode = MD_FM; break; case RIG_MODE_AM: amode = MD_AM; break; default: rig_debug(RIG_DEBUG_ERR, "dxsr8_set_mode: unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), AL "~RW_RFM%02d" EOM, amode); retval = dxsr8_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { wide_filter = 1; // AL~RW_NAR01 Set narrow bandwidth } else { wide_filter = 0; // AL~RW_NAR00 Set wide bandwidth } SNPRINTF(mdbuf, sizeof(mdbuf), AL "~RW_NAR%02d" EOM, wide_filter); retval = dxsr8_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * dxsr8_get_mode * Assumes rig!=NULL, mode!=NULL */ int dxsr8_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int amode; int filter; retval = dxsr8_read_num(rig, AL "~RR_RFM" EOM, &amode); if (retval != RIG_OK) { return retval; } switch (amode) { case MD_CWL: case MD_CWU: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "dxsr8_get_mode: unknown mode %02d\n", amode); return -RIG_EINVAL; } filter = 0; // avoid compiler warnings of being possibly uninitialized retval = dxsr8_read_num(rig, AL "~RR_NAR" EOM, &filter); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: dxsr8_read_num:%s\n", __func__, rigerror(retval)); return retval; } if (filter == 0) { *width = rig_passband_wide(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * dxsr8_set_func * Assumes rig!=NULL */ int dxsr8_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmd[BUFSZ]; switch (func) { case RIG_FUNC_FAGC: SNPRINTF(cmd, sizeof(cmd), AL "~RW_AGC%02d" EOM, status ? 0 : 1); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_FUNC_NB: SNPRINTF(cmd, sizeof(cmd), AL "~RW_NZB%d" EOM, status ? 1 : 0); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_func * Assumes rig!=NULL, status!=NULL */ int dxsr8_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int setting; switch (func) { case RIG_FUNC_FAGC: retval = dxsr8_read_num(rig, AL "~RR_AGC" EOM, &setting); if (retval != RIG_OK) { return retval; } // 00 = Fast AGC // 01 = Slow AGC *status = setting ? 0 : 1; break; case RIG_FUNC_NB: retval = dxsr8_read_num(rig, AL "~RR_NZB" EOM, &setting); if (retval != RIG_OK) { return retval; } // 00 = noise blanker off // 01 = noise blanker on *status = setting ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int dxsr8_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int lvl; char cmd[BUFSZ]; switch (level) { case RIG_LEVEL_PREAMP: switch (val.i) { case 0: lvl = 0; break; // AL~RW_RFG00 - RF gain 0dB case 10: lvl = 3; break; // AL~RW_RFG03 - RF gain +10dB default: rig_debug(RIG_DEBUG_ERR, "Unsupported Preamp %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RFG%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_LEVEL_ATT: switch (val.i) { case 0: lvl = 0; break; // AL~RW_RFG00 - RF gain 0dB case 10: lvl = 1; break; // AL~RW_RFG01 - RF gain -10dB case 20: lvl = 2; break; // AL~RW_RFG02 - RF gain -20dB default: rig_debug(RIG_DEBUG_ERR, "Unsupported Att %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RFG%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvl = 2; // AL~RW_PWR02 - Sub low power (QRP mode) } else if (val.f <= 0.1) { lvl = 1; // AL~RW_PWR01 - Low power } else { lvl = 0; // AL~RW_PWR00 - High power } SNPRINTF(cmd, sizeof(cmd), AL "~RW_PWR%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_level * Assumes rig!=NULL, val!=NULL */ int dxsr8_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; int lvl; switch (level) { case RIG_LEVEL_PREAMP: retval = dxsr8_read_num(rig, AL "~RR_RFG" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: val->i = 0; break; // RF gain 0dB case 3: val->i = 10; break; // RF gain +10dB default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %02d\n", lvl); } break; case RIG_LEVEL_ATT: retval = dxsr8_read_num(rig, AL "~RR_RFG" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: val->i = 0; break; // RF gain 0dB case 1: val->i = 10; break; // RF gain -10dB case 2: val->i = 10; break; // RF gain -20dB default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %02d\n", lvl); } break; case RIG_LEVEL_RFPOWER: retval = dxsr8_read_num(rig, AL "~RR_PWR" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: // 00 - High power val->f = 1.0; // 100 W break; case 1: // 01 - Low power val->f = 0.1; // 10 W break; case 3: // 02 - Sub low power (QRP mode) val->f = 0.01; // 1 W break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Power %02d\n", lvl); break; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int dxsr8_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; int pttval; retval = dxsr8_read_num(rig, AL "~RR_PTT" EOM, &pttval); if (retval != RIG_OK) { return retval; } *ptt = pttval ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * dxsr8_set_ptt * Assumes rig!=NULL */ int dxsr8_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmd[BUFSZ]; SNPRINTF(cmd, sizeof(cmd), AL "~RW_PTT%02d" EOM, ptt); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); } hamlib-4.6.5/rigs/alinco/Makefile.am0000664000175000017500000000023315056640442012716 ALINCOSRC = dx77.c dxsr8.c alinco.c alinco.h noinst_LTLIBRARIES = libhamlib-alinco.la libhamlib_alinco_la_SOURCES = $(ALINCOSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/tuner/0000775000175000017500000000000015056640500010627 5hamlib-4.6.5/rigs/tuner/videodev2.h0000664000175000017500000017753715056640443012641 /* * Video for Linux Two header file * * Copyright (C) 1999-2007 the contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * Alternatively you can redistribute this file under the terms of the * BSD license as stated below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Header file for v4l or V4L2 drivers and applications * with public API. * All kernel-specific stuff were moved to media/v4l2-dev.h, so * no #if __KERNEL tests are allowed here * * See http://linuxtv.org for more info * * Author: Bill Dirks * Justin Schoeman * Hans Verkuil * et al. */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H #include #include #include /* * Common stuff for both V4L1 and V4L2 * Moved from videodev.h */ #define VIDEO_MAX_FRAME 32 /* These defines are V4L1 specific and should not be used with the V4L2 API! They will be removed from this header in the future. */ #define VID_TYPE_CAPTURE 1 /* Can capture */ #define VID_TYPE_TUNER 2 /* Can tune */ #define VID_TYPE_TELETEXT 4 /* Does teletext */ #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ #define VID_TYPE_CLIPPING 32 /* Can clip */ #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ /* * M I S C E L L A N E O U S */ /* Four-character-code (FOURCC) */ #define v4l2_fourcc(a, b, c, d)\ ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) /* * E N U M S */ enum v4l2_field { V4L2_FIELD_ANY = 0, /* driver can choose from none, top, bottom, interlaced depending on whatever it thinks is approximate ... */ V4L2_FIELD_NONE = 1, /* this device has no fields ... */ V4L2_FIELD_TOP = 2, /* top field only */ V4L2_FIELD_BOTTOM = 3, /* bottom field only */ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one buffer, top-bottom order */ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into separate buffers */ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field first and the top field is transmitted first */ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field first and the bottom field is transmitted first */ }; #define V4L2_FIELD_HAS_TOP(field) \ ((field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTTOM(field) \ ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTH(field) \ ((field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, #if 1 /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, }; enum v4l2_tuner_type { V4L2_TUNER_RADIO = 1, V4L2_TUNER_ANALOG_TV = 2, V4L2_TUNER_DIGITAL_TV = 3, }; enum v4l2_memory { V4L2_MEMORY_MMAP = 1, V4L2_MEMORY_USERPTR = 2, V4L2_MEMORY_OVERLAY = 3, }; /* see also http://vektor.theorem.ca/graphics/ycbcr/ */ enum v4l2_colorspace { /* ITU-R 601 -- broadcast NTSC/PAL */ V4L2_COLORSPACE_SMPTE170M = 1, /* 1125-Line (US) HDTV */ V4L2_COLORSPACE_SMPTE240M = 2, /* HD and modern captures. */ V4L2_COLORSPACE_REC709 = 3, /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ V4L2_COLORSPACE_BT878 = 4, /* These should be useful. Assume 601 extents. */ V4L2_COLORSPACE_470_SYSTEM_M = 5, V4L2_COLORSPACE_470_SYSTEM_BG = 6, /* I know there will be cameras that send this. So, this is * unspecified chromaticities and full 0-255 on each of the * Y'CbCr components */ V4L2_COLORSPACE_JPEG = 7, /* For RGB colourspaces, this is probably a good start. */ V4L2_COLORSPACE_SRGB = 8, }; enum v4l2_priority { V4L2_PRIORITY_UNSET = 0, /* not initialized */ V4L2_PRIORITY_BACKGROUND = 1, V4L2_PRIORITY_INTERACTIVE = 2, V4L2_PRIORITY_RECORD = 3, V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, }; struct v4l2_rect { __s32 left; __s32 top; __s32 width; __s32 height; }; struct v4l2_fract { __u32 numerator; __u32 denominator; }; /* * D R I V E R C A P A B I L I T I E S */ struct v4l2_capability { __u8 driver[16]; /* i.e. "bttv" */ __u8 card[32]; /* i.e. "Hauppauge WinTV" */ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ __u32 version; /* should use KERNEL_VERSION() */ __u32 capabilities; /* Device capabilities */ __u32 reserved[4]; }; /* Values for 'capabilities' field */ #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ #define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ #define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ #define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ #define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ /* * V I D E O I M A G E F O R M A T */ struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; enum v4l2_field field; __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; /* private data, depends on pixelformat */ }; /* Pixel format FOURCC depth Description */ /* RGB formats */ #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ #define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ #define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ /* Grey formats */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ /* Luminance+Chrominance formats */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ #define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ /* 10bit raw bayer DPCM compressed to 8 bits */ #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') /* * 10bit raw bayer, expanded to 16 bits * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... */ #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ #define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ #define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ #define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ #define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ /* * F O R M A T E N U M E R A T I O N */ struct v4l2_fmtdesc { __u32 index; /* Format number */ enum v4l2_buf_type type; /* buffer type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ __u32 reserved[4]; }; #define V4L2_FMT_FLAG_COMPRESSED 0x0001 #define V4L2_FMT_FLAG_EMULATED 0x0002 #if 1 /* Experimental Frame Size and frame rate enumeration */ /* * F R A M E S I Z E E N U M E R A T I O N */ enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; /* * F R A M E R A T E E N U M E R A T I O N */ enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; #endif /* * T I M E C O D E */ struct v4l2_timecode { __u32 type; __u32 flags; __u8 frames; __u8 seconds; __u8 minutes; __u8 hours; __u8 userbits[4]; }; /* Type */ #define V4L2_TC_TYPE_24FPS 1 #define V4L2_TC_TYPE_25FPS 2 #define V4L2_TC_TYPE_30FPS 3 #define V4L2_TC_TYPE_50FPS 4 #define V4L2_TC_TYPE_60FPS 5 /* Flags */ #define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ #define V4L2_TC_FLAG_COLORFRAME 0x0002 #define V4L2_TC_USERBITS_field 0x000C #define V4L2_TC_USERBITS_USERDEFINED 0x0000 #define V4L2_TC_USERBITS_8BITCHARS 0x0008 /* The above is based on SMPTE timecodes */ struct v4l2_jpegcompression { int quality; int APPn; /* Number of APP segment to be written, * must be 0..15 */ int APP_len; /* Length of data in JPEG APPn segment */ char APP_data[60]; /* Data in the JPEG APPn segment. */ int COM_len; /* Length of data in JPEG COM segment */ char COM_data[60]; /* Data in JPEG COM segment */ __u32 jpeg_markers; /* Which markers should go into the JPEG * output. Unless you exactly know what * you do, leave them untouched. * Including less markers will make the * resulting code smaller, but there will * be fewer applications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ #define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ #define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ #define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ #define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ #define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will * always use APP0 */ }; /* * M E M O R Y - M A P P I N G B U F F E R S */ struct v4l2_requestbuffers { __u32 count; enum v4l2_buf_type type; enum v4l2_memory memory; __u32 reserved[2]; }; struct v4l2_buffer { __u32 index; enum v4l2_buf_type type; __u32 bytesused; __u32 flags; enum v4l2_field field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ enum v4l2_memory memory; union { __u32 offset; unsigned long userptr; } m; __u32 length; __u32 input; __u32 reserved; }; /* Flags for 'flags' field */ #define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ #define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ #define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ #define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ #define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ #define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ /* Buffer is ready, but the data contained within is corrupted. */ #define V4L2_BUF_FLAG_ERROR 0x0040 #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ #define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ /* * O V E R L A Y P R E V I E W */ struct v4l2_framebuffer { __u32 capability; __u32 flags; /* FIXME: in theory we should pass something like PCI device + memory * region + offset instead of some physical address */ void *base; struct v4l2_pix_format fmt; }; /* Flags for the 'capability' field. Read only */ #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 #define V4L2_FBUF_CAP_LOCAL_BETA 0x0010 #define V4L2_FBUF_CAP_GLOBAL_BETA 0x0020 #define V4L2_FBUF_CAP_LOCAL_INV_BETA 0x0040 #define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 /* Flags for the 'flags' field. */ #define V4L2_FBUF_FLAG_PRIMARY 0x0001 #define V4L2_FBUF_FLAG_OVERLAY 0x0002 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 #define V4L2_FBUF_FLAG_LOCAL_BETA 0x0008 #define V4L2_FBUF_FLAG_GLOBAL_BETA 0x0010 #define V4L2_FBUF_FLAG_LOCAL_INV_BETA 0x0020 #define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 struct v4l2_clip { struct v4l2_rect c; struct v4l2_clip *next; }; struct v4l2_window { struct v4l2_rect w; enum v4l2_field field; __u32 chromakey; struct v4l2_clip *clips; __u32 clipcount; void *bitmap; __u8 global_alpha; }; /* * C A P T U R E P A R A M E T E R S */ struct v4l2_captureparm { __u32 capability; /* Supported modes */ __u32 capturemode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in .1us units */ __u32 extendedmode; /* Driver-specific extensions */ __u32 readbuffers; /* # of buffers for read */ __u32 reserved[4]; }; /* Flags for 'capability' and 'capturemode' fields */ #define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ #define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ struct v4l2_outputparm { __u32 capability; /* Supported modes */ __u32 outputmode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in seconds */ __u32 extendedmode; /* Driver-specific extensions */ __u32 writebuffers; /* # of buffers for write */ __u32 reserved[4]; }; /* * I N P U T I M A G E C R O P P I N G */ struct v4l2_cropcap { enum v4l2_buf_type type; struct v4l2_rect bounds; struct v4l2_rect defrect; struct v4l2_fract pixelaspect; }; struct v4l2_crop { enum v4l2_buf_type type; struct v4l2_rect c; }; /* * A N A L O G V I D E O S T A N D A R D */ typedef __u64 v4l2_std_id; /* one bit for each */ #define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) #define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) #define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) #define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) #define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) #define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) #define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) #define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) #define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) #define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) #define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) #define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) #define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) #define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) #define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) #define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) #define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) #define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) #define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) /* ATSC/HDTV */ #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) /* FIXME: Although std_id is 64 bits, there is an issue on PPC32 architecture that makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding this value to 32 bits. As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), it should work fine. However, if needed to add more than two standards, v4l2-common.c should be fixed. */ /* some merged standards */ #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) #define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) #define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) /* some common needed stuff */ #define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ V4L2_STD_PAL_B1 |\ V4L2_STD_PAL_G) #define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ V4L2_STD_PAL_D1 |\ V4L2_STD_PAL_K) #define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ V4L2_STD_PAL_DK |\ V4L2_STD_PAL_H |\ V4L2_STD_PAL_I) #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ V4L2_STD_NTSC_M_JP |\ V4L2_STD_NTSC_M_KR) #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) #define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ V4L2_STD_SECAM_G |\ V4L2_STD_SECAM_H |\ V4L2_STD_SECAM_DK |\ V4L2_STD_SECAM_L |\ V4L2_STD_SECAM_LC) #define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ V4L2_STD_PAL_60 |\ V4L2_STD_NTSC |\ V4L2_STD_NTSC_443) #define V4L2_STD_625_50 (V4L2_STD_PAL |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc |\ V4L2_STD_SECAM) #define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ V4L2_STD_ATSC_16_VSB) #define V4L2_STD_UNKNOWN 0 #define V4L2_STD_ALL (V4L2_STD_525_60 |\ V4L2_STD_625_50) struct v4l2_standard { __u32 index; v4l2_std_id id; __u8 name[24]; struct v4l2_fract frameperiod; /* Frames, not fields */ __u32 framelines; __u32 reserved[4]; }; /* * V I D E O T I M I N G S D V P R E S E T */ struct v4l2_dv_preset { __u32 preset; __u32 reserved[4]; }; /* * D V P R E S E T S E N U M E R A T I O N */ struct v4l2_dv_enum_preset { __u32 index; __u32 preset; __u8 name[32]; /* Name of the preset timing */ __u32 width; __u32 height; __u32 reserved[4]; }; /* * D V P R E S E T V A L U E S */ #define V4L2_DV_INVALID 0 #define V4L2_DV_480P59_94 1 /* BT.1362 */ #define V4L2_DV_576P50 2 /* BT.1362 */ #define V4L2_DV_720P24 3 /* SMPTE 296M */ #define V4L2_DV_720P25 4 /* SMPTE 296M */ #define V4L2_DV_720P30 5 /* SMPTE 296M */ #define V4L2_DV_720P50 6 /* SMPTE 296M */ #define V4L2_DV_720P59_94 7 /* SMPTE 274M */ #define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ #define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ #define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ #define V4L2_DV_1080I25 11 /* BT.1120 */ #define V4L2_DV_1080I50 12 /* SMPTE 296M */ #define V4L2_DV_1080I60 13 /* SMPTE 296M */ #define V4L2_DV_1080P24 14 /* SMPTE 296M */ #define V4L2_DV_1080P25 15 /* SMPTE 296M */ #define V4L2_DV_1080P30 16 /* SMPTE 296M */ #define V4L2_DV_1080P50 17 /* BT.1120 */ #define V4L2_DV_1080P60 18 /* BT.1120 */ /* * D V B T T I M I N G S */ /* BT.656/BT.1120 timing data */ struct v4l2_bt_timings { __u32 width; /* width in pixels */ __u32 height; /* height in lines */ __u32 interlaced; /* Interlaced or progressive */ __u32 polarities; /* Positive or negative polarity */ __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ __u32 hfrontporch; /* Horizpontal front porch in pixels */ __u32 hsync; /* Horizontal Sync length in pixels */ __u32 hbackporch; /* Horizontal back porch in pixels */ __u32 vfrontporch; /* Vertical front porch in pixels */ __u32 vsync; /* Vertical Sync length in lines */ __u32 vbackporch; /* Vertical back porch in lines */ __u32 il_vfrontporch; /* Vertical front porch for bottom field of * interlaced field formats */ __u32 il_vsync; /* Vertical sync length for bottom field of * interlaced field formats */ __u32 il_vbackporch; /* Vertical back porch for bottom field of * interlaced field formats */ __u32 reserved[16]; } __attribute__ ((packed)); /* Interlaced or progressive format */ #define V4L2_DV_PROGRESSIVE 0 #define V4L2_DV_INTERLACED 1 /* Polarities. If bit is not set, it is assumed to be negative polarity */ #define V4L2_DV_VSYNC_POS_POL 0x00000001 #define V4L2_DV_HSYNC_POS_POL 0x00000002 /* DV timings */ struct v4l2_dv_timings { __u32 type; union { struct v4l2_bt_timings bt; __u32 reserved[32]; }; } __attribute__ ((packed)); /* Values for the type field */ #define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ /* * V I D E O I N P U T S */ struct v4l2_input { __u32 index; /* Which input */ __u8 name[32]; /* Label */ __u32 type; /* Type of input */ __u32 audioset; /* Associated audios (bitfield) */ __u32 tuner; /* Associated tuner */ v4l2_std_id std; __u32 status; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ #define V4L2_IN_ST_NO_SIGNAL 0x00000002 #define V4L2_IN_ST_NO_COLOR 0x00000004 /* field 'status' - sensor orientation */ /* If sensor is mounted upside down set both bits */ #define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ #define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ #define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ #define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ /* field 'status' - VCR and set-top box */ #define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ /* capabilities flags */ #define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ #define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ /* * V I D E O O U T P U T S */ struct v4l2_output { __u32 index; /* Which output */ __u8 name[32]; /* Label */ __u32 type; /* Type of output */ __u32 audioset; /* Associated audios (bitfield) */ __u32 modulator; /* Associated modulator */ v4l2_std_id std; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_OUTPUT_TYPE_MODULATOR 1 #define V4L2_OUTPUT_TYPE_ANALOG 2 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 /* capabilities flags */ #define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ #define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ /* * C O N T R O L S */ struct v4l2_control { __u32 id; __s32 value; }; struct v4l2_ext_control { __u32 id; __u32 size; __u32 reserved2[1]; union { __s32 value; __s64 value64; char *string; }; } __attribute__ ((packed)); struct v4l2_ext_controls { __u32 ctrl_class; __u32 count; __u32 error_idx; __u32 reserved[2]; struct v4l2_ext_control *controls; }; /* Values for ctrl_class field */ #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ #define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ #define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ #define V4L2_CTRL_ID_MASK (0x0fffffff) #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, V4L2_CTRL_TYPE_BOOLEAN = 2, V4L2_CTRL_TYPE_MENU = 3, V4L2_CTRL_TYPE_BUTTON = 4, V4L2_CTRL_TYPE_INTEGER64 = 5, V4L2_CTRL_TYPE_CTRL_CLASS = 6, V4L2_CTRL_TYPE_STRING = 7, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ struct v4l2_queryctrl { __u32 id; enum v4l2_ctrl_type type; __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; __s32 step; __s32 default_value; __u32 flags; __u32 reserved[2]; }; /* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ struct v4l2_querymenu { __u32 id; __u32 index; __u8 name[32]; /* Whatever */ __u32 reserved; }; /* Control flags */ #define V4L2_CTRL_FLAG_DISABLED 0x0001 #define V4L2_CTRL_FLAG_GRABBED 0x0002 #define V4L2_CTRL_FLAG_READ_ONLY 0x0004 #define V4L2_CTRL_FLAG_UPDATE 0x0008 #define V4L2_CTRL_FLAG_INACTIVE 0x0010 #define V4L2_CTRL_FLAG_SLIDER 0x0020 #define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 /* Query flag, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 /* User-class control IDs defined by V4L2 */ #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) #define V4L2_CID_USER_BASE V4L2_CID_BASE /* IDs reserved for driver specific controls */ #define V4L2_CID_PRIVATE_BASE 0x08000000 #define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) #define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) #define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) #define V4L2_CID_SATURATION (V4L2_CID_BASE+2) #define V4L2_CID_HUE (V4L2_CID_BASE+3) #define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) #define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) #define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) #define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) #define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) #define V4L2_CID_GAMMA (V4L2_CID_BASE+16) #define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ #define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) #define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) #define V4L2_CID_GAIN (V4L2_CID_BASE+19) #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) /* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ #define V4L2_CID_HCENTER (V4L2_CID_BASE+22) #define V4L2_CID_VCENTER (V4L2_CID_BASE+23) #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) enum v4l2_power_line_frequency { V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, }; #define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) #define V4L2_CID_COLORFX (V4L2_CID_BASE+31) enum v4l2_colorfx { V4L2_COLORFX_NONE = 0, V4L2_COLORFX_BW = 1, V4L2_COLORFX_SEPIA = 2, V4L2_COLORFX_NEGATIVE = 3, V4L2_COLORFX_EMBOSS = 4, V4L2_COLORFX_SKETCH = 5, V4L2_COLORFX_SKY_BLUE = 6, V4L2_COLORFX_GRASS_GREEN = 7, V4L2_COLORFX_SKIN_WHITEN = 8, V4L2_COLORFX_VIVID = 9, }; #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) #define V4L2_CID_ROTATE (V4L2_CID_BASE+34) #define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) /* last CID + 1 */ #define V4L2_CID_LASTP1 (V4L2_CID_BASE+37) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) /* MPEG streams */ #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) enum v4l2_mpeg_stream_type { V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ }; #define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) #define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) #define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) #define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) #define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) #define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) #define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) enum v4l2_mpeg_stream_vbi_fmt { V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ }; /* MPEG audio */ #define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) enum v4l2_mpeg_audio_sampling_freq { V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, }; #define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, V4L2_MPEG_AUDIO_ENCODING_AAC = 3, V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, }; #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, }; #define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) enum v4l2_mpeg_audio_l2_bitrate { V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, }; #define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) enum v4l2_mpeg_audio_l3_bitrate { V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, }; #define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) enum v4l2_mpeg_audio_mode { V4L2_MPEG_AUDIO_MODE_STEREO = 0, V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, V4L2_MPEG_AUDIO_MODE_DUAL = 2, V4L2_MPEG_AUDIO_MODE_MONO = 3, }; #define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) enum v4l2_mpeg_audio_mode_extension { V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, }; #define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) enum v4l2_mpeg_audio_emphasis { V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, }; #define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_NONE = 0, V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) enum v4l2_mpeg_audio_ac3_bitrate { V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, }; /* MPEG video */ #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) enum v4l2_mpeg_video_encoding { V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, }; #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) enum v4l2_mpeg_video_aspect { V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, }; #define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) #define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) #define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) #define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) #define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) enum v4l2_mpeg_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, }; #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) #define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) enum v4l2_mpeg_cx2341x_video_median_filter_type { V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) #define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) enum v4l2_exposure_auto_type { V4L2_EXPOSURE_AUTO = 0, V4L2_EXPOSURE_MANUAL = 1, V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, V4L2_EXPOSURE_APERTURE_PRIORITY = 3 }; #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) #define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) #define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) #define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) #define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) #define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) #define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) #define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) #define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) #define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) #define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) #define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) #define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) #define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) #define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) #define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) #define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) #define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) #define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) #define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) #define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) #define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) #define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) #define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) #define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) #define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) #define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) #define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) #define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) #define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) #define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) enum v4l2_preemphasis { V4L2_PREEMPHASIS_DISABLED = 0, V4L2_PREEMPHASIS_50_uS = 1, V4L2_PREEMPHASIS_75_uS = 2, }; #define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) #define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) /* * T U N I N G */ struct v4l2_tuner { __u32 index; __u8 name[32]; enum v4l2_tuner_type type; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 rxsubchans; __u32 audmode; __s32 signal; __s32 afc; __u32 reserved[4]; }; struct v4l2_modulator { __u32 index; __u8 name[32]; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 txsubchans; __u32 reserved[4]; }; /* Flags for the 'capability' field */ #define V4L2_TUNER_CAP_LOW 0x0001 #define V4L2_TUNER_CAP_NORM 0x0002 #define V4L2_TUNER_CAP_STEREO 0x0010 #define V4L2_TUNER_CAP_LANG2 0x0020 #define V4L2_TUNER_CAP_SAP 0x0020 #define V4L2_TUNER_CAP_LANG1 0x0040 #define V4L2_TUNER_CAP_RDS 0x0080 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 #define V4L2_TUNER_SUB_STEREO 0x0002 #define V4L2_TUNER_SUB_LANG2 0x0004 #define V4L2_TUNER_SUB_SAP 0x0004 #define V4L2_TUNER_SUB_LANG1 0x0008 #define V4L2_TUNER_SUB_RDS 0x0010 /* Values for the 'audmode' field */ #define V4L2_TUNER_MODE_MONO 0x0000 #define V4L2_TUNER_MODE_STEREO 0x0001 #define V4L2_TUNER_MODE_LANG2 0x0002 #define V4L2_TUNER_MODE_SAP 0x0002 #define V4L2_TUNER_MODE_LANG1 0x0003 #define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 struct v4l2_frequency { __u32 tuner; enum v4l2_tuner_type type; __u32 frequency; __u32 reserved[8]; }; struct v4l2_hw_freq_seek { __u32 tuner; enum v4l2_tuner_type type; __u32 seek_upward; __u32 wrap_around; __u32 reserved[8]; }; /* * R D S */ struct v4l2_rds_data { __u8 lsb; __u8 msb; __u8 block; } __attribute__ ((packed)); #define V4L2_RDS_BLOCK_MSK 0x7 #define V4L2_RDS_BLOCK_A 0 #define V4L2_RDS_BLOCK_B 1 #define V4L2_RDS_BLOCK_C 2 #define V4L2_RDS_BLOCK_D 3 #define V4L2_RDS_BLOCK_C_ALT 4 #define V4L2_RDS_BLOCK_INVALID 7 #define V4L2_RDS_BLOCK_CORRECTED 0x40 #define V4L2_RDS_BLOCK_ERROR 0x80 /* * A U D I O */ struct v4l2_audio { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* Flags for the 'capability' field */ #define V4L2_AUDCAP_STEREO 0x00001 #define V4L2_AUDCAP_AVL 0x00002 /* Flags for the 'mode' field */ #define V4L2_AUDMODE_AVL 0x00001 struct v4l2_audioout { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* * M P E G S E R V I C E S * * NOTE: EXPERIMENTAL API */ #if 1 #define V4L2_ENC_IDX_FRAME_I (0) #define V4L2_ENC_IDX_FRAME_P (1) #define V4L2_ENC_IDX_FRAME_B (2) #define V4L2_ENC_IDX_FRAME_MASK (0xf) struct v4l2_enc_idx_entry { __u64 offset; __u64 pts; __u32 length; __u32 flags; __u32 reserved[2]; }; #define V4L2_ENC_IDX_ENTRIES (64) struct v4l2_enc_idx { __u32 entries; __u32 entries_cap; __u32 reserved[4]; struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; }; #define V4L2_ENC_CMD_START (0) #define V4L2_ENC_CMD_STOP (1) #define V4L2_ENC_CMD_PAUSE (2) #define V4L2_ENC_CMD_RESUME (3) /* Flags for V4L2_ENC_CMD_STOP */ #define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) struct v4l2_encoder_cmd { __u32 cmd; __u32 flags; union { struct { __u32 data[8]; } raw; }; }; #endif /* * D A T A S E R V I C E S ( V B I ) * * Data services API by Michael Schimek */ /* Raw VBI */ struct v4l2_vbi_format { __u32 sampling_rate; /* in 1 Hz */ __u32 offset; __u32 samples_per_line; __u32 sample_format; /* V4L2_PIX_FMT_* */ __s32 start[2]; __u32 count[2]; __u32 flags; /* V4L2_VBI_* */ __u32 reserved[2]; /* must be zero */ }; /* VBI flags */ #define V4L2_VBI_UNSYNC (1 << 0) #define V4L2_VBI_INTERLACED (1 << 1) /* Sliced VBI * * This implements is a proposal V4L2 API to allow SLICED VBI * required for some hardware encoders. It should change without * notice in the definitive implementation. */ struct v4l2_sliced_vbi_format { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; __u32 io_size; __u32 reserved[2]; /* must be zero */ }; /* Teletext World System Teletext (WST), defined on ITU-R BT.653-2 */ #define V4L2_SLICED_TELETEXT_B (0x0001) /* Video Program System, defined on ETS 300 231*/ #define V4L2_SLICED_VPS (0x0400) /* Closed Caption, defined on EIA-608 */ #define V4L2_SLICED_CAPTION_525 (0x1000) /* Wide Screen System, defined on ITU-R BT1119.1 */ #define V4L2_SLICED_WSS_625 (0x4000) #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) struct v4l2_sliced_vbi_cap { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; enum v4l2_buf_type type; __u32 reserved[3]; /* must be 0 */ }; struct v4l2_sliced_vbi_data { __u32 id; __u32 field; /* 0: first field, 1: second field */ __u32 line; /* 1-23 */ __u32 reserved; /* must be 0 */ __u8 data[48]; }; /* * Sliced VBI data inserted into MPEG Streams */ /* * V4L2_MPEG_STREAM_VBI_FMT_IVTV: * * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI * data * * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header * definitions are not included here. See the MPEG-2 specifications for details * on these headers. */ /* Line type IDs */ #define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) #define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) #define V4L2_MPEG_VBI_IVTV_WSS_625 (5) #define V4L2_MPEG_VBI_IVTV_VPS (7) struct v4l2_mpeg_vbi_itv0_line { __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ __u8 data[42]; /* Sliced VBI data for the line */ } __attribute__ ((packed)); struct v4l2_mpeg_vbi_itv0 { __le32 linemask[2]; /* Bitmasks of VBI service lines present */ struct v4l2_mpeg_vbi_itv0_line line[35]; } __attribute__ ((packed)); struct v4l2_mpeg_vbi_ITV0 { struct v4l2_mpeg_vbi_itv0_line line[36]; } __attribute__ ((packed)); #define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" #define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" struct v4l2_mpeg_vbi_fmt_ivtv { __u8 magic[4]; union { struct v4l2_mpeg_vbi_itv0 itv0; struct v4l2_mpeg_vbi_ITV0 ITV0; }; } __attribute__ ((packed)); /* * A G G R E G A T E S T R U C T U R E S */ /* Stream data format */ struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ __u8 raw_data[200]; /* user-defined */ } fmt; }; /* Stream type-dependent parameters */ struct v4l2_streamparm { enum v4l2_buf_type type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; __u8 raw_data[200]; /* user-defined */ } parm; }; /* * E V E N T S */ #define V4L2_EVENT_ALL 0 #define V4L2_EVENT_VSYNC 1 #define V4L2_EVENT_EOS 2 #define V4L2_EVENT_PRIVATE_START 0x08000000 /* Payload for V4L2_EVENT_VSYNC */ struct v4l2_event_vsync { /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ __u8 field; } __attribute__ ((packed)); struct v4l2_event { __u32 type; union { struct v4l2_event_vsync vsync; __u8 data[64]; } u; __u32 pending; __u32 sequence; struct timespec timestamp; __u32 reserved[9]; }; struct v4l2_event_subscription { __u32 type; __u32 reserved[7]; }; /* * A D V A N C E D D E B U G G I N G * * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! */ /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ #define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ struct v4l2_dbg_match { __u32 type; /* Match type */ union { /* Match this chip, meaning determined by type */ __u32 addr; char name[32]; }; } __attribute__ ((packed)); struct v4l2_dbg_register { struct v4l2_dbg_match match; __u32 size; /* register size in bytes */ __u64 reg; __u64 val; } __attribute__ ((packed)); /* VIDIOC_DBG_G_CHIP_IDENT */ struct v4l2_dbg_chip_ident { struct v4l2_dbg_match match; __u32 ident; /* chip identifier as specified in */ __u32 revision; /* chip revision, chip specific */ } __attribute__ ((packed)); /* * I O C T L C O D E S F O R V I D E O D E V I C E S * */ #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) #define VIDIOC_RESERVED _IO('V', 1) #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) #define VIDIOC_OVERLAY _IOW('V', 14, int) #define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) #define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW('V', 18, int) #define VIDIOC_STREAMOFF _IOW('V', 19, int) #define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) #define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) #define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) #define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) #define VIDIOC_G_INPUT _IOR('V', 38, int) #define VIDIOC_S_INPUT _IOWR('V', 39, int) #define VIDIOC_G_OUTPUT _IOR('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) #define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) #define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) #define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) #define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) #define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) #define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) #define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority) #define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority) #define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) #define VIDIOC_LOG_STATUS _IO('V', 70) #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) #if 1 #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) #endif #if 1 /* Experimental, meant for debugging, testing and internal use. Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. You must be root to use these ioctls. Never use these in applications! */ #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) /* Experimental, meant for debugging, testing and internal use. Never use this ioctl in applications! */ #define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) #define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) #define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) #define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) #define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ #define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int) #define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm) #define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control) #define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio) #define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout) #define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap) #endif #define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ #endif /* __LINUX_VIDEODEV2_H */ hamlib-4.6.5/rigs/tuner/videodev.h0000664000175000017500000002746315056640443012547 /* This header is extracted from linux/videodev.h, approximately version 2.6.0. We can't use linux/videodev.h directly because it indirectly defines struct timespec, which is also defined by the standard C library headers. Argh. -blp */ #ifndef FM_VIDEODEV_H #define FM_VIDEODEV_H 1 #include #include #define VID_TYPE_CAPTURE 1 /* Can capture */ #define VID_TYPE_TUNER 2 /* Can tune */ #define VID_TYPE_TELETEXT 4 /* Does teletext */ #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ #define VID_TYPE_CLIPPING 32 /* Can clip */ #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ struct video_capability { char name[32]; int type; int channels; /* Num channels */ int audios; /* Num audio devices */ int maxwidth; /* Supported width */ int maxheight; /* And height */ int minwidth; /* Supported width */ int minheight; /* And height */ }; struct video_channel { int channel; char name[32]; int tuners; uint32_t flags; #define VIDEO_VC_TUNER 1 /* Channel has a tuner */ #define VIDEO_VC_AUDIO 2 /* Channel has audio */ uint16_t type; #define VIDEO_TYPE_TV 1 #define VIDEO_TYPE_CAMERA 2 uint16_t norm; /* Norm set by channel */ }; struct video_tuner { int tuner; char name[32]; unsigned long rangelow, rangehigh; /* Tuner range */ uint32_t flags; #define VIDEO_TUNER_PAL 1 #define VIDEO_TUNER_NTSC 2 #define VIDEO_TUNER_SECAM 4 #define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ #define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ #define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ #define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ #define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ uint16_t mode; /* PAL/NTSC/SECAM/OTHER */ #define VIDEO_MODE_PAL 0 #define VIDEO_MODE_NTSC 1 #define VIDEO_MODE_SECAM 2 #define VIDEO_MODE_AUTO 3 uint16_t signal; /* Signal strength 16bit scale */ }; struct video_picture { uint16_t brightness; uint16_t hue; uint16_t colour; uint16_t contrast; uint16_t whiteness; /* Black and white only */ uint16_t depth; /* Capture depth */ uint16_t palette; /* Palette in use */ #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ #define VIDEO_PALETTE_YUYV 8 #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ #define VIDEO_PALETTE_YUV420 10 #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ }; struct video_audio { int audio; /* Audio channel */ uint16_t volume; /* If settable */ uint16_t bass, treble; uint32_t flags; #define VIDEO_AUDIO_MUTE 1 #define VIDEO_AUDIO_MUTABLE 2 #define VIDEO_AUDIO_VOLUME 4 #define VIDEO_AUDIO_BASS 8 #define VIDEO_AUDIO_TREBLE 16 #define VIDEO_AUDIO_BALANCE 32 char name[16]; #define VIDEO_SOUND_MONO 1 #define VIDEO_SOUND_STEREO 2 #define VIDEO_SOUND_LANG1 4 #define VIDEO_SOUND_LANG2 8 uint16_t mode; uint16_t balance; /* Stereo balance */ uint16_t step; /* Step actual volume uses */ }; struct video_clip { int32_t x,y; int32_t width, height; struct video_clip *next; /* For user use/driver use only */ }; struct video_window { uint32_t x,y; /* Position of window */ uint32_t width,height; /* Its size */ uint32_t chromakey; uint32_t flags; struct video_clip *clips; /* Set only */ int clipcount; #define VIDEO_WINDOW_INTERLACE 1 #define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ #define VIDEO_CLIP_BITMAP -1 /* bitmap is 1024x625, a '1' bit represents a clipped pixel */ #define VIDEO_CLIPMAP_SIZE (128 * 625) }; struct video_capture { uint32_t x,y; /* Offsets into image */ uint32_t width, height; /* Area to capture */ uint16_t decimation; /* Decimation divider */ uint16_t flags; /* Flags for capture */ #define VIDEO_CAPTURE_ODD 0 /* Temporal */ #define VIDEO_CAPTURE_EVEN 1 }; struct video_buffer { void *base; int height,width; int depth; int bytesperline; }; struct video_mmap { unsigned int frame; /* Frame (0 - n) for double buffer */ int height,width; unsigned int format; /* should be VIDEO_PALETTE_* */ }; struct video_key { uint8_t key[8]; uint32_t flags; }; #define VIDEO_MAX_FRAME 32 struct video_mbuf { int size; /* Total memory to map */ int frames; /* Frames */ int offsets[VIDEO_MAX_FRAME]; }; #define VIDEO_NO_UNIT (-1) struct video_unit { int video; /* Video minor */ int vbi; /* VBI minor */ int radio; /* Radio minor */ int audio; /* Audio minor */ int teletext; /* Teletext minor */ }; struct vbi_format { uint32_t sampling_rate; /* in Hz */ uint32_t samples_per_line; uint32_t sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ int32_t start[2]; /* starting line for each frame */ uint32_t count[2]; /* count of lines for each frame */ uint32_t flags; #define VBI_UNSYNC 1 /* can distingues between top/bottom field */ #define VBI_INTERLACED 2 /* lines are interlaced */ }; /* video_info is biased towards hardware mpeg encode/decode */ /* but it could apply generically to any hardware compressor/decompressor */ struct video_info { uint32_t frame_count; /* frames output since decode/encode began */ uint32_t h_size; /* current unscaled horizontal size */ uint32_t v_size; /* current unscaled vertical size */ uint32_t smpte_timecode; /* current SMPTE timecode (for current GOP) */ uint32_t picture_type; /* current picture type */ uint32_t temporal_reference; /* current temporal reference */ uint8_t user_data[256]; /* user data last found in compressed stream */ /* user_data[0] contains user data flags, user_data[1] has count */ }; /* generic structure for setting playback modes */ struct video_play_mode { int mode; int p1; int p2; }; /* for loading microcode / fpga programming */ struct video_code { char loadwhat[16]; /* name or tag of file being passed */ int datasize; uint8_t *data; }; #define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ #define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ #define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ #define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ #define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ #define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ #define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ #define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ #define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ #define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ #define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ #define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ #define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ #define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ #define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ #define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ #define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ #define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ #define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ #define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ #define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ #define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ #define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ #define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ #define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ #define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ #define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ #define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ #define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ #define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ /* VIDIOCSWRITEMODE */ #define VID_WRITE_MPEG_AUD 0 #define VID_WRITE_MPEG_VID 1 #define VID_WRITE_OSD 2 #define VID_WRITE_TTX 3 #define VID_WRITE_CC 4 #define VID_WRITE_MJPEG 5 /* VIDIOCSPLAYMODE */ #define VID_PLAY_VID_OUT_MODE 0 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ #define VID_PLAY_GENLOCK 1 /* p1: 0 = OFF, 1 = ON */ /* p2: GENLOCK FINE DELAY value */ #define VID_PLAY_NORMAL 2 #define VID_PLAY_PAUSE 3 #define VID_PLAY_SINGLE_FRAME 4 #define VID_PLAY_FAST_FORWARD 5 #define VID_PLAY_SLOW_MOTION 6 #define VID_PLAY_IMMEDIATE_NORMAL 7 #define VID_PLAY_SWITCH_CHANNELS 8 #define VID_PLAY_FREEZE_FRAME 9 #define VID_PLAY_STILL_MODE 10 #define VID_PLAY_MASTER_MODE 11 /* p1: see below */ #define VID_PLAY_MASTER_NONE 1 #define VID_PLAY_MASTER_VIDEO 2 #define VID_PLAY_MASTER_AUDIO 3 #define VID_PLAY_ACTIVE_SCANLINES 12 /* p1 = first active; p2 = last active */ #define VID_PLAY_RESET 13 #define VID_PLAY_END_MARK 14 #define VID_HARDWARE_BT848 1 #define VID_HARDWARE_QCAM_BW 2 #define VID_HARDWARE_PMS 3 #define VID_HARDWARE_QCAM_C 4 #define VID_HARDWARE_PSEUDO 5 #define VID_HARDWARE_SAA5249 6 #define VID_HARDWARE_AZTECH 7 #define VID_HARDWARE_SF16MI 8 #define VID_HARDWARE_RTRACK 9 #define VID_HARDWARE_ZOLTRIX 10 #define VID_HARDWARE_SAA7146 11 #define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ #define VID_HARDWARE_RTRACK2 13 #define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ #define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ #define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ #define VID_HARDWARE_BROADWAY 17 /* Broadway project */ #define VID_HARDWARE_GEMTEK 18 #define VID_HARDWARE_TYPHOON 19 #define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ #define VID_HARDWARE_CADET 21 /* Cadet radio */ #define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ #define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ #define VID_HARDWARE_CPIA 24 #define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ #define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ #define VID_HARDWARE_OV511 27 #define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ #define VID_HARDWARE_W9966 29 #define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ #define VID_HARDWARE_PWC 31 /* Philips webcams */ #define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ #define VID_HARDWARE_CPIA2 33 #define VID_HARDWARE_VICAM 34 #define VID_HARDWARE_SF16FMR2 35 #endif /* videodev.h */ hamlib-4.6.5/rigs/tuner/tuner.h0000664000175000017500000000227515056640443012071 /* * Hamlib Tuners backend - main header * Copyright (c) 2004-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TUNER_H #define _TUNER_H 1 #include "hamlib/config.h" /* * So far, only Linux has Video4Linux support through ioctl :) * until someone port it to some other OS... */ #ifdef HAVE_LINUX_IOCTL_H #define V4L_IOCTL #endif #include "hamlib/rig.h" extern struct rig_caps v4l_caps; extern struct rig_caps v4l2_caps; #endif /* _TUNER_H */ hamlib-4.6.5/rigs/tuner/v4l.c0000664000175000017500000002375615056640443011443 /* * Hamlib Tuner backend - Video4Linux (v1) 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include #include "hamlib/rig.h" #include "tuner.h" /* include config.h */ #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef V4L_IOCTL #include "idx_builtin.h" #define V4L_FUNC (RIG_FUNC_MUTE) #define V4L_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RAWSTR) #define V4L_PARM_ALL (RIG_PARM_NONE) #define V4L_VFO (RIG_VFO_A) /* FIXME: per card measures? */ #define V4L_STR_CAL { 2, { \ { 0, -60 }, \ { 65535, 60 }, \ } } static int v4l_init(RIG *rig); static int v4l_open(RIG *rig); static int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *v4l_get_info(RIG *rig); /* * v4l (v1) rig capabilities. * * */ struct rig_caps v4l_caps = { RIG_MODEL(RIG_MODEL_V4L), .model_name = "SW/FM radio", .mfg_name = "Video4Linux", .version = "20120107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_DEVICE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 1, .has_get_func = V4L_FUNC, .has_set_func = V4L_FUNC, .has_get_level = V4L_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(V4L_LEVEL_ALL), .has_get_parm = V4L_PARM_ALL, .has_set_parm = RIG_PARM_SET(V4L_PARM_ALL), .vfo_ops = RIG_OP_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 65535 } }, }, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* will be rewritten at runtime */ .rx_range_list1 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_WFM, 100}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(230)}, /* guess */ {RIG_MODE_AM, kHz(8)}, /* guess */ RIG_FLT_END, }, .str_cal = V4L_STR_CAL, .rig_init = v4l_init, .rig_open = v4l_open, .set_freq = v4l_set_freq, .get_freq = v4l_get_freq, .set_func = v4l_set_func, .get_func = v4l_get_func, .set_level = v4l_set_level, .get_level = v4l_get_level, .get_info = v4l_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #include "videodev.h" #define DEFAULT_V4L_PATH "/dev/radio0" int v4l_init(RIG *rig) { RIGPORT(rig)->type.rig = RIG_PORT_DEVICE; strncpy(RIGPORT(rig)->pathname, DEFAULT_V4L_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int v4l_open(RIG *rig) { int i; struct video_tuner vt; struct rig_state *rs = STATE(rig); for (i = 0; i < 8; i++) { int ret; double fact; vt.tuner = i; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGTUNER, &vt); if (ret < 0) { break; } fact = (vt.flags & VIDEO_TUNER_LOW) == 0 ? 16 : 16000; rs->rx_range_list[i].startf = vt.rangelow / fact; rs->rx_range_list[i].endf = vt.rangehigh / fact; rs->rx_range_list[i].modes = vt.rangehigh / fact < MHz(30) ? RIG_MODE_AM : RIG_MODE_WFM; /* hack! hack! store the resolution in low_power! */ rs->rx_range_list[i].low_power = rint(fact); } return RIG_OK; } int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct video_tuner vt; const freq_range_t *range; unsigned long f; double fact; int ret; /* AM or WFM */ range = rig_get_range(rs->rx_range_list, freq, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } /* at this point, we are trying to tune to a frequency */ vt.tuner = (rs->rx_range_list - range) / sizeof(freq_range_t); ret = ioctl(rp->fd, VIDIOCSTUNER, &vt); /* set tuner # */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSTUNER: %s\n", strerror(errno)); return -RIG_EIO; } fact = range->low_power; f = rint(freq * fact); /* rounding to nearest int */ ret = ioctl(rp->fd, VIDIOCSFREQ, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSFREQ: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct rig_state *rs = STATE(rig); const freq_range_t *range; unsigned long f; double fact; int ret; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGFREQ, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGFREQ: %s\n", strerror(errno)); return -RIG_EIO; } /* FIXME: remember tuner and current *fact* */ range = rig_get_range(rs->rx_range_list, f / 16, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } fact = range->low_power; *freq = f / fact; return RIG_OK; } int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct video_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } va.flags = status ? VIDEO_AUDIO_MUTE : 0; ret = ioctl(rp->fd, VIDIOCSAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct video_audio va; int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(RIGPORT(rig)->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } *status = (va.flags & VIDEO_AUDIO_MUTE) == VIDEO_AUDIO_MUTE ; break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct video_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } switch (level) { case RIG_LEVEL_AF: va.volume = val.f * 65535; break; default: return -RIG_EINVAL; } ret = ioctl(rp->fd, VIDIOCSAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct video_audio va; struct video_tuner vt; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (level) { case RIG_LEVEL_AF: ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } val->f = (float)va.volume / 65535.; break; case RIG_LEVEL_RAWSTR: ret = ioctl(rp->fd, VIDIOCGTUNER, &vt); /* get info */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n", strerror(errno)); return -RIG_EIO; } val->i = vt.signal; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * FIXME: static buf does not allow reentrancy! */ const char *v4l_get_info(RIG *rig) { static struct video_tuner vt; int ret; vt.tuner = 0; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGTUNER, &vt); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n", strerror(errno)); return "Get info failed"; } return vt.name; } #endif /* V4L_IOCTL */ hamlib-4.6.5/rigs/tuner/Android.mk0000664000175000017500000000040515056640443012465 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := tuner.c v4l.c v4l2.c LOCAL_MODULE := tuner LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/tuner/tuner.c0000664000175000017500000000217715056640443012065 /* * Hamlib Tuner backend - main file * Copyright (C) 2004-2011 Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "tuner.h" /* config.h */ #include "hamlib/rig.h" #include "register.h" DECLARE_INITRIG_BACKEND(tuner) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); #ifdef V4L_IOCTL rig_register(&v4l_caps); rig_register(&v4l2_caps); #endif return RIG_OK; } hamlib-4.6.5/rigs/tuner/Makefile.in0000664000175000017500000005316315056640453012633 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tuner ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tuner_la_LIBADD = am__objects_1 = v4l.lo v4l2.lo tuner.lo am_libhamlib_tuner_la_OBJECTS = $(am__objects_1) libhamlib_tuner_la_OBJECTS = $(am_libhamlib_tuner_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/tuner.Plo ./$(DEPDIR)/v4l.Plo \ ./$(DEPDIR)/v4l2.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tuner_la_SOURCES) DIST_SOURCES = $(libhamlib_tuner_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TUNERSRC = v4l.c v4l2.c tuner.c tuner.h videodev.h videodev2.h noinst_LTLIBRARIES = libhamlib-tuner.la libhamlib_tuner_la_SOURCES = $(TUNERSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tuner/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tuner/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-tuner.la: $(libhamlib_tuner_la_OBJECTS) $(libhamlib_tuner_la_DEPENDENCIES) $(EXTRA_libhamlib_tuner_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tuner_la_OBJECTS) $(libhamlib_tuner_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tuner.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l2.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/tuner.Plo -rm -f ./$(DEPDIR)/v4l.Plo -rm -f ./$(DEPDIR)/v4l2.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/tuner.Plo -rm -f ./$(DEPDIR)/v4l.Plo -rm -f ./$(DEPDIR)/v4l2.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/tuner/v4l2.c0000664000175000017500000002443515056640443011520 /* * Hamlib Tuner backend - Video4Linux (v2) description * Copyright (c) 2004-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include #include "hamlib/rig.h" #include "tuner.h" /* include config.h */ #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef V4L_IOCTL #include "idx_builtin.h" #define V4L2_FUNC (RIG_FUNC_MUTE) #define V4L2_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RAWSTR) #define V4L2_PARM_ALL (RIG_PARM_NONE) #define V4L2_VFO (RIG_VFO_A) /* FIXME: per card measures? */ #define V4L2_STR_CAL { 2, { \ { 0, -60 }, \ { 65535, 60 }, \ } } static int v4l2_init(RIG *rig); static int v4l2_open(RIG *rig); static int v4l2_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int v4l2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int v4l2_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int v4l2_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int v4l2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int v4l2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *v4l2_get_info(RIG *rig); /* * v4l (v1) rig capabilities. * * */ struct rig_caps v4l2_caps = { RIG_MODEL(RIG_MODEL_V4L2), .model_name = "SW/FM radio", .mfg_name = "Video4Linux2", .version = "20191223.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_DEVICE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 1, .has_get_func = V4L2_FUNC, .has_set_func = V4L2_FUNC, .has_get_level = V4L2_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(V4L2_LEVEL_ALL), .has_get_parm = V4L2_PARM_ALL, .has_set_parm = RIG_PARM_SET(V4L2_PARM_ALL), .vfo_ops = RIG_OP_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 65535 } }, }, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* will be rewritten at runtime */ .rx_range_list1 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L2_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L2_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_WFM, 100}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(230)}, /* guess */ {RIG_MODE_AM, kHz(8)}, /* guess */ RIG_FLT_END, }, .str_cal = V4L2_STR_CAL, .rig_init = v4l2_init, .rig_open = v4l2_open, .set_freq = v4l2_set_freq, .get_freq = v4l2_get_freq, .set_func = v4l2_set_func, .get_func = v4l2_get_func, .set_level = v4l2_set_level, .get_level = v4l2_get_level, .get_info = v4l2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #include "videodev2.h" #define DEFAULT_V4L2_PATH "/dev/radio0" int v4l2_init(RIG *rig) { RIGPORT(rig)->type.rig = RIG_PORT_DEVICE; strncpy(RIGPORT(rig)->pathname, DEFAULT_V4L2_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int v4l2_open(RIG *rig) { int i; struct v4l2_tuner vt; struct rig_state *rs = STATE(rig); for (i = 0; i < 8; i++) { int ret; double fact; vt.index = i; ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_TUNER, &vt); if (ret < 0) { break; } fact = (vt.capability & V4L2_TUNER_CAP_LOW) == 0 ? 16 : 16000; rs->rx_range_list[i].startf = vt.rangelow / fact; rs->rx_range_list[i].endf = vt.rangehigh / fact; rs->rx_range_list[i].modes = vt.rangehigh / fact < MHz(30) ? RIG_MODE_AM : RIG_MODE_WFM; /* hack! hack! store the resolution in low_power! */ rs->rx_range_list[i].low_power = rint(fact); } return RIG_OK; } int v4l2_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct v4l2_tuner vt; const freq_range_t *range; unsigned long f; double fact; int ret; /* AM or WFM */ range = rig_get_range(rs->rx_range_list, freq, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } /* at this point, we are trying to tune to a frequency */ vt.index = (rs->rx_range_list - range) / sizeof(freq_range_t); ret = ioctl(rp->fd, VIDIOC_S_TUNER, &vt); /* set tuner # */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_TUNER: %s\n", strerror(errno)); return -RIG_EIO; } fact = range->low_power; f = rint(freq * fact); /* rounding to nearest int */ ret = ioctl(rp->fd, VIDIOC_S_FREQUENCY, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_FREQUENCY: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct rig_state *rs = STATE(rig); const freq_range_t *range; unsigned long f; double fact; int ret; /* FIXME */ ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_FREQUENCY, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_FREQUENCY: %s\n", strerror(errno)); return -RIG_EIO; } /* FIXME: remember tuner and current *fact* */ range = rig_get_range(rs->rx_range_list, f / 16, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } fact = range->low_power; *freq = f / fact; return RIG_OK; } int v4l2_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct v4l2_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } va.capability = status ? V4L2_CID_AUDIO_MUTE : 0; ret = ioctl(rp->fd, VIDIOC_S_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l2_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct v4l2_audio va; int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } *status = (va.capability & V4L2_CID_AUDIO_MUTE) == V4L2_CID_AUDIO_MUTE ; break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct v4l2_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } // TODO RIG_LEVEL_AGC:V4L2_CID_AUTOGAIN & RIG_LEVEL_RF:V4L2_CID_GAIN //V4L2_CID_AUDIO_VOLUME switch (level) { case RIG_LEVEL_AF: //va.volume = val.f * 65535; break; default: return -RIG_EINVAL; } ret = ioctl(rp->fd, VIDIOC_S_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct v4l2_audio va; struct v4l2_tuner vt; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (level) { case RIG_LEVEL_AF: ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } //val->f = (float)va.volume / 65535.; break; case RIG_LEVEL_RAWSTR: /* FE_READ_SIGNAL_STRENGTH ? */ ret = ioctl(rp->fd, VIDIOC_G_TUNER, &vt); /* get info */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_TUNER: %s\n", strerror(errno)); return -RIG_EIO; } val->i = vt.signal; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * FIXME: static buf does not allow reentrancy! */ const char *v4l2_get_info(RIG *rig) { static struct v4l2_tuner vt; int ret; vt.index = 0; ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_TUNER, &vt); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_TUNER: %s\n", strerror(errno)); return "Get info failed"; } return (const char *)vt.name; } #endif /* V4L_IOCTL */ hamlib-4.6.5/rigs/tuner/Makefile.am0000664000175000017500000000025215056640443012610 TUNERSRC = v4l.c v4l2.c tuner.c tuner.h videodev.h videodev2.h noinst_LTLIBRARIES = libhamlib-tuner.la libhamlib_tuner_la_SOURCES = $(TUNERSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/yaesu/0000775000175000017500000000000015056640500010620 5hamlib-4.6.5/rigs/yaesu/newcat.c0000664000175000017500000125555515056640443012215 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * and the Hamlib Group (hamlib-developer at lists.sourceforge.net) * * newcat.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2010 * (C) David Fannin (kk6df at arrl.net) * * This shared library provides an API for communicating * via serial interface to any newer Yaesu radio using the * "new" text CAT interface. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "iofunc.h" #include "misc.h" #include "cal.h" #include "newcat.h" #include "serial.h" /* global variables */ static const char cat_term = ';'; /* Yaesu command terminator */ // static const char cat_unknown_cmd[] = "?;"; /* Yaesu ? */ /* Internal Backup and Restore VFO Memory Channels */ #define NC_MEM_CHANNEL_NONE 2012 #define NC_MEM_CHANNEL_VFO_A 2013 #define NC_MEM_CHANNEL_VFO_B 2014 /* ID 0310 == 310, Must drop leading zero */ typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 570, NC_RIGID_FT991A = 670, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX10 = 761, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX3000DM = 462, // an undocumented FT-DX3000DM 50W rig NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682, NC_RIGID_FT710 = 800, } nc_rigid_t; /* * The following table defines which commands are valid for any given * rig supporting the "new" CAT interface. */ typedef struct _yaesu_newcat_commands { char *command; ncboolean ft450; ncboolean ft950; ncboolean ft891; ncboolean ft991; ncboolean ft2000; ncboolean ft9000; ncboolean ft5000; ncboolean ft1200; ncboolean ft3000; ncboolean ft101d; ncboolean ftdx10; ncboolean ft101mp; ncboolean ft710; ncboolean ft9000Old; } yaesu_newcat_commands_t; /** * Yaesu FT-991 S-meter scale, default for new Yaesu rigs. * Determined by data from W6HN -- seems to be pretty linear * * SMeter, rig answer, %fullscale * S0 SM0000 0 * S2 SM0026 10 * S4 SM0051 20 * S6 SM0081 30 * S7.5 SM0105 40 * S9 SM0130 50 * +12db SM0157 60 * +25db SM0186 70 * +35db SM0203 80 * +50db SM0237 90 * +60db SM0255 100 * * 114dB range over 0-255 referenced to S0 of -54dB */ const cal_table_t yaesu_default_str_cal = { 11, { { 0, -54, }, // S0 { 26, -42, }, // S2 { 51, -30, }, // S4 { 81, -18, }, // S6 { 105, -9, }, // S7.5 { 130, 0, }, // S9 { 157, 12, }, // S9+12dB { 186, 25, }, // S9+25dB { 203, 35, }, // S9+35dB { 237, 50, }, // S9+50dB { 255, 60, }, // S9+60dB } }; /** * First cut at generic Yaesu table, need more points probably * based on testing by Adam M7OTP on FT-991 */ const cal_table_float_t yaesu_default_swr_cal = { 5, { {12, 1.0f}, {39, 1.35f}, {65, 1.5f}, {89, 2.0f}, {242, 5.0f} } }; // TODO: Provide sane defaults const cal_table_float_t yaesu_default_alc_cal = { 2, { {0, 0.0f}, {64, 1.0f} } }; const cal_table_float_t yaesu_default_comp_meter_cal = { 9, { { 0, 0.0f }, { 40, 2.5f }, { 60, 5.0f }, { 85, 7.5f }, { 135, 10.0f }, { 150, 12.5f }, { 175, 15.0f }, { 195, 17.5f }, { 220, 20.0f } } }; // TODO: Provide sane defaults const cal_table_float_t yaesu_default_rfpower_meter_cal = { 3, { {0, 0.0f}, {148, 50.0f}, {255, 100.0f}, } }; const cal_table_float_t yaesu_default_vd_meter_cal = { 3, { {0, 0.0f}, {196, 13.8f}, {255, 17.95f}, } }; const cal_table_float_t yaesu_default_id_meter_cal = { 3, { {0, 0.0f}, {100, 10.0f}, {255, 25.5f}, } }; // Easy reference to rig model -- it is set in newcat_valid_command static ncboolean is_ft450; static ncboolean is_ft710; static ncboolean is_ft891; static ncboolean is_ft897; static ncboolean is_ft897d; static ncboolean is_ft950; static ncboolean is_ft991; static ncboolean is_ft2000; static ncboolean is_ftdx9000; static ncboolean is_ftdx5000; static ncboolean is_ftdx1200; static ncboolean is_ftdx3000; static ncboolean is_ftdx3000dm; static ncboolean is_ftdx101d; static ncboolean is_ftdx101mp; static ncboolean is_ftdx10; static ncboolean is_ftdx9000Old; /* * Even thought this table does make a handy reference, it could be depreciated as it is not really needed. * All of the CAT commands used in the newcat interface are available on the FT-950, FT-2000, FT-5000, and FT-9000. * There are 5 CAT commands used in the newcat interface that are not available on the FT-450. * Thesec CAT commands are XT -TX Clarifier ON/OFF, AN - Antenna select, PL - Speech Proc Level, * PR - Speech Proc ON/OFF, and BC - Auto Notch filter ON/OFF. * The FT-450 returns -RIG_ENVAIL for these unavailable CAT commands. * * NOTE: The following table must be in alphabetical order by the * command. This is because it is searched using a binary search * to determine whether or not a command is valid for a given rig. * * The list of supported commands is obtained from the rig's operator's * or CAT programming manual. * */ static const yaesu_newcat_commands_t valid_commands[] = { /* Command FT-450 FT-950 FT-891 FT-991 FT-2000 FT-9000 FT-5000 FT-1200 FT-3000 FTDX101D FTDX10 FTDX101MP FT710 FT9000Old*/ {"AB", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AM", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AN", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"AO", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BA", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BC", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CF", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE }, {"CH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CO", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DP", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"DS", TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"DT", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"ED", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"EK", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"EM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }, {"EN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"EU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"EX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FK", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"FN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"FR", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"FT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"GT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"ID", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"IF", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"IS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"LK", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"LM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MA", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"MC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MK", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"ML", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"MW", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MX", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NA", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"NB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"OI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"OS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PR", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RO", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"RP", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, {"RS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, {"RU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SQ", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SS", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ST command has two meanings Step or Split Status // If new rig is added that has ST ensure it means Split // Otherwise modify newcat_(set|get)_split {"ST", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"SV", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SY", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE}, {"TS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"TX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"UL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"UP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"VG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VR", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, {"VS", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"VT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }, {"VV", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, {"VX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"XT", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, {"ZI", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, } ; int valid_commands_count = sizeof(valid_commands) / sizeof( yaesu_newcat_commands_t); /* * configuration Tokens * */ #define TOK_FAST_SET_CMD TOKEN_BACKEND(1) const struct confparams newcat_cfg_params[] = { { TOK_FAST_SET_CMD, "fast_commands_token", "High throughput of commands", "Enabled high throughput of >200 messages/sec by not waiting for ACK/NAK of messages", "0", RIG_CONF_NUMERIC, { .n = { 0, 1, 1 } } }, { RIG_CONF_END, NULL, } }; /* NewCAT Internal Functions */ static ncboolean newcat_is_rig(RIG *rig, rig_model_t model); static int newcat_set_split(RIG *rig, split_t split, vfo_t *rx_vfo, vfo_t *tx_vfo); static int newcat_get_split(RIG *rig, split_t *split, vfo_t *tx_vfo); static int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo); static int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width); static int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow); static int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow); static int newcat_set_faststep(RIG *rig, ncboolean fast_step); static int newcat_get_faststep(RIG *rig, ncboolean *fast_step); static int newcat_get_rigid(RIG *rig); static int newcat_get_vfo_mode(RIG *rig, vfo_t vfo, vfo_t *vfo_mode); static int newcat_vfomem_toggle(RIG *rig); static int set_roofing_filter(RIG *rig, vfo_t vfo, int index); static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width); static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter); static int newcat_set_clarifier(RIG *rig, vfo_t vfo, int rx, int tx); static int newcat_get_clarifier(RIG *rig, vfo_t vfo, int *rx, int *tx); static int newcat_set_apf_frequency(RIG *rig, vfo_t vfo, int freq); static int newcat_get_apf_frequency(RIG *rig, vfo_t vfo, int *freq); static int newcat_set_apf_width(RIG *rig, vfo_t vfo, int choice); static int newcat_get_apf_width(RIG *rig, vfo_t vfo, int *choice); static int newcat_set_contour(RIG *rig, vfo_t vfo, int status); static int newcat_get_contour(RIG *rig, vfo_t vfo, int *status); static int newcat_set_contour_frequency(RIG *rig, vfo_t vfo, int freq); static int newcat_get_contour_frequency(RIG *rig, vfo_t vfo, int *freq); static int newcat_set_contour_level(RIG *rig, vfo_t vfo, int level); static int newcat_get_contour_level(RIG *rig, vfo_t vfo, int *level); static int newcat_set_contour_width(RIG *rig, vfo_t vfo, int width); static int newcat_get_contour_width(RIG *rig, vfo_t vfo, int *width); static ncboolean newcat_valid_command(RIG *rig, char const *const command); /* * The BS command needs to know what band we're on so we can restore band info * So this converts freq to band index */ static int newcat_band_index(freq_t freq) { int band = 11; // general // restrict band memory recall to ITU 1,2,3 band ranges // using < instead of <= for the moment // does anybody work LSB or RTTYR at the upper band edge? // what about band 13 -- what is it? if (freq >= MHz(420) && freq < MHz(470)) { band = 16; } else if (freq >= MHz(144) && freq < MHz(148)) { band = 15; } // band 14 is RX only // override band 15 with 14 if needed else if (freq >= MHz(118) && freq < MHz(164)) { band = 14; } else if (freq >= MHz(70) && freq < MHz(70.5)) { band = 17; } else if (freq >= MHz(50) && freq < MHz(55)) { band = 10; } else if (freq >= MHz(28) && freq < MHz(29.7)) { band = 9; } else if (freq >= MHz(24.890) && freq < MHz(24.990)) { band = 8; } else if (freq >= MHz(21) && freq < MHz(21.45)) { band = 7; } else if (freq >= MHz(18) && freq < MHz(18.168)) { band = 6; } else if (freq >= MHz(14) && freq < MHz(14.35)) { band = 5; } else if (freq >= MHz(10) && freq < MHz(10.15)) { band = 4; } else if (freq >= MHz(7) && freq < MHz(7.3)) { band = 3; } else if (freq >= MHz(5.3515) && freq < MHz(5.3665)) { band = 2; } else if (freq >= MHz(3.5) && freq < MHz(4)) { band = 1; } else if (freq >= MHz(1.8) && freq < MHz(2)) { band = 0; } else if (freq >= MHz(0.5) && freq < MHz(1.705)) { band = 12; } // MW Medium Wave rig_debug(RIG_DEBUG_TRACE, "%s: freq=%g, band=%d\n", __func__, freq, band); return (band); } /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ int newcat_init(RIG *rig) { struct newcat_priv_data *priv; ENTERFUNC; STATE(rig)->priv = (struct newcat_priv_data *) calloc(1, sizeof(struct newcat_priv_data)); if (!STATE( rig)->priv) /* whoops! memory shortage! */ { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; // priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ // priv->current_vfo = RIG_VFO_A; priv->rig_id = NC_RIGID_NONE; priv->current_mem = NC_MEM_CHANNEL_NONE; priv->fast_set_commands = FALSE; /* * Determine the type of rig from the model number. Note it is * possible for several model variants to exist; i.e., all the * FT-9000 variants. */ is_ft450 = newcat_is_rig(rig, RIG_MODEL_FT450); is_ft450 |= newcat_is_rig(rig, RIG_MODEL_FT450D); is_ft891 = newcat_is_rig(rig, RIG_MODEL_FT891); is_ft897 = newcat_is_rig(rig, RIG_MODEL_FT897); is_ft897d = newcat_is_rig(rig, RIG_MODEL_FT897D); is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950); is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991); is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000); is_ftdx9000 = newcat_is_rig(rig, RIG_MODEL_FT9000); is_ftdx9000Old = newcat_is_rig(rig, RIG_MODEL_FT9000OLD); is_ftdx5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000); is_ftdx1200 = newcat_is_rig(rig, RIG_MODEL_FTDX1200); is_ftdx3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000); is_ftdx3000dm = FALSE; // Detected dynamically is_ftdx101d = newcat_is_rig(rig, RIG_MODEL_FTDX101D); is_ftdx101mp = newcat_is_rig(rig, RIG_MODEL_FTDX101MP); is_ftdx10 = newcat_is_rig(rig, RIG_MODEL_FTDX10); is_ft710 = newcat_is_rig(rig, RIG_MODEL_FT710); RETURNFUNC(RIG_OK); } /* * rig_cleanup * * the serial port is closed by the frontend * */ int newcat_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * rig_open * * New CAT does not support pacing * */ int newcat_open(RIG *rig) { struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv = rig_s->priv; hamlib_port_t *rp = RIGPORT(rig); const char *handshake[3] = {"None", "Xon/Xoff", "Hardware"}; int err; int set_only = 0; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: Rig=%s, version=%s\n", __func__, rig->caps->model_name, rig->caps->version); rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: serial_handshake = %s \n", __func__, handshake[rig->caps->serial_handshake]); /* Ensure rig is powered on */ if (priv->poweron == 0 && rig_s->auto_power_on) { rig_set_powerstat(rig, 1); priv->poweron = 1; } priv->question_mark_response_means_rejected = 0; /* get current AI state so it can be restored */ priv->trn_state = -1; // for this sequence we will shorten the timeout so we can detect rig is powered off faster int timeout = rp->timeout; rp->timeout = 100; newcat_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ if (priv->trn_state > 0) { newcat_set_trn(rig, RIG_TRN_OFF); } /* ignore status in case it's not supported */ /* Initialize rig_id in case any subsequent commands need it */ (void)newcat_get_rigid(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: rig_id=%d\n", __func__, priv->rig_id); rp->timeout = timeout; // some rigs have a CAT TOT timeout that defaults to 10ms // so we'll increase CAT timeout to 100ms // 10ms seemed problematic on some rigs/computers if (priv->rig_id == NC_RIGID_FT2000 || priv->rig_id == NC_RIGID_FT2000D || priv->rig_id == NC_RIGID_FT891 || priv->rig_id == NC_RIGID_FT991 || priv->rig_id == NC_RIGID_FT991A || priv->rig_id == NC_RIGID_FT950 || priv->rig_id == NC_RIGID_FTDX10 || priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX3000DM) { char *cmd = "EX0291;EX029;"; // FT2000/D int retry_save; if (priv->rig_id == NC_RIGID_FT950 || rig->caps->rig_model == RIG_MODEL_FT950) { cmd = "EX0271;EX027;"; } else if (priv->rig_id == NC_RIGID_FT891 || rig->caps->rig_model == RIG_MODEL_FT891) { cmd = "EX05071;EX0507;"; } else if (priv->rig_id == NC_RIGID_FT991 || rig->caps->rig_model == RIG_MODEL_FT991) { cmd = "EX0321;EX032;"; } else if (priv->rig_id == NC_RIGID_FT991A || rig->caps->rig_model == RIG_MODEL_FT991) { cmd = "EX0321;EX032;"; } else if (priv->rig_id == NC_RIGID_FTDX3000 || rig->caps->rig_model == RIG_MODEL_FTDX3000) { cmd = "EX0391;"; set_only = 1; } else if (priv->rig_id == NC_RIGID_FTDX3000DM || rig->caps->rig_model == RIG_MODEL_FTDX3000) { cmd = "EX0391;"; set_only = 1; } else if (priv->rig_id == NC_RIGID_FTDX5000 || rig->caps->rig_model == RIG_MODEL_FTDX5000) { cmd = "EX0331;EX033"; } else if (priv->rig_id == NC_RIGID_FTDX10 || rig->caps->rig_model == RIG_MODEL_FTDX10) { cmd = "EX0301091;EX030109;"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", cmd); retry_save = rp->retry; rp->retry = 0; if (set_only) { err = newcat_set_cmd(rig); } else { err = newcat_get_cmd(rig); } rp->retry = retry_save; if (err != RIG_OK) { // if we can an err we just ignore the failure -- Win4Yaesu was not recognizing EX032 command } } if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX3000DM) { rig_s->disable_yaesu_bandselect = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: disabling FTDX3000 band select\n", __func__); } #if 0 // this apparently does not work if (is_ftdx5000) { // Remember EX103 status SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX103;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); if (set_only) { err = newcat_set_cmd(rig); } else { err = newcat_get_cmd(rig); } if (err != RIG_OK) { RETURNFUNC(err); } if (priv->ret_data[6] == ';') { priv->front_rear_status = priv->ret_data[5]; } } #endif priv->band_index = -1; RETURNFUNC(RIG_OK); } /* * rig_close * */ int newcat_close(RIG *rig) { struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv = rig_s->priv; ENTERFUNC; if (!no_restore_ai && priv->trn_state >= 0 && rig_s->comm_state && rig_s->powerstat != RIG_POWER_OFF) { /* restore AI state */ newcat_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } if (priv->poweron != 0 && rig_s->auto_power_off && rig_s->comm_state) { rig_set_powerstat(rig, 0); priv->poweron = 0; } #if 0 // this apparently does not work -- we can't query EX103 if (is_ftdx5000) { // Restore EX103 status SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX103%c;", priv->front_rear_status); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } #endif RETURNFUNC(RIG_OK); } /* * rig_set_config * * Set Configuration Token for Yaesu Radios */ int newcat_set_conf(RIG *rig, hamlib_token_t token, const char *val) { int ret = RIG_OK; struct newcat_priv_data *priv; ENTERFUNC; priv = (struct newcat_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } switch (token) { char *end; long value; case TOK_FAST_SET_CMD: ; //using strtol because atoi can lead to undefined behaviour value = strtol(val, &end, 10); if (end == val) { RETURNFUNC(-RIG_EINVAL); } if ((value == 0) || (value == 1)) { priv->fast_set_commands = (int)value; } else { RETURNFUNC(-RIG_EINVAL); } break; default: ret = -RIG_EINVAL; } RETURNFUNC(ret); } /* * rig_get_config * * Get Configuration Token for Yaesu Radios */ int newcat_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { int ret = RIG_OK; struct newcat_priv_data *priv; ENTERFUNC; priv = (struct newcat_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } switch (token) { case TOK_FAST_SET_CMD: if (sizeof(val) < 2) { RETURNFUNC(-RIG_ENOMEM); } SNPRINTF(val, val_len, "%d", priv->fast_set_commands); break; default: ret = -RIG_EINVAL; } RETURNFUNC(ret); } static int freq_60m[] = { 5332000, 5348000, 5358500, 5373000, 5405000 }; /* returns 0 if no exception or 1 if rig needs special handling */ int newcat_60m_exception(RIG *rig, freq_t freq, mode_t mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int channel = -1; int i; vfo_t vfo_mode; if (!(freq > 5.2 && freq < 5.5)) // we're not on 60M { return 0; } if (mode != RIG_MODE_CW && mode != RIG_MODE_USB && mode != RIG_MODE_PKTUSB && mode != RIG_MODE_RTTYR) { rig_debug(RIG_DEBUG_ERR, "%s: only USB, PKTUSB, RTTYR, and CW allowed for 60M operations\n", __func__); return -RIG_EINVAL; } // some rigs need to skip freq/mode settings as 60M only operates in memory mode if (is_ft991 || is_ft897 || is_ft897d || is_ftdx5000 || is_ftdx10) { return 1; } if (!is_ftdx10 && !is_ft710 && !is_ftdx101d && !is_ftdx101mp) { return 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: 60M exception ignoring freq/mode commands\n", __func__); // If US mode we need to use memory channels SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0301%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } // 01 is the only exception so far -- others may be like UK and have full control too if (strncmp(&priv->ret_data[6], "01", 2) != 0) { return 0; } // no exception // so now we should have a rig that has fixed memory channels 501-510 in USB/CW-U mode // toggle vfo mode if we need to rig_debug(RIG_DEBUG_VERBOSE, "%s: 60M exception ignoring freq/mode commands\n", __func__); newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (vfo_mode != RIG_VFO_MEM) { err = newcat_vfomem_toggle(rig); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Error toggling VFO_MEM\n", __func__); return -err; } } // find the nearest slot below what is requested for (i = 0; i < 5; ++i) { if ((long)freq == freq_60m[i]) { channel = i; } } if ((long)freq == 5357000) { channel = 3; } // 60M channel for FT8 if (channel < 0) { rig_debug(RIG_DEBUG_ERR, "%s: 60M allowed frequencies are 5.332, 5.348, 5.3585, 5.373,5.405, got %g\n", __func__, freq / 1000); return -RIG_EINVAL; } if (mode == RIG_MODE_CW) { channel += 5; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%3d%c", channel + 501, cat_term); if ((err = newcat_set_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } return 1; } /* * newcat_set_freq * * Set frequency for a given VFO * RIG_TARGETABLE_VFO * Does not SET priv->current_vfo * */ int newcat_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char c; char target_vfo; int err; struct rig_caps *caps; struct rig_cache *cachep = CACHE(rig); struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv; int special_60m = 0; vfo_t vfo_mode; ENTERFUNC; if (newcat_60m_exception(rig, freq, cachep->modeMainA)) { // we don't try to set freq on 60m for some rigs since we must be in memory mode // and we can't run split mode on 60M memory mode either if (cachep->split == RIG_SPLIT_ON) { rig_set_split_vfo(rig, RIG_VFO_A, RIG_VFO_A, RIG_SPLIT_OFF); } RETURNFUNC(RIG_OK); } // we don't set freq in this case if (!newcat_valid_command(rig, "FA")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "FB")) { RETURNFUNC(-RIG_ENAVAIL); } priv = (struct newcat_priv_data *)rig_s->priv; caps = rig->caps; newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (vfo_mode == RIG_VFO_MEM) { // then we need to toggle back to VFO mode newcat_vfomem_toggle(rig); } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); // rig_debug(RIG_DEBUG_TRACE, "%s: translated vfo = %s\n", __func__, rig_strvfo(tvfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { ERRMSG(err, "newcat_set_vfo_from_alias"); RETURNFUNC(err); } /* vfo should now be modified to a valid VFO constant. */ /* DX3000/DX5000/450 can only do VFO_MEM on 60M */ /* So we will not change freq in that case */ // did have FTDX3000 as not capable of 60M set_freq but as of 2021-01-21 it works // special_60m = newcat_is_rig(rig, RIG_MODEL_FTDX3000); /* duplicate the following line to add more rigs */ // disabled to check 2019 firmware on FTDX5000 and FT450 behavior //special_60m = newcat_is_rig(rig, RIG_MODEL_FTDX5000); //special_60m |= newcat_is_rig(rig, RIG_MODEL_FT450); rig_debug(RIG_DEBUG_TRACE, "%s: special_60m=%d, 60m freq=%d, is_ftdx3000=%d,is_ftdx3000dm=%d\n", __func__, special_60m, freq >= 5300000 && freq <= 5410000, is_ftdx3000, is_ftdx3000dm); if (special_60m && (freq >= 5300000 && freq <= 5410000)) { rig_debug(RIG_DEBUG_TRACE, "%s: 60M VFO_MEM exception, no freq change done\n", __func__); RETURNFUNC(RIG_OK); /* make it look like we changed */ } if ((is_ftdx101d || is_ftdx101mp) && (freq >= 70000000 && freq <= 70499999)) { // ensure the tuner is off for 70cm -- can cause damage to the rig newcat_set_func(rig, RIG_VFO_A, RIG_FUNC_TUNER, 0); hl_usleep(100 * 1000); // give it a chance to turn off } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: case RIG_VFO_MEM: c = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: c = 'B'; break; default: RETURNFUNC(-RIG_ENIMPL); /* Only VFO_A or VFO_B are valid */ } target_vfo = 'A' == c ? '0' : '1'; // some rigs like FTDX101D cannot change non-TX vfo freq // but they can change the TX vfo if ((is_ftdx101d || is_ftdx101mp) && cachep->ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_TRACE, "%s: ftdx101 check vfo OK, vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rig_s->tx_vfo)); // when in split we can change VFOB but not VFOA if (cachep->split == RIG_SPLIT_ON && target_vfo == '0') { RETURNFUNC(-RIG_ENTARGET); } // when not in split we can't change VFOA at all if (cachep->split == RIG_SPLIT_OFF && target_vfo == '0') { RETURNFUNC(-RIG_ENTARGET); } if (vfo != rig_s->tx_vfo) { RETURNFUNC(-RIG_ENTARGET); } } if (is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx1200) { // we have a few rigs that can't set freq while PTT_ON // so we'll try a few times to see if we just need to wait a bit // 3 retries should be about 400ms -- hopefully more than enough ptt_t ptt; int retry = 3; do { if (RIG_OK != (err = newcat_get_ptt(rig, vfo, &ptt))) { ERRMSG(err, "newcat_set_cmd failed"); RETURNFUNC(err); } if (ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_WARN, "%s: ptt still on...retry#%d\n", __func__, retry); hl_usleep(100 * 1000); // 100ms pause if ptt still on } } while (err == RIG_OK && ptt == RIG_PTT_ON && retry-- > 0); if (ptt) { RETURNFUNC(-RIG_ENTARGET); } } if (RIG_MODEL_FT450 == caps->rig_model) { /* The FT450 only accepts F[A|B]nnnnnnnn; commands for the current VFO so we must use the VS[0|1]; command to check and select the correct VFO before setting the frequency */ // Plus we can't do the VFO swap if transmitting if (target_vfo == '1' && cachep->ptt == RIG_PTT_ON) { RETURNFUNC(-RIG_ENTARGET); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%c", cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { ERRMSG(err, "newcat_get_cmd"); RETURNFUNC(err); } if (priv->ret_data[2] != target_vfo) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%c%c", target_vfo, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); if (RIG_OK != (err = newcat_set_cmd(rig))) { ERRMSG(err, "newcat_set_cmd failed"); RETURNFUNC(err); } } } // W1HKJ // creation of the priv structure guarantees that the string can be NEWCAT_DATA_LEN // bytes in length. the SNPRINTF will only allow (NEWCAT_DATA_LEN - 1) chars // followed by the NULL terminator. // CAT command string for setting frequency requires that 8 digits be sent // including leading fill zeros // Call this after open to set width_frequency for later use if (priv->width_frequency == 0) { vfo_t vfo_mode; newcat_get_vfo_mode(rig, vfo, &vfo_mode); } // // Restore band memory if we can and band is changing -- we do it before we set the frequency // And only when not in split mode (note this check has been removed for testing) int changing; rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: STATE(rig)->current_vfo=%s\n", __FILE__, __LINE__, __func__, rig_strvfo(rig_s->current_vfo)); CACHE_RESET; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq_t freqA; rig_get_freq(rig, RIG_VFO_A, &freqA); rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: checking VFOA for band change \n", __FILE__, __LINE__, __func__); changing = newcat_band_index(freq) != newcat_band_index(freqA); rig_debug(RIG_DEBUG_TRACE, "%s: VFO_A band changing=%d\n", __func__, changing); } else { freq_t freqB; rig_get_freq(rig, RIG_VFO_B, &freqB); rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: checking VFOB for band change \n", __FILE__, __LINE__, __func__); changing = newcat_band_index(freq) != newcat_band_index(freqB); rig_debug(RIG_DEBUG_TRACE, "%s: VFO_B band changing=%d\n", __func__, changing); } if (newcat_valid_command(rig, "BS") && changing && !rig_s->disable_yaesu_bandselect // remove the split check here -- hopefully works OK //&& !cachep->split // seems some rigs are problematic // && !(is_ftdx3000 || is_ftdx3000dm) // some rigs can't do BS command on 60M // && !(is_ftdx3000 || is_ftdx3000dm && newcat_band_index(freq) == 2) && !(is_ft2000 && newcat_band_index(freq) == 2) && !(is_ftdx1200 && newcat_band_index(freq) == 2) && !is_ft891 // 891 does not remember bandwidth so don't do this && !is_ft991 // 991 does not behave well with bandstack changes && rig->caps->get_vfo != NULL && rig->caps->set_vfo != NULL) // gotta' have get_vfo too { if (rig_s->current_vfo != vfo) { int vfo1 = 1, vfo2 = 0; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { vfo1 = 0; vfo2 = 1; } // we need to change vfos, BS, and change back if (is_ft991 == FALSE && is_ft891 == FALSE && newcat_valid_command(rig, "VS")) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%d;BS%02d%c", vfo1, newcat_band_index(freq), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); } if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#1=%s\n", __func__, rigerror(err)); } hl_usleep(500 * 1000); // wait for BS to do its thing and swap back if (newcat_valid_command(rig, "VS")) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%d;", vfo2); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#3=%s\n", __func__, rigerror(err)); } } } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#2=%s\n", __func__, rigerror(err)); } hl_usleep(500 * 1000); // wait for BS to do its thing } #if 0 // disable for testing else { // Also need to do this for the other VFO on some Yaesu rigs // is redundant for rigs where band stack includes both vfos vfo_t vfotmp; freq_t freqtmp; err = rig_get_vfo(rig, &vfotmp); if (err != RIG_OK) { RETURNFUNC(err); } if (rig_s->vfo_list & RIG_VFO_MAIN) { err = rig_set_vfo(rig, vfotmp == RIG_VFO_MAIN ? RIG_VFO_SUB : RIG_VFO_MAIN); } else { err = rig_set_vfo(rig, vfotmp == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); } if (err != RIG_OK) { RETURNFUNC(err); } rig_get_freq(rig, RIG_VFO_CURR, &freqtmp); if (err != RIG_OK) { RETURNFUNC(err); } // Cross band should work too // If the BS works on both VFOs then VFOB will have the band select answer // so now change needed // If the BS is by VFO then we'll need to do BS for the other VFO too if (newcat_band_index(freqtmp) != newcat_band_index(freq)) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#3=%s\n", __func__, rigerror(err)); } } // switch back to the starting vfo if (rig_s->vfo_list & RIG_VFO_MAIN) { err = rig_set_vfo(rig, vfotmp == RIG_VFO_MAIN ? RIG_VFO_MAIN : RIG_VFO_SUB); } else { err = rig_set_vfo(rig, vfotmp == RIG_VFO_A ? RIG_VFO_A : RIG_VFO_B); } if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_vfo failed: %s\n", __func__, rigerror(err)); RETURNFUNC(err); } // after band select re-read things -- may not have to change anything freq_t tmp_freqA, tmp_freqB; rmode_t tmp_mode; pbwidth_t tmp_width; rig_get_freq(rig, RIG_VFO_MAIN, &tmp_freqA); rig_get_freq(rig, RIG_VFO_SUB, &tmp_freqB); rig_get_mode(rig, RIG_VFO_MAIN, &tmp_mode, &tmp_width); rig_get_mode(rig, RIG_VFO_SUB, &tmp_mode, &tmp_width); if ((target_vfo == 0 && tmp_freqA == freq) || (target_vfo == 1 && tmp_freqB == freq)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq after band select already set to %"PRIfreq"\n", __func__, freq); RETURNFUNC(RIG_OK); // we're done then!! } } #endif // after band select re-read things -- may not have to change anything // reading both VFOs is really only needed for rigs with just one VFO stack // but we read them all to ensure we cover both types freq_t tmp_freqA = 0, tmp_freqB = 0; rmode_t tmp_mode; pbwidth_t tmp_width; // we need to update some info that BS may have caused CACHE_RESET; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { rig_get_freq(rig, RIG_VFO_SUB, &tmp_freqA); } else { rig_get_freq(rig, RIG_VFO_MAIN, &tmp_freqB); } rig_get_mode(rig, RIG_VFO_MAIN, &tmp_mode, &tmp_width); rig_get_mode(rig, RIG_VFO_SUB, &tmp_mode, &tmp_width); if ((target_vfo == 0 && tmp_freqA == freq) || (target_vfo == 1 && tmp_freqB == freq)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq after band select already set to %"PRIfreq"\n", __func__, freq); RETURNFUNC(RIG_OK); // we're done then!! } // just drop through } rig_debug(RIG_DEBUG_VERBOSE, "%s: is_ft991=%d, CACHE(rig)->split=%d, vfo=%s\n", __func__, is_ft991, cachep->split, rig_strvfo(vfo)); if (priv->band_index < 0) { priv->band_index = newcat_band_index(freq); } // only use bandstack method when actually changing bands // there are multiple bandstacks so we just use the 1st one if (is_ft991 && vfo == RIG_VFO_A && priv->band_index != newcat_band_index(freq)) { if (cachep->split) { // FT991/991A bandstack does not work in split mode // so for a VFOA change we stop split, change bands, change freq, enable split SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FT2;BS%02d;FA%09.0f;FT3;", newcat_band_index(freq), freq); } else // in non-split us BS to get bandstack info { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d;FA%09.0f;", newcat_band_index(freq), freq); } priv->band_index = newcat_band_index(freq); } else if (RIG_MODEL_FT450 == caps->rig_model) { if (c == 'B') { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS1;F%c%0*"PRIll";VS0;", c, priv->width_frequency, (int64_t)freq); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "F%c%0*"PRIll";", c, priv->width_frequency, (int64_t)freq); } } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "F%c%0*"PRIll";", c, priv->width_frequency, (int64_t)freq); } rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__, priv->cmd_str); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC(err); } rig_debug(RIG_DEBUG_TRACE, "%s: band changing? old=%d, new=%d\n", __func__, newcat_band_index(freq), newcat_band_index(rig_s->current_freq)); if (RIG_MODEL_FT450 == caps->rig_model && priv->ret_data[2] != target_vfo) { /* revert current VFO */ rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__, priv->ret_data); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } /* * rig_get_freq * * Return Freq for a given VFO * RIG_TARGETABLE_FREQ * Does not SET priv->current_vfo * */ int newcat_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char command[3]; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); if (!newcat_valid_command(rig, "FA")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "FB")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: // what about MAIN_A/MAIN_B? c = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: // what about SUB_A/SUB_B? c = 'B'; break; case RIG_VFO_MEM: c = 'A'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported vfo=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); /* sorry, unsupported VFO */ } /* Build the command string */ SNPRINTF(command, sizeof(command), "F%c", c); if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); /* get freq */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* convert the read frequency string into freq_t and store in *freq */ sscanf(priv->ret_data + 2, "%"SCNfreq, freq); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo %s\n", __func__, *freq, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } int newcat_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv; struct rig_cache *cachep = CACHE(rig); int err; rmode_t tmode; pbwidth_t twidth; split_t split_save = cachep->split; priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; if (newcat_60m_exception(rig, cachep->freqMainA, mode)) { RETURNFUNC(RIG_OK); } // we don't set mode in this case if (!newcat_valid_command(rig, "MD")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } // if vfo is current the same don't do anything // we don't want to use cache in case the user is twiddling the rig if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { rig_get_mode(rig, vfo, &tmode, &twidth); if (mode == tmode && (twidth == width || width == RIG_PASSBAND_NOCHANGE)) { RETURNFUNC(RIG_OK); } if (mode != tmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: mode changing from %s to %s\n", __func__, rig_strrmode(mode), rig_strrmode(tmode)); } if (width != twidth) { rig_debug(RIG_DEBUG_VERBOSE, "%s: width changing from %d to %d\n", __func__, (int)width, (int)twidth); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD0x%c", cat_term); priv->cmd_str[3] = newcat_modechar(mode); if (priv->cmd_str[3] == '0') { RETURNFUNC(-RIG_EINVAL); } /* FT9000 RIG_TARGETABLE_MODE (mode and width) */ /* FT2000 mode only */ if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s \n", __func__, rig_strrmode(mode)); err = newcat_set_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { cachep->modeMainA = mode; } else { cachep->modeMainB = mode; } if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(err); } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* Set width after mode has been set */ err = newcat_set_rx_bandwidth(rig, vfo, mode, width); // some rigs if you set mode on VFOB it will turn off split // so if we started in split we query split and turn it back on if needed if (split_save) { split_t split; vfo_t tx_vfo; err = rig_get_split_vfo(rig, RIG_VFO_A, &split, &tx_vfo); // we'll just reset to split to what we want if we need to if (!split) { rig_debug(RIG_DEBUG_TRACE, "%s: turning split back on...buggy rig\n", __func__); err = rig_set_split_vfo(rig, RIG_VFO_A, split_save, RIG_VFO_B); } } RETURNFUNC(err); } int newcat_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "MD")) { RETURNFUNC(-RIG_ENAVAIL); } if (STATE(rig)->powerstat == 0) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD%c%c", main_sub_vfo, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get MODE */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* * The current mode value is a digit '0' ... 'C' * embedded at ret_data[3] in the read string. */ c = priv->ret_data[3]; /* default, unless set otherwise */ *width = RIG_PASSBAND_NORMAL; *mode = newcat_rmode_width(rig, vfo, c, width); if (*mode == '0') { rig_debug(RIG_DEBUG_ERR, "%s: *mode = '0'??\n", __func__); RETURNFUNC(-RIG_EPROTO); } if (RIG_PASSBAND_NORMAL == *width) { *width = rig_passband_normal(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: returning newcat_get_rx_bandwidth\n", __func__); RETURNFUNC(newcat_get_rx_bandwidth(rig, vfo, *mode, width)); } /* * newcat_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int newcat_set_vfo(RIG *rig, vfo_t vfo) { struct newcat_priv_data *priv; struct rig_state *state; char c; int err, mem; vfo_t vfo_mode; char command[] = "VS"; state = STATE(rig); priv = (struct newcat_priv_data *)state->priv; priv->cache_start.tv_sec = 0; // invalidate the cache ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); // we can't change VFO while transmitting if (CACHE(rig)->ptt == RIG_PTT_ON) { RETURNFUNC(RIG_OK); } if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); /* passes RIG_VFO_MEM, RIG_VFO_A, RIG_VFO_B */ if (err < 0) { RETURNFUNC(err); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MAIN: case RIG_VFO_SUB: if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { c = '1'; } else { c = '0'; } err = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo_mode == RIG_VFO_MEM) { priv->current_mem = NC_MEM_CHANNEL_NONE; state->current_vfo = RIG_VFO_A; err = newcat_vfomem_toggle(rig); RETURNFUNC(err); } break; case RIG_VFO_MEM: if (priv->current_mem == NC_MEM_CHANNEL_NONE) { /* Only works correctly for VFO A */ if (state->current_vfo != RIG_VFO_A && state->current_vfo != RIG_VFO_MAIN) { RETURNFUNC(-RIG_ENTARGET); } /* get current memory channel */ err = newcat_get_mem(rig, vfo, &mem); if (err != RIG_OK) { RETURNFUNC(err); } /* turn on memory channel */ err = newcat_set_mem(rig, vfo, mem); if (err != RIG_OK) { RETURNFUNC(err); } /* Set current_mem now */ priv->current_mem = mem; } /* Set current_vfo now */ state->current_vfo = vfo; RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_ENIMPL); /* sorry, VFO not implemented */ } /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); err = newcat_set_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } state->current_vfo = vfo; /* if set_vfo worked, set current_vfo */ rig_debug(RIG_DEBUG_TRACE, "%s: STATE(rig)->current_vfo = %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } // Either returns a valid RIG_VFO* or if < 0 an error code static vfo_t newcat_set_vfo_if_needed(RIG *rig, vfo_t vfo) { vfo_t oldvfo = STATE(rig)->current_vfo; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, oldvfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(oldvfo)); if (oldvfo != vfo) { int ret; ret = newcat_set_vfo(rig, vfo); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting vfo=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(ret); } } RETURNFUNC(oldvfo); } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ int newcat_get_vfo(RIG *rig, vfo_t *vfo) { struct rig_state *state = STATE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)state->priv; int err; vfo_t vfo_mode; char const *command = "VS"; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } /* Build the command string */ if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s;", command); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get VFO */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* * The current VFO value is a digit ('0' or '1' ('A' or 'B' * respectively)) embedded at ret_data[2] in the read string. */ switch (priv->ret_data[2]) { case '0': if (state->vfo_list & RIG_VFO_MAIN) { *vfo = RIG_VFO_MAIN; } else { *vfo = RIG_VFO_A; } break; case '1': if (state->vfo_list & RIG_VFO_SUB) { *vfo = RIG_VFO_SUB; } else { *vfo = RIG_VFO_B; } break; default: RETURNFUNC(-RIG_EPROTO); /* sorry, wrong current VFO */ } /* Check to see if RIG is in MEM mode */ err = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo_mode == RIG_VFO_MEM) { *vfo = RIG_VFO_MEM; } state->current_vfo = *vfo; /* set now */ rig_debug(RIG_DEBUG_TRACE, "%s: STATE(rig)->current_vfo = %s\n", __func__, rig_strvfo(state->current_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err = -RIG_EPROTO; char txon[] = "TX1;"; ENTERFUNC; priv->cache_start.tv_sec = 0; // invalidate the cache if (!newcat_valid_command(rig, "TX")) { RETURNFUNC(-RIG_ENAVAIL); } switch (ptt) { case RIG_PTT_ON_MIC: /* Build the command string */ // the FTDX5000 uses menu 103 for front/rear audio in USB mode if (is_ftdx5000) { // Ensure FT5000 is back to MIC input SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1030;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_ON_DATA: /* Build the command string */ // the FTDX5000 uses menu 103 for front/rear audio in USB mode if (is_ftdx5000) { // Ensure FT5000 is back to MIC input SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1031;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_ON: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_OFF: { const char txoff[] = "TX0;"; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txoff); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); // some rigs like the FT991 need time before doing anything else like set_freq // We won't mess with CW mode -- no freq change expected hopefully if (STATE(rig)->current_mode != RIG_MODE_CW && STATE(rig)->current_mode != RIG_MODE_CWR && STATE(rig)->current_mode != RIG_MODE_CWN && (is_ftdx3000 || is_ftdx3000dm) ) { // DX3000 with separate rx/tx antennas was failing frequency change // so we increased the sleep from 100ms to 300ms hl_usleep(300 * 1000); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(err); } int newcat_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; ENTERFUNC; if (!newcat_valid_command(rig, "TX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", "TX", cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get PTT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[2]; switch (c) { case '0': /* FT-950 "TX OFF", Original Release Firmware */ *ptt = RIG_PTT_OFF; break; case '1' : /* Just because, what the CAT Manual Shows */ case '2' : /* FT-950 Radio: Mic, Dataport, CW "TX ON" */ case '3' : /* FT-950 CAT port: Radio in "TX ON" mode [Not what the CAT Manual Shows] */ *ptt = RIG_PTT_ON; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } int newcat_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "OS"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: c = '0'; break; case RIG_RPT_SHIFT_PLUS: c = '1'; break; case RIG_RPT_SHIFT_MINUS: c = '2'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command, main_sub_vfo, c, cat_term); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "OS"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get Rptr Shift */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; switch (c) { case '0': *rptr_shift = RIG_RPT_SHIFT_NONE; break; case '1': *rptr_shift = RIG_RPT_SHIFT_PLUS; break; case '2': *rptr_shift = RIG_RPT_SHIFT_MINUS; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char command[32]; freq_t freq = 0; ENTERFUNC; err = newcat_get_freq(rig, vfo, &freq); // Need to get freq to determine band if (err < 0) { RETURNFUNC(err); } if (is_ft450) { strcpy(command, "EX050"); // Step size is 100 kHz offs /= 100000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%03li%c", command, offs, cat_term); } else if (is_ft2000) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX076"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX077"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft950) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX057"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX058"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft891) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX0904"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX0905"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft991) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX080"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX081"); } else if (freq >= 144000000 && freq <= 148000000) { strcpy(command, "EX082"); } else if (freq >= 430000000 && freq <= 450000000) { strcpy(command, "EX083"); } else { // only valid on 10m to 70cm bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft710) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX010318"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX010319"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx1200) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX087"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX088"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX086"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX087"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx5000) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX081"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX082"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX010315"); if (is_ftdx10) { strcpy(command, "EX010317"); } } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX010316"); if (is_ftdx10) { strcpy(command, "EX010318"); } } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else { RETURNFUNC(-RIG_ENAVAIL); } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *retoffs; freq_t freq = 0; int step = 0; ENTERFUNC; err = newcat_get_freq(rig, vfo, &freq); // Need to get freq to determine band if (err < 0) { RETURNFUNC(err); } if (is_ft450) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX050%c", cat_term); // Step size is 100 kHz step = 100000; } else if (is_ft2000) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX076%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX077%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft950) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX057%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX058%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft891) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0904%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0905%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft991) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX080%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX081%c", cat_term); } else if (freq >= 144000000 && freq <= 148000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX082%c", cat_term); } else if (freq >= 430000000 && freq <= 450000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX083%c", cat_term); } else { // only valid on 10m to 70cm bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft710) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010318%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010319%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx1200) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX087%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX088%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx3000 || is_ftdx3000dm) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX086%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX087%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx5000) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX081%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX082%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (freq >= 28000000 && freq <= 29700000) { char *cmd = "EX010315%c"; if (is_ftdx10) { cmd = "EX010317%c"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), cmd, cat_term); } else if (freq >= 50000000 && freq <= 54000000) { char *cmd = "EX010316%c"; if (is_ftdx10) { cmd = "EX010318%c"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), cmd, cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_get_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retoffs = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *offs = atol(retoffs) * step; RETURNFUNC(RIG_OK); } int newcat_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { ENTERFUNC; rmode_t tmp_mode; pbwidth_t tmp_width; int err; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, tx_mode=%s, tx_width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(tx_mode), (int)tx_width); err = newcat_get_mode(rig, RIG_VFO_B, &tmp_mode, &tmp_width); if (err < 0) { RETURNFUNC(err); } if (tmp_mode == tx_mode && (tmp_width == tx_width || tmp_width == RIG_PASSBAND_NOCHANGE)) { RETURNFUNC(RIG_OK); } err = rig_set_mode(rig, vfo, tx_mode, tx_width); if (err < 0) { RETURNFUNC(err); } if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { CACHE(rig)->modeMainA = tx_mode; } else { CACHE(rig)->modeMainB = tx_mode; } RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int err; ENTERFUNC; err = newcat_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); if (err < 0) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int newcat_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int err; ENTERFUNC; vfo_t rx_vfo = RIG_VFO_NONE; rig_debug(RIG_DEBUG_TRACE, "%s: entered, rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (newcat_60m_exception(rig, CACHE(rig)->freqMainA, CACHE(rig)->modeMainA)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: force set_split off since we're on 60M exception\n", __func__); split = RIG_SPLIT_OFF; //RETURNFUNC(RIG_OK); // fake the return code to make things happy } if (is_ft991) { // FT-991(A) doesn't have a concept of an active VFO, so VFO B needs to be the split VFO vfo = RIG_VFO_A; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A; } else if (is_ftdx101d || is_ftdx101mp) { // FTDX101(D/MP) always use Sub VFO for transmit when in split mode vfo = RIG_VFO_MAIN; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_SUB : RIG_VFO_MAIN; } else if (is_ftdx10) { // FTDX10 always uses VFO B for transmit when in split mode vfo = RIG_VFO_A; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A; } else { err = newcat_get_vfo(rig, &rx_vfo); /* sync to rig current vfo */ if (err != RIG_OK) { RETURNFUNC(err); } } switch (split) { case RIG_SPLIT_OFF: err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_set_split(rig, split, &rx_vfo, &tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_set_tx_vfo(rig, vfo); if (err != RIG_OK) { RETURNFUNC(err); } } if (rx_vfo != vfo && newcat_valid_command(rig, "VS")) { err = rig_set_vfo(rig, vfo); if (err != RIG_OK) { RETURNFUNC(err); } } break; case RIG_SPLIT_ON: err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_set_split(rig, split, &rx_vfo, &tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_set_tx_vfo(rig, tx_vfo); if (err != RIG_OK) { RETURNFUNC(err); } } if (rx_vfo != vfo) { err = rig_set_vfo(rig, vfo); if (err != RIG_OK && err != -RIG_ENAVAIL) { RETURNFUNC(err); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int err; ENTERFUNC; err = newcat_set_vfo_from_alias(rig, &vfo); if (err != RIG_OK) { RETURNFUNC(err); } err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_get_split(rig, split, tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_get_tx_vfo(rig, tx_vfo); if (err != RIG_OK) { RETURNFUNC(err); } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(*tx_vfo), rig_strvfo(STATE(rig)->current_vfo)); if (*tx_vfo != STATE(rig)->current_vfo) { *split = RIG_SPLIT_ON; } else { *split = RIG_SPLIT_OFF; } } rig_debug(RIG_DEBUG_TRACE, "SPLIT = %d, vfo = %s, TX_vfo = %s\n", *split, rig_strvfo(vfo), rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int oldvfo; int ret; ENTERFUNC; if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } if (rit > rig->caps->max_rit) { rit = rig->caps->max_rit; /* + */ } else if (labs(rit) > rig->caps->max_rit) { rit = - rig->caps->max_rit; /* - */ } if (rit == 0) // don't turn it off just because it is zero { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%c", cat_term); } else if (rit < 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, labs(rit), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, labs(rit), cat_term); } ret = newcat_set_cmd(rig); oldvfo = newcat_set_vfo_if_needed(rig, oldvfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } RETURNFUNC(ret); } int newcat_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } *rit = 0; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get RIT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 13; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 14; break; default: offset = 0; } if (offset == 0) { rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %du\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } retval = priv->ret_data + offset; retval[5] = '\0'; // return the current offset even if turned off *rit = (shortfreq_t) atoi(retval); RETURNFUNC(RIG_OK); } int newcat_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int oldvfo; int ret; ENTERFUNC; if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } if (xit > rig->caps->max_xit) { xit = rig->caps->max_xit; /* + */ } else if (labs(xit) > rig->caps->max_xit) { xit = - rig->caps->max_xit; /* - */ } if (xit == 0) { // don't turn it off just because the offset is zero SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%c", cat_term); } else if (xit < 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, labs(xit), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, labs(xit), cat_term); } ret = newcat_set_cmd(rig); oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } RETURNFUNC(ret); } int newcat_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } *xit = 0; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get XIT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 13; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 14; break; default: offset = 0; } if (offset == 0) { rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %du\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } retval = priv->ret_data + offset; retval[5] = '\0'; // return the offset even when turned off *xit = (shortfreq_t) atoi(retval); RETURNFUNC(RIG_OK); } int newcat_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int err, i; pbwidth_t width; rmode_t mode; ncboolean ts_match; ENTERFUNC; err = newcat_get_mode(rig, vfo, &mode, &width); if (err < 0) { RETURNFUNC(err); } /* assume 2 tuning steps per mode */ for (i = 0, ts_match = FALSE; i < HAMLIB_TSLSTSIZ && rig->caps->tuning_steps[i].ts; i++) if (rig->caps->tuning_steps[i].modes & mode) { if (ts <= rig->caps->tuning_steps[i].ts) { err = newcat_set_faststep(rig, FALSE); } else { err = newcat_set_faststep(rig, TRUE); } if (err != RIG_OK) { RETURNFUNC(err); } ts_match = TRUE; break; } /* if mode */ rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, ts = %d\n", ts_match, i, (int)ts); if (ts_match) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ENAVAIL); } } int newcat_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { pbwidth_t width; rmode_t mode; int err, i; ncboolean ts_match; ncboolean fast_step = FALSE; ENTERFUNC; err = newcat_get_mode(rig, vfo, &mode, &width); if (err < 0) { RETURNFUNC(err); } err = newcat_get_faststep(rig, &fast_step); if (err < 0) { RETURNFUNC(err); } /* assume 2 tuning steps per mode */ for (i = 0, ts_match = FALSE; i < HAMLIB_TSLSTSIZ && rig->caps->tuning_steps[i].ts; i++) if (rig->caps->tuning_steps[i].modes & mode) { if (fast_step == FALSE) { *ts = rig->caps->tuning_steps[i].ts; } else { *ts = rig->caps->tuning_steps[i + 1].ts; } ts_match = TRUE; break; } rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, i+1 = %d, *ts = %d\n", ts_match, i, i + 1, (int)*ts); if (ts_match) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ENAVAIL); } } int newcat_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_tone(RIG *rig, vfo_t vfo, tone_t tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_tone(RIG *rig, vfo_t vfo, tone_t *tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int i; ncboolean tone_match; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "CN")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } rig_debug(RIG_DEBUG_TRACE, "%s: tone = %u, tone_match = %d, i = %d", __func__, tone, tone_match, i); if (tone_match == FALSE && tone != 0) { RETURNFUNC(-RIG_ENAVAIL); } if (tone == 0) /* turn off ctcss */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT%c0%c", main_sub_vfo, cat_term); } else { if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN%c0%03d%cCT%c2%c", main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN%c%02d%cCT%c2%c", main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); } } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int t; int ret_data_len; char *retlvl; char cmd[] = "CN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c0%c", cmd, main_sub_vfo, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, cat_term); } /* Get CTCSS TONE */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ if (t < 0 || t > 49) { RETURNFUNC(-RIG_ENAVAIL); } *tone = rig->caps->ctcss_list[t]; RETURNFUNC(RIG_OK); } int newcat_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_tone_sql(RIG *rig, vfo_t vfo, tone_t tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_tone_sql(RIG *rig, vfo_t vfo, tone_t *tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int err; ENTERFUNC; err = newcat_set_ctcss_tone(rig, vfo, tone); if (err != RIG_OK) { RETURNFUNC(err); } /* Change to sql */ if (tone) { err = newcat_set_func(rig, vfo, RIG_FUNC_TSQL, TRUE); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } int newcat_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int err; ENTERFUNC; err = newcat_get_ctcss_tone(rig, vfo, tone); RETURNFUNC(err); } int newcat_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = newcat_get_rigid(rig); switch (rig_id) { case NC_RIGID_FT450: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FT950: /* 100 Watts */ *mwpower = power * 100000; /* 0..100 Linear scale */ rig_debug(RIG_DEBUG_TRACE, "case FT950 - rig_id = %d, power = %f, *mwpower = %u\n", rig_id, power, *mwpower); break; case NC_RIGID_FT2000: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FT2000D: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX5000: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000D: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000Contest: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000Contest - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000MP: /* 400 Watts */ *mwpower = power * 400000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX1200: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; default: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); } RETURNFUNC(RIG_OK); } int newcat_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = newcat_get_rigid(rig); switch (rig_id) { case NC_RIGID_FT450: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FT950: /* 100 Watts */ *power = mwpower / 100000.0; /* 0..100 Linear scale */ rig_debug(RIG_DEBUG_TRACE, "case FT950 - rig_id = %d, mwpower = %u, *power = %f\n", rig_id, mwpower, *power); break; case NC_RIGID_FT2000: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FT2000D: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX5000: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000D: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000Contest: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000Contest - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000MP: /* 400 Watts */ *power = mwpower / 400000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX1200: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *power = %f\n", rig_id, *power); break; default: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *power = %f\n", rig_id, *power); } RETURNFUNC(RIG_OK); } int newcat_set_powerstat(RIG *rig, powerstat_t status) { hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int i = 0; int retry_save; ENTERFUNC; #if 0 // all Yaesu rigs have PS and calling this here interferes with power on if (!newcat_valid_command(rig, "PS")) { RETURNFUNC(-RIG_ENAVAIL); } #endif switch (status) { case RIG_POWER_ON: // When powering on a Yaesu rig needs dummy bytes to wake it up, // then wait from 1 to 2 seconds and issue the power-on command again HAMLIB_TRACE; write_block(rp, (unsigned char *) "PS1;", 4); hl_usleep(1200000); write_block(rp, (unsigned char *) "PS1;", 4); // some rigs reset the serial port during power up // so we reopen the com port again HAMLIB_TRACE; //oser_close(rp); // we can add more rigs to this exception to speed them up if (!is_ft991) { rig_close(rig); hl_usleep(3000000); //PTTPORT(rig)->fd = ser_open(rp); rig_open(rig); } break; case RIG_POWER_OFF: case RIG_POWER_STANDBY: retval = write_block(rp, (unsigned char *) "PS0;", 4); priv->poweron = 0; RETURNFUNC(retval); default: RETURNFUNC(-RIG_EINVAL); } HAMLIB_TRACE; retry_save = rp->retry; rp->retry = 0; if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < 8; ++i) // up to ~10 seconds including the timeouts { freq_t freq; hl_usleep(1000000); rig_flush(rp); retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval == RIG_OK) { rp->retry = retry_save; priv->poweron = 1; RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait #%d for power up\n", __func__, i + 1); retval = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)); if (retval != RIG_OK) { RETURNFUNC(retval); } } } rp->retry = retry_save; if (i == 9) { rig_debug(RIG_DEBUG_TRACE, "%s: timeout waiting for powerup, try %d\n", __func__, i + 1); retval = -RIG_ETIMEOUT; } RETURNFUNC(retval); } /* * This functions returns an error if the rig is off, dah */ int newcat_get_powerstat(RIG *rig, powerstat_t *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int result; char ps; char command[] = "PS"; ENTERFUNC; *status = RIG_POWER_OFF; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } // The first PS command has two purposes: // 1. to detect that the rig is turned on when it responds with PS1 immediately // 2. to act as dummy wake-up data for a rig that is turned off SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); // Timeout needs to be set temporarily to a low value, // so that the second command can be sent in 2 seconds, which is what Yaesu rigs expect. short retry_save; short timeout_retry_save; int timeout_save; retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; timeout_save = rp->timeout; rp->retry = 0; rp->timeout_retry = 0; rp->timeout = 500; result = newcat_get_cmd(rig); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; rp->timeout = timeout_save; // Rig may respond here already if (result == RIG_OK) { ps = priv->ret_data[2]; switch (ps) { case '1': *status = RIG_POWER_ON; priv->poweron = 1; RETURNFUNC(RIG_OK); case '0': *status = RIG_POWER_OFF; priv->poweron = 0; RETURNFUNC(RIG_OK); default: // fall through to retry command break; } } // Yeasu rigs in powered-off state require the PS command to be sent between 1 and 2 seconds after dummy data hl_usleep(1100000); // Discard any unsolicited data rig_flush(rp); result = newcat_get_cmd(rig); if (result != RIG_OK) { RETURNFUNC(result); } ps = priv->ret_data[2]; switch (ps) { case '1': *status = RIG_POWER_ON; break; case '0': *status = RIG_POWER_OFF; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } int newcat_reset(RIG *rig, reset_t reset) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } /* If we ever want to support ANT3 better on the FTDX101D Maybe make ANT_4/5/6/7? Since firmware version 201906 EX0301030 => RX 3 - TX 3 => MONITOR [3] EX0301031 => RX 3 - TX 1 => MONITOR [R/T1] EX0301032 => RX 3 - TX 2 => MONITOR [R/T2] EX0301033 => RX-ANT => MONITOR [RANT] */ int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char which_ant; char command[] = "AN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if ((rig->caps->targetable_vfo & RIG_TARGETABLE_ANT)) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (ant) { case RIG_ANT_1: which_ant = '1'; break; case RIG_ANT_2: which_ant = '2'; break; case RIG_ANT_3: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } which_ant = '3'; break; case RIG_ANT_4: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } which_ant = '4'; break; case RIG_ANT_5: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } /* RX only, on FT-2000/FT-5000/FT-9000 */ which_ant = '5'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command, main_sub_vfo, which_ant, cat_term); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "AN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_ANT) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get ANT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; switch (c) { case '1': *ant_curr = RIG_ANT_1; break; case '2' : *ant_curr = RIG_ANT_2; break; case '3' : *ant_curr = RIG_ANT_3; break; case '4' : *ant_curr = RIG_ANT_4; break; case '5' : *ant_curr = RIG_ANT_5; break; default: RETURNFUNC(-RIG_EPROTO); } *ant_tx = * ant_rx = *ant_curr; RETURNFUNC(RIG_OK); } static int band2rig(hamlib_band_t band) { int retval = 0; switch (band) { case RIG_BAND_160M: retval = 0; break; case RIG_BAND_80M: retval = 1; break; case RIG_BAND_60M: retval = 2; break; case RIG_BAND_40M: retval = 3; break; case RIG_BAND_30M: retval = 4; break; case RIG_BAND_20M: retval = 5; break; case RIG_BAND_17M: retval = 6; break; case RIG_BAND_15M: retval = 7; break; case RIG_BAND_12M: retval = 8; break; case RIG_BAND_10M: retval = 9; break; case RIG_BAND_6M: retval = 10; break; case RIG_BAND_GEN: retval = 11; break; case RIG_BAND_MW: retval = 12; break; case RIG_BAND_AIR: retval = 14; break; case RIG_BAND_144MHZ: retval = 15; break; case RIG_BAND_430MHZ: retval = 16; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown band index=%d\n", __func__, band); retval = -RIG_EINVAL; break; } return retval; } int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *state = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int i; int fpf; char main_sub_vfo = '0'; char *format; gran_t *level_info; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } err = check_level_param(rig, level, val, &level_info); if (err != RIG_OK) { RETURNFUNC(err); } switch (level) { case RIG_LEVEL_RFPOWER: if (!newcat_valid_command(rig, "PC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx3000dm) /* No separate rig->caps for this rig :-( */ { fpf = (int)((val.f * 50.0f) + 0.5f); } else { fpf = (int)((val.f / level_info->step.f) + 0.5f); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%03d%c", fpf, cat_term); break; case RIG_LEVEL_AF: if (!newcat_valid_command(rig, "AG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%03d%c", main_sub_vfo, fpf, cat_term); break; case RIG_LEVEL_AGC: if (!newcat_valid_command(rig, "GT")) { RETURNFUNC(-RIG_ENAVAIL); } switch (val.i) { case RIG_AGC_OFF: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT00;"); break; case RIG_AGC_FAST: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT01;"); break; case RIG_AGC_MEDIUM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT02;"); break; case RIG_AGC_SLOW: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT03;"); break; case RIG_AGC_AUTO: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT04;"); break; default: RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_IF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "IS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } rig_debug(RIG_DEBUG_TRACE, "%s: LEVEL_IF val.i=%d\n", __func__, val.i); if (abs(val.i) > rig->caps->max_ifshift) { if (val.i > 0) { val.i = rig->caps->max_ifshift; } else { val.i = rig->caps->max_ifshift * -1; } } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c0%+.4d%c", main_sub_vfo, val.i, cat_term); } else if (is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS00%+.4d%c", val.i, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS0%d%+.4d%c", val.i == 0 ? 0 : 1, val.i, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%+.4d%c", main_sub_vfo, val.i, cat_term); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in AM/FM modes if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_CWPITCH: { int kp; if (!newcat_valid_command(rig, "KP")) { RETURNFUNC(-RIG_ENAVAIL); } // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps kp = (val.i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", kp, cat_term); break; } case RIG_LEVEL_KEYSPD: if (!newcat_valid_command(rig, "KS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KS%03d%c", val.i, cat_term); break; case RIG_LEVEL_MICGAIN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "MG")) { RETURNFUNC(-RIG_ENAVAIL); } rmode_t exclude = RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR; if ((STATE(rig)->tx_vfo == RIG_VFO_A && (cachep->modeMainA & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_B && (cachep->modeMainB & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_C && (cachep->modeMainC & exclude))) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig cannot set MG in CW/RTTY modes\n", __func__); RETURNFUNC(RIG_OK); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term); // Some Yaesu rigs reject this command in RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_METER: if (!newcat_valid_command(rig, "MS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) // new format for the command with VFO selection { format = "MS0%d;"; if (vfo == RIG_VFO_SUB) { format = "MS1%d;"; } } else if (is_ftdx10) { format = "MS%d0;"; } else { format = "MS%d;"; } rig_debug(RIG_DEBUG_TRACE, "%s: format=%s\n", __func__, format); switch (val.i) { case RIG_METER_ALC: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 1); break; case RIG_METER_PO: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(RIG_OK); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 2); } break; case RIG_METER_SWR: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 3); break; case RIG_METER_COMP: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 0); break; case RIG_METER_IC: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 4); break; case RIG_METER_VDD: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 5); break; rig_debug(RIG_DEBUG_ERR, "%s: unknown val.i=%d\n", __func__, val.i); default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_PREAMP: if (!newcat_valid_command(rig, "PA")) { RETURNFUNC(-RIG_ENAVAIL); } if (val.i == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; } priv->cmd_str[0] = '\0'; for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) { if (state->preamp[i] == val.i) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA0%d%c", i + 1, cat_term); break; } } if (strlen(priv->cmd_str) == 0) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_ATT: if (!newcat_valid_command(rig, "RA")) { RETURNFUNC(-RIG_ENAVAIL); } if (val.i == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; } priv->cmd_str[0] = '\0'; for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) { if (state->attenuator[i] == val.i) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA0%d%c", i + 1, cat_term); break; } } if (strlen(priv->cmd_str) == 0) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_RF: if (!newcat_valid_command(rig, "RG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%03d%c", main_sub_vfo, fpf, cat_term); break; case RIG_LEVEL_NR: if (!newcat_valid_command(rig, "RL")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5); if (newcat_is_rig(rig, RIG_MODEL_FT450)) { if (fpf < 1) { fpf = 1; } if (fpf > 11) { fpf = 11; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term); } else { if (is_ft991) { if (fpf > 15) { fpf = 15; } if (fpf < 1) { fpf = 1; } } else { if (fpf > 15) { fpf = 10; } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } } break; case RIG_LEVEL_COMP: if (!newcat_valid_command(rig, "PL")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term); break; case RIG_LEVEL_BKINDL: { int millis; value_t keyspd; if (!newcat_valid_command(rig, "SD")) { RETURNFUNC(-RIG_ENAVAIL); } // Convert 10/ths of dots to milliseconds using the current key speed err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); if (err != RIG_OK) { RETURNFUNC(err); } millis = dot10ths_to_millis(val.i, keyspd.i); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { if (millis <= 30) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); } else if (millis <= 50) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); } else if (millis <= 100) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); } else if (millis <= 150) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); } else if (millis <= 200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); } else if (millis <= 250) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); } else if (millis > 2900) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); } else { // This covers 300-2900 06-32 SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((millis - 300) / 100)); } } else if (is_ftdx5000) { if (millis < 20) { millis = 20; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else if (is_ft950 || is_ft450 || is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm) { if (millis < 30) { millis = 30; } if (millis > 3000) { millis = 3000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else if (is_ft2000 || is_ftdx9000) { if (millis < 0) { millis = 0; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else // default { if (millis < 1) { millis = 1; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } break; } case RIG_LEVEL_SQL: if (!newcat_valid_command(rig, "SQ")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%03d%c", main_sub_vfo, fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_VOXDELAY: if (!newcat_valid_command(rig, "VD")) { RETURNFUNC(-RIG_ENAVAIL); } /* VOX delay, api int (tenth of seconds), ms for rig */ val.i = val.i * 100; rig_debug(RIG_DEBUG_TRACE, "%s: vali=%d\n", __func__, val.i); if (is_ft950 || is_ft450 || is_ftdx1200) { if (val.i < 100) /* min is 30ms but spec is 100ms Unit Intervals */ { val.i = 30; } if (val.i > 3000) { val.i = 3000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) // new lookup table argument { rig_debug(RIG_DEBUG_TRACE, "%s: ft101 #1 val.i=%d\n", __func__, val.i); if (val.i == 0) { ; } else if (val.i <= 100) { val.i = 2; } else if (val.i <= 200) { val.i = 4; } else if (val.i > 3000) { val.i = 33; } else { val.i = (val.i - 300) / 100 + 6; } rig_debug(RIG_DEBUG_TRACE, "%s: ftdx101/ftdx10 #1 val.i=%d\n", __func__, val.i); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%02d%c", val.i, cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { if (val.i < 0) { val.i = 0; } if (val.i > 5000) { val.i = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } break; case RIG_LEVEL_VOXGAIN: if (!newcat_valid_command(rig, "VG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term); break; case RIG_LEVEL_ANTIVOX: fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AV%03d%c", fpf, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX176%03d%c", fpf, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX145%03d%c", fpf, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%03d%c", fpf, cat_term); } else if (is_ft950) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term); } else if (is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX042%03d%c", fpf, cat_term); } else { RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_NOTCHF: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } val.i = val.i / 10; if (is_ftdx9000) { if (val.i < 0) { val.i = 0; } } else { if (val.i < 1) { val.i = 1; } } if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (val.i > 320) { val.i = 320; } } if (is_ft950 || is_ftdx9000) { if (val.i > 300) { val.i = 300; } } else { if (val.i > 400) { val.i = 400; } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP01%03d%c", val.i, cat_term); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP%03d%c", val.i, cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_MONITOR_GAIN: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML%03d%c", fpf, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term); } break; case RIG_LEVEL_BAND_SELECT: if (newcat_valid_command(rig, "BS")) { int band = band2rig((hamlib_band_t)val.i); if (band < 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", band, cat_term); priv->band_index = band; } break; case RIG_LEVEL_NB: if (!newcat_valid_command(rig, "NL")) { RETURNFUNC(-RIG_ENAVAIL); } // Do not scale the value, level maximum value is set to 10 fpf = val.f; if (fpf < 0) { fpf = 0; } if (fpf > 10) { fpf = 10; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NL00%02d%c", fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710 && !is_ftdx101mp) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_USB_AF: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; float valf = val.f / level_info->step.f; switch (curmode) { case RIG_MODE_USB: case RIG_MODE_LSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%03.0f%c", valf, cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%03.0f%c", valf, cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%03.0f%c", valf, cat_term); break; case RIG_MODE_PKTFM: // is this the right place for this? case RIG_MODE_PKTFMN: // is this the right place for this? case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%03.0f%c", valf, cat_term); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to set USB_AF for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_set_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; RETURNFUNC(err); } int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *state = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *retlvl; int retlvl_len; char main_sub_vfo = '0'; int i; gran_t *level_info; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } level_info = &rig->caps->level_gran[rig_setting2idx(level)]; switch (level) { case RIG_LEVEL_RFPOWER: if (!newcat_valid_command(rig, "PC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%c", cat_term); break; case RIG_LEVEL_PREAMP: if (!newcat_valid_command(rig, "PA")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_AF: if (!newcat_valid_command(rig, "AG")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_AGC: if (!newcat_valid_command(rig, "GT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_IF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "IS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in AM/FM modes if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_CWPITCH: if (!newcat_valid_command(rig, "KP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KP%c", cat_term); break; case RIG_LEVEL_KEYSPD: if (!newcat_valid_command(rig, "KS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KS%c", cat_term); break; case RIG_LEVEL_MICGAIN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "MG")) { RETURNFUNC(-RIG_ENAVAIL); } rmode_t exclude = RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR; if ((STATE(rig)->tx_vfo == RIG_VFO_A && (cachep->modeMainA & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_B && (cachep->modeMainB & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_C && (cachep->modeMainC & exclude))) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig cannot read MG in CW/RTTY modes\n", __func__); RETURNFUNC(RIG_OK); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MG%c", cat_term); // Some Yaesu rigs reject this command in RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_METER: if (!newcat_valid_command(rig, "MS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MS%c", cat_term); break; case RIG_LEVEL_ATT: if (!newcat_valid_command(rig, "RA")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_RF: if (!newcat_valid_command(rig, "RG")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%c", main_sub_vfo, cat_term); break; case RIG_LEVEL_COMP: if (!newcat_valid_command(rig, "PL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PL%c", cat_term); break; case RIG_LEVEL_NR: if (!newcat_valid_command(rig, "RL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_BKINDL: if (!newcat_valid_command(rig, "SD")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%c", cat_term); break; case RIG_LEVEL_SQL: if (!newcat_valid_command(rig, "SQ")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_VOXDELAY: /* VOX delay, arg int (tenth of seconds) */ if (!newcat_valid_command(rig, "VD")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%c", cat_term); break; case RIG_LEVEL_VOXGAIN: if (!newcat_valid_command(rig, "VG")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VG%c", cat_term); break; case RIG_LEVEL_NB: if (!newcat_valid_command(rig, "NL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NL0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710 && !is_ftdx101mp) { priv->cmd_str[2] = main_sub_vfo; } break; /* * Read only levels */ case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: if (!newcat_valid_command(rig, "SM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SM%c%c", main_sub_vfo, cat_term); break; case RIG_LEVEL_SWR: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM09%c", cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx5000) { // The 3000 has to use the meter read for SWR when the tuner is on // We'll assume the 5000 is the same way for now // Also need to ensure SWR is selected for the meter int tuner; value_t meter; newcat_get_func(rig, RIG_VFO_A, RIG_FUNC_TUNER, &tuner); newcat_get_level(rig, RIG_VFO_A, RIG_LEVEL_METER, &meter); if (tuner && meter.i != RIG_METER_SWR) { RETURNFUNC(-RIG_ENAVAIL); // if meter not SWR can't read SWR } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM%c%c", (tuner && meter.i == RIG_METER_SWR) ? '2' : '6', cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM6%c", cat_term); } break; case RIG_LEVEL_ALC: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM07%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM4%c", cat_term); } break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM08%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM5%c", cat_term); } break; case RIG_LEVEL_COMP_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM06%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM3%c", cat_term); } break; case RIG_LEVEL_VD_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM11%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM8%c", cat_term); } break; case RIG_LEVEL_ID_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM10%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM7%c", cat_term); } break; case RIG_LEVEL_ANTIVOX: if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AV%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX176%c", cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX147%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%c", cat_term); } else if (is_ft950) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term); } else if (is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX042%c", cat_term); } else { RETURNFUNC(-RIG_ENAVAIL); } break; case RIG_LEVEL_NOTCHF: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP01%c", cat_term); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP%c", cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_MONITOR_GAIN: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term); } break; case RIG_LEVEL_TEMP_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM14%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM9%c", cat_term); } break; case RIG_LEVEL_USB_AF_INPUT: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; switch (curmode) { case RIG_MODE_LSB: case RIG_MODE_USB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%c", cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%c", cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%c", cat_term); break; case RIG_MODE_PKTFM: case RIG_MODE_PKTFMN: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%c", cat_term); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to get USB_AF_INPUT for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_LEVEL_USB_AF: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; switch (curmode) { case RIG_MODE_LSB: case RIG_MODE_USB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010109%c", cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010209%c", cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010309%c", cat_term); break; case RIG_MODE_PKTFM: case RIG_MODE_PKTFMN: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010411%c", cat_term); break; case RIG_MODE_RTTY: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010511%c", cat_term); break; // we have PSK level too but no means to have this mode yet default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to get USB_AF for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } else { RETURNFUNC(-RIG_ENIMPL); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08llx\n", __func__, (long long unsigned int)level); RETURNFUNC(-RIG_EINVAL); } err = newcat_get_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; retlvl_len = strlen(retlvl); rig_debug(RIG_DEBUG_TRACE, "%s: retlvl='%s'\n", __func__, retlvl); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; switch (level) { case RIG_LEVEL_SWR: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->swr_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_swr_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->swr_cal); } break; case RIG_LEVEL_ALC: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->alc_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_alc_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->alc_cal); } break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: rig_debug(RIG_DEBUG_VERBOSE, "%s: RFPOWER_METER retlvl=%s\n", __func__, retlvl); if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl of %s getting truncated\n", __func__, retlvl); retlvl[3] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl truncated to %s\n", __func__, retlvl); } if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_rfpower_meter_cal) / (level == RIG_LEVEL_RFPOWER_METER_WATTS ? 1.0 : 100.0); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->rfpower_meter_cal) / (level == RIG_LEVEL_RFPOWER_METER_WATTS ? 1.0 : 100.0); if (priv->rig_id == NC_RIGID_FT2000) { // we reuse the FT2000D table for the FT2000 so need to divide by 2 // hopefully this works well otherwise we need a separate table val->f /= 2; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: RFPOWER_METER=%s, converted to %f\n", __func__, retlvl, val->f); if (level == RIG_LEVEL_RFPOWER_METER && val->f > 1.0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: val->f(%f) clipped at 1.0\n", __func__, val->f); val->f = 1.0; } break; case RIG_LEVEL_COMP_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->comp_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_comp_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->comp_meter_cal); } break; case RIG_LEVEL_VD_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->vd_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_vd_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->vd_meter_cal); } break; case RIG_LEVEL_ID_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->id_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_id_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->id_meter_cal); } break; case RIG_LEVEL_AF: case RIG_LEVEL_RF: case RIG_LEVEL_NR: case RIG_LEVEL_SQL: case RIG_LEVEL_COMP: case RIG_LEVEL_ANTIVOX: case RIG_LEVEL_MICGAIN: case RIG_LEVEL_VOXGAIN: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_MONITOR_GAIN: val->f = (float)atoi(retlvl) * level_info->step.f; break; case RIG_LEVEL_BKINDL: { int raw_value = atoi(retlvl); int millis; value_t keyspd; if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (raw_value) { case 0: millis = 30; break; case 1: millis = 50; break; case 2: millis = 100; break; case 3: millis = 150; break; case 4: millis = 200; break; case 5: millis = 250; break; case 6: millis = 300; break; default: millis = (raw_value - 6) * 100 + 300; } } else { // The rest of Yaesu rigs indicate break-in delay directly as milliseconds millis = raw_value; } // Convert milliseconds to 10/ths of dots using the current key speed err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); if (err != RIG_OK) { RETURNFUNC(err); } val->i = millis_to_dot10ths(millis, keyspd.i); break; } case RIG_LEVEL_STRENGTH: if (rig->caps->str_cal.size > 0) { val->i = round(rig_raw2val(atoi(retlvl), &rig->caps->str_cal)); break; } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { val->i = round(rig_raw2val(atoi(retlvl), &yaesu_default_str_cal)); } else { // Some Yaesu rigs return straight S-meter answers // Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; } else { val->i = (atoi(retlvl) - 9) * 6; } } break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_KEYSPD: if (rig->caps->rig_model == RIG_MODEL_TS570D || rig->caps->rig_model == RIG_MODEL_TS570S) { // TS570 uses 010-~060 scale according to manual val->i = atoi(retlvl) / 2 + 10; } else { val->i = atoi(retlvl); } break; case RIG_LEVEL_IF: // IS00+0400 rig_debug(RIG_DEBUG_TRACE, "%s: ret_data=%s(%d), retlvl=%s\n", __func__, priv->ret_data, (int)strlen(priv->ret_data), retlvl); if (strlen(priv->ret_data) == 9) { int n = sscanf(priv->ret_data, "IS%*c0%d\n", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse level from %s\n", __func__, priv->ret_data); } } else { val->i = atoi(retlvl); } break; case RIG_LEVEL_VOXDELAY: val->i = atoi(retlvl); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (val->i) { case 0: val->i = 0; break; // 30ms=0 we only do tenths case 1: val->i = 0; break; // 50ms=0 case 2: val->i = 1; break; // 100ms=1 case 3: val->i = 1; break; // 150ms=1 case 4: val->i = 2; break; // 200ms=2 case 5: val->i = 2; break; // 250ms=2 default: val->i = (val->i - 6) + 3; break; } } else { /* VOX delay, arg int (tenth of seconds), rig in ms */ val->i /= 10; // Convert from ms to tenths } break; case RIG_LEVEL_PREAMP: { int preamp; if (retlvl[0] < '0' || retlvl[0] > '9') { RETURNFUNC(-RIG_EPROTO); } preamp = retlvl[0] - '0'; val->i = 0; if (preamp > 0) { for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) { if (i == preamp - 1) { val->i = state->preamp[i]; break; } } } break; } case RIG_LEVEL_ATT: { int att; if (retlvl[0] < '0' || retlvl[0] > '9') { RETURNFUNC(-RIG_EPROTO); } att = retlvl[0] - '0'; val->i = 0; if (att > 0) { for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) { if (i == att - 1) { val->i = state->attenuator[i]; break; } } } break; } case RIG_LEVEL_AGC: switch (retlvl[0]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_SLOW; break; case '4': case '5': case '6': val->i = RIG_AGC_AUTO; break; default: RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_CWPITCH: // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps val->i = (atoi(retlvl) * level_info->step.i) + level_info->min.i; break; case RIG_LEVEL_METER: switch (retlvl[0]) { case '0': val->i = RIG_METER_COMP; break; case '1': val->i = RIG_METER_ALC; break; case '2': val->i = RIG_METER_PO; break; case '3': val->i = RIG_METER_SWR; break; case '4': val->i = RIG_METER_IC; break; /* ID CURRENT */ case '5': val->i = RIG_METER_VDD; break; /* Final Amp Voltage */ default: RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_NOTCHF: val->i = atoi(retlvl) * 10; break; case RIG_LEVEL_NB: // Do not scale the value, level maximum value is set to 10 val->f = (float) atoi(retlvl); break; case RIG_LEVEL_TEMP_METER: // return value in centigrade -- first 3 digits i = 0; sscanf(retlvl, "%3d", &i); val->f = i / 255. * 100.; rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl=%s, i=%d, val=%g\n", __func__, retlvl, i, val->f); break; case RIG_LEVEL_USB_AF: case RIG_LEVEL_USB_AF_INPUT: i = 0; sscanf(retlvl, "%3d", &i); val->f = i * level_info->step.f; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char main_sub_vfo = '0'; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (func) { case RIG_FUNC_ANF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BC0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC && !is_ft2000 && !is_ftdx10) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_MN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP00%03d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC && !is_ft2000 && !is_ftdx10) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_FBKIN: if (!newcat_valid_command(rig, "BI")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BI%d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_TONE: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 2 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_TSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_CSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 3 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_LOCK: if (!newcat_valid_command(rig, "LK")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { // These rigs can lock Main/Sub VFO dials individually SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 7 : 4, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_MON: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML0%03d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_NB: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NB2: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%d%c", status ? 2 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NR: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "NR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NR0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_COMP: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "PR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } if (is_ft891 || is_ft991 || is_ft710 || is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx101d || is_ftdx101mp) { // There seems to be an error in the manuals for some of these rigs stating that values should be 1 = OFF and 2 = ON, but they are 0 = OFF and 1 = ON instead SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0, cat_term); } // Some Yaesu rigs reject this command in AM/FM/RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN || mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_VOX: if (!newcat_valid_command(rig, "VX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VX%d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_TUNER: if (!newcat_valid_command(rig, "AC")) { RETURNFUNC(-RIG_ENAVAIL); } priv->question_mark_response_means_rejected = 1; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC00%d%c", status == 0 ? 0 : status, cat_term); break; case RIG_FUNC_RIT: if (is_ft710) { RETURNFUNC(newcat_set_clarifier(rig, vfo, status, -1)); } else { if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RT%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_XIT: if (is_ft710) { RETURNFUNC(newcat_set_clarifier(rig, vfo, -1, status)); } else { if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "XT%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_APF: if (!newcat_valid_command(rig, "CO")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c2%04d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx10 || is_ft710 || is_ft991 || is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%04d%c", status ? 1 : 0, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%02d%c", main_sub_vfo, status ? 2 : 0, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%02d%c", status ? 2 : 0, cat_term); } else { RETURNFUNC(-RIG_ENIMPL); } priv->question_mark_response_means_rejected = 1; break; case RIG_FUNC_SYNC: if (!newcat_valid_command(rig, "SY")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SY%d%c", status ? 1 : 0, cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_set_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; RETURNFUNC(err); } int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; int last_char_index; char *retfunc; char main_sub_vfo = '0'; ENTERFUNC; if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (func) { case RIG_FUNC_ANF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BC0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_MN: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_FBKIN: if (!newcat_valid_command(rig, "BI")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BI%c", cat_term); break; case RIG_FUNC_TONE: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_TSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_CSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_LOCK: if (!newcat_valid_command(rig, "LK")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%c", cat_term); break; case RIG_FUNC_MON: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML0%c", cat_term); break; case RIG_FUNC_NB: case RIG_FUNC_NB2: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NR: if (!newcat_valid_command(rig, "NR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NR0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_COMP: if (!newcat_valid_command(rig, "PR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ft891 || is_ft991 || is_ft710 || is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR0%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR%c", cat_term); } break; case RIG_FUNC_VOX: if (!newcat_valid_command(rig, "VX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VX%c", cat_term); break; case RIG_FUNC_TUNER: if (!newcat_valid_command(rig, "AC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC%c", cat_term); break; case RIG_FUNC_RIT: if (is_ft710) { RETURNFUNC(newcat_get_clarifier(rig, vfo, status, NULL)); } else { if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RT%c", cat_term); } break; case RIG_FUNC_XIT: if (is_ft710) { RETURNFUNC(newcat_get_clarifier(rig, vfo, NULL, status)); } else { if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "XT%c", cat_term); } break; case RIG_FUNC_APF: if (!newcat_valid_command(rig, "CO")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c2%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft710 || is_ft991 || is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_FUNC_SYNC: if (!newcat_valid_command(rig, "SY")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SY%c", cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_get_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retfunc = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; last_char_index = strlen(retfunc) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: retfunc='%s'\n", __func__, retfunc); switch (func) { case RIG_FUNC_MN: *status = (retfunc[2] == '0') ? 0 : 1; break; case RIG_FUNC_COMP: *status = (retfunc[0] == '0') ? 0 : 1; break; case RIG_FUNC_MON: // The number of digits varies by rig, but the last digit indicates the status always *status = (retfunc[last_char_index] == '0') ? 0 : 1; break; case RIG_FUNC_LOCK: if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { // These rigs can lock Main/Sub VFO dials individually *status = (retfunc[0] == '0' || retfunc[0] == '4') ? 0 : 1; } else { *status = (retfunc[0] == '0') ? 0 : 1; } break; case RIG_FUNC_ANF: case RIG_FUNC_FBKIN: case RIG_FUNC_NR: case RIG_FUNC_VOX: *status = (retfunc[0] == '0') ? 0 : 1; break; case RIG_FUNC_NB: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_NB2: *status = (retfunc[0] == '2') ? 1 : 0; break; case RIG_FUNC_TONE: *status = (retfunc[0] == '2') ? 1 : 0; break; case RIG_FUNC_TSQL: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_CSQL: *status = (retfunc[0] == '3') ? 1 : 0; break; case RIG_FUNC_TUNER: *status = (retfunc[2] == '1') ? 1 : 0; break; case RIG_FUNC_RIT: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_XIT: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_APF: if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { *status = (retfunc[last_char_index] == '1') ? 1 : 0; } else if (is_ftdx5000) { *status = (retfunc[last_char_index] == '2') ? 1 : 0; } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { *status = (retfunc[last_char_index] == '2') ? 1 : 0; } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_FUNC_SYNC: *status = (retfunc[0] == '1') ? 1 : 0; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_parm(RIG *rig, setting_t parm, value_t val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int rigband = 0; int band = 0; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: if (!newcat_valid_command(rig, "BS")) { RETURNFUNC(-RIG_ENAVAIL); } // we should have a string for the desired band rigband = rig_get_band_rig(rig, 0.0, val.s); //rigband = band2rig(rigband); switch (rigband) { case RIG_BAND_160M: band = 0; break; case RIG_BAND_80M: band = 1; break; case RIG_BAND_40M: band = 3; break; case RIG_BAND_30M: band = 4; break; case RIG_BAND_20M: band = 5; break; case RIG_BAND_17M: band = 6; break; case RIG_BAND_15M: band = 7; break; case RIG_BAND_12M: band = 8; break; case RIG_BAND_10M: band = 9; break; case RIG_BAND_6M: band = 10; break; case RIG_BAND_144MHZ: band = 15; break; case RIG_BAND_430MHZ: band = 16; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown band %s=%d\n", __func__, val.s, rigband); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", band, cat_term); retval = newcat_set_cmd(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->band_index = band; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_ENIMPL); } int newcat_get_parm(RIG *rig, setting_t parm, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: if (!newcat_valid_command(rig, "BS")) { RETURNFUNC(-RIG_ENAVAIL); } freq_t freq; retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval != RIG_OK) { RETURNFUNC(retval); } hamlib_band_t band = rig_get_band(rig, freq, 0); val->cs = rig_get_band_str(rig, band, 0); priv->band_index = band; RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_ENAVAIL); } static int newcat_set_maxpower(RIG *rig, vfo_t vfo, hamlib_token_t token, float val) { return -RIG_ENIMPL; } static int newcat_get_maxpower(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int code = 0; int offset = 0; val->i = 0; if (newcat_is_rig(rig, RIG_MODEL_FT991)) { offset = 5; switch (token) { case TOK_MAXPOWER_HF: code = 137; break; case TOK_MAXPOWER_6M: code = 138; break; case TOK_MAXPOWER_VHF: code = 139; break; case TOK_MAXPOWER_UHF: code = 140; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX%03d%c", code, cat_term); } else if (newcat_is_rig(rig, RIG_MODEL_FTDX101MP) || newcat_is_rig(rig, RIG_MODEL_FTDX101D)) { offset = 6; switch (token) { case TOK_MAXPOWER_HF: code = 1; break; case TOK_MAXPOWER_6M: code = 2; break; case TOK_MAXPOWER_4M: code = 3; break; case TOK_MAXPOWER_AM: code = 4; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0304%02d%c", code, cat_term); } retval = newcat_get_cmd(rig); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: offset=%d, scanning '%s'\n", __func__, offset, &priv->ret_data[offset]); sscanf(&priv->ret_data[offset], "%d", &val->i); } return retval; } int newcat_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (token) { case TOK_ROOFING_FILTER: RETURNFUNC(set_roofing_filter(rig, vfo, val.i)); case TOK_KEYER: if (!newcat_valid_command(rig, "KR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KR%d%c", val.i ? 1 : 0, cat_term); RETURNFUNC(newcat_set_cmd(rig)); case TOK_APF_FREQ: RETURNFUNC(newcat_set_apf_frequency(rig, vfo, val.f)); case TOK_APF_WIDTH: RETURNFUNC(newcat_set_apf_width(rig, vfo, val.i)); case TOK_CONTOUR: RETURNFUNC(newcat_set_contour(rig, vfo, val.i)); case TOK_CONTOUR_FREQ: RETURNFUNC(newcat_set_contour_frequency(rig, vfo, val.f)); case TOK_CONTOUR_LEVEL: RETURNFUNC(newcat_set_contour_level(rig, vfo, val.f)); case TOK_CONTOUR_WIDTH: RETURNFUNC(newcat_set_contour_width(rig, vfo, val.f)); case TOK_MAXPOWER_HF: case TOK_MAXPOWER_6M: case TOK_MAXPOWER_VHF: case TOK_MAXPOWER_UHF: RETURNFUNC(newcat_set_maxpower(rig, vfo, token, val.f)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); RETURNFUNC(-RIG_EINVAL); } } int newcat_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *result; int retval; int value; ENTERFUNC; switch (token) { case TOK_ROOFING_FILTER: { struct newcat_roofing_filter *roofing_filter; retval = get_roofing_filter(rig, vfo, &roofing_filter); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = roofing_filter->index; break; } case TOK_KEYER: if (!newcat_valid_command(rig, "KR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KR%c", cat_term); retval = newcat_get_cmd(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } /* skip command */ result = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[strlen(priv->ret_data) - 1] = '\0'; val->i = result[0] == '0' ? 0 : 1; break; case TOK_APF_FREQ: retval = newcat_get_apf_frequency(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_APF_WIDTH: retval = newcat_get_apf_width(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = value; break; case TOK_CONTOUR: retval = newcat_get_contour(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = value; break; case TOK_CONTOUR_WIDTH: retval = newcat_get_contour_width(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_CONTOUR_FREQ: retval = newcat_get_contour_frequency(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_CONTOUR_LEVEL: retval = newcat_get_contour_level(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_MAXPOWER_HF: case TOK_MAXPOWER_6M: case TOK_MAXPOWER_VHF: case TOK_MAXPOWER_UHF: RETURNFUNC(newcat_get_maxpower(rig, vfo, token, val)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int rc; ENTERFUNC; char chan = '1'; if (newcat_is_rig(rig, RIG_MODEL_FT450) && strlen(msg) == 1 && msg[0] > '4') { // 450 manual says 1/2/3 playback needs P1=6/7/8 rig_debug(RIG_DEBUG_ERR, "%s: only messages 1-3 accepted\n", __func__); RETURNFUNC(-RIG_EINVAL); } else { // 5-chan playback 6-A: FT-1200, FT-2000, FT-3000, FTDX-5000, FT-891, FT-9000, FT-950, FT-991, FTDX-101MP/D, FTDX10 // 5-chan but 1-5 playback: FT-710 if (strlen(msg) == 1 && (msg[0] < '1' || msg[0] > '5')) { rig_debug(RIG_DEBUG_ERR, "%s: only messages 1-5 accepted\n", __func__); RETURNFUNC(-RIG_EINVAL); } if (!newcat_is_rig(rig, RIG_MODEL_FT710)) { chan += 5; // 6,7,8 needed for playback } } char *msg2 = strdup(msg); // copy so we can modify it if needed if (strlen(msg2) == 1) { switch (*msg2) { // do all Yaeus rigs play back with chan+5? case '1': msg2[0] = '6'; break; case '2': msg2[0] = '7'; break; case '3': msg2[0] = '8'; break; case '4': msg2[0] = '9'; break; case '5': msg2[0] = 'A'; break; case '6': // we'll let these pass case '7': case '8': case '9': case 'A': case 'a': break; default: RETURNFUNC(-RIG_EINVAL); } } else { if (strlen(msg2) > 50) { msg2[51] = 0; // truncate if too long rig_debug(RIG_DEBUG_ERR, "%s: msg length of %d truncated to 50\n", __func__, (int)strlen(msg)); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KM1%s;", msg2); rc = newcat_set_cmd(rig); if (rc != RIG_OK) { free(msg2); RETURNFUNC(-RIG_EINVAL); } chan = '6'; // the channel we use to key msg 1 } free(msg2); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KY%c%c", chan, cat_term); rc = newcat_set_cmd(rig); RETURNFUNC(rc); } int newcat_set_bank(RIG *rig, vfo_t vfo, int bank) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_mem(RIG *rig, vfo_t vfo, int ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err, i; ncboolean restore_vfo; chan_t *chan_list; channel_t valid_chan; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MC")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (ch >= chan_list[i].startc && ch <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } /* Test for valid usable channel, skip if empty */ memset(&valid_chan, 0, sizeof(channel_t)); valid_chan.channel_num = ch; err = newcat_get_channel(rig, vfo, &valid_chan, 1); if (err < 0) { RETURNFUNC(err); } if (valid_chan.freq <= 1.0) { mem_caps = NULL; } rig_debug(RIG_DEBUG_TRACE, "%s: valChan Freq = %f\n", __func__, valid_chan.freq); /* Out of Range, or empty */ if (!mem_caps) { RETURNFUNC(-RIG_EINVAL); } /* set to usable vfo if needed */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } /* Restore to VFO mode or leave in Memory Mode */ switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: /* Jump back from memory channel */ restore_vfo = TRUE; break; case RIG_VFO_MEM: /* Jump from channel to channel in memory mode */ restore_vfo = FALSE; break; case RIG_VFO_B: case RIG_VFO_SUB: default: /* Only works with VFO A */ RETURNFUNC(-RIG_ENTARGET); } /* Set Memory Channel Number ************** */ rig_debug(RIG_DEBUG_TRACE, "channel_num = %d, vfo = %s\n", ch, rig_strvfo(vfo)); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%03d%c", ch, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } /* Restore VFO even if setting to blank memory channel */ if (restore_vfo) { err = newcat_vfomem_toggle(rig); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } int newcat_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; ENTERFUNC; if (!newcat_valid_command(rig, "MC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%c", cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Memory Channel Number */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } *ch = atoi(priv->ret_data + 2); RETURNFUNC(RIG_OK); } int newcat_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char main_sub_vfo = '0'; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (op) { case RIG_OP_TUNE: if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC003%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC002%c", cat_term); } break; case RIG_OP_CPY: if (newcat_is_rig(rig, RIG_MODEL_FT450)) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VV%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB%c", cat_term); } break; case RIG_OP_XCHG: case RIG_OP_TOGGLE: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SV%c", cat_term); break; case RIG_OP_UP: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "UP%c", cat_term); break; case RIG_OP_DOWN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DN%c", cat_term); break; case RIG_OP_BAND_UP: if (main_sub_vfo == 1) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BU1%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BU0%c", cat_term); } break; case RIG_OP_BAND_DOWN: if (main_sub_vfo == 1) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BD1%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BD0%c", cat_term); } break; case RIG_OP_FROM_VFO: /* VFOA ! */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AM%c", cat_term); break; case RIG_OP_TO_VFO: /* VFOA ! */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MA%c", cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; if (scan != RIG_SCAN_VFO) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SC%d%c", scan == RIG_SCAN_STOP ? 0 : ch, cat_term); if (RIG_OK != (retval = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, retval); RETURNFUNC(retval); } RETURNFUNC(retval); } int newcat_set_trn(RIG *rig, int trn) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; ENTERFUNC; if (!newcat_valid_command(rig, "AI")) { RETURNFUNC(-RIG_ENAVAIL); } if (trn == RIG_TRN_OFF) { c = '0'; } else { c = '1'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AI%c%c", c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_trn(RIG *rig, int *trn) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "AI"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); /* Get Auto Information */ if (RIG_OK != newcat_get_cmd(rig)) { // if we failed to get AI we turn it off and try again SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s0%c", command, cat_term); hl_usleep(500 * 1000); // is 500ms enough for the rig to stop sending info? newcat_set_cmd(rig); // don't care about any errors here SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); err = newcat_get_cmd(rig); RETURNFUNC(err); } c = priv->ret_data[2]; if (c == '0') { *trn = RIG_TRN_OFF; } else { *trn = RIG_TRN_RIG; } RETURNFUNC(RIG_OK); } int newcat_decode_event(RIG *rig) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct rig_state *state = STATE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)state->priv; int err, i; int rxit; char c_rit, c_xit, c_mode, c_vfo, c_tone, c_rptr_shift; tone_t tone; ncboolean restore_vfo; chan_t *chan_list; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MW")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (chan->channel_num >= chan_list[i].startc && chan->channel_num <= chan_list[i].endc && // writable memory types... NOT 60-METERS or READ-ONLY channels (chan_list[i].type == RIG_MTYPE_MEM || chan_list[i].type == RIG_MTYPE_EDGE)) { mem_caps = &chan_list[i].mem_caps; break; } } /* Out of Range */ if (!mem_caps) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Restore to VFO or leave in memory mode */ switch (state->current_vfo) { case RIG_VFO_A: case RIG_VFO_B: /* Jump back from memory channel */ restore_vfo = TRUE; break; case RIG_VFO_MEM: /* Jump from channel to channel in memory mode */ restore_vfo = FALSE; break; case RIG_VFO_SUB: default: /* Only works with VFO Main */ RETURNFUNC(-RIG_ENTARGET); } /* Write Memory Channel ************************* */ /* Clarifier TX, RX */ if (chan->rit) { rxit = chan->rit; c_rit = '1'; c_xit = '0'; } else if (chan->xit) { rxit = chan->xit; c_rit = '0'; c_xit = '1'; } else { rxit = 0; c_rit = '0'; c_xit = '0'; } /* MODE */ c_mode = newcat_modechar(chan->mode); /* VFO Fixed */ c_vfo = '0'; /* CTCSS Tone / Sql */ if (chan->ctcss_tone) { c_tone = '2'; tone = chan->ctcss_tone; } else if (chan->ctcss_sql) { c_tone = '1'; tone = chan->ctcss_sql; } else { c_tone = '0'; tone = 0; } for (i = 0; rig->caps->ctcss_list[i] != 0; i++) if (tone == rig->caps->ctcss_list[i]) { tone = i; if (tone > 49) { tone = 0; } break; } /* Repeater Shift */ switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE: c_rptr_shift = '0'; break; case RIG_RPT_SHIFT_PLUS: c_rptr_shift = '1'; break; case RIG_RPT_SHIFT_MINUS: c_rptr_shift = '2'; break; default: c_rptr_shift = '0'; } if (priv->width_frequency == 9) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MW%03d%09d%+.4d%c%c%c%c%c%02u%c%c", chan->channel_num, (int)chan->freq, rxit, c_rit, c_xit, c_mode, c_vfo, c_tone, tone, c_rptr_shift, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MW%03d%08d%+.4d%c%c%c%c%c%02u%c%c", chan->channel_num, (int)chan->freq, rxit, c_rit, c_xit, c_mode, c_vfo, c_tone, tone, c_rptr_shift, cat_term); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Set Memory Channel */ priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } /* Restore VFO ********************************** */ if (restore_vfo) { err = newcat_vfomem_toggle(rig); RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int newcat_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; char c, c2; int err, i; chan_t *chan_list; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MR")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (chan->channel_num >= chan_list[i].startc && chan->channel_num <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } /* Out of Range */ if (!mem_caps) { RETURNFUNC(-RIG_ENAVAIL); } rig_debug(RIG_DEBUG_TRACE, "sizeof(channel_t) = %d\n", (int)sizeof(channel_t)); rig_debug(RIG_DEBUG_TRACE, "sizeof(priv->cmd_str) = %d\n", (int)sizeof(priv->cmd_str)); if (is_ftdx101d || is_ftdx101mp || is_ft991 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MT%03d%c", chan->channel_num, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MR%03d%c", chan->channel_num, cat_term); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Memory Channel */ priv->question_mark_response_means_rejected = 1; err = newcat_get_cmd(rig); priv->question_mark_response_means_rejected = 0; if (RIG_OK != err) { if (-RIG_ERJCTED == err) { /* Invalid channel, has not been set up, make sure freq is 0 to indicate empty channel */ chan->freq = 0.; RETURNFUNC(RIG_OK); } RETURNFUNC(err); } int offset = 0; if (priv->width_frequency == 9) { offset = 1; } /* ret_data string to channel_t struct :: this will destroy ret_data */ /* rptr_shift P10 ************************ */ retval = priv->ret_data + 25 + offset; switch (*retval) { 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; default: chan->rptr_shift = RIG_RPT_SHIFT_NONE; } *retval = '\0'; /* CTCSS Encoding P8 ********************* */ retval = priv->ret_data + 22 + offset; c = *retval; /* CTCSS Tone P9 ************************* */ chan->ctcss_tone = 0; chan->ctcss_sql = 0; retval = priv->ret_data + 23 + offset; i = atoi(retval); if (c == '1') { chan->ctcss_sql = rig->caps->ctcss_list[i]; } else if (c == '2') { chan->ctcss_tone = rig->caps->ctcss_list[i]; } /* vfo, mem, P7 ************************** */ retval = priv->ret_data + 21 + offset; if (*retval == '1') { chan->vfo = RIG_VFO_MEM; } else { chan->vfo = RIG_VFO_CURR; } /* MODE P6 ******************************* */ chan->width = 0; retval = priv->ret_data + 20 + offset; chan->mode = newcat_rmode(*retval); if (chan->mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%c\n", __func__, *retval); chan->mode = RIG_MODE_LSB; } /* Clarifier TX P5 *********************** */ retval = priv->ret_data + 19 + offset; c2 = *retval; /* Clarifier RX P4 *********************** */ retval = priv->ret_data + 18 + offset; c = *retval; *retval = '\0'; /* Clarifier Offset P3 ******************* */ chan->rit = 0; chan->xit = 0; retval = priv->ret_data + 13 + offset; if (c == '1') { chan->rit = atoi(retval); } else if (c2 == '1') { chan->xit = atoi(retval); } *retval = '\0'; /* Frequency P2 ************************** */ retval = priv->ret_data + 5; chan->freq = atof(retval); chan->tag[0] = '?'; // assume nothing if (priv->ret_data[28] != ';') // must have TAG data? { // get the TAG data sscanf(&priv->ret_data[28], "%31s", chan->tag); char *p = strchr(chan->tag, ';'); if (p) { *p = 0; } } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } const char *newcat_get_info(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; static char idbuf[129]; /* extra large static string array */ /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ID;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Identification Channel */ if (RIG_OK != newcat_get_cmd(rig)) { return (NULL); } priv->ret_data[6] = '\0'; SNPRINTF(idbuf, sizeof(idbuf), "%s", priv->ret_data); return (idbuf); } /* * newcat_valid_command * * Determine whether or not the command is valid for the specified * rig. This function should be called before sending the command * to the rig to make it easier to differentiate invalid and illegal * commands (for a rig). */ ncboolean newcat_valid_command(RIG *rig, char const *const command) { struct rig_caps *caps; int search_high; int search_low; rig_debug(RIG_DEBUG_TRACE, "%s %s\n", __func__, command); caps = rig->caps; if (!caps) { rig_debug(RIG_DEBUG_ERR, "%s: Rig capabilities not valid\n", __func__); RETURNFUNC2(FALSE); } if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000 && !is_ftdx5000 && !is_ftdx9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101d && !is_ftdx101mp && !is_ftdx10 && !is_ft710) { rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", __func__, caps->model_name); RETURNFUNC2(FALSE); } /* * Make sure the command is known, and then check to make sure * is it valid for the rig. */ search_low = 0; search_high = valid_commands_count; while (search_low <= search_high) { int search_test; int search_index; search_index = (search_low + search_high) / 2; search_test = strcmp(valid_commands[search_index].command, command); if (search_test > 0) { search_high = search_index - 1; } else if (search_test < 0) { search_low = search_index + 1; } else { /* * The command is valid. Now make sure it is supported by the rig. */ if (is_ft450 && valid_commands[search_index].ft450) { RETURNFUNC2(TRUE); } else if (is_ft891 && valid_commands[search_index].ft891) { RETURNFUNC2(TRUE); } else if (is_ft950 && valid_commands[search_index].ft950) { RETURNFUNC2(TRUE); } else if (is_ft991 && valid_commands[search_index].ft991) { RETURNFUNC2(TRUE); } else if (is_ft2000 && valid_commands[search_index].ft2000) { RETURNFUNC2(TRUE); } else if (is_ftdx5000 && valid_commands[search_index].ft5000) { RETURNFUNC2(TRUE); } else if (is_ftdx9000 && valid_commands[search_index].ft9000) { RETURNFUNC2(TRUE); } else if (is_ftdx1200 && valid_commands[search_index].ft1200) { RETURNFUNC2(TRUE); } else if (is_ftdx3000 && valid_commands[search_index].ft3000) { RETURNFUNC2(TRUE); } else if (is_ftdx3000dm && valid_commands[search_index].ft3000) { RETURNFUNC2(TRUE); } else if (is_ftdx101d && valid_commands[search_index].ft101d) { RETURNFUNC2(TRUE); } else if (is_ftdx101mp && valid_commands[search_index].ft101mp) { RETURNFUNC2(TRUE); } else if (is_ftdx10 && valid_commands[search_index].ftdx10) { RETURNFUNC2(TRUE); } else if (is_ft710 && valid_commands[search_index].ft710) { RETURNFUNC2(TRUE); } else { rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not supported\n", __func__, caps->model_name, command); RETURNFUNC2(FALSE); } } } rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not valid\n", __func__, caps->model_name, command); RETURNFUNC2(FALSE); } ncboolean newcat_is_rig(RIG *rig, rig_model_t model) { ncboolean is_rig; //a bit too verbose so disable this unless needed //rig_debug(RIG_DEBUG_TRACE, "%s(%d):%s called\n", __FILE__, __LINE__, __func__); is_rig = (model == rig->caps->rig_model) ? TRUE : FALSE; return (is_rig); // RETURN is too verbose here } int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char *command = "FT"; int result; char p1; ENTERFUNC; if (!newcat_valid_command(rig, "FT")) { RETURNFUNC(-RIG_ENAVAIL); } result = newcat_set_vfo_from_alias(rig, &tx_vfo); if (result < 0) { RETURNFUNC(result); } switch (tx_vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: p1 = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: p1 = '1'; break; case RIG_VFO_MEM: /* VFO A */ if (priv->current_mem == NC_MEM_CHANNEL_NONE) { RETURNFUNC(RIG_OK); } else /* Memory Channel mode */ { p1 = '0'; } break; default: RETURNFUNC(-RIG_EINVAL); } // NOTE: FT-450 only has toggle command so not sure how to definitively set the TX VFO (VS; doesn't seem to help either) if (is_ft950 || is_ft2000 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx1200 || is_ft991 || is_ftdx10 || is_ftdx101d || is_ftdx101mp) { // These rigs use numbers 2 and 3 to denote A/B or Main/Sub VFOs - 0 and 1 are for toggling TX function p1 = p1 + 2; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, p1, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s, vfo=%s\n", priv->cmd_str, rig_strvfo(tx_vfo)); result = newcat_set_cmd(rig); if (result != RIG_OK) { RETURNFUNC(result); } STATE(rig)->tx_vfo = tx_vfo; RETURNFUNC(result); } int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char const *command = "FT"; vfo_t vfo_mode; int result; char c; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); if (RIG_OK != (result = newcat_get_cmd(rig))) { RETURNFUNC(result); } c = priv->ret_data[2]; switch (c) { case '0': if (STATE(rig)->vfo_list & RIG_VFO_MAIN) { *tx_vfo = RIG_VFO_MAIN; } else { *tx_vfo = RIG_VFO_A; } break; case '1' : if (STATE(rig)->vfo_list & RIG_VFO_SUB) { *tx_vfo = RIG_VFO_SUB; } else { *tx_vfo = RIG_VFO_B; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown tx_vfo=%c from index 2 of %s\n", __func__, c, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } /* Check to see if RIG is in MEM mode */ result = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (result != RIG_OK) { RETURNFUNC(result); } if (vfo_mode == RIG_VFO_MEM && *tx_vfo == RIG_VFO_A) { *tx_vfo = RIG_VFO_MEM; } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = %s\n", __func__, rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } static int newcat_set_split(RIG *rig, split_t split, vfo_t *rx_vfo, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char *command = "ST"; char p1; int result; ENTERFUNC; if (!newcat_valid_command(rig, "ST") || is_ft450 || priv->split_st_command_missing) { RETURNFUNC(-RIG_ENAVAIL); } result = newcat_set_vfo_from_alias(rig, tx_vfo); if (result < 0) { RETURNFUNC(result); } switch (split) { case RIG_SPLIT_OFF: p1 = '0'; break; case RIG_SPLIT_ON: p1 = '1'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, p1, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s, vfo=%s\n", priv->cmd_str, rig_strvfo(*tx_vfo)); result = newcat_set_cmd(rig); if (result != RIG_OK) { priv->split_st_command_missing = 1; RETURNFUNC(result); } switch (split) { case RIG_SPLIT_OFF: *rx_vfo = STATE(rig)->current_vfo; *tx_vfo = STATE(rig)->current_vfo; break; case RIG_SPLIT_ON: // These rigs have fixed RX and TX VFOs when using the ST split command if (is_ftdx101d || is_ftdx101mp) { *rx_vfo = RIG_VFO_MAIN; *tx_vfo = RIG_VFO_SUB; } else if (is_ftdx10) { *rx_vfo = RIG_VFO_A; *tx_vfo = RIG_VFO_B; } else { *rx_vfo = STATE(rig)->current_vfo; result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(result); } static int newcat_get_split(RIG *rig, split_t *split, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char const *command = "ST"; int result; char c; ENTERFUNC; if (!newcat_valid_command(rig, "ST") || is_ft450 || priv->split_st_command_missing) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); result = newcat_get_cmd(rig); if (result != RIG_OK) { priv->split_st_command_missing = 1; RETURNFUNC(result); } c = priv->ret_data[2]; switch (c) { case '0': *split = RIG_SPLIT_OFF; result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } break; case '1' : *split = RIG_SPLIT_ON; // These rigs have fixed RX and TX VFOs when using the ST split command if (is_ftdx101d || is_ftdx101mp) { *tx_vfo = RIG_VFO_SUB; } else if (is_ftdx10) { *tx_vfo = RIG_VFO_B; } else { result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown split=%c from index 2 of %s\n", __func__, c, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = %s\n", __func__, rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: alias vfo = %s\n", __func__, rig_strvfo(*vfo)); if (*vfo == RIG_VFO_NONE) { int rc = rig_get_vfo(rig, vfo); if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_vfo failed: %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(rc); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo==None so get vfo=%s\n", __func__, rig_strvfo(*vfo)); } switch (*vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MEM: /* passes through */ break; case RIG_VFO_CURR: /* RIG_VFO_RX == RIG_VFO_CURR */ case RIG_VFO_VFO: *vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: /* set to another vfo for split or uplink */ if (STATE(rig)->vfo_list & RIG_VFO_MAIN) { *vfo = (STATE(rig)->current_vfo == RIG_VFO_SUB) ? RIG_VFO_MAIN : RIG_VFO_SUB; } else { *vfo = (STATE(rig)->current_vfo == RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_B; } break; case RIG_VFO_MAIN: *vfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB: *vfo = RIG_VFO_SUB; break; default: rig_debug(RIG_DEBUG_TRACE, "Unrecognized. vfo= %s\n", rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "NA")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (narrow == TRUE) { c = '1'; } else { c = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c%c", main_sub_vfo, c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "NA"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get NAR */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; if (c == '1') { *narrow = TRUE; } else { *narrow = FALSE; } RETURNFUNC(RIG_OK); } // returns 1 if in narrow mode 0 if not, < 0 if error // if vfo != RIG_VFO_NONE then will use NA0 or NA1 depending on vfo Main or Sub static int get_narrow(RIG *rig, vfo_t vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int narrow = 0; int err; ENTERFUNC; // find out if we're in narrow or wide mode SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c", vfo == RIG_VFO_SUB ? '1' : '0', cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (sscanf(priv->ret_data, "NA%*1d%3d", &narrow) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(narrow); } int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int w = 0; char main_sub_vfo = '0'; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (!newcat_valid_command(rig, "SH")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_SUB == vfo) ? '1' : '0'; } // NOTE: RIG_PASSBAND_NORMAL (0) should select the default filter width (SH00) if (is_ft950) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 100) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 300) { w = 5; } else if (width <= 400) { w = 6; } else if (width <= 500) { w = 7; } else if (width <= 800) { w = 8; } else if (width <= 1200) { w = 9; } else if (width <= 1400) { w = 10; } else if (width <= 1700) { w = 11; } else if (width <= 2000) { w = 12; } else { w = 13; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2250) { w = 12; } else if (width <= 2400) { w = 13; } else if (width <= 2450) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else { w = 20; } // 3000 Hz break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: RETURNFUNC(RIG_OK); } } // end is_ft950 */ else if (is_ft891) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else if (width <= 2400) { w = 16; } else { w = 17; } // 3000 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else { w = 21; } // 3000 Hz break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) } // end is_ft891 else if (is_ft991) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else if (width <= 2400) { w = 16; } else { w = 17; } // 3000 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else { w = 21; } // 3200 Hz break; case RIG_MODE_AM: // Only 1 passband each for AM or AMN if (width == RIG_PASSBAND_NORMAL || width == 9000) { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_AMN: if (width == RIG_PASSBAND_NORMAL || width == 6000) { err = newcat_set_narrow(rig, vfo, TRUE); } RETURNFUNC(err); case RIG_MODE_FM: // Only 1 passband each for FM or FMN if (width == RIG_PASSBAND_NORMAL || width == 16000) { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: if (width == RIG_PASSBAND_NORMAL || width == 9000) { err = newcat_set_narrow(rig, vfo, TRUE); } RETURNFUNC(err); case RIG_MODE_C4FM: if (width == RIG_PASSBAND_NORMAL || width == 16000) { err = newcat_set_narrow(rig, vfo, TRUE); } else if (width == 9000) { err = newcat_set_narrow(rig, vfo, FALSE); } else { RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(err); case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) } // end is_ft991 else if (is_ftdx1200 || is_ftdx3000) { // FTDX 1200 and FTDX 3000 have the same set of filter choices switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else { w = 16; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3400) { w = 22; } else if (width <= 3600) { w = 23; } else if (width <= 3800) { w = 24; } else { w = 25; } // 4000 Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } // end is_ftdx1200 and is_ftdx3000 else if (is_ftdx5000) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else { w = 16; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2250) { w = 12; } else if (width <= 2400) { w = 13; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3400) { w = 22; } else if (width <= 3600) { w = 23; } else if (width <= 3800) { w = 24; } else { w = 25; } // 4000 Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } // end is_ftdx5000 else if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 600) { w = 11; } else if (width <= 800) { w = 12; } else if (width <= 1200) { w = 13; } else if (width <= 1400) { w = 14; } else if (width <= 1700) { w = 15; } else if (width <= 2000) { w = 16; } else if (width <= 2400) { w = 17; } else if (width <= 3000) { w = 18; } else if (width <= 3200) { w = 19; } else if (width <= 3500) { w = 20; } else { w = 21; } // 4000Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 300) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1200) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3500) { w = 22; } else { w = 23; } // 4000Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_AMN: case RIG_MODE_FMN: RETURNFUNC(RIG_OK); } } // end is_ftdx101 else if (is_ft2000) { // We need details on the widths here, manuals lack information. switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); // CW bandwidth is 2400 Hz at value 16 if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 200) { w = 4; } else if (width <= 500) { w = 6; } else if (width <= 2400) { w = 16; } else { w = 31; } // No effect? break; case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); // Packet SSB bandwidth is 2400 Hz at value 31 if (width == RIG_PASSBAND_NORMAL) { w = 31; } else if (width <= 200) { w = 8; } else if (width <= 500) { w = 16; } else { w = 31; } // 2400 break; case RIG_MODE_RTTY: case RIG_MODE_RTTYR: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 300) { w = 8; } else if (width <= 500) { w = 16; } else { w = 31; } // 2400 break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 1800) { w = 8; } else if (width <= 2400) { w = 16; } else if (width <= 3000) { w = 25; } else { w = 31; } // 4000 break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_AMN: case RIG_MODE_FMN: RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } else { // FT-450, FTDX 9000 // We need details on the widths here, manuals lack information. switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 500) { w = 6; } else if (width <= 1800) { w = 16; } else { w = 24; } break; case RIG_MODE_LSB: case RIG_MODE_USB: if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 1800) { w = 8; } else if (width <= 2400) { w = 16; } else { w = 25; } // 3000 break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end else */ if (is_ftdx101d || is_ftdx101mp || is_ft891) { // some rigs now require the bandwidth be turned "on" int on = is_ft891; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH%c%d%02d;", main_sub_vfo, on, w); } else if (is_ft2000 || is_ftdx3000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH0%02d;", w); } else if (is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH00%02d;", w); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH%c%02d;", main_sub_vfo, w); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Set RX Bandwidth */ RETURNFUNC(newcat_set_cmd(rig)); } static int set_roofing_filter(RIG *rig, vfo_t vfo, int index) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; struct newcat_roofing_filter *roofing_filters; char main_sub_vfo = '0'; char roofing_filter_choice = 0; int err; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } roofing_filters = priv_caps->roofing_filters; if (rig->caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (!newcat_valid_command(rig, "RF")) { RETURNFUNC(-RIG_ENAVAIL); } for (i = 0; roofing_filters[i].index >= 0; i++) { const struct newcat_roofing_filter *current_filter = &roofing_filters[i]; char set_value = current_filter->set_value; if (set_value == 0) { continue; } roofing_filter_choice = set_value; if (current_filter->index == index) { break; } } if (roofing_filter_choice == 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c%c", main_sub_vfo, roofing_filter_choice, cat_term); priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (RIG_OK != err) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width) { struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; int index = 0; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } for (i = 0; i < priv_caps->roofing_filter_count; i++) { const struct newcat_roofing_filter *current_filter = &priv_caps->roofing_filters[i]; char set_value = current_filter->set_value; // Skip get-only values and optional filters if (set_value == 0 || current_filter->optional) { continue; } // The last filter is always the narrowest if (current_filter->width < width) { break; } index = current_filter->index; } RETURNFUNC(set_roofing_filter(rig, vfo, index)); } static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; struct newcat_roofing_filter *roofing_filters; char roofing_filter_choice; char main_sub_vfo = '0'; char rf_vfo = 'X'; int err; int n; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } roofing_filters = priv_caps->roofing_filters; if (rig->caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo, cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter_choice); if (n != 2) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing '%s' for vfo and roofing filter, got %d parsed\n", __func__, priv->ret_data, n); RETURNFUNC(-RIG_EPROTO); } for (i = 0; i < priv_caps->roofing_filter_count; i++) { struct newcat_roofing_filter *current_filter = &roofing_filters[i]; if (current_filter->get_value == roofing_filter_choice) { *roofing_filter = current_filter; RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: Expected a valid roofing filter but got %c from '%s'\n", __func__, roofing_filter_choice, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int w; int sh_command_valid = 1; int narrow = 0; char cmd[] = "SH"; char main_sub_vfo = '0'; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s vfo=%s, mode=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode)); if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (is_ft950 || is_ftdx5000 || is_ftdx3000) { // Some Yaesu rigs cannot query SH in modes such as AM/FM switch (mode) { case RIG_MODE_FM: case RIG_MODE_FMN: case RIG_MODE_PKTFM: case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_PKTAM: sh_command_valid = 0; break; } } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (sh_command_valid) { if (is_ft2000 || is_ftdx10 || is_ftdx3000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s0%c", cmd, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, cat_term); } err = newcat_get_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } w = 0; // use default in case of error if (strlen(priv->ret_data) == 7) { int on; // do we need to pay attention to the Main/Sub here? int n = sscanf(priv->ret_data, "SH%*1d%1d%3d", &on, &w); if (n != 2) { err = -RIG_EPROTO; } #if 0 // this may apply to another Yaesu rig if (n == 2) { if (!on) { w = 0; } } else { err = -RIG_EPROTO; } #endif } else if (strlen(priv->ret_data) == 6) { int n = sscanf(priv->ret_data, "SH%3d", &w); if (n != 1) { err = -RIG_EPROTO; } } else { err = -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } } else { // Some Yaesu rigs cannot query filter width using SH command in modes such as AM/FM w = 0; } if (is_ft950) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 300 : 500; break; case 3: *width = 100; break; case 4: *width = 200; break; case 5: *width = 300; break; case 6: *width = 400; break; case 7: *width = 5000; break; case 8: *width = 800; break; case 9: *width = 1200; break; case 10: *width = 1400; break; case 11: *width = 1700; break; case 12: *width = 2000; break; case 13: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1800 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; case 14: *width = 2450; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft950 */ else if (is_ft891) { if ((narrow = get_narrow(rig, vfo)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error narrow < 0, narrow=%d\n", __func__, narrow); RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; } else { *width = narrow ? 300 : 500; } break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; case 17: *width = 3000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown w=%d\n", __func__, w); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_PKTFM: *width = 16000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft891 */ else if (is_ft991) { // some modes are fixed and can't be queried with "NA0" if (mode != RIG_MODE_C4FM && mode != RIG_MODE_PKTFM && mode != RIG_MODE_PKTFMN && (narrow = get_narrow(rig, vfo)) < 0) { RETURNFUNC(-RIG_EPROTO); } narrow = 0; switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; } else { *width = narrow ? 300 : 500; } break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; case 17: *width = 3000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_C4FM: case RIG_MODE_PKTFM: *width = 16000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft991 */ else if (is_ftdx1200 || is_ftdx3000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 500 : 2400; break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; case 14: *width = 2450; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3400; break; case 23: *width = 3600; break; case 24: *width = 3800; break; case 25: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ftdx1200 or is_ftdx3000 */ else if (is_ftdx5000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 500 : 2400; break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; // 14 is not defined for FTDX 5000, but leaving here for completeness case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3400; break; case 23: *width = 3600; break; case 24: *width = 3800; break; case 25: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ftdx5000 */ else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { rig_debug(RIG_DEBUG_TRACE, "%s: is_ftdx101 w=%d, mode=%s\n", __func__, w, rig_strrmode(mode)); if (w == 0) // then we need to know the roofing filter { struct newcat_roofing_filter *roofing_filter; err = get_roofing_filter(rig, vfo, &roofing_filter); if (err == RIG_OK) { *width = roofing_filter->width; } } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: break; /* use roofing filter width */ case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 600; break; case 12: *width = 800; break; case 13: *width = 1200; break; case 14: *width = 1400; break; case 15: *width = 1700; break; case 16: *width = 2000; break; case 17: *width = 2400; break; case 18: *width = 3000; break; case 19: *width = 3200; break; case 20: *width = 3500; break; case 21: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: break; /* use roofing filter width */ case 1: *width = 300; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1200; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3500; break; case 23: *width = 4000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown width=%d\n", __func__, w); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: case RIG_MODE_PKTFMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_PKTFM: *width = 16000; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: bad mode\n", __func__); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ rig_debug(RIG_DEBUG_TRACE, "%s: end if FTDX101D\n", __func__); } /* end if is_ftdx101 */ else if (is_ft2000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: if (w <= 4) { *width = 200; } else if (w <= 6) { *width = 500; } else if (w <= 16) { *width = 2400; } else { *width = 3000; } break; case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: if (w <= 8) { *width = 200; } else if (w <= 16) { *width = 500; } else { *width = 2400; } break; case RIG_MODE_RTTY: case RIG_MODE_RTTYR: if (w <= 8) { *width = 300; } else if (w <= 16) { *width = 500; } else { *width = 2400; } break; case RIG_MODE_LSB: case RIG_MODE_USB: if (w <= 8) { *width = 1800; } else if (w <= 16) { *width = 2400; } else if (w <= 25) { *width = 3000; } else { *width = 4000; } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch (mode) */ } /* end if is_ft2000 */ else { /* FT450, FT9000 */ switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_LSB: case RIG_MODE_USB: if (w < 16) { *width = rig_passband_narrow(rig, mode); } else if (w > 16) { *width = rig_passband_wide(rig, mode); } else { *width = rig_passband_normal(rig, mode); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch (mode) */ } /* end else */ rig_debug(RIG_DEBUG_TRACE, "%s: RETURNFUNC(RIG_OK)\n", __func__); RETURNFUNC(RIG_OK); } int newcat_set_faststep(RIG *rig, ncboolean fast_step) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; ENTERFUNC; if (!newcat_valid_command(rig, "FS")) { RETURNFUNC(-RIG_ENAVAIL); } if (fast_step == TRUE) { c = '1'; } else { c = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FS%c%c", c, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_faststep(RIG *rig, ncboolean *fast_step) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "FS"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); /* Get Fast Step */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[2]; if (c == '1') { *fast_step = TRUE; } else { *fast_step = FALSE; } RETURNFUNC(RIG_OK); } int newcat_get_rigid(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; const char *s = NULL; ENTERFUNC; /* if first valid get */ if (priv->rig_id == NC_RIGID_NONE) { s = newcat_get_info(rig); if (s != NULL) { s += 2; /* ID0310, jump past ID */ priv->rig_id = atoi(s); is_ftdx3000dm = priv->rig_id == NC_RIGID_FTDX3000DM; } rig_debug(RIG_DEBUG_TRACE, "rig_id = %d, idstr = %s\n", priv->rig_id, s == NULL ? "NULL" : s); } else { rig_debug(RIG_DEBUG_TRACE, "rig_id = %d\n", priv->rig_id); } RETURNFUNC(priv->rig_id); } /* * input: RIG *, vfo_t * * output: VFO mode: RIG_VFO_VFO for VFO A or B * RIG_VFO_MEM for VFO MEM * return: RIG_OK or error */ int newcat_get_vfo_mode(RIG *rig, vfo_t vfo, vfo_t *vfo_mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } /* Get VFO Information ****************** */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (STATE(rig)->powerstat == 0) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } /* vfo, mem, P7 ************************** */ // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 21; priv->width_frequency = 8; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 22; priv->width_frequency = 9; break; default: rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %d\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_TRACE, "%s: offset=%d, width_frequency=%d\n", __func__, offset, priv->width_frequency); switch (priv->ret_data[offset]) { case '0': *vfo_mode = RIG_VFO_VFO; break; case '1': /* Memory */ case '2': /* Memory Tune */ case '3': /* Quick Memory Bank */ case '4': /* Quick Memory Bank Tune */ default: *vfo_mode = RIG_VFO_MEM; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo mode = %s\n", __func__, rig_strvfo(*vfo_mode)); RETURNFUNC(err); } /* * Writes data and waits for response * input: complete CAT command string including termination in cmd_str * output: complete CAT command answer string in ret_data * return: RIG_OK or error */ int newcat_vfomem_toggle(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char command[] = "VM"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* copy set command */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } /* * Writes a null terminated command string from priv->cmd_str to the * CAT port and returns a response from the rig in priv->ret_data * which is also null terminated. * * Honors the 'retry' capabilities field by resending the command up * to 'retry' times until a valid response is received. In the special * cases of receiving a valid response to a different command or the * "?;" busy please wait response; the command is not resent but up to * 'retry' retries to receive a valid response are made. */ int newcat_get_cmd(RIG *rig) { struct rig_state *state = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retry_count = 0; int rc = -RIG_EPROTO; int is_read_cmd = 0; int is_power_status_cmd = strncmp(priv->cmd_str, "PS", 2) == 0; ENTERFUNC; priv->ret_data[0] = 0; // ensure zero-length ret_data by default if (state->powerstat == 0 && !is_power_status_cmd) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } // try to cache rapid repeats of the IF command // this is for WSJT-X/JTDX sequence of v/f/m/t // should allow rapid repeat of any call using the IF; cmd // Any call that changes something in the IF response should invalidate the cache if (strcmp(priv->cmd_str, "IF;") == 0 && priv->cache_start.tv_sec != 0) { int cache_age_ms; cache_age_ms = elapsed_ms(&priv->cache_start, 0); if (cache_age_ms < 500) // 500ms cache time { rig_debug(RIG_DEBUG_TRACE, "%s: cache hit, age=%dms\n", __func__, cache_age_ms); strcpy(priv->ret_data, priv->last_if_response); RETURNFUNC(RIG_OK); } // we drop through and do the real IF command } // any command that is read only should not expire cache is_read_cmd = strcmp(priv->cmd_str, "AG0;") == 0 || strcmp(priv->cmd_str, "AG1;") == 0 || strcmp(priv->cmd_str, "AN0;") == 0 || strcmp(priv->cmd_str, "AN1;") == 0 || strcmp(priv->cmd_str, "BP00;") == 0 || strcmp(priv->cmd_str, "BP01;") == 0 || strcmp(priv->cmd_str, "BP10;") == 0 || strcmp(priv->cmd_str, "BP11;") == 0 || strcmp(priv->cmd_str, "CN00;") == 0 || strcmp(priv->cmd_str, "CN10;") == 0 || strcmp(priv->cmd_str, "CO00;") == 0 || strcmp(priv->cmd_str, "CO01;") == 0 || strcmp(priv->cmd_str, "CO02;") == 0 || strcmp(priv->cmd_str, "CO03;") == 0 || strcmp(priv->cmd_str, "CO10;") == 0 || strcmp(priv->cmd_str, "CO11;") == 0 || strcmp(priv->cmd_str, "CO12;") == 0 || strcmp(priv->cmd_str, "CO13;") == 0 || strcmp(priv->cmd_str, "IS0;") == 0 || strcmp(priv->cmd_str, "IS1;") == 0 || strcmp(priv->cmd_str, "MD0;") == 0 || strcmp(priv->cmd_str, "MD1;") == 0 || strcmp(priv->cmd_str, "NA0;") == 0 || strcmp(priv->cmd_str, "NA1;") == 0 || strcmp(priv->cmd_str, "NB0;") == 0 || strcmp(priv->cmd_str, "NB1;") == 0 || strcmp(priv->cmd_str, "NL0;") == 0 || strcmp(priv->cmd_str, "NL1;") == 0 || strcmp(priv->cmd_str, "NR0;") == 0 || strcmp(priv->cmd_str, "NR1;") == 0 || strcmp(priv->cmd_str, "OI;") == 0 || strcmp(priv->cmd_str, "OS0;") == 0 || strcmp(priv->cmd_str, "OS1;") == 0 || strcmp(priv->cmd_str, "PA0;") == 0 || strcmp(priv->cmd_str, "PA1;") == 0 || strcmp(priv->cmd_str, "RA0;") == 0 || strcmp(priv->cmd_str, "RA1;") == 0 || strcmp(priv->cmd_str, "RF0;") == 0 || strcmp(priv->cmd_str, "RF1;") == 0 || strcmp(priv->cmd_str, "RL0;") == 0 || strcmp(priv->cmd_str, "RL1;") == 0 || strncmp(priv->cmd_str, "RM", 2) == 0 || strcmp(priv->cmd_str, "SM0;") == 0 || strcmp(priv->cmd_str, "SM1;") == 0 || strcmp(priv->cmd_str, "SQ0;") == 0 || strcmp(priv->cmd_str, "SQ1;") == 0 || strcmp(priv->cmd_str, "VT0;") == 0 || strcmp(priv->cmd_str, "VT1;") == 0; if (priv->cmd_str[2] != ';' && !is_read_cmd) { // then we must be setting something so we'll invalidate the cache rig_debug(RIG_DEBUG_TRACE, "%s: cache invalidated\n", __func__); priv->cache_start.tv_sec = 0; } while (rc != RIG_OK && retry_count++ <= rp->retry) { rig_flush(rp); /* discard any unsolicited data */ if (rc != -RIG_BUSBUSY) { /* send the command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); rc = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)); if (rc != RIG_OK) { RETURNFUNC(rc); } } /* read the reply */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) <= 0) { // if we get a timeout from PS probably means power is off if (rc == -RIG_ETIMEOUT && is_power_status_cmd) { rig_debug(RIG_DEBUG_WARN, "%s: rig power is off?\n", __func__); RETURNFUNC(rc); } continue; /* usually a timeout - retry */ } rig_debug(RIG_DEBUG_TRACE, "%s: read count = %d, ret_data = %s\n", __func__, rc, priv->ret_data); rc = RIG_OK; /* received something */ /* Check that command termination is correct - alternative is response is longer than the buffer */ if (cat_term != priv->ret_data[strlen(priv->ret_data) - 1]) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, priv->ret_data); rc = -RIG_EPROTO; /* retry */ /* we could decrement retry_count here but there is a danger of infinite looping so we just use up a retry for safety's sake */ continue; } /* check for error codes */ if (2 == strlen(priv->ret_data)) { /* The following error responses are documented for Kenwood but not for Yaesu, but at least one of them is known to occur in that the FT-450 certainly responds to "IF;" occasionally with "?;". The others are harmless even of they do not occur as they are unambiguous. */ switch (priv->ret_data[0]) { case 'N': /* Command recognized by rig but invalid data entered. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENAVAIL); case 'O': // Too many characters sent without a carriage return rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EPROTO; break; /* retry */ case 'E': /* Communication error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EIO; break; /* retry */ case '?': /* The ? response is ambiguous and undocumented by Yaesu, but for get commands it seems to * indicate that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue, * as the error is caused by the an invalid combination of rig state. * * For example, the following cases have been observed: * - MR and MC commands are rejected when referring to an _empty_ memory channel even * if the channel number is in a valid range * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are * supported only in SSB/CW/RTTY modes * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode * * There are many more cases like these and they vary by rig model. * * So far, "rig busy" type situations with the ? response have not been observed for get commands. * Followup 20201213 FTDX3000 FB; command returning ?; so do NOT abort * see https://github.com/Hamlib/Hamlib/issues/464 */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (get): '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying %d of %d: '%s'\n", __func__, retry_count, rp->retry, priv->cmd_str); // DX3000 was taking 1.6 seconds in certain command sequences hl_usleep(600 * 1000); // 600ms wait should cover most cases hopefully rc = -RIG_ERJCTED; /* retry */ break; } continue; } /* verify that reply was to the command we sent */ if ((priv->ret_data[0] != priv->cmd_str[0] || priv->ret_data[1] != priv->cmd_str[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %.2s for command %.2s\n", __func__, priv->ret_data, priv->cmd_str); // we were using BUSBUSY but microham devices need retries // this should be OK under all other circumstances too //rc = -RIG_BUSBUSY; /* retry read only */ rc = -RIG_EPROTO; } } // update the cache if (strncmp(priv->cmd_str, "IF;", 3) == 0) { elapsed_ms(&priv->cache_start, 1); strcpy(priv->last_if_response, priv->ret_data); } RETURNFUNC(rc); } /* * This tries to set and read to validate the set command actually worked * returns RIG_OK if set, -RIG_EIMPL if not implemented yet, or -RIG_EPROTO if unsuccessful */ int newcat_set_cmd_validate(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char valcmd[16]; int retries = 8; int retry = 0; int sleepms = 50; int rc = -RIG_EPROTO; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: priv->cmd_str=%s\n", __func__, priv->cmd_str); // For FA and FB rig.c now tries to verify the set_freq actually works // For example the FT-2000 can't do a FA set followed by an immediate read // We were using "ID" to verify the command but rig.c now does // a verification of frequency and retries if it doesn't match if ((strncmp(priv->cmd_str, "FA", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FA;"); if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX5000 || priv->rig_id == NC_RIGID_FTDX3000DM) { strcpy(valcmd, ""); } } else if ((strncmp(priv->cmd_str, "FB", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FB;"); if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX5000 || priv->rig_id == NC_RIGID_FTDX3000DM) { strcpy(valcmd, ""); } } else if ((strncmp(priv->cmd_str, "MD", 2) == 0) && (strlen(priv->cmd_str) > 3)) { #if 0 strcpy(valcmd, priv->cmd_str); // pull the needed part of the cmd valcmd[3] = ';'; valcmd[4] = 0; #endif // Win4Yaesu was not responding fast enough to validate the MD cmd strcpy(valcmd, ""); } else if ((strncmp(priv->cmd_str, "TX", 2) == 0) && (strlen(priv->cmd_str) > 3)) { if (priv->cmd_str[2] == '1' && rig->caps->rig_model == RIG_MODEL_FT950) // FT950 didn't like TX; after TX1; { valcmd[0] = 0; } else { strcpy(valcmd, "TX;"); } } else if ((strncmp(priv->cmd_str, "FT", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FT;"); } else if ((strncmp(priv->cmd_str, "AI", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "AI;"); } else if ((strncmp(priv->cmd_str, "VS", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "VS;"); // Some models treat the 2nd VS as a mute request if (is_ftdx3000 || is_ftdx9000) { strcpy(valcmd, ""); } } else if (strncmp(priv->cmd_str, "SV", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BA", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "AB", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BS", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "MS", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "SH", 2) == 0) { // could validate with SH but different formats need to be handled strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "RF", 2) == 0) { // could validate with RF but different formats need to be handled strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BU", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BD", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "EX", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "ST;", 3) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "ST", 2) == 0) { strcpy(valcmd, "ST;"); } else if (strncmp(priv->cmd_str, "KM", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "KY", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "PC", 2) == 0) { strcpy(valcmd, "PC;"); } else if (strncmp(priv->cmd_str, "AC", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "SY", 2) == 0) { strcpy(valcmd, "SY;"); } else { rig_debug(RIG_DEBUG_TRACE, "%s: %s not implemented\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENIMPL); } while (rc != RIG_OK && retry++ < retries) { int bytes; hamlib_port_t *rp = RIGPORT(rig); char cmd[256]; // big enough repeat: rig_flush(rp); /* discard any unsolicited data */ SNPRINTF(cmd, sizeof(cmd), "%s", priv->cmd_str); rc = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (rc != RIG_OK) { RETURNFUNC(-RIG_EIO); } if (strlen(valcmd) == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd, sizeof(cmd), "%s", valcmd); // some rigs like FT-450/Signalink need a little time before we can ask for TX status again if (strncmp(valcmd, "TX", 2) == 0) { hl_usleep(50 * 1000); } rc = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (rc != RIG_OK) { RETURNFUNC(-RIG_EIO); } bytes = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1); // we're expecting a response so we'll repeat if needed if (bytes == 0) { goto repeat; } // FA and FB success is now verified in rig.c with a followup query // so no validation is needed if (strncmp(priv->cmd_str, "FA", 2) == 0 || strncmp(priv->cmd_str, "FB", 2) == 0) { RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "PC", 2) == 0 && priv->ret_data[0] == '?') { rig_debug(RIG_DEBUG_ERR, "%s: Power level error, check if exceeding max power setting\n", __func__); RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "FT", 2) == 0 && strncmp(priv->ret_data, "FT", 2) == 0) { // FT command does not echo what's sent so we just check the basic command RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "TX", 2) == 0 && strncmp(priv->ret_data, "TX", 2) == 0) { if (strstr(priv->ret_data, "TX2")) { goto repeat; } // TX command does not echo what's sent so we just check the basic command RETURNFUNC(RIG_OK); } if (bytes > 0) { // for the BS command we can only run it once // so we'll assume it worked // maybe Yaesu will make this command more intelligent if (strstr(priv->cmd_str, "BS")) { RETURNFUNC(RIG_OK); } // if the first two chars match we are validated if (strncmp(priv->cmd_str, "VS", 2) == 0 && strncmp(priv->cmd_str, priv->ret_data, 2) == 0) { RETURNFUNC(RIG_OK); } else if (strcmp(priv->cmd_str, priv->ret_data) == 0) { RETURNFUNC(RIG_OK); } else if (priv->cmd_str[0] == ';' && priv->ret_data[0] == '?') { hl_usleep(50 * 1000); RETURNFUNC(RIG_OK); } else { rc = -RIG_EPROTO; } } rig_debug(RIG_DEBUG_WARN, "%s: cmd validation failed, '%s'!='%s', try#%d\n", __func__, priv->cmd_str, priv->ret_data, retry); hl_usleep(sleepms * 1000); } RETURNFUNC(-RIG_EPROTO); } /* * Writes a null terminated command string from priv->cmd_str to the * CAT port that is not expected to have a response. * * Honors the 'retry' capabilities field by resending the command up * to 'retry' times until a valid response is received. In the special * cases of receiving a valid response to a different command or the * "?;" busy please wait response; the command is not resent but up to * 'retry' retries to receive a valid response are made. */ int newcat_set_cmd(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retry_count = 0; int rc = -RIG_EPROTO; ENTERFUNC; /* pick a basic quick query command for verification */ char const *const verify_cmd = RIG_MODEL_FT9000 == rig->caps->rig_model ? "AI;" : "ID;"; while (rc != RIG_OK && retry_count++ <= rp->retry) { rig_flush(rp); /* discard any unsolicited data */ /* send the command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); rc = newcat_set_cmd_validate(rig); if (rc == RIG_OK) { // if we were able to set and and validate we're done rig_debug(RIG_DEBUG_TRACE, "%s: cmd_validate OK\n", __func__); RETURNFUNC(RIG_OK); } else if (rc == -RIG_EPROTO) { rig_debug(RIG_DEBUG_TRACE, "%s: set_cmd_validate failed\n", __func__); RETURNFUNC(rc); } rig_debug(RIG_DEBUG_TRACE, "%s: newcat_set_cmd_validate not implemented...continuing\n", __func__); if (RIG_OK != (rc = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { RETURNFUNC(rc); } /* skip validation if high throughput is needed */ if (priv->fast_set_commands == TRUE) { RETURNFUNC(RIG_OK); } // freq set and ptt are now verified in rig.c // ST command is not validated -- caused problems on FTDX101D if (strncmp(priv->cmd_str, "FA", 2) == 0 || strncmp(priv->cmd_str, "FB", 2) == 0 || strncmp(priv->cmd_str, "TX", 2) == 0 || strncmp(priv->cmd_str, "MD", 2) == 0 // Win4Yaesu not responding fast enough on MD change || strncmp(priv->cmd_str, "ST", 2) == 0) { RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "BS", 2) == 0) { // the BS command needs time to do its thing hl_usleep(500 * 1000); priv->cache_start.tv_sec = 0; // invalidate the cache } /* send the verification command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", verify_cmd); if (RIG_OK != (rc = write_block(rp, (unsigned char *) verify_cmd, strlen(verify_cmd)))) { RETURNFUNC(rc); } /* read the reply */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) <= 0) { continue; /* usually a timeout - retry */ } rig_debug(RIG_DEBUG_TRACE, "%s(%d): read count = %d, ret_data = %s\n", __func__, __LINE__, rc, priv->ret_data); rc = RIG_OK; /* received something */ /* check for error codes */ if (2 == strlen(priv->ret_data)) { /* The following error responses are documented for Kenwood but not for Yaesu, but at least one of them is known to occur in that the FT-450 certainly responds to "IF;" occasionally with "?;". The others are harmless even of they do not occur as they are unambiguous. */ switch (priv->ret_data[0]) { case 'N': /* Command recognized by rig but invalid data entered. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENAVAIL); case 'O': // Too many characters sent without a carriage return rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EPROTO; break; /* retry */ case 'E': /* Communication error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EIO; break; /* retry */ case '?': /* The ? response is ambiguous and undocumented by Yaesu. For set commands it seems to indicate: * 1) either that the rig is busy and the command needs to be retried * 2) or that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue * in this case, as the error is caused by the an invalid combination of rig state. * The latter case is consistent with behaviour of get commands. * * For example, the following cases have been observed: * - MR and MC commands are rejected when referring to an _empty_ memory channel even * if the channel number is in a valid range * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are * supported only in SSB/CW/RTTY modes * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode * * There are many more cases like these and they vary by rig model. */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (set): '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ERJCTED); } /* Rig busy wait please */ rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying: '%s'\n", __func__, priv->cmd_str); /* read/flush the verify command reply which should still be there */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): read count = %d, ret_data = %s\n", __func__, __LINE__, rc, priv->ret_data); rc = -RIG_BUSBUSY; /* retry */ } break; } } if (RIG_OK == rc) { /* Check that response prefix and response termination is correct - alternative is response is longer that the buffer */ if (strncmp(verify_cmd, priv->ret_data, strlen(verify_cmd) - 1) || (cat_term != priv->ret_data[strlen(priv->ret_data) - 1])) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected verify command response '%s'\n", __func__, priv->ret_data); rc = -RIG_BUSBUSY; continue; /* retry */ } } } RETURNFUNC(rc); } struct { rmode_t mode; char modechar; ncboolean chk_width; } static const newcat_mode_conv[] = { { RIG_MODE_LSB, '1', FALSE }, { RIG_MODE_USB, '2', FALSE }, { RIG_MODE_CW, '3', FALSE }, { RIG_MODE_FM, '4', TRUE}, { RIG_MODE_AM, '5', TRUE}, { RIG_MODE_RTTY, '6', FALSE }, { RIG_MODE_CWR, '7', FALSE }, { RIG_MODE_PKTLSB, '8', FALSE }, { RIG_MODE_RTTYR, '9', FALSE }, { RIG_MODE_PKTFM, 'A', TRUE}, { RIG_MODE_FMN, 'B', TRUE}, { RIG_MODE_PKTUSB, 'C', FALSE }, { RIG_MODE_AMN, 'D', TRUE}, { RIG_MODE_C4FM, 'E', TRUE}, { RIG_MODE_PKTFMN, 'F', TRUE} }; rmode_t newcat_rmode(char mode) { int i; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].modechar == mode) { rig_debug(RIG_DEBUG_TRACE, "%s: %s for %c\n", __func__, rig_strrmode(newcat_mode_conv[i].mode), mode); return (newcat_mode_conv[i].mode); } } return (RIG_MODE_NONE); } char newcat_modechar(rmode_t rmode) { int i; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].mode == rmode) { rig_debug(RIG_DEBUG_TRACE, "%s: return %c for %s\n", __func__, newcat_mode_conv[i].modechar, rig_strrmode(rmode)); return (newcat_mode_conv[i].modechar); } } return ('0'); } rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width) { ncboolean narrow; int i; ENTERFUNC2; *width = RIG_PASSBAND_NORMAL; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].modechar == mode) { if (newcat_mode_conv[i].chk_width == TRUE) { // crude fix because 991 hangs on NA0; command while in C4FM if (newcat_is_rig(rig, RIG_MODEL_FT991)) { if (mode == 'E') { *width = 16000; } else if (mode == 'F') { *width = 9000; } rig_debug(RIG_DEBUG_TRACE, "991A & C4FM Skip newcat_get_narrow in %s\n", __func__); } else { if (newcat_get_narrow(rig, vfo, &narrow) != RIG_OK) { RETURNFUNC2(newcat_mode_conv[i].mode); } if (narrow == TRUE) { *width = rig_passband_narrow(rig, mode); } else { *width = rig_passband_normal(rig, mode); } } } // don't use RETURNFUNC here as that macros expects an int for the return code RETURNFUNC2(newcat_mode_conv[i].mode); } } rig_debug(RIG_DEBUG_VERBOSE, "%s fell out the bottom %c %s\n", __func__, mode, rig_strrmode(mode)); RETURNFUNC2('0'); } int newcat_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { char *p1 = "0"; // newer rigs have 2 bytes where is fixed at zero e.g. FT991 struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "PB")) { RETURNFUNC2(-RIG_ENAVAIL); } // we don't do any channel checking -- varies by rig -- could do it but not critical SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PB%s%d%c", p1, ch, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_set_clarifier(RIG *rig, vfo_t vfo, int rx, int tx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } // Negative value keeps the current state for RIT/XIT if (rx < 0 || tx < 0) { int current_rx, current_tx, result; result = newcat_get_clarifier(rig, vfo, ¤t_rx, ¤t_tx); if (result == RIG_OK) { if (rx < 0) { rx = current_rx; } if (tx < 0) { tx = current_tx; } } else { if (rx < 0) { rx = 0; } if (tx < 0) { tx = 0; } } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c00%d%d000%c", main_sub_vfo, rx ? 1 : 0, tx ? 1 : 0, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_clarifier(RIG *rig, vfo_t vfo, int *rx, int *tx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c00%c", main_sub_vfo, cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; if (rx != NULL) { *rx = (ret_data[0] == '1') ? 1 : 0; } if (tx != NULL) { *tx = (ret_data[1] == '1') ? 1 : 0; } RETURNFUNC2(RIG_OK); } int newcat_set_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c01%+05d%c", main_sub_vfo, (int) freq, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } int newcat_get_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; int err; int ret_data_len; char *ret_data; int freq_result; int result; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c01%c", main_sub_vfo, cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; result = sscanf(ret_data, "%05d", &freq_result); if (result != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing clarifier frequency: %s\n", __func__, ret_data); RETURNFUNC2(-RIG_EPROTO); } *freq = (shortfreq_t) freq_result; RETURNFUNC2(RIG_OK); } static int newcat_set_apf_frequency(RIG *rig, vfo_t vfo, int freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } // Range seems to be -250..250 Hz in 10 Hz steps if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c3%04d%c", main_sub_vfo, (freq + 250) / 10, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO03%04d%c", (freq + 250) / 10, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%02d%c", (freq + 250) / 10, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_apf_frequency(RIG *rig, vfo_t vfo, int *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c3%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO03%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; int raw_value = atoi(ret_data); // Range seems to be -250..250 Hz in 10 Hz steps *freq = raw_value * 10 - 250; RETURNFUNC2(RIG_OK); } static int newcat_set_apf_width(RIG *rig, vfo_t vfo, int choice) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030201%d%c", choice, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030204%d%c", choice, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX111%d%c", choice, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1201%d%c", choice, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%d%c", choice, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX107%d%c", choice, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_apf_width(RIG *rig, vfo_t vfo, int *choice) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030201%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030204%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX111%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1201%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX107%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *choice = atoi(ret_data); RETURNFUNC2(RIG_OK); } static int newcat_set_contour(RIG *rig, vfo_t vfo, int status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%04d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%04d%c", status ? 1 : 0, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%02d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%02d%c", status ? 1 : 0, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour(RIG *rig, vfo_t vfo, int *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; int last_char_index; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; last_char_index = strlen(ret_data) - 1; *status = (ret_data[last_char_index] == '1') ? 1 : 0; RETURNFUNC2(RIG_OK); } static int newcat_set_contour_frequency(RIG *rig, vfo_t vfo, int freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { // Range is 10..3200 Hz SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%04d%c", main_sub_vfo, freq, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { // Range is 10..3200 Hz SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%04d%c", freq, cat_term); } else if (is_ftdx5000) { // Range is 100..4000 Hz in 100 Hz steps SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%01d%c", main_sub_vfo, freq / 100, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { // Range is 100..4000 Hz in 100 Hz steps SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%02d%c", freq / 100, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_frequency(RIG *rig, vfo_t vfo, int *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; int raw_value = atoi(ret_data); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft991 || is_ft891) { *freq = raw_value; } else if (is_ftdx5000 || is_ftdx3000 || is_ftdx1200 || is_ft2000) { *freq = raw_value * 100; } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(RIG_OK); } static int newcat_set_contour_level(RIG *rig, vfo_t vfo, int level) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030202%+03d%c", level, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030205%+03d%c", level, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%+03d%c", level, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1202%+03d%c", level, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%+03d%c", level, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX108%+03d%c", level, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_level(RIG *rig, vfo_t vfo, int *level) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030202%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030205%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1202%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX108%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *level = atoi(ret_data); RETURNFUNC2(RIG_OK); } static int newcat_set_contour_width(RIG *rig, vfo_t vfo, int width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030203%02d%c", width, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030206%02d%c", width, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%02d%c", width, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1203%02d%c", width, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX114%02d%c", width, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX109%02d%c", width, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_width(RIG *rig, vfo_t vfo, int *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030203%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030206%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1203%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX114%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX109%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *width = atoi(ret_data); RETURNFUNC2(RIG_OK); } int newcat_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int retval = RIG_OK; int err; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "DT")) { RETURNFUNC2(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT0%04d%02d%02d%c", year, month, day, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } if (hour < 0) { RETURNFUNC2(RIG_OK); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT1%02d%02d%02d%c", hour, min, sec, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT2%c%04d%c", utc_offset >= 0 ? '+' : '-', utc_offset, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } RETURNFUNC2(retval); } int newcat_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval = RIG_OK; int err; int n; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "DT")) { RETURNFUNC2(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT0%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } n = sscanf(priv->ret_data, "DT0%04d%02d%02d", year, month, day); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: DT0 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT1%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } n = sscanf(priv->ret_data, "DT1%02d%02d%02d", hour, min, sec); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: DT1 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT2%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } // we keep utc_offset in HHMM format rather than converting n = sscanf(priv->ret_data, "DT2%d", utc_offset); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: DT2 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } RETURNFUNC2(retval); } hamlib-4.6.5/rigs/yaesu/ft747.h0000664000175000017500000000466515056640443011605 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft747.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-747GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT747_H #define _FT747_H 1 /* * According to manual, the UPDATE data length should be 345 * but some rigs are short by one byte. */ #define FT747_STATUS_UPDATE_DATA_LENGTH 344 #define FT747_PACING_DEFAULT_VALUE 0 #define FT747_WRITE_DELAY 5 /* manual say 50 ms, but it doesn't work though */ /* Sequential fast writes confuse my FT747 without this delay */ /* Node Red combined "F 028074000 M USB 0" needed 10ms */ #define FT747_POST_WRITE_DELAY 10 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte in 2.2917 msec * => 345 bytes in 790 msec * * delay for 1 byte = 2.2917 + (pace_interval * 5) * * pace_interval time to read 345 bytes * ------------ ---------------------- * * 0 790 msec * 1 2515 msec * 2 4240 msec * 255 441 sec => 7 min 21 seconds * */ /* * The time the status block is cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is set to at least the time to transfer the block (790ms) * plus post write delay, plus some margin as get_freq was taking > 1000ms */ #define FT747_CACHE_TIMEOUT 1500 #endif /* _FT747_H */ hamlib-4.6.5/rigs/yaesu/vr5000.c0000664000175000017500000004307415056640443011656 /* * vr5000.c - (C) Stephane Fillod and Jacob Heder 2005 * * This shared library provides an API for communicating * via serial interface to an VR-5000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Undocumented notes on the VR5000. * * There are some mishaps in the manual. The CAT serial delay times seems * not to be correct. More correct estimates are 70 mS write_delay ( * between bytes), 200 mS post_write_delay (between command), but when * reading s-meter, the delay must be over 500 mS. * * The read s-meter CAT command seems only to return 17 to 23 depending * on the strength of the signal. Setting the RF attenuator on with no * antenna on does not decrease the level below 17. If you wish to read * the s-meter on a specific frequency, set the frequency and wait a * 500-1000 mS before reading it. * The vr5000 has two vfo, but only 1 native. The second vfo is a following * vfo which only can tune into the frequency range of VFO_A (+,-) 20 Mhz. * * The vr5000 has no CAT commands for reading the frequency, ts nor mode. * These function are emulated, because the vr5000 thunkates the input * frequency. Secondly when changing the mode, ts will change, and since * ts it the one that decides how the frequency is thunkated, the frequency * will change. * * True receiver range was not specified correctly in manual. No all * mode allow to go down to 100 Khz. Therefore the minimum frequency * which will be allowed is 101.5 kKz. Maximum is 2599.99 Mhz. * * * Supported : VFO_A, 101.5 Khz to 2599.99 Mhz. */ // cppcheck-suppress * #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #define VR5000_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define VR5000_VFOS RIG_VFO_A #define VR5000_ANTS 0 #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x04 #define MODE_AMW 0x44 #define MODE_AMN 0x84 #define MODE_WFM 0x48 #define MODE_FMN 0x88 #define SAFETY_WRITE_DELAY 70 /* security value for beta version, ok to set lower later */ #define SAFETY_POST_DELAY 210 /* security value for beta version, */ /* TODO: get real measure numbers */ #define VR5000_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 63, 60 } /* +60 */ \ } } /* Private helper function prototypes */ static int vr5000_init(RIG *rig); static int vr5000_cleanup(RIG *rig); static int vr5000_open(RIG *rig); static int vr5000_close(RIG *rig); static int vr5000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int vr5000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int vr5000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int vr5000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int vr5000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int vr5000_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int vr5000_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int vr5000_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); /* * Private helper function prototypes. */ static int set_vr5000(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width, shortfreq_t ts); static int mode2rig(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static void correct_frequency(RIG *rig, vfo_t vfo, freq_t curr_freq, freq_t *freq); static int find_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t *ts); static int check_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t ts); /* * vr5000 rigs capabilities. */ struct rig_caps vr5000_caps = { RIG_MODEL(RIG_MODEL_VR5000), .model_name = "VR-5000", .mfg_name = "Yaesu", .version = "20200505.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = SAFETY_WRITE_DELAY, .post_write_delay = SAFETY_POST_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { }, .rx_range_list1 = { {kHz(101) + 500, GHz(2.6) - 1000, VR5000_MODES, -1, -1, RIG_VFO_A, VR5000_ANTS }, RIG_FRNG_END, }, /* api supported region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(101) + 500, GHz(2.6) - 1000, VR5000_MODES, -1, -1, RIG_VFO_A, VR5000_ANTS }, RIG_FRNG_END, }, /* api supported region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, Hz(20)}, {RIG_MODE_SSB | RIG_MODE_CW, Hz(100)}, {RIG_MODE_SSB | RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(1)}, {RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(100)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(500)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = VR5000_STR_CAL, .rig_init = vr5000_init, .rig_cleanup = vr5000_cleanup, .rig_open = vr5000_open, .rig_close = vr5000_close, .get_level = vr5000_get_level, .get_dcd = vr5000_get_dcd, .set_freq = vr5000_set_freq, .get_freq = vr5000_get_freq, .set_mode = vr5000_set_mode, .get_mode = vr5000_get_mode, .set_ts = vr5000_set_ts, .get_ts = vr5000_get_ts, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * VR-5000 backend needs priv data to handle composite cmds */ struct vr5000_priv_data { vfo_t curr_vfo; shortfreq_t curr_ts; freq_t curr_freq; rmode_t curr_mode; pbwidth_t curr_width; }; int vr5000_init(RIG *rig) { STATE(rig)->priv = (struct vr5000_priv_data *) calloc(1, sizeof(struct vr5000_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } int vr5000_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * vr5000_open : Set CAT on and set tuner into known mode */ int vr5000_open(RIG *rig) { struct vr5000_priv_data *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char b_off[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x31}; int retval; /* CAT write command on */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* disable RIG_VFO_B (only on display) */ retval = write_block(rp, b_off, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* set RIG_VFO_A to 10 Mhz normal AM, step 10 kHz */ priv->curr_vfo = RIG_VFO_A; priv->curr_mode = RIG_MODE_WFM; priv->curr_width = RIG_PASSBAND_NORMAL; priv->curr_ts = kHz(10); priv->curr_freq = kHz(10000); retval = set_vr5000(rig, priv->curr_vfo, priv->curr_freq, priv->curr_mode, priv->curr_width, priv->curr_ts); if (retval != RIG_OK) { return retval; } return RIG_OK; } int vr5000_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int vr5000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct vr5000_priv_data *priv = STATE(rig)->priv; return set_vr5000(rig, vfo, freq, priv->curr_mode, priv->curr_width, priv->curr_ts); } int vr5000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *freq = priv->curr_freq; return RIG_OK; } int vr5000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct vr5000_priv_data *priv = STATE(rig)->priv; if (check_tuning_step(rig, vfo, mode, priv->curr_ts) != RIG_OK) { find_tuning_step(rig, vfo, mode, &priv->curr_ts); } priv->curr_mode = mode; return set_vr5000(rig, vfo, priv->curr_freq, mode, width, priv->curr_ts); } int vr5000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *mode = priv->curr_mode; *width = priv->curr_width; return RIG_OK; } int vr5000_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { struct vr5000_priv_data *priv = STATE(rig)->priv; int retval; retval = check_tuning_step(rig, vfo, priv->curr_mode, ts); if (retval != RIG_OK) { return retval; } priv->curr_ts = ts; return set_vr5000(rig, vfo, priv->curr_freq, priv->curr_mode, priv->curr_width, ts); } int vr5000_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *ts = priv->curr_ts; return RIG_OK; } int vr5000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0] & 0x3f; rig_debug(RIG_DEBUG_ERR, "Read(%x) RawValue(%x): \n", cmd[0], val->i); return RIG_OK; } int vr5000_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } *dcd = (cmd[0] & 0x80) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } int mode2rig(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int md; /* * translate mode from generic to vr5000 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_CW: md = MODE_CW; break; case RIG_MODE_WFM: md = MODE_WFM; break; case RIG_MODE_FM: md = MODE_FMN; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md = MODE_AMN; } else if (width != RIG_PASSBAND_NORMAL && width > rig_passband_normal(rig, mode)) { md = MODE_AMW; } else { md = MODE_AM; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } /* * This function corrects the frequency */ void correct_frequency(RIG *rig, vfo_t vfo, freq_t curr_freq, freq_t *freq) { const struct vr5000_priv_data *priv = STATE(rig)->priv; shortfreq_t ts = priv->curr_ts; unsigned long long correct_freq = (unsigned long long)curr_freq; /* RIG_VFO_A frequency correction */ if (correct_freq % ts != 0) { if ((correct_freq % ts) > (ts >> 1)) { correct_freq += (ts - (correct_freq % ts)); } else { correct_freq -= (correct_freq % ts); } } /* Check for frequencies out on true rx range */ if ((freq_t)correct_freq < rig->caps->rx_range_list1->startf) { correct_freq = (unsigned long long)rig->caps->rx_range_list1->startf; if (correct_freq % ts != 0) { correct_freq += (ts - (correct_freq % ts)); } } else if ((freq_t)correct_freq > rig->caps->rx_range_list1->endf) { correct_freq = (unsigned long long)rig->caps->rx_range_list1->endf; if (correct_freq % ts != 0) { correct_freq -= (correct_freq % ts); } } *freq = (freq_t) correct_freq; return; } /* * Set mode and ts, then frequency. Both mode/ts and frequency are set * every time one of them changes. */ int set_vr5000(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width, shortfreq_t ts) { struct vr5000_priv_data *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd_mode_ts[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x07}; unsigned char cmd_freq[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; static const unsigned char steps[] = { 0x21, 0x42, 0x02, 0x03, 0x43, 0x53, 0x63, 0x04, 0x14, 0x24, 0x35, 0x44, 0x05, 0x45 }; unsigned int frq; int retval; int i; if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } retval = mode2rig(rig, vfo, mode, width); if (retval < 0) { return retval; } /* fill in m1 */ cmd_mode_ts[0] = retval; for (i = 0; i < sizeof(steps); i++) { if (rig->caps->tuning_steps[i].ts == ts) { break; } } if (i >= sizeof(steps)) { return -RIG_EINVAL; /* not found, unsupported */ } /* fill in m2 */ cmd_mode_ts[1] = steps[i]; retval = write_block(rp, cmd_mode_ts, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* Correct frequency */ correct_frequency(rig, vfo, freq, &freq); priv->curr_freq = freq; frq = (unsigned int)(freq / 10); cmd_freq[0] = (frq >> 24) & 0xff; cmd_freq[1] = (frq >> 16) & 0xff; cmd_freq[2] = (frq >> 8) & 0xff; cmd_freq[3] = frq & 0xff; /* frequency set */ return write_block(rp, cmd_freq, YAESU_CMD_LENGTH); } /* * find_tuning_step : return the lowest ts for a giving mode */ int find_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t *ts) { int i; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if ((rig->caps->tuning_steps[i].modes & mode) != 0) { *ts = rig->caps->tuning_steps[i].ts; return RIG_OK; } } return -RIG_EINVAL; /* not found, unsupported */ } /* * check_tuning_step : return RIG_OK if this ts is supported by the mode */ int check_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t ts) { int i; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (rig->caps->tuning_steps[i].ts == ts && ((rig->caps->tuning_steps[i].modes & mode) != 0)) { return RIG_OK; } } return -RIG_EINVAL; /* not found, unsupported */ } hamlib-4.6.5/rigs/yaesu/README.ft8900000664000175000017500000000144315056640443012301 Quirks, known bugs, and other notes. ==================================== In this document I'll try to describe the behavior of the Yaesu FT-890 transceiver with Hamlib. Some of these are limitations of the radio while others are programming trade-offs with Hamlib. This document is organized by Hamlib function calls and documents observed behavior with each call. rig_set_rit * RIG_VFO_* value is respected so the rig VFO may be changed with this call. * To "zero" the RIT pass a value > 0 or < 10 with this call. The digit will be dropped as resolution is 10 Hz minimum and the clarifier offset set to 0 Hz. General notes. As with most all Yaesu radios the radio must be polled by the application for status updates, i.e. no transceive mode in CAT. hamlib-4.6.5/rigs/yaesu/ft990.h0000775000175000017500000002221015056640443011572 /* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft990.h - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT990_H #define _FT990_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT990_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT990_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT990_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT990_AM_RX_MODES (RIG_MODE_AM) #define FT990_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT990_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT990_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT990_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT990_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT990_ANTS 0 #define FT990_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /* Returned data length in bytes */ #define FT990_ALL_DATA_LENGTH 1508 /* 0x10 P1 = 00 return size */ #define FT990_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT990_OP_DATA_LENGTH 32 /* 0x10 P1 = 02 return size */ #define FT990_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT990_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT990_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT990_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT990_BCD_DIAL 8 #define FT990_BCD_RIT 3 #define FT990_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT990_PACING_INTERVAL 5 #define FT990_PACING_DEFAULT_VALUE 0 #define FT990_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT990_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT990_DEFAULT_READ_TIMEOUT FT990_ALL_DATA_LENGTH * ( 5 + (FT990_PACING_INTERVAL * FT990_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kft990 * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT990_CMD_SPLIT 0x01 #define FT990_CMD_RECALLMEM 0x02 #define FT990_CMD_VFO2MEM 0x03 #define FT990_CMD_LOCK 0x04 #define FT990_CMD_SELVFOAB 0x05 #define FT990_CMD_MEM2VFO 0x06 #define FT990_CMD_UP 0x07 #define FT990_CMD_DOWN 0x08 #define FT990_CMD_CLARIFIER 0x09 #define FT990_CMD_SETVFOA 0x0a #define FT990_CMD_SELOPMODE 0x0c #define FT990_CMD_PACING 0x0e #define FT990_CMD_PTT 0x0f #define FT990_CMD_UPDATE 0x10 #define FT990_CMD_TUNER 0x81 #define FT990_CMD_START 0x82 #define FT990_CMD_RPT 0x84 #define FT990_CMD_VFOA2B 0x85 #define FT990_CMD_BW 0x8c #define FT990_CMD_MEMSCANSKIP 0x8d #define FT990_CMD_STEPVFO 0x8e #define FT990_CMD_RDMETER 0xf7 #define FT990_CMD_DIMLEVEL 0xf8 #define FT990_CMD_RPTROFFSET 0xf9 #define FT990_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT990_BW_F2400 0x00 #define FT990_BW_F2000 0x01 #define FT990_BW_F500 0x02 #define FT990_BW_F250 0x03 #define FT990_BW_F6000 0x04 #define FT990_BW_FMPKTRTTY 0x80 // Operating Mode Status #define FT990_MODE_LSB 0x00 #define FT990_MODE_USB 0x01 #define FT990_MODE_CW 0x02 #define FT990_MODE_AM 0x03 #define FT990_MODE_FM 0x04 #define FT990_MODE_RTTY 0x05 #define FT990_MODE_PKT 0x06 // Operation Mode Selection #define FT990_OP_MODE_LSB 0x00 #define FT990_OP_MODE_USB 0x01 #define FT990_OP_MODE_CW2400 0x02 #define FT990_OP_MODE_CW500 0x03 #define FT990_OP_MODE_AM6000 0x04 #define FT990_OP_MODE_AM2400 0x05 #define FT990_OP_MODE_FM 0x06 #define FT990_OP_MODE_RTTYLSB 0x08 #define FT990_OP_MODE_RTTYUSB 0x09 #define FT990_OP_MODE_PKTLSB 0x0a #define FT990_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT990_CLAR_TX_EN 0x01 #define FT990_CLAR_RX_EN 0x02 #define FT990_CLAR_RX_OFF 0x00 #define FT990_CLAR_RX_ON 0x01 #define FT990_CLAR_TX_OFF 0x80 #define FT990_CLAR_TX_ON 0x81 #define FT990_CLAR_CLEAR 0xff #define FT990_CLAR_TUNE_UP 0x00 #define FT990_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT990_RPT_POS_EN 0x04 #define FT990_RPT_NEG_EN 0x08 #define FT990_RPT_MASK 0x0C // Status Flag 1 Masks #define FT990_SF_SPLIT 0x01 #define FT990_SF_VFOB 0x02 #define FT990_SF_FAST 0x04 #define FT990_SF_CAT 0x08 #define FT990_SF_TUNING 0x10 #define FT990_SF_KEY_ENTRY 0x20 #define FT990_SF_MEM_EMPTY 0x40 #define FT990_SF_XMIT 0x80 // Status Flag 2 Masks #define FT990_SF_MEM_SCAN_PAUSE 0x01 #define FT990_SF_MEM_CHECK 0x02 #define FT990_SF_MEM_SCAN 0x04 #define FT990_SF_LOCKED 0x08 #define FT990_SF_MTUNE 0x10 #define FT990_SF_VFO 0x20 #define FT990_SF_MEM 0x40 #define FT990_SF_GEN 0x80 // Status Flag 3 Masks #define FT990_SF_PTT 0x01 #define FT990_SF_TX_INHIBIT 0x02 #define FT990_SF_KEY_TIMER 0x04 #define FT990_SF_MEM_TIMER 0x08 #define FT990_SF_PTT_INHIBIT 0x10 #define FT990_SF_XMIT_MON 0x20 #define FT990_SF_TUNER_ON 0x40 #define FT990_SF_SIDETONE 0x80 #define FT990_EMPTY_MEM 0x80 #define FT990_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft990_flags1_t { unsigned split: 1; unsigned vfob: 1; unsigned fast: 1; unsigned cat: 1; unsigned tuning: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft990_flags1_t; // Flags Byte 2 typedef struct _ft990_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft990_flags2_t; // Flags Byte 3 typedef struct _ft990_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned sidetone: 1; } ft990_flags3_t; typedef union _ft990_flags1_u { ft990_flags1_t bits; unsigned char byte; } ft990_flags1_u; typedef union _ft990_flags2_u { ft990_flags2_t bits; unsigned char byte; } ft990_flags2_u; typedef union _ft990_flags3_u { ft990_flags3_t bits; unsigned char byte; } ft990_flags3_u; typedef struct _ft990_status_data_t { ft990_flags1_u flags1; ft990_flags2_u flags2; ft990_flags3_u flags3; unsigned char id1; unsigned char id2; } ft990_status_data_t; typedef struct _ft990_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft990_meter_data_t; typedef struct _ft990_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft990_op_data_t; // Update Data Structure typedef struct _ft990_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft990_op_data_t current_front; ft990_op_data_t current_rear; ft990_op_data_t vfoa; ft990_op_data_t vfob; ft990_op_data_t channel[90]; } ft990_update_data_t; // Command Structure typedef struct _ft990_command_t { unsigned char data[4]; unsigned char opcode; } ft990_command_t; #endif /* _FT990_H */ hamlib-4.6.5/rigs/yaesu/ft450.h0000664000175000017500000001051415056640443011562 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft450.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-450 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT450_H #define _FT450_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT450_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ /* FT450 USER-L == RIG_MODE_PKTLSB */ /* FT450 USER-U == RIG_MODE_PKTUSB */ /* */ #define FT450_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT450_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT450_AM_RX_MODES (RIG_MODE_AM) #define FT450_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT450_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT450_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT450_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT450_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT450_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|\ RIG_LEVEL_BAND_SELECT) #define FT450_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_MN|RIG_FUNC_TUNER|\ RIG_FUNC_RIT|RIG_FUNC_XIT\ ) #define FT450_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT450_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT450_STR_CAL { 3, \ { \ { 10, -60 }, /* S0 */ \ { 125, 0 }, /* S9 */ \ { 240, 60 } /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT450_ANTS 0 #define FT450_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT450_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT450_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT450_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT450_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT450_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT450_PACING_INTERVAL 5 // #define FT450_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-450 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT450_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT450_POST_WRITE_DELAY 5 #endif /* _FT450_H */ hamlib-4.6.5/rigs/yaesu/ft890.c0000664000175000017500000015267215056640443011601 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft890.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2005 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-890 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft890.h" /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* * Native FT890 functions. More to come :-) * */ enum ft890_native_cmd_e { FT890_NATIVE_SPLIT_OFF = 0, FT890_NATIVE_SPLIT_ON, FT890_NATIVE_RECALL_MEM, FT890_NATIVE_VFO_TO_MEM, FT890_NATIVE_VFO_A, FT890_NATIVE_VFO_B, FT890_NATIVE_MEM_TO_VFO, FT890_NATIVE_CLARIFIER_OPS, FT890_NATIVE_FREQ_SET, FT890_NATIVE_MODE_SET, FT890_NATIVE_PACING, FT890_NATIVE_PTT_OFF, FT890_NATIVE_PTT_ON, FT890_NATIVE_MEM_CHNL, FT890_NATIVE_OP_DATA, FT890_NATIVE_VFO_DATA, FT890_NATIVE_MEM_CHNL_DATA, FT890_NATIVE_TUNER_OFF, FT890_NATIVE_TUNER_ON, FT890_NATIVE_TUNER_START, FT890_NATIVE_READ_METER, FT890_NATIVE_READ_FLAGS, FT890_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft890_native_cmd_e ft890_native_cmd_t; /* * Internal MODES - when setting modes via FT890_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT890_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-890 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-890 manual on page 33. * */ #define FT890_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT890_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT890_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-890 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-890 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT890_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT890_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT890_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT890_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT890_SUMO_DISPLAYED_FLAG 0x09 #define FT890_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT890_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT890_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT890_SUMO_VFO_A_FLAG 0x08 #define FT890_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT890_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT890_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT890_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-890 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT890_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-890 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-890 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * API local implementation * */ static int ft890_init(RIG *rig); static int ft890_cleanup(RIG *rig); static int ft890_open(RIG *rig); static int ft890_close(RIG *rig); static int ft890_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft890_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft890_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft890_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft890_set_vfo(RIG *rig, vfo_t vfo); static int ft890_get_vfo(RIG *rig, vfo_t *vfo); static int ft890_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft890_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft890_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft890_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft890_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft890_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft890_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft890_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft890_send_static_cmd(RIG *rig, unsigned char ci); static int ft890_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft890_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft890_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft890 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft890_caps.priv? -N0NB */ struct ft890_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT890_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ }; /* * ft890 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft890_caps = { RIG_MODEL(RIG_MODEL_FT890), .model_name = "FT-890", .mfg_name = "Yaesu", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT890_WRITE_DELAY, .post_write_delay = FT890_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 32 */ .rx_range_list1 = { {kHz(100), MHz(30), FT890_ALL_RX_MODES, -1, -1, FT890_VFO_ALL, FT890_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT890_OTHER_TX_MODES, W(5), W(100), FT890_VFO_ALL, FT890_ANTS), FRQ_RNG_HF(1, FT890_AM_TX_MODES, W(2), W(25), FT890_VFO_ALL, FT890_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT890_ALL_RX_MODES, -1, -1, FT890_VFO_ALL, FT890_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT890_OTHER_TX_MODES, W(5), W(100), FT890_VFO_ALL, FT890_ANTS), FRQ_RNG_HF(2, FT890_AM_TX_MODES, W(2), W(25), FT890_VFO_ALL, FT890_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT890_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT890_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT890_AM_RX_MODES, Hz(100)}, /* Normal */ {FT890_AM_RX_MODES, kHz(1)}, /* Fast */ {FT890_FM_RX_MODES, Hz(100)}, /* Normal */ {FT890_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft890_init, .rig_cleanup = ft890_cleanup, .rig_open = ft890_open, /* port opened */ .rig_close = ft890_close, /* port closed */ .set_freq = ft890_set_freq, .get_freq = ft890_get_freq, .set_mode = ft890_set_mode, .get_mode = ft890_get_mode, .set_vfo = ft890_set_vfo, .get_vfo = ft890_get_vfo, .set_ptt = ft890_set_ptt, .get_ptt = ft890_get_ptt, .set_split_vfo = ft890_set_split_vfo, .get_split_vfo = ft890_get_split_vfo, .set_rit = ft890_set_rit, .get_rit = ft890_get_rit, .set_func = ft890_set_func, .get_level = ft890_get_level, .vfo_op = ft890_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft890_init(RIG *rig) { struct ft890_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft890_priv_data *) calloc(1, sizeof(struct ft890_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT890_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft890_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft890_open(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft890_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft890_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft890_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft890_send_dial_freq(rig, FT890_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft890_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft890_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft890_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_A_FREQ; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_B_FREQ; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT890_NATIVE_OP_DATA; offset = FT890_SUMO_DISPLAYED_FREQ; count = FT890_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft890_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft890_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft890_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %li Hz\n", __func__, width); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft890 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft890_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft890_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-890 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft890_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft890_priv_data *priv; unsigned char my_mode, m_offset; /* ft890 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; m_offset = FT890_SUMO_VFO_A_MODE; f_offset = FT890_SUMO_VFO_A_FLAG; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; m_offset = FT890_SUMO_VFO_B_MODE; f_offset = FT890_SUMO_VFO_B_FLAG; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT890_NATIVE_OP_DATA; m_offset = FT890_SUMO_DISPLAYED_MODE; f_offset = FT890_SUMO_DISPLAYED_FLAG; count = FT890_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft890_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft890 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft890_set_vfo(RIG *rig, vfo_t vfo) { struct ft890_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT890_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft890_get_vfo(RIG *rig, vfo_t *vfo) { struct ft890_priv_data *priv; unsigned char status_0; /* ft890 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT890_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft890 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-890 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft890_get_update_data(rig, FT890_NATIVE_MEM_CHNL, FT890_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT890_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '890 into TX mode * * vfo is respected by calling ft890_set_vfo if * passed vfo != priv->current_vfo * */ static int ft890_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft890_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft890_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT890_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT890_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ static int ft890_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft890_priv_data *priv; unsigned char status_2; /* ft890 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT890_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } /* * rig_set_split_vfo * * set the '890 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft890_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT890_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT890_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '890 is in split mode * * vfo value is not used * */ static int ft890_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft890_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT890_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ static int ft890_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft890_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft890_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft890_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: clarifier off error: %s\n", __func__, rigerror(err)); } return err; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft890_send_rit_freq(rig, FT890_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft890_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft890_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT890_NATIVE_OP_DATA; offset = FT890_SUMO_DISPLAYED_CLAR; length = FT890_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_A_CLAR; length = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_B_CLAR; length = FT890_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft890_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '890 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %i\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT890_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT890_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '890 meter level * * vfo is ignored for now * * Meter level returned from FT-890 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft890_priv_data *priv; unsigned char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft890_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft890_get_update_data(rig, FT890_NATIVE_READ_METER, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT890_SUMO_METER]; /* * My FT-890 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (*p > 160) { val->i = 60; } else if (*p <= 72) { val->i = ((72 - *p) / 1.3333) * -1; } else { val->i = ((*p - 72) / 1.4667); } rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft890_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT890_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft890 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 890 has several ways to * get data and several ways to return it. * * Need to use this when doing ft890_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft890_priv_data *priv; int n, err; /* for read_ */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; err = ft890_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft890_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT890_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT890_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft890_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft890_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT890_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %d Hz\n", __func__, (int)from_bcd(priv->p_cmd, FT890_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/vx1700.h0000664000175000017500000000462515056640443011673 /* * Copyright (c) 2010-2011 by Mikhail Kshevetskiy (mikhail.kshevetskiy@gmail.com) * * Code based on VX-1700 CAT manual: * http://www.vertexstandard.com/downloadFile.cfm?FileID=3397&FileCatID=135&FileName=VX-1700_CAT_MANUAL_10_14_2008.pdf&FileContentType=application%2Fpdf * * WARNING: this manual have two errors * 1) Status Update Command (10h), U=01 returns 0..199 for channels 1..200 * 2) Frequency Data (bytes 1--4 of 9-Byte VFO Data Assignment, Status Update * Command (10h), U=02 and U=03) uses bytes 1--3 for frequency, byte 4 is * not used and always zero. Thus bytes 0x15,0xBE,0x68,0x00 means * frequency = 10 * 0x15BE68 = 10 * 1425000 = 14.25 MHz * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _VX1700_H #define _VX1700_H 1 #include #define VX1700_MIN_CHANNEL 1 #define VX1700_MAX_CHANNEL 200 #define VX1700_MODES (RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH) #define VX1700_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define VX1700_ANTS RIG_ANT_1 #define VX1700_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define VX1700_FILTER_WIDTH_NARROW kHz(0.5) #define VX1700_FILTER_WIDTH_WIDE kHz(2.2) #define VX1700_FILTER_WIDTH_SSB kHz(2.2) #define VX1700_FILTER_WIDTH_AM kHz(6.0) /* Returned data length in bytes */ #define VX1700_MEM_CHNL_LENGTH 1 /* 0x10 p1=01 return size */ #define VX1700_OP_DATA_LENGTH 19 /* 0x10 p1=02 return size */ #define VX1700_VFO_DATA_LENGTH 18 /* 0x10 p1=03 return size */ #define VX1700_READ_METER_LENGTH 5 /* 0xf7 return size */ #define VX1700_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define VX1700_BCD_DIAL 8 #endif /* _VX1700_H */ hamlib-4.6.5/rigs/yaesu/ft9000.h0000664000175000017500000001205015056640443011637 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft9000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2009 * * This shared library provides an API for communicating * via serial interface to an FT-9000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT9000_H #define _FT9000_H 1 #if 0 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #endif #define FT9000_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT9000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT9000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT9000_AM_RX_MODES (RIG_MODE_AM) #define FT9000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TRX caps */ #define FT9000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT9000_AM_TX_MODES (RIG_MODE_AM) #define FT9000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT9000_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT9000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TBC */ #define FT9000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_MONITOR_GAIN|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FT9000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|\ RIG_FUNC_RIT|RIG_FUNC_XIT) /* TBC */ #define FT9000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT9000_RFPOWER_METER_CAL \ { \ 11, \ { \ {35, 10.0f}, \ {53, 20.0f}, \ {80, 40.0f}, \ {97, 60.0f}, \ {119, 80.0f}, \ {137, 100.0f}, \ {154, 120.0f}, \ {167, 140.0f}, \ {177, 160.0f}, \ {188, 180.0f}, \ {197, 200.0f}, \ } \ } /* TBC */ #define FT9000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT9000_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define FT9000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT9000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT9000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT9000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT9000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT9000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT9000_PACING_INTERVAL 5 // #define FT9000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-9000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT9000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT9000_POST_WRITE_DELAY 5 #endif /* _FT9000_H */ hamlib-4.6.5/rigs/yaesu/ft710.h0000664000175000017500000001412415056640443011562 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * FT710.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Michael Black W9MDB 2020 * (C) Mikael Nousiainen 2023 * * This shared library provides an API for communicating * via serial interface to an FT-710 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT710_H #define _FT710_H 1 #define FT710_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT710_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FT710_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT710_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT710_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FT710_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT710_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FT710_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT710_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT710_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FT710_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT710_RFPOWER_METER_CAL \ { \ 5, \ { \ {27, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner for the FT7101D #define FT710_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } /* TBC */ #define FT710_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } #define FT710_ID_CAL { 7, \ { \ { 0, 0.0f }, \ { 53, 5.0f }, \ { 65, 6.0f }, \ { 78, 7.0f }, \ { 86, 8.0f }, \ { 98, 9.0f }, \ { 107, 10.0f } \ } \ } /* TBC */ #define FT710_VD_CAL { 2, \ { \ { 0, 0.0f }, \ { 192, 13.8f }, \ } \ } #define FT710_COMP_CAL { 9, \ { \ { 0, 0.0f }, \ { 40, 2.5f }, \ { 60, 5.0f }, \ { 85, 7.5f }, \ { 135, 10.0f }, \ { 150, 12.5f }, \ { 175, 15.0f }, \ { 195, 17.5f }, \ { 220, 20.0f } \ } \ } /* * Other features (used by rig_caps) */ #define FT710_TX_ANTS RIG_ANT_CURR #define FT710_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT710_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT710_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT710_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT710_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT710_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT710_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT710_POST_WRITE_DELAY 5 #endif /* _FT710_H */ hamlib-4.6.5/rigs/yaesu/ft980.c0000664000175000017500000011455415056640443011576 /* * ft980.c - (C) Stephane Fillod 2004-2010 * (C) Wolfgang Buesser 2010 * * (C) Mathew Breton 2021 * * This shared library provides an API for communicating * via serial interface to an FT-980 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * FT-980 Hamlib API functions considered to be Stable: * sadly, none yet * * Functions considered to be Beta: * init * cleanup * set_freq * get_freq * set_mode * get_mode * set_mem * get_mem * open * close * * Functions considered to be Alpha: * set_vfo * get_vfo * * Functions not yet implemented * get_xit * set_xit * set_func * get_func * get_ptt * set_ptt * get_dcd * set_rptr_shift * get_rptr_shift * set_rptr_offs * get_rptr_offs * set_split_freq * get_split_freq * set_split_mode * get_split_mode * set_split_freq_mode * get_split_freq_mode * set_split_vfo * get_split_vfo * set_ts * get_ts * vfo_op * * Functions the radio does not support: see readme.ft980 for more details * power2mW * mW2power * newcat_get_ant * newcat_set_ant * set_dcs_code * get_dcs_code * set_tone * get_tone * set_ctcss_tone * get_ctcss_tone * set_dcs_sql * get_dcs_sql * set_tone_sql * get_tone_sql * set_ctcss_sql * get_ctcss_sql * set_powerstat * get_powerstat * set_ant * get_ant * send_dtmf * recv_dtmf * send_morse * stop_morse * wait_morse * send_voice_mem * set_trn * get_trn * set_channel * get_channel * set_bank * scan * set_parm * get_parm * get_info * reset * set_vfo_opt * decode_event * * No idea yet what these do * set_chan_all_cb * get_chan_all_cb * set_conf * get_conf */ #include #include /* String function definitions */ #include /* for timeofday call */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft980.h" /* * Private data */ struct ft980_priv_data { _ft980_memory_t update_data; /* returned data */ vfo_t current_vfo; /* active VFO from last cmd */ struct timeval status_tv; /* update_data caching */ }; /************************************************************************************* * Private Prototype Declarations */ static int ft980_transaction(RIG *rig, const unsigned char *cmd, unsigned char *data, int expected_len); static int ft980_get_status_data(RIG *rig); /* Dump routines are for debug purposes */ static void dump_freq(unsigned char *data); static void dump_vfo(unsigned char data); static void dump_mode(unsigned char data); static void dump_switch(unsigned char data); static void dump_if_shift(unsigned char data); static void dump_rptr_split_code(unsigned char data); static void dump_fsk_shift(unsigned char data); static void dump_if_width(unsigned char data); static void dump_mem_shift_flag(unsigned char data); static void dump_clar_flag(unsigned char data); static void dump_tab_flag(unsigned char data); static void dump_freq_select_sws(unsigned char data); static void dump_mode_sw(unsigned char data); static void dump_mem_ch_sw(unsigned char data); static void dump_status_flag_bits(unsigned char data); static void dump_memory(_ft980_memory_t *memory); static void dump_freq(unsigned char *data) { rig_debug(RIG_DEBUG_TRACE, "%02x%02x%02x%02x ", data[3], data[2], data[1], data[0]); } static void dump_vfo(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "GEN"); break; case 128: rig_debug(RIG_DEBUG_TRACE, "%s", "HAM"); break; } } static void dump_mode(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", " LSB\n"); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", " USB\n"); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", " CW-W\n"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", " CW-N\n"); break; case 4: rig_debug(RIG_DEBUG_TRACE, "%s", " AM-W\n"); break; case 5: rig_debug(RIG_DEBUG_TRACE, "%s", " AM-N\n"); break; case 6: rig_debug(RIG_DEBUG_TRACE, "%s", " FSK\n"); break; case 7: rig_debug(RIG_DEBUG_TRACE, "%s", " FM\n"); break; } } static void dump_switch(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF"); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "ON "); break; } } static void dump_if_shift(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%d\n", __func__, data - 15); } static void dump_rptr_split_code(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%02x\n", __func__, data); } static void dump_fsk_shift(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%02x\n", __func__, data); } static void dump_if_width(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%d\n", __func__, data); } static void dump_mem_shift_flag(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:", __func__); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF\n"); break; case 16: rig_debug(RIG_DEBUG_TRACE, "%s", "ON\n"); break; } } static void dump_clar_flag(unsigned char data) { unsigned char RX_CLAR = data & 0x20; unsigned char TX_CLAR = data & 0x40; rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_SHIFT RX/TX:"); switch ((unsigned int)RX_CLAR) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF "); break; case 0x20: rig_debug(RIG_DEBUG_TRACE, "%s", "ON "); break; } switch ((unsigned int)TX_CLAR) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", " OFF "); break; case 0x40: rig_debug(RIG_DEBUG_TRACE, "%s", " ON "); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_tab_flag(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "TAB FLAG :"); switch (data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF\n"); break; case 0x80: rig_debug(RIG_DEBUG_TRACE, "%s", "ON\n"); break; } } static void dump_freq_select_sws(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "freq_select_sws :"); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "VFO "); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "MR "); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", "RX_M"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", "RX_V"); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_mode_sw(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "mode_sw :"); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "LSB "); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "USB "); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", "CW-W"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", "CW-N"); break; case 4: rig_debug(RIG_DEBUG_TRACE, "%s", "AM-W"); break; case 5: rig_debug(RIG_DEBUG_TRACE, "%s", "AM-N"); break; case 6: rig_debug(RIG_DEBUG_TRACE, "%s", "FSK"); break; case 7: rig_debug(RIG_DEBUG_TRACE, "%s", "FM"); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_mem_ch_sw(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "mem_ch_sw :%d\n", data + 1); } static void dump_status_flag_bits(unsigned char data) { unsigned char TX = data & 0x01; unsigned char SPLIT = data & 0x08; unsigned char VFO = data & 0x20; unsigned char CLAR = data & 0x40; rig_debug(RIG_DEBUG_TRACE, "%s", "status_flag_bits :"); if (TX) { rig_debug(RIG_DEBUG_TRACE, "%s", "TX "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "RX "); } if (SPLIT) { rig_debug(RIG_DEBUG_TRACE, "%s", "SPLIT "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "SIMPLEX "); } if (VFO) { rig_debug(RIG_DEBUG_TRACE, "%s", "VFO "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "MEMORY "); } if (CLAR) { rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_ON "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_OFF"); } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_memory(_ft980_memory_t *memory) { if (!rig_need_debug(RIG_DEBUG_TRACE)) { return; } rig_debug(RIG_DEBUG_TRACE, "%s", "mem_1 :"); dump_freq(memory->mem_1); dump_vfo(memory->vfo_1); dump_mode(memory->mode_1); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_2 :"); dump_freq(memory->mem_2); dump_vfo(memory->vfo_2); dump_mode(memory->mode_2); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_3 :"); dump_freq(memory->mem_3); dump_vfo(memory->vfo_3); dump_mode(memory->mode_3); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_4 :"); dump_freq(memory->mem_4); dump_vfo(memory->vfo_4); dump_mode(memory->mode_4); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_5 :"); dump_freq(memory->mem_5); dump_vfo(memory->vfo_5); dump_mode(memory->mode_5); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_6 :"); dump_freq(memory->mem_6); dump_vfo(memory->vfo_6); dump_mode(memory->mode_6); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_7 :"); dump_freq(memory->mem_7); dump_vfo(memory->vfo_7); dump_mode(memory->mode_7); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_8 :"); dump_freq(memory->mem_8); dump_vfo(memory->vfo_8); dump_mode(memory->mode_8); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_9 :"); dump_freq(memory->mem_9); dump_vfo(memory->vfo_9); dump_mode(memory->mode_9); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_10 :"); dump_freq(memory->mem_10); dump_vfo(memory->vfo_10); dump_mode(memory->mode_10); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_11 :"); dump_freq(memory->mem_11); dump_vfo(memory->vfo_11); dump_mode(memory->mode_11); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_12 :"); dump_freq(memory->mem_12); dump_vfo(memory->vfo_12); dump_mode(memory->mode_12); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_13 :"); dump_freq(memory->mem_13); dump_vfo(memory->vfo_13); dump_mode(memory->mode_13); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_14 :"); dump_freq(memory->mem_14); dump_vfo(memory->vfo_14); dump_mode(memory->mode_14); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_15 :"); dump_freq(memory->mem_15); dump_vfo(memory->vfo_15); dump_mode(memory->mode_15); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_16 :"); dump_freq(memory->mem_16); dump_vfo(memory->vfo_16); dump_mode(memory->mode_16); rig_debug(RIG_DEBUG_TRACE, "%s", "gen_vfo_freq :"); dump_freq(memory->gen_vfo_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\nHAM :"); dump_freq(memory->ham_vfo_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n "); dump_vfo(memory->vfo); dump_mode(memory->mode); rig_debug(RIG_DEBUG_TRACE, "%s", "clar_freq :"); dump_freq(memory->clar_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_shift_freq :"); dump_freq(memory->mem_shift_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_clar_freq :"); dump_freq(memory->mem_clar_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", " "); dump_vfo(memory->vfo); dump_mode(memory->mode); rig_debug(RIG_DEBUG_TRACE, "%s", "ldb_flag :"); dump_switch(memory->ldb_flag); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "ext_ctl_flag :"); dump_switch(memory->ext_ctl_flag); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_if_shift(memory->if_shift); dump_rptr_split_code(memory->rptr_split_code); dump_fsk_shift(memory->fsk_shift); dump_if_width(memory->if_width); dump_mem_shift_flag(memory->mem_shift_flag); dump_clar_flag(memory->clar_flag); dump_tab_flag(memory->tab_flag); dump_freq_select_sws(memory->freq_select_sws); rig_debug(RIG_DEBUG_TRACE, "%s", "offset_sw :"); dump_switch(memory->offset_sw); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_mode_sw(memory->mode_sw); dump_mem_ch_sw(memory->mem_ch_sw); rig_debug(RIG_DEBUG_TRACE, "%s", "lower_tab_freq :"); dump_freq(memory->lower_tab_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "upper_tab_freq :"); dump_freq(memory->upper_tab_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", " "); dump_vfo(memory->op_vfo); dump_mode(memory->op_mode); rig_debug(RIG_DEBUG_TRACE, "%s", "op_freq :"); dump_freq(memory->op_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_status_flag_bits(memory->status_flag_bits); } int ft980_transaction(RIG *rig, const unsigned char *cmd, unsigned char *data, int expected_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char echo_back[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } if (retval != YAESU_CMD_LENGTH || (memcmp(echo_back, cmd, YAESU_CMD_LENGTH) != 0)) { return -RIG_EPROTO; } retval = write_block(rp, cmd_OK, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } retval = read_block(rp, data, expected_len); if (retval < 0) { return retval; } if (retval != expected_len) { return -RIG_EPROTO; } return RIG_OK; } int ft980_get_status_data(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01 }; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig_check_cache_timeout(&priv->status_tv, FT980_CACHE_TIMEOUT)) { return RIG_OK; } retval = ft980_transaction(rig, cmd, (unsigned char *)&priv->update_data, FT980_ALL_STATUS_LENGTH); if (retval != RIG_OK) { return retval; } /* update cache date */ gettimeofday(&priv->status_tv, NULL); dump_memory(&priv->update_data); return retval; } /**************************************************************************** * rig_init* * * Initialize memory & rig private data structure * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * */ int ft980_init(RIG *rig) { struct ft980_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft980_priv_data *) calloc(1, sizeof(struct ft980_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = (struct ft980_priv_data *)STATE(rig)->priv; memset(priv, 0, sizeof(struct ft980_priv_data)); // Initialize operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /**************************************************************************** * rig_cleanup* * * Release memory in rig private data structure for a clean exit * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * */ int ft980_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /**************************************************************************** * rig_open* * * Initialize memory & rig private data structure * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Should be able to optimize * ToDo: add check so we don't get stuck in EXT CTRL toggle trap/loop * */ int ft980_open(RIG *rig) { unsigned char echo_back[YAESU_CMD_LENGTH]; struct ft980_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int retry_count1 = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft980_priv_data *)STATE(rig)->priv; /* send Ext Cntl ON: Activate CAT */ do { int retval; int retry_count2 = 0; do { write_block(rp, cmd_ON_OFF, YAESU_CMD_LENGTH); retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); } while (retval != 5 && retry_count2++ < rp->retry); write_block(rp, cmd_OK, YAESU_CMD_LENGTH); read_block(rp, (unsigned char *) &priv->update_data, FT980_ALL_STATUS_LENGTH); } while (!priv->update_data.ext_ctl_flag && retry_count1++ < rp->retry); return RIG_OK; } /**************************************************************************** * rig_close* * * Send command to toggle out of EXT CTRL mode * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * Could be optimized. * */ int ft980_close(RIG *rig) { unsigned char echo_back[YAESU_CMD_LENGTH]; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retry_count1 = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); do { int retval; int retry_count2 = 0; do { write_block(rp, cmd_ON_OFF, YAESU_CMD_LENGTH); retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); } while (retval != 5 && retry_count2++ < rp->retry); write_block(rp, cmd_OK, YAESU_CMD_LENGTH); read_block(rp, (unsigned char *) &priv->update_data, FT980_ALL_STATUS_LENGTH); } while (priv->update_data.ext_ctl_flag && retry_count1++ < rp->retry); return RIG_OK; } /* * Only the current VFO frequency can be set * Other Hamlib backends (ex FT-990) switch VFO, change freq, then exit * They do not return to the original VFO. * We will stick with this convention for now. * * ToDo: Check return data to verify frequency was set correctly */ /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * Issues: an error will occur with the 4.0 rig.c set_cache_freq routine when * targeting VFO_MEM. */ int ft980_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x08}; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, " %s: passed freq = %lf Hz\n", __func__, freq); // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, " %s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft980_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } /* store bcd format in cmd (MSB) */ to_bcd(cmd, freq / 10, 8); /* why is this done ? */ rig_force_cache_timeout(&priv->status_tv); /* Frequency set */ return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, 5), 5); } /* * We can get HAM, GEN, Memory Shift (?), "Operating" * What is memory "Shift"? */ /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; freq_t f; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); /* Frequency get */ retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_CURR: f = from_bcd(priv->update_data.op_freq, 8); break; case RIG_VFO_MAIN: f = from_bcd(priv->update_data.ham_vfo_freq, 8); break; case RIG_VFO_SUB: f = from_bcd(priv->update_data.gen_vfo_freq, 8); break; case RIG_VFO_MEM: f = from_bcd(priv->update_data.mem_shift_freq, 8); break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: Selected Memory Freq = %lf\n", __func__, f * 10); *freq = f * 10; /* return displayed frequency */ return RIG_OK; } /* * Only the current VFO mode can be set * Other Hamlib backends (ex FT-990) switch VFO, change mode, then exit * They do not return to the original VFO. * We will stick with this convention for now. * * ToDo: Check return data to verify mode was set correctly */ /* * rig_set_mode* * * Set mode for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, Sub, MEM * mode | input | byte * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A}; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; unsigned char md; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, " %s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, " %s: passed width = %ld Hz\n", __func__, width); // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft980_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } /* * translate mode from generic to ft980 specific */ switch (mode) { case RIG_MODE_CW : md = FT980_CMD0A_MD_CW; break; case RIG_MODE_USB: md = FT980_CMD0A_MD_USB; break; case RIG_MODE_LSB: md = FT980_CMD0A_MD_LSB; break; case RIG_MODE_FM: md = FT980_CMD0A_MD_FM; break; case RIG_MODE_AM: md = FT980_CMD0A_MD_AM; break; case RIG_MODE_RTTY: md = FT980_CMD0A_MD_RTTY; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { switch (md) { case FT980_CMD0A_MD_CW: md = FT980_CMD0A_MD_CWN; break; case FT980_CMD0A_MD_AM: md = FT980_CMD0A_MD_AMN; break; } } cmd[3] = md; /* Might be deprecated in Hamlib 4.1 */ rig_force_cache_timeout(&priv->status_tv); /* Mode set */ return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /* * rig_get_mode * * get mode eg AM, CW etc * ??? What is the difference between byte 6 (operating mode vfo_op * and byte 30 (selected VFO mode) ??? */ /* * rig_get_mode* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * mode * | output | byte * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { unsigned char my_mode; /* ft890 mode, mode offset */ struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval, norm; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_CURR: my_mode = priv->update_data.op_mode; rig_debug(RIG_DEBUG_TRACE, " %s: Current VFO Mode = 0x%02x\n", __func__, my_mode); break; case RIG_VFO_MAIN: case RIG_VFO_SUB: /* This is a point of confusion: what exactly is byte 30? */ my_mode = priv->update_data.mode; rig_debug(RIG_DEBUG_TRACE, " %s: HAM/GEN VFO Mode = 0x%02x\n", __func__, my_mode); break; case RIG_VFO_MEM: my_mode = priv->update_data.mem_mode; rig_debug(RIG_DEBUG_TRACE, " %s: MEM VFO Mode = 0x%02x\n", __func__, my_mode); break; default: return -RIG_EVFO; } /* * translate mode from ft980 to generic. */ switch (my_mode) { case 0: *mode = RIG_MODE_LSB; norm = 1; break; case 1: *mode = RIG_MODE_USB; norm = 1; break; case 2: *mode = RIG_MODE_CW; norm = 1; break; case 3: *mode = RIG_MODE_CW; norm = 0; break; case 4: *mode = RIG_MODE_AM; norm = 1; break; case 5: *mode = RIG_MODE_AM; norm = 0; break; case 6: *mode = RIG_MODE_RTTY; norm = 1; break; case 7: *mode = RIG_MODE_FM; norm = 1; break; default: return -RIG_EPROTO; /* Oops! file bug report */ } rig_debug(RIG_DEBUG_TRACE, " %s: Hamlib mode = %s\n", __func__, rig_strrmode(*mode)); if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, " %s: Filter width = %d Hz\n", __func__, (int)*width); return RIG_OK; } int ft980_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { return -RIG_ENIMPL; #if 0 // deprecated as was ignored before now unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8e}; /* * this can be misleading as Yaesu call it "Full duplex" * or "sat mode", and split Yaesu terms is repeater shift. */ cmd[4] = split == RIG_SPLIT_ON ? 0x0e : 0x8e; return write_block(RIGPORT(rig), (char *) cmd, YAESU_CMD_LENGTH); #endif } int ft980_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { return -RIG_ENIMPL; } int ft980_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return -RIG_ENIMPL; } int ft980_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A }; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ch > 16 || ch < 1) { return -RIG_EINVAL; } cmd[3] = ch - 1; return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /**************************************************************************** * rig_get_mem * * Get the number of the currently selected memory * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | Not applicable for FT-980 * ch | output | pointer to channel integer to be returned * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: returns currently selected memory channel regardlessof front * panel knob selection (can be different when CAT is enabled). */ int ft980_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } *ch = priv->update_data.mem_ch_sw + 1; return RIG_OK; } /**************************************************************************** * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFO_MAIN, VFOB/GEN, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will essentially "no op" * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ /* VFO_CURR: Whatever is shown in op_freq/op_mode */ /* VFO_MAIN: Mode = VFO, VFO = MAIN */ /* VFO_SUB: Mode = VFO, VFO = GEN */ /* VFO_MEM: Mode = Memory, VFO = don't care */ int ft980_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A }; struct ft980_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EARG; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); priv = (struct ft980_priv_data *)STATE(rig)->priv; switch (vfo) { case RIG_VFO_CURR: rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, priv->current_vfo); return RIG_OK; break; case RIG_VFO_MAIN: cmd[3] = FT980_CMD0A_VFO_SEL_HAM; rig_debug(RIG_DEBUG_TRACE, "%s: set VFO GEN/HAM = 0x%02x\n", __func__, cmd[3]); err = ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); if (err != RIG_OK) { return err; } cmd[3] = FT980_CMD0A_FREQ_SEL_VFO; break; case RIG_VFO_SUB: cmd[3] = FT980_CMD0A_VFO_SEL_GEN; rig_debug(RIG_DEBUG_TRACE, "%s: set VFO GEN/HAM = 0x%02x\n", __func__, cmd[3]); err = ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); if (err != RIG_OK) { return err; } cmd[3] = FT980_CMD0A_FREQ_SEL_VFO; break; case RIG_VFO_MEM: cmd[3] = FT980_CMD0A_FREQ_SEL_MR; break; default: return -RIG_EVFO; } rig_debug(RIG_DEBUG_TRACE, "%s: set VFO Status = %s\n", __func__, rig_strvfo(vfo)); return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /**************************************************************************** * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | currVFO, VFO_MAIN, VFOB/GEN, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: * VFO_MAIN: If (Status = VFO && VFO = MAIN) || (Status = RXV && VFO = MAIN) * VFO_SUB: If (Status = VFO && VFO = GEN) || (Status = RXV && VFO = GEN) * VFO_MEM: If *Status = Memory) || (Status = RXM) * * If operating in split (RXM, RXV) then get_vfo returns the receive vfo */ int ft980_get_vfo(RIG *rig, vfo_t *vfo) { int err; struct ft980_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EARG; } priv = (struct ft980_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft980_get_status_data(rig); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: status_flag_bits = 0x%02x\n", __func__, priv->update_data.status_flag_bits); rig_debug(RIG_DEBUG_TRACE, "%s: op_vfo = %s\n", __func__, rig_strvfo(priv->update_data.op_vfo)); /* Decode the VFO Setting and VFO States */ if (!(priv->update_data.status_flag_bits & FT_980_STATUSFLAG_VFO_MASK)) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.op_vfo == FT980_VFO_HAM_SEL) { priv->current_vfo = RIG_VFO_MAIN; } else if (priv->update_data.op_vfo == FT980_VFO_GEN_SEL) { priv->current_vfo = RIG_VFO_SUB; } else { return -RIG_EVFO; } rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = %s\n", __func__, rig_strvfo(priv->current_vfo)); *vfo = priv->current_vfo; return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft817.c0000664000175000017500000020262715056640443011574 /* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft817.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-817: * * - RX status command returns info that is not used: * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) TBC * * - TX status command returns info that is not used: * - high swr flag * * Todo / tocheck list (oz9aec): * - test get_dcd; rigctl does not support it? * - squelch * - the many "fixme" stuff around */ #include #include /* String function definitions */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft817.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" enum ft817_native_cmd_e { FT817_NATIVE_CAT_LOCK_ON = 0, FT817_NATIVE_CAT_LOCK_OFF, FT817_NATIVE_CAT_PTT_ON, FT817_NATIVE_CAT_PTT_OFF, FT817_NATIVE_CAT_SET_FREQ, FT817_NATIVE_CAT_SET_MODE_LSB, FT817_NATIVE_CAT_SET_MODE_USB, FT817_NATIVE_CAT_SET_MODE_CW, FT817_NATIVE_CAT_SET_MODE_CWR, FT817_NATIVE_CAT_SET_MODE_AM, FT817_NATIVE_CAT_SET_MODE_FM, FT817_NATIVE_CAT_SET_MODE_FM_N, FT817_NATIVE_CAT_SET_MODE_DIG, FT817_NATIVE_CAT_SET_MODE_PKT, FT817_NATIVE_CAT_CLAR_ON, FT817_NATIVE_CAT_CLAR_OFF, FT817_NATIVE_CAT_SET_CLAR_FREQ, FT817_NATIVE_CAT_SET_VFOAB, FT817_NATIVE_CAT_SPLIT_ON, FT817_NATIVE_CAT_SPLIT_OFF, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT817_NATIVE_CAT_SET_RPT_OFFSET, FT817_NATIVE_CAT_SET_DCS_ON, FT817_NATIVE_CAT_SET_CTCSS_ON, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT817_NATIVE_CAT_SET_CTCSS_FREQ, FT817_NATIVE_CAT_SET_DCS_CODE, FT817_NATIVE_CAT_GET_RX_STATUS, FT817_NATIVE_CAT_GET_TX_STATUS, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT817_NATIVE_CAT_PWR_WAKE, FT817_NATIVE_CAT_PWR_ON, FT817_NATIVE_CAT_PWR_OFF, FT817_NATIVE_CAT_EEPROM_READ, FT817_NATIVE_CAT_EEPROM_WRITE, FT817_NATIVE_CAT_GET_TX_METERING, FT817_NATIVE_SIZE /* end marker */ }; struct ft817_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* Raw data from rig. Highest bit 0 = PTT */ /* tx levels */ struct timeval tx_level_tv; unsigned char swr_level; unsigned char alc_level; unsigned char mod_level; unsigned char pwr_level; /* TX power level */ /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[5]; /* 5 bytes, NOT related to YAESU_CMD_LENGTH */ /* Digi mode is not part of regular fm_status response. * So keep track of it in a separate variable. */ unsigned char dig_mode; float swr; }; static int ft817_init(RIG *rig); static int ft817_open(RIG *rig); static int ft817_cleanup(RIG *rig); static int ft817_close(RIG *rig); static int ft817_get_vfo(RIG *rig, vfo_t *vfo); static int ft817_set_vfo(RIG *rig, vfo_t vfo); static int ft817_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft817_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft817_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft817_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft817_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft817_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft817_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft817_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft817_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft817_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft817_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft817_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft817_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft817_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft817_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft817_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft817_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft817_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft817_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft817_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int ft817_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); static int ft817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); static int ft818_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); /* Native ft817 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbc } }, /* eeprom write */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xbd } }, /* get TX metering levels (PWR, SWR, MOD, ALC) */ }; enum ft817_digi { FT817_DIGI_RTTY = 0, FT817_DIGI_PSK_L, FT817_DIGI_PSK_U, FT817_DIGI_USER_L, FT817_DIGI_USER_U, }; #define FT817_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTFM|\ RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY) #define FT817_CWN_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY) #define FT817_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT817_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_AM_TX_MODES (RIG_MODE_AM) #define FT817_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT817_ANT_FRONT (RIG_ANT_1) #define FT817_ANT_REAR (RIG_ANT_2) #define FT817_ANTS (FT817_ANT_FRONT | FT817_ANT_REAR) #define FT817_STR_CAL { 16, \ { \ { 0x00, -54 }, /* S0 */ \ { 0x01, -48 }, \ { 0x02, -42 }, \ { 0x03, -36 }, \ { 0x04, -30 }, \ { 0x05, -24 }, \ { 0x06, -18 }, \ { 0x07, -12 }, \ { 0x08, -6 }, \ { 0x09, 0 }, /* S9 */ \ { 0x0A, 10 }, /* +10 */ \ { 0x0B, 20 }, /* +20 */ \ { 0x0C, 30 }, /* +30 */ \ { 0x0D, 40 }, /* +40 */ \ { 0x0E, 50 }, /* +50 */ \ { 0x0F, 60 } /* +60 */ \ } } // Thanks to Olivier Schmitt sc.olivier@gmail.com for these tables #define FT817_PWR_CAL { 9, \ { \ { 0x00, 0.0f }, \ { 0x01, 0.5f }, \ { 0x02, 0.75f }, \ { 0x03, 1.0f }, \ { 0x04, 1.7f }, \ { 0x05, 2.5f }, \ { 0x06, 3.3f }, \ { 0x07, 4.1f }, \ { 0x08, 5.0f } \ } } #define FT817_ALC_CAL { 6, \ { \ { 0x00, 0 }, \ { 0x01, 20 }, \ { 0x02, 40 }, \ { 0x03, 60 }, \ { 0x04, 80 }, \ { 0x05, 100 } \ } } // SWR values from Christian WA4YA, DL4YA #define FT817_SWR_CAL { 16, \ { \ { 0, 1.0f }, \ { 1, 1.4f }, \ { 2, 1.8f }, \ { 3, 2.13f }, \ { 4, 2.25f }, \ { 5, 3.7f }, \ { 6, 6.0f }, \ { 7, 7.0f }, \ { 8, 8.0f }, \ { 9, 9.0f }, \ { 10, 10.0f }, \ { 11, 10.0f }, \ { 12, 10.0f }, \ { 13, 10.0f }, \ { 14, 10.0f }, \ { 15, 10.0f } \ } } struct rig_caps ft817_caps = { RIG_MODEL(RIG_MODEL_FT817), .model_name = "FT-817", .mfg_name = "Yaesu", .version = "20241117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR | RIG_LEVEL_RFPOWER_METER_WATTS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft817_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps q900_caps = { RIG_MODEL(RIG_MODEL_Q900), .model_name = "Q900", .mfg_name = "Guohe", .version = "20241117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft817_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft818_caps = { RIG_MODEL(RIG_MODEL_FT818), .model_name = "FT-818", .mfg_name = "Yaesu", .version = "20221117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* One of the key differences between 817 and 818: the 818 has 60m! */ FRQ_RNG_60m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_60m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* One of the key differences between 817 and 818: the 818 has 60m! */ FRQ_RNG_60m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_60m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft818_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ static int ft817_init(RIG *rig) { struct ft817_priv_data *p; rig_debug(RIG_DEBUG_VERBOSE, "%s: called, version %s\n", __func__, rig->caps->version); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft817_priv_data))) == NULL) { return -RIG_ENOMEM; } p = (struct ft817_priv_data *) STATE(rig)->priv; p->swr = 10; return RIG_OK; } static int ft817_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } static int ft817_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); hl_usleep(1500 * 1000); // rig needs a bit to allow commands to come through on startup return RIG_OK; } static int ft817_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT817_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "ft817: using cache (%ld ms)\n", t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "ft817: cache timed out (%ld ms)\n", t); return 1; } } static int ft817_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; hamlib_port_t *rp = RIGPORT(rig); int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); memcpy(data, ncmd[FT817_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xff; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } if (addr == 0x55) // for some reason VFO returns high byte { *out = data[0]; } else { *out = data[addr % 2]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: data[0]=%02x, data[1]=%02x, out=%02x\n", __func__, data[0], data[1], *out); memcpy(out, data, 2); return RIG_OK; } static int ft817_get_status(RIG *rig, int status) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; int retries = rp->retry; unsigned char result[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; /* Answer is 5 long; 4 bytes BCD freq, 1 byte status */ len = 5; tv = &p->fm_status_tv; break; case FT817_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT817_NATIVE_CAT_GET_TX_METERING: data = result; len = sizeof(result) / sizeof(result[0]); /* We expect two bytes */ tv = &p->tx_level_tv; break; case FT817_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Internal error!\n", __func__); return -RIG_EINTERNAL; } do { rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); n = read_block(rp, data, len); } while (retries-- && n < 0); if (n < 0) { return n; } if (n != len) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Length mismatch exp %d got %d!\n", __func__, len, n); return -RIG_EIO; } switch (status) { case FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS: { /* Only in digimode we need fetch to extra bits from EEPROM. * This save communication cycle for all other modes. * Because mode and frequency are shared this saves also when * getting the frequency. */ switch (p->fm_status[4] & 0x7f) { unsigned char dig_mode[2]; case 0x0a: if ((n = ft817_read_eeprom(rig, 0x0065, dig_mode)) < 0) { return n; } /* Top 3 bit define the digi mode */ p->dig_mode = dig_mode[0] >> 5; default: break; } } break; case FT817_NATIVE_CAT_GET_TX_METERING: /* FT-817 returns 2 bytes with 4 nibbles. * Extract raw values here; * convert to float when they are requested. */ p->swr_level = (result[1] & 0xF0) >> 4; p->pwr_level = (result[0] & 0xF0) >> 4; p->alc_level = result[0] & 0x0F; p->mod_level = result[1] >> 4; rig_debug(RIG_DEBUG_TRACE, "%s: swr: %d, pwr %d, alc %d, mod %d\n", __func__, p->swr_level, p->pwr_level, p->alc_level, p->mod_level); break; } gettimeofday(tv, NULL); return RIG_OK; } /* ---------------------------------------------------------------------- */ static int ft817_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; freq_t f1 = 0, f2 = 0; struct rig_cache *cachep = CACHE(rig); int retries = RIGPORT(rig)->retry + 1; // +1 because, because 2 steps are needed even in best scenario rig_debug(RIG_DEBUG_VERBOSE, "%s: called, vfo=%s, ptt=%d, split=%d\n", __func__, rig_strvfo(vfo), cachep->ptt, cachep->split); // we can't query VFOB while in transmit and split mode if (cachep->ptt && vfo == RIG_VFO_B && cachep->split) { *freq = cachep->freqMainB; return RIG_OK; } while ((f1 == 0 || f1 != f2) && retries-- > 0) { int n; rig_debug(RIG_DEBUG_TRACE, "%s: retries=%d\n", __func__, retries); if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } f1 = f2; f2 = from_bcd_be(p->fm_status, 8); dump_hex(p->fm_status, sizeof(p->fm_status) / sizeof(p->fm_status[0])); } #if 1 // user must be twiddling the VFO // usually get_freq is OK but we have to allow that f1 != f2 when knob is moving *freq = f2 * 10; return RIG_OK; #else // remove this if no complaints if (retries >= 0) { *freq = f1 * 10; return RIG_OK; } else { return -RIG_EIO; } #endif } static int ft817_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } switch (p->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (p->dig_mode) { case FT817_DIGI_RTTY: *mode = RIG_MODE_RTTYR; break; case FT817_DIGI_PSK_L: *mode = RIG_MODE_PSKR; break; case FT817_DIGI_PSK_U: *mode = RIG_MODE_PSK; break; case FT817_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT817_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; default: *mode = RIG_MODE_NONE; } break; case 0x0C: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (p->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } static int ft817_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; ptt_t ptt; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); n = ft817_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } /* Check if rig is in TX mode */ if (ptt == RIG_PTT_OFF) { // TX status not valid when in RX unsigned char c[2]; /* Get split status from EEPROM */ n = ft817_read_eeprom(rig, 0x7a, c); if (n != RIG_OK) { return n; } *split = (c[0] & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_A; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_B; } return RIG_OK; } static int ft817_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = p->tx_status != 0xff; return RIG_OK; } static int ft817_get_tx_level(RIG *rig, value_t *val, unsigned char *tx_level, const cal_table_float_t *cal) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_level_tv)) { int n; ptt_t ptt; /* Default to not keyed */ *tx_level = 0; /* TX metering is special; it sends 1 byte if not keyed and 2 if keyed. * To handle this properly we first verify the rig is keyed. * Otherwise we experience at least a full timeout and * perhaps pointless retries + timeouts. */ n = ft817_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } if (ptt == RIG_PTT_OFF) { val->f = p->swr; return RIG_OK; } n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_METERING); if (n != RIG_OK) { return n; } } p->swr = val->f = rig_raw2val_float(*tx_level, cal); rig_debug(RIG_DEBUG_VERBOSE, "%s: level %f\n", __func__, val->f); return RIG_OK; } /* frontend will always use RAWSTR+cal_table */ static int ft817_get_smeter_level(RIG *rig, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } //n = (p->rx_status & 0x0F) - 9; //val->i = n * ((n > 0) ? 10 : 6); /* S-meter value is returned in the lower 4 bits. 0x00 = S0 (-54dB) 0x01 = S1 0x02 = S2 ... 0x09 = S9 (0dB) 0x0A = S9+10 (10dB) 0x0B = S9+20 and so on */ n = (p->rx_status & 0x0F); if (n < 0x0A) { val->i = (6 * n) - 54; } else { val->i = 10 * (n - 9); } return RIG_OK; } static int ft817_get_raw_smeter_level(RIG *rig, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int ft817_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: /* The front-end will always call for RAWSTR and use the cal_table */ return ft817_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft817_get_raw_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: return ft817_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); case RIG_LEVEL_ALC: return ft817_get_tx_level(rig, val, &p->alc_level, &rig->caps->alc_cal); case RIG_LEVEL_SWR: return ft817_get_tx_level(rig, val, &p->swr_level, &rig->caps->swr_cal); case RIG_LEVEL_RFPOWER_METER_WATTS: return ft817_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); default: return -RIG_EINVAL; } return RIG_OK; } static int ft817_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } static int ft818_817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx, bool is817) { /* The FT818/817 has no RIG_TARGETABLE_ALL * so rig.c switched the active VFO to the one requested */ int ret; unsigned char eeprom_band[2], eeprom_ant[2]; /* Read eeprom for current 'band' for both VFO's */ ret = ft817_read_eeprom(rig, 0x59, eeprom_band); if (ret != RIG_OK) { return ret; } /* Read eeprom for antenna selection per band. * The FT818/817 stores antenna per band not per VFO! * So changing antenna will change for both VFO's */ ret = ft817_read_eeprom(rig, 0x7A, eeprom_ant); if (ret != RIG_OK) { return ret; } /* if CURR then get real VFO before parsing EEPROM */ if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } /* band info is 4 bit per VFO, for A lower nibble, B is upper nible */ switch (vfo) { case RIG_VFO_A: eeprom_band[0] &= 0xF; break; case RIG_VFO_B: eeprom_band[0] = eeprom_band[0] >> 4; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %0x!\n", __func__, vfo); return -RIG_EINTERNAL; } /* The 818 and the 817 differ in bands: the 818 has 60m. * The band selection flags for the 818 and 817 thus differ: * 2 means 60m on 818 and 40m for 817. * And the rest of the values are shifted. * * So to make the code simple: if we have a 817 and 2 or higher band then * add 1 to the value to align it on the 818 mapping. */ if (is817 && eeprom_band[0] >= 2) { eeprom_band[0]++; } /* The 817/818 does not have a antenna selection per VFO but per band. * So we read the band for the requested VFO and then map it to the * selected antenna. */ switch (eeprom_band[0]) { case 0: /* 160M */ case 1: /* 80M */ case 2: /* 60M, 818 only */ case 3: /* 40M */ case 4: /* 30M */ case 5: /* 20M */ case 6: /* 17M */ case 7: /* 15M */ case 8: /* 12M */ case 9: /* 10M */ /* All HF use the same antenna setting, bit 0 */ eeprom_ant[0] &= 1 << 0; break; case 0xA: /* 6m, bit 1 */ eeprom_ant[0] &= 1 << 1; break; case 0xB: /* FM BCB 76Mhz - 108Mhz, bit 2 */ eeprom_ant[0] &= 1 << 2; break; case 0xC: /* Airband, bit 3 */ eeprom_ant[0] &= 1 << 3; break; case 0xD: /* 2M, bit 4 */ eeprom_ant[0] &= 1 << 4; break; case 0xE: /* 70cm / UHF, bit 5 */ eeprom_ant[0] &= 1 << 5; break; case 0xF: /* Free-tuning?, bit 6 */ eeprom_ant[0] &= 1 << 6; break; } /* We have no split TX/RX capability per VFO. * So only set ant_curr and leave rx/tx set to unknown. */ *ant_curr = eeprom_ant[0] ? FT817_ANT_REAR : FT817_ANT_FRONT; return RIG_OK; } static int ft817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { return ft818_817_get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx, true); } static int ft818_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { return ft818_817_get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx, false); } /* ---------------------------------------------------------------------- */ int ft817_read_ack(RIG *rig) { unsigned char dummy; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (rp->post_write_delay == 0) { if (read_block(rp, &dummy, 1) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error reading ack\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: adjusting post_write_delay to avoid ack\n", __func__); rp->post_write_delay = 10; // arbitrary choice right now of max 100 cmds/sec return RIG_OK; // let it continue without checking for ack now } rig_debug(RIG_DEBUG_TRACE, "%s: ack value=0x%x\n", __func__, dummy); #if 0 // don't know of any reject codes -- none documented if (dummy != 0) { return -RIG_ERJCTED; } #endif } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft817_send_cmd(RIG *rig, int index) { hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Incomplete sequence\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft817_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ static int ft817_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char c[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ft817_read_eeprom(rig, 0x55, c) < 0) /* get vfo status */ { return -RIG_EPROTO; } if ((c[0] & 0x1) == 0) { *vfo = RIG_VFO_A; } else { *vfo = RIG_VFO_B; } return RIG_OK; } static int ft817_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curvfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); retval = ft817_get_vfo(rig, &curvfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error get_vfo '%s'\n", __func__, rigerror(retval)); return retval; } if (curvfo == vfo) { return RIG_OK; } retval = ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(50 * 1000); // can take a little while for vfo swap to happen -- otherwise we get errors trying to read eeprom to quickly return retval; } static int ft817_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "ft817: requested freq = %"PRIfreq" Hz\n", freq); /* fill in the frequency */ /* changed to truncate the freq for gpredict compatibility */ to_bcd_be(data, (freq + 0) / 10, 8); rig_force_cache_timeout( &((struct ft817_priv_data *)STATE(rig)->priv)->fm_status_tv); retval = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_FREQ, data); hl_usleep(50 * 1000); // FT817 needs a little time after setting freq return retval; } static int ft817_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT817_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT817_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT817_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT817_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_PSK: case RIG_MODE_PSKR: { // first we get our dig mode to see if it needs changing unsigned char data[YAESU_CMD_LENGTH]; unsigned char digmode[2]; int ret = ft817_read_eeprom(rig, 0x65, digmode); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: digmode=0x%02x%02x\n", __func__, digmode[0], digmode[1]); digmode[0] = digmode[0] >> 5; // shift 5 bits // check if we're already in the mode and return if so // the memory check was failing when in FM mode -- still showing digmode if (STATE(rig)->current_mode == mode) { if (digmode[0] == 0x00 && mode == RIG_MODE_RTTY) { return RIG_OK; } else if (digmode[0] == 0x01 && mode == RIG_MODE_PSKR) { return RIG_OK; } else if (digmode[0] == 0x02 && mode == RIG_MODE_PSK) { return RIG_OK; } else if (digmode[0] == 0x03 && mode == RIG_MODE_PKTLSB) { return RIG_OK; } else if (digmode[0] == 0x04 && mode == RIG_MODE_PKTUSB) { return RIG_OK; } } memcpy(data, ncmd[FT817_NATIVE_CAT_EEPROM_WRITE].nseq, YAESU_CMD_LENGTH); data[0] = 0x00; data[1] = 0x65; if (mode == RIG_MODE_RTTY) { data[2] = 0; } if (mode == RIG_MODE_PSKR) { data[2] = 1 << 5; } if (mode == RIG_MODE_PSK) { data[2] = 2 << 5; } if (mode == RIG_MODE_PKTLSB) { data[2] = 3 << 5; } if (mode == RIG_MODE_PKTUSB) { data[2] = 4 << 5; } // data[3] should be the original value at address 0x66, // i.e. "DCS INV" / digmode[1]. This is so we don't end // up overwriting this setting by mistake. data[3] = digmode[1]; index = FT817_NATIVE_CAT_SET_MODE_DIG; ret = ft817_send_cmd(rig, index); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ft817_send_cmd: %s\n", __func__, rigerror(ret)); } index = FT817_NATIVE_CAT_EEPROM_WRITE; ret = ft817_send_icmd(rig, index, data); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ft817_send_icmd: %s\n", __func__, rigerror(ret)); } return RIG_OK; } case RIG_MODE_FM: index = FT817_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT817_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT817_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } /* just ignore passband */ /* if (width != RIG_PASSBAND_NORMAL) */ /* return -RIG_EINVAL; */ rig_force_cache_timeout( &((struct ft817_priv_data *)STATE(rig)->priv)->fm_status_tv); return ft817_send_cmd(rig, index); } static int ft817_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index; ptt_t ptt_response = -1; int retries = RIGPORT(rig)->retry; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT817_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT817_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } do { int n; n = ft817_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: send ptt cmd failed\n", __func__); return n; } /* Read TX status it contains the PTT flag. * Use TX_STATUS instead of ft817_get_ptt to skip the cache. */ n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_STATUS); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: get ptt cmd failed\n", __func__); return n; } /* Should be in cache now! But if above command was rejected * we will still try again here. */ n = ft817_get_ptt(rig, vfo, &ptt_response); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: get ptt cmd failed\n", __func__); return n; } if (ptt_response != ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: ptt not requested level, retry\n", __func__); hl_usleep(1000l * FT817_RETRY_DELAY); // Wait before next try. Helps with slower rigs cloning FT817 protocol (e.g. MCHF) } } while (ptt_response != ptt && retries-- > 0); if (retries >= 0) { return RIG_OK; } else { return -RIG_EIO; } } static int ft817_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_LOCK_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } default: return -RIG_EINVAL; } } static int ft817_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; /* int n; */ rig_debug(RIG_DEBUG_VERBOSE, "ft817: set DCS code (%u)\n", code); if (code == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); /* FT-817 does not have the DCS_ENC_ON command, so we just set the tone here */ /* if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) */ /* return n; */ /* return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ENC_ON); */ return ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data); } static int ft817_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set DCS sql (%u)\n", code); if (code == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } static int ft817_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } static int ft817_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } static int ft817_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { /* Note: this doesn't have effect unless FT817 is in FM mode although the command is accepted in any mode. */ rig_debug(RIG_DEBUG_VERBOSE, "ft817: set repeater shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } static int ft817_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set repeater offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_RPT_OFFSET, data); } static int ft817_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } else { ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } */ return RIG_OK; } int ft817_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case RIG_POWER_OFF: return ft817_send_cmd(rig, FT817_NATIVE_CAT_PWR_OFF); case RIG_POWER_ON: // send 5 bytes first, snooze a bit, then PWR_ON write_block(RIGPORT(rig), ncmd[FT817_NATIVE_CAT_PWR_WAKE].nseq, YAESU_CMD_LENGTH); hl_usleep(200 * 1000); write_block(RIGPORT(rig), ncmd[FT817_NATIVE_CAT_PWR_ON].nseq, YAESU_CMD_LENGTH); return RIG_OK; case RIG_POWER_STANDBY: default: return -RIG_EINVAL; } } static int ft817_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { int n; case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct ft817_priv_data *) STATE(rig)->priv)->fm_status_tv); n = ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(100 * 1000); // rig needs a little time to do this return n; default: return -RIG_EINVAL; } } /* FIXME: this function silently ignores the vfo args and just turns split ON or OFF. */ static int ft817_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_ON: index = FT817_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: index = FT817_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } n = ft817_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { return n; } CACHE(rig)->split = split; return RIG_OK; } /* FIXME: currently ignores mode and freq */ /* No documentation on how to interpret it but the max number of bars on the display is 10 and I measure: 8 bars = 5W 5 bars = 2.5W 3 bars = 1W 1 bar = 0.5W */ static int ft817_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mwpower = (int)(power * 6000); return RIG_OK; } /* FIXME: currently ignores mode and freq */ static int ft817_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *power = mwpower / 6000.0; return RIG_OK; } /* ---------------------------------------------------------------------- */ hamlib-4.6.5/rigs/yaesu/ft736.c0000664000175000017500000004151415056640443011570 /* * ft736.c - (C) Stephane Fillod 2004-2010 * * This shared library provides an API for communicating * via serial interface to an FT-736R using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "tones.h" #include "cache.h" #define FT736_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_CWN) #define FT736_VFOS (RIG_VFO_A) /* Measurement by Ron W6FM using a signal generator. * Raw values supposed to be between 0x30 and 0xad according to manual. */ #define FT736_STR_CAL { 3, { \ { 0x1d, -54 }, /* S0 */ \ { 0x54, 0 }, /* S9 */ \ { 0x9d, 60 } /* +60 */ \ } } struct ft736_priv_data { split_t split; }; /* Private helper function prototypes */ static int ft736_open(RIG *rig); static int ft736_close(RIG *rig); static int ft736_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft736_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); // cached answer static int ft736_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft736_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft736_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft736_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft736_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft736_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft736_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft736_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft736_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft736_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft736_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft736_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft736_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); /* Some tones are present twice, the second value is * higher Q (80), according to manual. */ static tone_t ft736_ctcss_list[] = { 670, 719, 770, 825, 885, 948, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 670, 719, 744, 770, 797, 825, 854, 885, 915, 0 }; #define FT736_CTCSS_NB 42 /* * ft736 rigs capabilities. * * TODO: * - AQS */ struct rig_caps ft736_caps = { RIG_MODEL(RIG_MODEL_FT736R), .model_name = "FT-736R", .mfg_name = "Yaesu", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, /* RTS low, DTR high, and CTS low. */ .write_delay = 30, /* 50ms to be real safe */ .post_write_delay = 0, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .ctcss_list = ft736_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(50), MHz(53.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(144), MHz(145.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(430), MHz(439.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, -1, -1, FT736_VFOS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { {MHz(50), MHz(53.99999), FT736_MODES, W(5), W(30), FT736_VFOS }, {MHz(144), MHz(145.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(430), MHz(439.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, W(5), W(45), FT736_VFOS }, RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {MHz(50), MHz(53.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(144), MHz(147.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(220), MHz(224.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(430), MHz(449.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, -1, -1, FT736_VFOS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { {MHz(50), MHz(53.99999), FT736_MODES, W(5), W(30), FT736_VFOS }, {MHz(144), MHz(147.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(220), MHz(224.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(430), MHz(449.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, W(5), W(45), FT736_VFOS }, RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {FT736_MODES, Hz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FMN, kHz(8)}, {RIG_MODE_CWN, Hz(600)}, RIG_FLT_END, }, .str_cal = FT736_STR_CAL, .rig_open = ft736_open, .rig_close = ft736_close, .set_freq = ft736_set_freq, .get_freq = ft736_get_freq, .get_mode = ft736_get_mode, .set_mode = ft736_set_mode, .set_ptt = ft736_set_ptt, .get_dcd = ft736_get_dcd, .get_level = ft736_get_level, .set_split_vfo = ft736_set_split_vfo, .set_split_freq = ft736_set_split_freq, .set_split_mode = ft736_set_split_mode, .set_rptr_shift = ft736_set_rptr_shift, .set_rptr_offs = ft736_set_rptr_offs, .set_func = ft736_set_func, .set_ctcss_tone = ft736_set_ctcss_tone, .set_ctcss_sql = ft736_set_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft736_open routine * */ int ft736_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; struct ft736_priv_data *priv; int ret; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->priv = (struct ft736_priv_data *) calloc(1, sizeof(struct ft736_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->split = RIG_SPLIT_OFF; /* send Ext Cntl ON: Activate CAT */ ret = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { free(priv); } return ret; } int ft736_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x80, 0x80, 0x80, 0x80, 0x80}; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); free(STATE(rig)->priv); /* send Ext Cntl OFF: Deactivate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; const struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; int retval; // we will assume requesting to set VFOB is split mode if (vfo == RIG_VFO_B) { return rig_set_split_freq(rig, vfo, freq); } if (priv->split == RIG_SPLIT_ON) { cmd[4] = 0x1e; } /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, freq / 10, 8); /* special case for 1.2GHz band */ if (freq > GHz(1.2)) { cmd[0] = (cmd[0] & 0x0f) | 0xc0; } retval = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (retval == RIG_OK) { rig_set_cache_freq(rig, vfo, freq); } return retval; } int ft736_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { *freq = CACHE(rig)->freqMainA; } else { rig_get_cache_freq(rig, vfo, freq, NULL); } return RIG_OK; } #define MD_LSB 0x00 #define MD_USB 0x01 #define MD_CW 0x02 #define MD_CWN 0x82 #define MD_FM 0x08 #define MD_FMN 0x88 static int ft736_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mode = CACHE(rig)->modeMainA; switch (*mode) { case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_CW: *width = 2200; break; case RIG_MODE_CWN: *width = 600; break; case RIG_MODE_FM: *width = 12000; break; case RIG_MODE_FMN: *width = 800; break; default: *width = 2200; break; } return RIG_OK; } int ft736_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x07}; unsigned char md; const struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { return ft736_set_split_mode(rig, vfo, mode, width); } if (priv->split == RIG_SPLIT_ON) { cmd[4] = 0x17; } /* * translate mode from generic to ft736 specific */ switch (mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_CWN: md = MD_CWN; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_FMN: md = MD_FMN; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x80; } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8e}; struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; int ret; /* * this can be misleading as Yaesu call it "Full duplex" * or "sat mode", and split Yaesu terms is repeater shift. */ cmd[4] = split == RIG_SPLIT_ON ? 0x0e : 0x8e; ret = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (ret == RIG_OK) { priv->split = split; } return ret; } int ft736_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x2e}; int retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { return retval; } /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, freq / 10, 8); /* special case for 1.2GHz band */ if (freq > GHz(1.2)) { cmd[0] = (cmd[0] & 0x0f) | 0xc0; } /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x27}; unsigned char md; /* * translate mode from generic to ft736 specific */ switch (mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_CWN: md = MD_CWN; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_FMN: md = MD_FMN; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (RIG_PASSBAND_NOCHANGE != width && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x80; } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x88}; cmd[4] = ptt == RIG_PTT_ON ? 0x08 : 0x88; /* Tx/Rx set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read squelch failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } *dcd = cmd[0] == 0x00 ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } int ft736_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send Test S-meter cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } int ft736_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x89}; switch (shift) { case RIG_RPT_SHIFT_NONE: /* There's a typo in the manual. * "Split Dir. simplex" is in fact 0x89, and 0x88 is PTT off! */ cmd[4] = 0x89; break; case RIG_RPT_SHIFT_MINUS: cmd[4] = 0x09; break; case RIG_RPT_SHIFT_PLUS: cmd[4] = 0x49; break; default: return -RIG_EINVAL; } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf9}; /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, offs / 10, 8); /* Offset set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8a}; switch (func) { case RIG_FUNC_TONE: cmd[4] = status ? 0x4a : 0x8a; break; case RIG_FUNC_TSQL: cmd[4] = status ? 0x0a : 0x8a; break; default: return -RIG_EINVAL; } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xfa}; int i; for (i = 0; i < FT736_CTCSS_NB; i++) { if (ft736_ctcss_list[i] == tone) { break; } } if (i == FT736_CTCSS_NB) { return -RIG_EINVAL; } cmd[0] = 0x3e - i; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { /* same opcode as tone */ return ft736_set_ctcss_tone(rig, vfo, tone); } hamlib-4.6.5/rigs/yaesu/yaesu.h0000664000175000017500000000632015056640443012046 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * yaesu.h - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2001-2010 * * Common yaesu declarations for hamlib * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _YAESU_H #define _YAESU_H 1 #include "idx_builtin.h" /* * Length (in bytes) of yaesu command sequences */ #define YAESU_CMD_LENGTH 5 /* * Basic Data structure for yaesu native cmd set */ struct yaesu_cmd_set { unsigned char ncomp; /* 1 = complete, 0 = incomplete, needs extra info */ unsigned char nseq[YAESU_CMD_LENGTH]; /* native cmd sequence */ }; typedef struct yaesu_cmd_set yaesu_cmd_set_t; extern struct rig_caps ft100_caps; extern struct rig_caps ft450_caps; extern struct rig_caps ft450d_caps; extern struct rig_caps ft736_caps; extern struct rig_caps ft747_caps; extern struct rig_caps ft757gx_caps; extern struct rig_caps ft757gx2_caps; extern struct rig_caps ft600_caps; extern struct rig_caps ft767gx_caps; extern struct rig_caps ft817_caps; extern struct rig_caps ft857_caps; extern struct rig_caps ft897_caps; extern struct rig_caps ft897d_caps; extern struct rig_caps ft847_caps; extern struct rig_caps ft840_caps; extern struct rig_caps ft890_caps; extern struct rig_caps ft891_caps; extern struct rig_caps ft900_caps; extern struct rig_caps ft920_caps; extern struct rig_caps ft950_caps; extern struct rig_caps ft980_caps; extern struct rig_caps ft990_caps; extern struct rig_caps ft990uni_caps; extern struct rig_caps ft991_caps; extern struct rig_caps ft1000mp_caps; extern struct rig_caps ft1000mpmkv_caps; extern struct rig_caps ft1000mpmkvfld_caps; extern struct rig_caps ft1000_caps; extern struct rig_caps ft1000d_caps; extern struct rig_caps ft2000_caps; extern struct rig_caps ftdx3000_caps; extern struct rig_caps ftdx5000_caps; extern struct rig_caps ft9000_caps; extern struct rig_caps frg100_caps; extern struct rig_caps frg8800_caps; extern struct rig_caps frg9600_caps; extern struct rig_caps vr5000_caps; extern struct rig_caps vx1700_caps; extern struct rig_caps ftdx1200_caps; extern struct rig_caps ft847uni_caps; extern struct rig_caps ftdx101d_caps; extern struct rig_caps ft818_caps; extern struct rig_caps ftdx10_caps; extern struct rig_caps ftdx101mp_caps; extern struct rig_caps mchfqrp_caps; extern struct rig_caps ft650_caps; extern struct rig_caps ft710_caps; extern struct rig_caps ft9000Old_caps; extern struct rig_caps q900_caps; extern struct rig_caps pmr171_caps; #endif /* _YAESU_H */ hamlib-4.6.5/rigs/yaesu/ft980.h0000664000175000017500000003521415056640443011576 /* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft980.h - (C) Mat Breton, 2020 * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* This file is a bit of a hack at the moment, containing both public and private declarations * ToDo: Fix this point later, but temporarily necessary to sort stuff out right now */ #ifndef _FT980_H #define _FT980_H 1 /* Lets make the Linters Happy - remove later*/ #ifndef _RIG_H #include "hamlib/rig.h" #endif #ifndef _YAESU_H #include "yaesu.h" #endif #ifndef _BANDPLAN_H #include "bandplan.h" #endif /* End of Happy Linter Section */ /************************************************************************************* * Semi-Public prototypes: need to be placed before the caps construct * HAMLIB API implementation */ static int ft980_init(RIG *rig); static int ft980_cleanup(RIG *rig); static int ft980_open(RIG *rig); static int ft980_close(RIG *rig); static int ft980_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft980_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft980_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft980_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft980_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft980_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft980_set_vfo(RIG *rig, vfo_t vfo); static int ft980_get_vfo(RIG *rig, vfo_t *vfo); #if 0 static int ft980_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft980_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft980_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft980_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft980_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft980_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft980_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft980_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft980_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); #endif /************************************************************************************* * Constants (enums and defines, w/ a couple typedefs thrown in) */ /* Handy constants */ #ifndef TRUE #define TRUE 1 #endif #define ON TRUE #ifndef FALSE #define FALSE 0 #endif #define OFF FALSE /* FT-980 Status Return Message Lengths */ #define FT980_ALL_STATUS_LENGTH 148 #define FT980_OTHER_STATUS_LENGTH 22 #define FT980_RPTRSPLT_STATUS_LENGTH 6 #define FT980_UPDN_STATUS_LENGTH 5 #define FT980_ONEBYTE_STATUS_LENGTH 1 /* FT-980 Timing Constants (for caps structure)*/ /* Serial write timing values, in mS */ #define FT980_WRITE_DELAY 80 /* Delay sequential fast writes */ #define FT980_POST_WRITE_DELAY 5 /* Serial write timing values, in mS */ #define FT980_PACING_INTERVAL 5 /* The following may be deprecated into rig.c cache with 4.1 release*/ #define FT980_CACHE_TIMEOUT 500 /* Rough safe value for default read timeout = # bytes x (xmit speed + pacing_interval) x safety factor #define FT980_DEFAULT_READ_TIMEOUT FT980_ALL_DATA_LENGTH * ( 1.7 + FT980_PACING_INTERVAL) * 6 */ #define FT980_DEFAULT_READ_TIMEOUT 2000 /* FT-980 Configuration Constants (for caps structure)*/ #define FT980_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_RTTY|RIG_MODE_FM) #define FT980_ANTS (RIG_ANT_1) /* */ #define FT980_VFOS (RIG_VFO_CURR|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* TODO: RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN */ #define FT980_VFO_OPS (RIG_OP_NONE) /* TODO: RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN #define FT890_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) */ /* * ft980 rigs capabilities. * * Protocol is documented in FT 980 Technical Supplement, page 13. * */ #define FT980_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } struct rig_caps ft980_caps = { RIG_MODEL(RIG_MODEL_FT980), .model_name = "FT-980", .mfg_name = "Yaesu", .version = "20200114.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_SERIAL_RTS, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT980_WRITE_DELAY, .post_write_delay = FT980_POST_WRITE_DELAY, .timeout = FT980_DEFAULT_READ_TIMEOUT, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = FT980_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(10000), .max_xit = Hz(10000), .max_ifshift = Hz(1500), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 16, RIG_MTYPE_MEM, FT980_MEM_CAP}, }, .rx_range_list1 = { {kHz(150), MHz(30) - 100, FT980_MODES, -1, -1, FT980_VFOS, FT980_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, RIG_MODE_SSB | RIG_MODE_CW, W(5), W(100), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(1, RIG_MODE_FM | RIG_MODE_RTTY, W(2), W(50), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), FT980_VFOS, FT980_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - 100, FT980_MODES, -1, -1, FT980_VFOS, FT980_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, RIG_MODE_SSB | RIG_MODE_CW, W(5), W(100), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(2, RIG_MODE_FM | RIG_MODE_RTTY, W(2), W(50), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), FT980_VFOS, FT980_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT980_MODES, Hz(10)}, {FT980_MODES, kHz(5)}, {FT980_MODES, kHz(500)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.5)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(5)}, {RIG_MODE_AM, kHz(3)}, RIG_FLT_END, }, .rig_init = ft980_init, .rig_cleanup = ft980_cleanup, .rig_open = ft980_open, .rig_close = ft980_close, .set_freq = ft980_set_freq, .get_freq = ft980_get_freq, .set_mode = ft980_set_mode, .get_mode = ft980_get_mode, .set_mem = ft980_set_mem, .get_mem = ft980_get_mem, .get_vfo = ft980_get_vfo, .set_vfo = ft980_set_vfo, #ifdef XXREMOVEDXX .set_split_vfo = ft980_set_split_vfo, .set_split_freq = ft980_set_split_freq, .set_split_mode = ft980_set_split_mode, .set_rptr_shift = ft980_set_rptr_shift, .set_rptr_offs = ft980_set_rptr_offs, #endif }; /* FT-980 Status Return Lengths (for memory structure)*/ #define FT980_ALL_STATUS_LENGTH 148 #define FT980_OTHER_STATUS_LENGTH 22 #define FT980_RPTRSPLT_STATUS_LENGTH 6 #define FT980_UPDN_STATUS_LENGTH 5 #define FT980_ONEBYTE_STATUS_LENGTH 1 /* Do not change the order of the memory structure */ typedef struct _ft980_memory_t { unsigned char mem_16[4]; unsigned char vfo_16; unsigned char mode_16; unsigned char mem_15[4]; unsigned char vfo_15; unsigned char mode_15; unsigned char mem_14[4]; unsigned char vfo_14; unsigned char mode_14; unsigned char mem_13[4]; unsigned char vfo_13; unsigned char mode_13; unsigned char mem_12[4]; unsigned char vfo_12; unsigned char mode_12; unsigned char mem_11[4]; unsigned char vfo_11; unsigned char mode_11; unsigned char mem_10[4]; unsigned char vfo_10; unsigned char mode_10; unsigned char mem_9[4]; unsigned char vfo_9; unsigned char mode_9; unsigned char mem_8[4]; unsigned char vfo_8; unsigned char mode_8; unsigned char mem_7[4]; unsigned char vfo_7; unsigned char mode_7; unsigned char mem_6[4]; unsigned char vfo_6; unsigned char mode_6; unsigned char mem_5[4]; unsigned char vfo_5; unsigned char mode_5; unsigned char mem_4[4]; unsigned char vfo_4; unsigned char mode_4; unsigned char mem_3[4]; unsigned char vfo_3; unsigned char mode_3; unsigned char mem_2[4]; unsigned char vfo_2; unsigned char mode_2; unsigned char mem_1[4]; unsigned char vfo_1; unsigned char mode_1; unsigned char clar_freq[4]; unsigned char gen_vfo_freq[4]; unsigned char ham_vfo_freq[4]; unsigned char vfo; /* ??? */ unsigned char mode; /* ??? */ unsigned char mem_shift_freq[4]; unsigned char mem_clar_freq[4]; unsigned char mem_vfo; unsigned char mem_mode; unsigned char ldb_flag; unsigned char ext_ctl_flag; unsigned char if_shift; unsigned char rptr_split_code; unsigned char fsk_shift; unsigned char if_width; unsigned char mem_shift_flag; unsigned char clar_flag; unsigned char tab_flag; unsigned char freq_select_sws; unsigned char offset_sw; unsigned char mode_sw; unsigned char mem_ch_sw; unsigned char lower_tab_freq[4]; unsigned char upper_tab_freq[4]; unsigned char op_vfo; unsigned char op_mode; unsigned char op_freq[4]; unsigned char status_flag_bits; } _ft980_memory_t; /* * Start of Return Status Code Defines * These are the memory decode define (for the _ft980_memory_structure) */ /* status_flag_bits: STATUS FLAG BYTE BIT decode MASKS */ #define FT_980_STATUSFLAG_TXRX_MASK 0x01 #define FT_980_STATUSFLAG_SPLIT_MASK 0x08 #define FT_980_STATUSFLAG_VFO_MASK 0x20 #define FT_980_STATUSFLAG_UPDN_MASK 0X30 #define FT_980_STATUSFLAG_CLAR_MASK 0x40 /* op_vfo: VFO decode: Main, Gen, and 3 unused AUX */ #define FT980_VFO_HAM_SEL 0x80 #define FT980_VFO_GEN_SEL 0x00 #define FT980_VFO_AUX1_SEL 0x81 #define FT980_VFO_AUX2_SEL 0x82 #define FT980_VFO_AUX3_SEL 0x83 /* freq_select_sws: Frequency source decode, either a VFO, Mem, or Split */ #define FT980_FREQ_SRC_SW_VFO 0x00 #define FT980_FREQ_SRC_SW_MR 0x01 #define FT980_FREQ_SRC_SW_RXM 0x02 #define FT980_FREQ_SRC_SW_RXV 0x03 /* Clarifier Active Decode Masks */ #define FT980_CLAR_RX_FLAG 0x20 #define FT980_CLAR_TX_FLAG 0x40 /* FSK Shift Decode */ #define FT980_FSK_SHIFT_INT 0x00 #define FT980_FSK_SHIFT_425 0x40 #define FT980_FSK_SHIFT_850 0x80 #define FT980_FSK_SHIFT_170 0xC0 /* Repeater Split Codes */ /* TBD: Is this table even needed */ /* * Start of Command Code Defines */ static const unsigned char cmd_OK[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0B}; static const unsigned char cmd_ON_OFF[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; /* Opcodes 00 to 0B */ enum ft980_native_cmd_e { FT980_CMD_TOGGLE_EXT_CNTL = 0x00, FT980_CMD_ALL_STATUS_CHECK = 0x01, FT980_CMD_UP_10HZ = 0x02, FT980_CMD_DN_10HZ = 0x03, FT980_CMD_IF_WIDTH = 0x04, FT980_CMD_IF_SHIFT = 0x05, FT980_CMD_FSK_FREQ = 0x06, FT980_CMD_RPTR_SPLIT_CODE = 0x07, FT980_CMD_FREQ = 0x08, FT980_CMD_LDB_SET = 0x09, FT980_CMD_USER_PROG = 0x0A, FT980_CMD0A_OK_SIGNAL = 0x0B }; /* OpCode command 0x0A byte 3 sub-codes */ /* The first 16 subcodes 00-0F are to command the memory channel */ // Operating Mode Status enum ft980_native_cmd0A_e { FT980_CMD0A_MD_LSB = 0x10, FT980_CMD0A_MD_USB = 0x11, FT980_CMD0A_MD_CW = 0x12, FT980_CMD0A_MD_CWN = 0x13, FT980_CMD0A_MD_AM = 0x14, FT980_CMD0A_MD_AMN = 0x15, FT980_CMD0A_MD_RTTY = 0x16, FT980_CMD0A_MD_FM = 0x17, FT980_CMD0A_SHOW_OFFSET = 0x1B, /* Frequency Source Select */ FT980_CMD0A_FREQ_SEL_RXM = 0x1C, FT980_CMD0A_FREQ_SEL_RXV = 0x1D, FT980_CMD0A_FREQ_SEL_MR = 0x1E, FT980_CMD0A_FREQ_SEL_VFO = 0x1F, /* VFO Select; Question ... how do you set AUX1,2,3? */ FT980_CMD0A_VFO_SEL_GEN = 0x21, FT980_CMD0A_VFO_SEL_HAM = 0x22, /* Set Tab to Current Operating Frequency */ FT980_CMD0A_SET_UPPER_TAB = 0x23, FT980_CMD0A_SET_LOWER_TAB = 0x24, FT980_CMD0A_TOGGLE_TABS = 0x25, /* Clarifier Commands */ FT980_CMD0A_TOGGLE_TX_CLAR = 0x26, FT980_CMD0A_TOGGLE_RX_CLAR = 0x27, /* Memory Commands */ FT980_CMD0A_MEM_SHIFT = 0x28, FT980_CMD0A_MEM_WRITE = 0x29, /* More Frequency Skips */ FT980_CMD0A_UP_100Hz = 0x18, FT980_CMD0A_DN_100Hz = 0x20, FT980_CMD0A_UP_5KHz = 0x2C, FT980_CMD0A_DN_5KHz = 0x2B, FT980_CMD0A_BANDUP = 0x2F, FT980_CMD0A_BANDOWN = 0x2D /* Missing 0A Sub-op-codes: 19,1A,2A,2E, after 2F */ }; /* End of OpCode command 0x0A byte 3 sub-codes */ /************************************************************************************* * Macro Definitions */ #define UPDATE_DATA_OFS(p, o) (((unsigned char*)((p)+1))-(o)) #endif /* _FT980_H */ hamlib-4.6.5/rigs/yaesu/ft991.h0000664000175000017500000001557615056640443011611 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft991.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT991_H #define _FT991_H 1 #define FT991_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT991_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_C4FM|RIG_MODE_FM|RIG_MODE_AMN|RIG_MODE_FMN) #define FT991_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT991_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT991_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_C4FM) #define FT991_FM_RX_MODES (FT991_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT991_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT991_RTTY_DATA_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) /* TRX caps */ #define FT991_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FT991_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT991_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_BKIN_DLYMS|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT991_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_CSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT991_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT991_RFPOWER_METER_CAL \ { \ 7, \ { \ {0, 0.0f}, \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT991_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } #define FT991_ID_CAL { 7, \ { \ { 0, 0.0f }, \ { 53, 5.0f }, \ { 65, 6.0f }, \ { 78, 7.0f }, \ { 86, 8.0f }, \ { 98, 9.0f }, \ { 107, 10.0f } \ } \ } /* TBC */ #define FT991_VD_CAL { 2, \ { \ { 0, 0.0f }, \ { 192, 13.8f }, \ } \ } #define FT991_COMP_CAL { 9, \ { \ { 0, 0.0f }, \ { 40, 2.5f }, \ { 60, 5.0f }, \ { 85, 7.5f }, \ { 135, 10.0f }, \ { 150, 12.5f }, \ { 175, 15.0f }, \ { 195, 17.5f }, \ { 220, 20.0f } \ } \ } /* * Other features (used by rig_caps) * */ // The FT991 does not have antenna selection #define FT991_ANTS (RIG_ANT_CURR) #define FT991_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT991_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT991_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT991_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT991_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT991_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT991_PACING_INTERVAL 5 // #define FT991_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-991 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT991_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT991_POST_WRITE_DELAY 2 typedef struct { char command[2]; /* depends on command "IF", "MR", "MW" "OI" */ char memory_ch[3]; /* 001 -> 117 */ char vfo_freq[9]; /* 9 digit value in Hz */ char clarifier[5]; /* '+' | '-', 0000 -> 9999 Hz */ char rx_clarifier; /* '0' = off, '1' = on */ char tx_clarifier; /* '0' = off, '1' = on */ char mode; /* '1'=LSB, '2'=USB, '3'=CW, '4'=FM, '5'=AM, */ /* '6'=RTTY-LSB, '7'=CW-R, '8'=DATA-LSB, */ /* '9'=RTTY-USB,'A'=DATA-FM, 'B'=FM-N, */ /* 'C'=DATA-USB, 'D'=AM-N, 'E'=C4FM */ char vfo_memory; /* '0'=VFO, '1'=Memory, '2'=Memory Tune, */ /* '3'=Quick Memory Bank, '4'=QMB-MT, '5'=PMS, '6'=HOME */ char tone_mode; /* '0' = off, CTCSS '1' ENC, '2' ENC/DEC, */ /* '3' = DCS ENC/DEC, '4' = ENC */ char fixed[2]; /* Always '0', '0' */ char repeater_offset; /* '0' = Simplex, '1' Plus, '2' minus */ char terminator; /* ';' */ } ft991info; #endif /* _FT991_H */ hamlib-4.6.5/rigs/yaesu/ft767gx.h0000664000175000017500000000321015056640443012127 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * * ft767gx.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * adapted from ft757gx.h by Steve Conklin * This shared library provides an API for communicating * via serial interface to an FT-767GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT767GX_H #define _FT767GX_H 1 #define FT767GX_STATUS_UPDATE_DATA_LENGTH 86 #define FT767GX_PACING_INTERVAL 5 #define FT767GX_PACING_DEFAULT_VALUE 0 #define FT767GX_WRITE_DELAY 0 /* Sequential fast writes confuse my FT767GX without this delay */ #define FT767GX_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT767GX_DEFAULT_READ_TIMEOUT 345 * ( 3 + (FT767GX_PACING_INTERVAL * FT767GX_PACING_DEFAULT_VALUE)) #endif /* _FT767GX_H */ hamlib-4.6.5/rigs/yaesu/ft5000.h0000664000175000017500000001266415056640443011646 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft5000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * * This shared library provides an API for communicating * via serial interface to an FT-DX5000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT5000_H #define _FT5000_H 1 #define FTDX5000_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* Receiver caps */ #define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) #define FTDX5000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX5000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FTDX5000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX5000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FTDX5000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ /* TBC */ #define FTDX5000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FTDX5000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FTDX5000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) /* TBC */ #define FTDX5000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ }\ } // Values stolen from FLRig -- thanks to Dave W1HKJ #define FT5000_RFPOWER_METER_CAL \ { \ 14, \ { \ {55, 10.0f}, \ {75, 20.0f}, \ {101, 40.0f}, \ {125, 60.0f}, \ {144, 80.0f}, \ {161, 100.0f}, \ {177, 120.0f}, \ {190, 140.0f}, \ {202, 160.0f}, \ {215, 180.0f}, \ {225, 200.0f}, \ {237, 220.0f}, \ {242, 240.0f}, \ {255, 250.0f}, \ } \ } /* * Other features (used by rig_caps) * */ #define FTDX5000_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define FTDX5000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX5000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX5000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX5000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX5000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX5000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FTDX5000_PACING_INTERVAL 5 // #define FTDX5000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-5000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ // a 1ms delay was not working with microham and eltima ports #define FTDX5000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX5000_POST_WRITE_DELAY 5 #endif /* _FT5000_H */ hamlib-4.6.5/rigs/yaesu/ft2000.h0000664000175000017500000001226415056640443011637 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft2000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-2000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT2000_H #define _FT2000_H 1 #define FT2000_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT2000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) #define FT2000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT2000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT2000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFM) #define FT2000_PKTSSB_RX_MODES (RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) /* TRX caps */ #define FT2000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) /* 100 W class */ #define FT2000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT2000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT2000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT2000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // From measurements on FT2000D by Stan UA3SAQ // We'll reuse this for now and divide by 2 for FT2000 #define FT2000D_RFPOWER_METER_CAL { 12, \ { \ {0, 0.0f}, \ {51, 10.0f}, \ {67, 20.0f}, \ {97, 40.0f}, \ {123, 60.0f}, \ {140, 80.0f}, \ {161, 100.0f}, \ {168, 120.0f}, \ {184, 140.0f}, \ {195, 160.0f}, \ {215, 180.0f}, \ {224, 200.0f}, \ } \ } #define FT2000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT2000_TX_ANTS (RIG_ANT_1|RIG_ANT_2) #define FT2000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT2000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT2000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT2000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT2000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT2000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT2000_PACING_INTERVAL 5 // #define FT2000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-2000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT2000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT2000_POST_WRITE_DELAY 5 #endif /* _FT2000_H */ hamlib-4.6.5/rigs/yaesu/ft1000d.h0000664000175000017500000002427715056640443012011 /* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft1000d.h - (C) 2016 Sean Sharkey (g0oan at icloud.com) * * This shared library provides an API for communicating * via serial interface to an FT-1000D using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT1000D_H #define _FT1000D_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT1000D_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT1000D_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT1000D_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT1000D_AM_RX_MODES (RIG_MODE_AM) #define FT1000D_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT1000D_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT1000D_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT1000D_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT1000D_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT1000D_ANTS 0 #define FT1000D_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) // Added the below to store currently selected VFO as set by CAT command Opcode 05h #define FT1000D_CURRENTLY_SELECTED_VFO /* Returned data length in bytes */ #define FT1000D_ALL_DATA_LENGTH 1636 /* 0x10 P1 = 00 return size */ #define FT1000D_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT1000D_OP_DATA_LENGTH 16 /* 0x10 P1 = 02 return size */ #define FT1000D_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT1000D_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT1000D_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT1000D_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT1000D_BCD_DIAL 8 #define FT1000D_BCD_RIT 3 #define FT1000D_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT1000D_PACING_INTERVAL 5 #define FT1000D_PACING_DEFAULT_VALUE 0 #define FT1000D_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT1000D_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT1000D_DEFAULT_READ_TIMEOUT FT1000D_ALL_DATA_LENGTH * ( 5 + (FT1000D_PACING_INTERVAL * FT1000D_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kFT1000D * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT1000D_CMD_SPLIT 0x01 #define FT1000D_CMD_RECALLMEM 0x02 #define FT1000D_CMD_VFO2MEM 0x03 #define FT1000D_CMD_LOCK 0x04 #define FT1000D_CMD_SELVFOAB 0x05 #define FT1000D_CMD_MEM2VFO 0x06 #define FT1000D_CMD_UP 0x07 #define FT1000D_CMD_DOWN 0x08 #define FT1000D_CMD_CLARIFIER 0x09 #define FT1000D_CMD_SETVFOA 0x0a #define FT1000D_CMD_SELOPMODE 0x0c #define FT1000D_CMD_PACING 0x0e #define FT1000D_CMD_PTT 0x0f #define FT1000D_CMD_UPDATE 0x10 #define FT1000D_CMD_TUNER 0x81 #define FT1000D_CMD_START 0x82 #define FT1000D_CMD_RPT 0x84 #define FT1000D_CMD_VFOA2B 0x85 #define FT1000D_CMD_SUBVFOFREQ 0X8a #define FT1000D_CMD_BW 0x8c #define FT1000D_CMD_MEMSCANSKIP 0x8d #define FT1000D_CMD_STEPVFO 0x8e #define FT1000D_CMD_RDMETER 0xf7 #define FT1000D_CMD_DIMLEVEL 0xf8 #define FT1000D_CMD_RPTROFFSET 0xf9 #define FT1000D_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT1000D_BW_F2400 0x00 #define FT1000D_BW_F2000 0x01 #define FT1000D_BW_F500 0x02 #define FT1000D_BW_F250 0x03 #define FT1000D_BW_F6000 0x04 #define FT1000D_BW_FMPKTRTTY 0x80 #define FT1000D_SUB_VFOB_BW_F2400 0x80 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F2000 0x81 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F500 0x82 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F250 0x83 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F6000 0x84 /* Added December 2016 */ // Operating Mode Status #define FT1000D_MODE_LSB 0x00 #define FT1000D_MODE_USB 0x01 #define FT1000D_MODE_CW 0x02 #define FT1000D_MODE_AM 0x03 #define FT1000D_MODE_FM 0x04 #define FT1000D_MODE_RTTY 0x05 #define FT1000D_MODE_PKT 0x06 // Operation Mode Selection #define FT1000D_OP_MODE_LSB 0x00 #define FT1000D_OP_MODE_USB 0x01 #define FT1000D_OP_MODE_CW2400 0x02 #define FT1000D_OP_MODE_CW500 0x03 #define FT1000D_OP_MODE_AM6000 0x04 #define FT1000D_OP_MODE_AM2400 0x05 #define FT1000D_OP_MODE_FM 0x06 #define FT1000D_OP_MODE_RTTYLSB 0x08 #define FT1000D_OP_MODE_RTTYUSB 0x09 #define FT1000D_OP_MODE_PKTLSB 0x0a #define FT1000D_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT1000D_CLAR_TX_EN 0x01 #define FT1000D_CLAR_RX_EN 0x02 #define FT1000D_CLAR_RX_OFF 0x00 #define FT1000D_CLAR_RX_ON 0x01 #define FT1000D_CLAR_TX_OFF 0x80 #define FT1000D_CLAR_TX_ON 0x81 #define FT1000D_CLAR_CLEAR 0xff #define FT1000D_CLAR_TUNE_UP 0x00 #define FT1000D_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT1000D_RPT_POS_EN 0x04 #define FT1000D_RPT_NEG_EN 0x08 #define FT1000D_RPT_MASK 0x0C // Status Flag 1 Masks #define FT1000D_SF_SPLIT 0x01 /* Added December 2016 */ #define FT1000D_SF_DUAL 0x02 /* Added December 2016 */ #define FT1000D_SF_ANT_TUNER_ACTIVE 0x04 /* Added December 2016 */ #define FT1000D_SF_CAT 0x08 /* Added December 2016 */ #define FT1000D_SF_VFOB_INUSE 0x10 /* Added December 2016 APPEARS NOT TO WORK RIG DOES NOT SET BIT */ #define FT1000D_SF_KEY_ENTRY 0x20 /* Added December 2016 */ #define FT1000D_SF_MEM_EMPTY 0x40 /* Added December 2016 */ #define FT1000D_SF_XMIT 0x80 /* Added December 2016 */ // Status Flag 2 Masks #define FT1000D_SF_MEM_SCAN_PAUSE 0x01 #define FT1000D_SF_MEM_CHECK 0x02 #define FT1000D_SF_MEM_SCAN 0x04 #define FT1000D_SF_LOCKED 0x08 #define FT1000D_SF_MTUNE 0x10 #define FT1000D_SF_VFO 0x20 #define FT1000D_SF_MEM 0x40 #define FT1000D_SF_GEN 0x80 // Status Flag 3 Masks #define FT1000D_SF_PTT 0x01 #define FT1000D_SF_TX_INHIBIT 0x02 #define FT1000D_SF_KEY_TIMER 0x04 #define FT1000D_SF_MEM_TIMER 0x08 #define FT1000D_SF_PTT_INHIBIT 0x10 #define FT1000D_SF_XMIT_MON 0x20 #define FT1000D_SF_TUNER_ON 0x40 #define FT1000D_SF_SUB_VFOB_LOCKED 0x80 #define FT1000D_EMPTY_MEM 0x80 #define FT1000D_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft1000d_flags1_t { unsigned split: 1; unsigned dualrx: 1; unsigned tuneact: 1; unsigned cat: 1; unsigned vfobinuse: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft1000d_flags1_t; // Flags Byte 2 typedef struct _ft1000d_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft1000d_flags2_t; // Flags Byte 3 typedef struct _ft1000d_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned subvfoblock: 1; } ft1000d_flags3_t; typedef union _ft1000d_flags1_u { ft1000d_flags1_t bits; unsigned char byte; } ft1000d_flags1_u; typedef union _ft1000d_flags2_u { ft1000d_flags2_t bits; unsigned char byte; } ft1000d_flags2_u; typedef union _ft1000d_flags3_u { ft1000d_flags3_t bits; unsigned char byte; } ft1000d_flags3_u; typedef struct _ft1000d_status_data_t { ft1000d_flags1_u flags1; ft1000d_flags2_u flags2; ft1000d_flags3_u flags3; unsigned char id1; unsigned char id2; } ft1000d_status_data_t; typedef struct _ft1000d_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft1000d_meter_data_t; typedef struct _ft1000d_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft1000d_op_data_t; // Update Data Structure typedef struct _ft1000d_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft1000d_op_data_t current_front; ft1000d_op_data_t current_rear; ft1000d_op_data_t vfoa; ft1000d_op_data_t vfob; ft1000d_op_data_t channel[90]; } ft1000d_update_data_t; // Command Structure typedef struct _ft1000d_command_t { unsigned char data[4]; unsigned char opcode; } ft1000d_command_t; #endif /* _FT1000D_H */ hamlib-4.6.5/rigs/yaesu/README.ft9200000664000175000017500000001362115056640443012274 Quirks, known bugs, and other notes. ==================================== In this document I'll try to describe the behavior of the Yaesu FT-920 transceiver with Hamlib. Some of these are limitations of the radio while others are programming trade-offs with Hamlib. This document is organized by Hamlib function calls and documents observed behavior with each call. rig_set_mode * No matter the status of the main display, MEM or VFO, display will be set to VFO mode if RIG_VFO_A or RIG_VFO_VFO is passed. * If radio is in MEM or MEM TUNE state, main display mode can be changed when RIG_VFO_MEM or RIG_VFO_MAIN is passed. * When RIG_VFO_CURR is passed, the display will be set per the VFO stored by the last rig_get_vfo call. * Modes DATA USB and DATA FM cannot be set at this time (Hamlib limitation). See below. * My FT-920 does not support USB/LSB narrow so attempting to set a narrow passband with these modes will return an Invalib Parameter error. rig_get_mode * Modes DATA USB and DATA FM cannot be returned as rig.h only has RIG_MODE_RTTY (Hamlib limitation). * DATA LSB is mapped to RIG_MODE_RTTY. * I would like to hear from anyone who gets a narrow passband value in USB/LSB mode returned. rig_set_freq * When passed RIG_VFO_A or RIG_VFO_VFO the main display is forced to VFO mode and then the frequency is set. * When passed RIG_VFO_B or RIG_VFO_SUB, the sub display frequency is set. * When passed RIG_VFO_MEM, or RIG_VFO_MAIN, the main display frequency is set regardless of whether the main display is in memory (thus activating MEM Tune) or VFO mode. * When RIG_VFO_CURR is passed, the display will be set per the VFO stored by the last rig_get_vfo call. * RIG_TARGETABLE_ALL is properly handled (I think). rig_get_freq * When passed RIG_VFO_A or RIG_VFO_VFO, the radio returns the frequency in the main VFO, even if the main display is in MEM or MEM Tune. * When passed RIG_VFO_B or RIG_VFO_SUB, the sub-display frequency is returned. * When passed RIG_VFO_MEM or RIG_VFO_MAIN, the current main display frequency is returned regardless of main display mode. * When passed RIG_VFO_CURR, the display will be read per the VFO stored by the last rig_get_vfo call. rig_set_vfo * When called with RIG_VFO_A or RIG_VFO_VFO, the radio appears to do nothing, however, rig_state->current_vfo will be updated. * When called with RIG_VFO_B, the radio will swap the main and sub displays, the same as if the front panel A<>B button is pressed. * No provision exists to make VFO-B (sub display) the active RX through CAT. rig_get_split * Both split capabilities are tested, i.e. RX A/TX B and RX B/TX A, but Hamlib only supports an indication that the radio is split. * The VFO value passed is not used by the ft920 backend lib. FIXME: Is this a problem? rig_set_split * When called with RIG_SPLIT_OFF the radio will make TX A active if TX B was active, otherwise no change. * When called with RIG_SPLIT_ON the radio will make TX B active if TX A was active, otherwise no change. * The FT-920 has no capability to change the active RX to RX B (sub display) through CAT. Thus if VFO-B is active RX/TX the setting RIG_SPLIT_ON will make no visible change on the radio. * The VFO value passed is not used by the ft920 backend lib. FIXME: Is this a problem? rig_set_split_freq * Backend simply wraps rig_set_freq--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_get_split_freq * Backend simply wraps rig_get_freq--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_set_split_mode * Backend simply wraps rig_set_mode--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_get_split_mode * Backend simply wraps rig_get_mode--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_set_rit * Hamlib specifies that passing 0 as the RIT frequency disables RIT. Thus there is no way to meet the spec and mimic the front panel RIT off function whilst keeping the RIT offset on the display. The Hamlib spec causes behavior analogous to shutting RIT off and then pressing the Clear button. * There is no direct way to set RIT offset of VFOB/SUB. However, rig_set_vfo can be used to swap VFO B and main, then set RIT, then call rig_set_vfo to swap VFO B and main. FIXME: Should backend do this automatically? rig_get_rit * Backend returns clarifier offset regardless of whether RIT is on. * vfo is honored and stored RIT is returned. rig_set_xit * Hamlib specifies that passing 0 as the XIT frequency disables XIT. Thus there is no way to meet the spec and mimic the front panel XIT off function whilst keeping the XIT offset on the display. The Hamlib spec causes behavior analogous to shutting XIT off and then pressing the Clear button. * There is no direct way to set XIT offset of VFOB/SUB. However, rig_set_vfo can be used to swap VFO B and main, then set XIT, then call rig_set_vfo to swap VFO B and main. FIXME: Should backend do this automatically? rig_get_xit * Backend returns clarifier offset regardless of whether XIT is on. * vfo is honored and stored XIT is returned. General notes. As with most all Yaesu radios the radio must be polled by the application for status updates, i.e. no transceive mode in CAT. hamlib-4.6.5/rigs/yaesu/ft840.c0000664000175000017500000014115015056640443011561 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft840.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2009 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-840 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft840.h" /* * Native FT840 functions. More to come :-) * */ enum ft840_native_cmd_e { FT840_NATIVE_SPLIT_OFF = 0, FT840_NATIVE_SPLIT_ON, FT840_NATIVE_RECALL_MEM, FT840_NATIVE_VFO_TO_MEM, FT840_NATIVE_VFO_A, FT840_NATIVE_VFO_B, FT840_NATIVE_MEM_TO_VFO, FT840_NATIVE_CLARIFIER_OPS, FT840_NATIVE_FREQ_SET, FT840_NATIVE_MODE_SET, FT840_NATIVE_PACING, FT840_NATIVE_PTT_OFF, FT840_NATIVE_PTT_ON, FT840_NATIVE_MEM_CHNL, FT840_NATIVE_OP_DATA, FT840_NATIVE_VFO_DATA, FT840_NATIVE_MEM_CHNL_DATA, FT840_NATIVE_TUNER_OFF, FT840_NATIVE_TUNER_ON, FT840_NATIVE_TUNER_START, FT840_NATIVE_READ_METER, FT840_NATIVE_READ_FLAGS, FT840_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * * The FT-840 backend is cloned after the FT-890 backend. * * The differences are (as reported by Thomas - DK6KD): * -the 840 has 100 Memory channel, the 890 has 20 * -the 840 has 5 flag bytes, like the 890 but the third isn't specified in * the manual (the 890 has the ptt_enabled bit there, which is used by the * FT-890's get_ptt function), i need to investigate if there is really no * information in the third byte from the 840. * -the 840 RIT offset can not be set by a CAT command. The command exists * but it can only enable/disable RIT, it seems that the following bytes * given to this command containing the offset are ignored. * -the display brightness of the 840 can not be set by CAT * (This is an important feature, isn't it? HI) */ /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* Enable these as needed: */ #undef USE_FT840_GET_PTT #undef USE_FT840_SET_RIT /* * API local implementation * */ static int ft840_init(RIG *rig); static int ft840_cleanup(RIG *rig); static int ft840_open(RIG *rig); static int ft840_close(RIG *rig); static int ft840_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft840_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft840_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft840_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft840_set_vfo(RIG *rig, vfo_t vfo); static int ft840_get_vfo(RIG *rig, vfo_t *vfo); static int ft840_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); #ifdef USE_FT840_GET_PTT static int ft840_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); #endif /* USE_FT840_GET_PTT */ static int ft840_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft840_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); #ifdef USE_FT840_SET_RIT static int ft840_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); #endif /* USE_FT840_SET_RIT */ static int ft840_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft840_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft840_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft840_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft840_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft840_send_static_cmd(RIG *rig, unsigned char ci); static int ft840_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft840_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); #ifdef USE_FT840_SET_RIT static int ft840_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); #endif /* USE_FT840_SET_RIT */ /* * Native ft840 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft840_caps.priv? -N0NB */ struct ft840_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT840_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ }; /* * ft840 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft840_caps = { RIG_MODEL(RIG_MODEL_FT840), .model_name = "FT-840", .mfg_name = "Yaesu", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT840_WRITE_DELAY, .post_write_delay = FT840_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 100 */ .rx_range_list1 = { {kHz(100), MHz(30), FT840_ALL_RX_MODES, -1, -1, FT840_VFO_ALL, FT840_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT840_OTHER_TX_MODES, W(5), W(100), FT840_VFO_ALL, FT840_ANTS), FRQ_RNG_HF(1, FT840_AM_TX_MODES, W(2), W(25), FT840_VFO_ALL, FT840_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT840_ALL_RX_MODES, -1, -1, FT840_VFO_ALL, FT840_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT840_OTHER_TX_MODES, W(5), W(100), FT840_VFO_ALL, FT840_ANTS), FRQ_RNG_HF(2, FT840_AM_TX_MODES, W(2), W(25), FT840_VFO_ALL, FT840_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT840_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT840_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT840_AM_RX_MODES, Hz(100)}, /* Normal */ {FT840_AM_RX_MODES, kHz(1)}, /* Fast */ {FT840_FM_RX_MODES, Hz(100)}, /* Normal */ {FT840_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .rig_init = ft840_init, .rig_cleanup = ft840_cleanup, .rig_open = ft840_open, /* port opened */ .rig_close = ft840_close, /* port closed */ .set_freq = ft840_set_freq, .get_freq = ft840_get_freq, .set_mode = ft840_set_mode, .get_mode = ft840_get_mode, .set_vfo = ft840_set_vfo, .get_vfo = ft840_get_vfo, .set_ptt = ft840_set_ptt, #ifdef USE_FT840_GET_PTT .get_ptt = ft840_get_ptt, #endif /* USE_FT840_GET_PTT */ .set_split_vfo = ft840_set_split_vfo, .get_split_vfo = ft840_get_split_vfo, #ifdef USE_FT840_SET_RIT .set_rit = ft840_set_rit, #endif /* USE_FT840_SET_RIT */ .get_rit = ft840_get_rit, .set_func = ft840_set_func, .get_level = ft840_get_level, .vfo_op = ft840_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft840_init(RIG *rig) { struct ft840_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft840_priv_data *) calloc(1, sizeof(struct ft840_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT840_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft840_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft840_open(RIG *rig) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft840_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft840_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft840_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft840_send_dial_freq(rig, FT840_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft840_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft840_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft840_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_A_FREQ; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_B_FREQ; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT840_NATIVE_OP_DATA; offset = FT840_SUMO_DISPLAYED_FREQ; count = FT840_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft840_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft840_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft840_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft840 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft840_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft840_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-840 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft840_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft840_priv_data *priv; unsigned char my_mode, m_offset; /* ft840 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; m_offset = FT840_SUMO_VFO_A_MODE; f_offset = FT840_SUMO_VFO_A_FLAG; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; m_offset = FT840_SUMO_VFO_B_MODE; f_offset = FT840_SUMO_VFO_B_FLAG; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT840_NATIVE_OP_DATA; m_offset = FT840_SUMO_DISPLAYED_MODE; f_offset = FT840_SUMO_DISPLAYED_FLAG; count = FT840_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft840_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft840 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft840_set_vfo(RIG *rig, vfo_t vfo) { struct ft840_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT840_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft840_get_vfo(RIG *rig, vfo_t *vfo) { struct ft840_priv_data *priv; unsigned char status_0; /* ft840 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT840_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft840 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-840 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft840_get_update_data(rig, FT840_NATIVE_MEM_CHNL, FT840_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT840_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '840 into TX mode * * vfo is respected by calling ft840_set_vfo if * passed vfo != priv->current_vfo * */ static int ft840_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft840_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft840_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT840_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT840_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ #ifdef USE_FT840_GET_PTT static int ft840_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft840_priv_data *priv; unsigned char status_2; /* ft840 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT840_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } #endif /* USE_FT840_GET_PTT */ /* * rig_set_split_vfo * * set the '840 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft840_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT840_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT840_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '840 is in split mode * * vfo value is not used * */ static int ft840_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft840_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT840_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ #ifdef USE_FT840_SET_RIT static int ft840_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft840_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft840_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft840_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); return RIG_OK; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft840_send_rit_freq(rig, FT840_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* USE_FT840_SET_RIT */ /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft840_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft840_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT840_NATIVE_OP_DATA; offset = FT840_SUMO_DISPLAYED_CLAR; length = FT840_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_A_CLAR; length = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_B_CLAR; length = FT840_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft840_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '840 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft840_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT840_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT840_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '840 meter level * * vfo is ignored for now * * Meter level returned from FT-840 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft840_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft840_priv_data *priv; unsigned char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft840_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft840_get_update_data(rig, FT840_NATIVE_READ_METER, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT840_SUMO_METER]; /* * My FT-840 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (*p > 160) { val->i = 60; } else if (*p <= 72) { val->i = ((72 - *p) / 1.3333) * -1; } else { val->i = ((*p - 72) / 1.4667); } rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft840_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT840_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft840 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 840 has several ways to * get data and several ways to return it. * * Need to use this when doing ft840_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft840_priv_data *priv; int n, err; /* for read_ */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; err = ft840_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft840_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT840_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT840_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ #ifdef USE_FT840_SET_RIT static int ft840_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft840_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT840_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %li Hz\n", __func__, from_bcd(priv->p_cmd, FT840_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* USE_FT840_SET_RIT */ hamlib-4.6.5/rigs/yaesu/ftdx10.h0000664000175000017500000001155315056640443012032 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx10.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Mikael Nousiainen 2020 * (C) Michael Black W9MDB 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX10(D/MP) using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX10_H #define _FTDX10_H 1 #define FTDX10_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FTDX10_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX10_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX10_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX10_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX10_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX10_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FTDX10_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FTDX10_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FTDX10_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FTDX10_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FTDX10_RFPOWER_METER_CAL \ { \ 5, \ { \ {27, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner for the FTDX101D #define FTDX10_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } /* * Other features (used by rig_caps) */ #define FTDX10_TX_ANTS RIG_ANT_CURR #define FTDX10_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX10_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX10_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX10_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX10_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX10_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX10_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX10_POST_WRITE_DELAY 5 #endif /* _FTDX10_H */ hamlib-4.6.5/rigs/yaesu/frg9600.c0000664000175000017500000001267715056640443012024 /* * frg9600.c - (C) Stephane Fillod 2002-2004 * * This shared library provides an API for communicating * via serial interface to an FRG-9600 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" /* Private helper function prototypes */ #define FRG9600_MODES (RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define FRG9600_VFOS (RIG_VFO_A) static int frg9600_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg9600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* * frg9600 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps frg9600_caps = { RIG_MODEL(RIG_MODEL_FRG9600), .model_name = "FRG-9600", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(60), MHz(905), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, FRG9600_VFOS }, {MHz(60), MHz(460), RIG_MODE_SSB, -1, -1, FRG9600_VFOS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {MHz(60), MHz(905), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, FRG9600_VFOS }, {MHz(60), MHz(460), RIG_MODE_SSB, -1, -1, FRG9600_VFOS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_AM, Hz(100)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_WFM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, at -3dB ! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(180)}, RIG_FLT_END, }, .set_freq = frg9600_set_freq, .set_mode = frg9600_set_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #define MODE_SET_LSB 0x10 #define MODE_SET_USB 0x11 #define MODE_SET_AMN 0x14 #define MODE_SET_AMW 0x15 #define MODE_SET_FMN 0x16 #define MODE_SET_WFM 0x17 int frg9600_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x0a, 0x00, 0x00, 0x00, 0x00}; /* store bcd format in cmd (MSB) */ to_bcd_be(cmd + 1, freq / 10, 8); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg9600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char md; /* * translate mode from generic to frg9600 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_SET_USB; break; case RIG_MODE_LSB: md = MODE_SET_LSB; break; case RIG_MODE_FM: md = MODE_SET_FMN; break; case RIG_MODE_WFM: md = MODE_SET_WFM; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md = MODE_SET_AMN; } else { md = MODE_SET_AMW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } hamlib-4.6.5/rigs/yaesu/ft817.h0000664000175000017500000000520415056640443011571 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT817_H #define _FT817_H 1 /* * No need to wait between written characters. */ #define FT817_WRITE_DELAY 1 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT817_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT817_TIMEOUT 3000 /* * Return from TX to RX may have a delay. If status is not changed * on the first attempt, wait this amount of milliseconds before * each next next attempts. */ #define FT817_RETRY_DELAY 100 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT817_CACHE_TIMEOUT 50 int ft817_set_powerstat(RIG *rig, powerstat_t status); int ft817_read_ack(RIG *rig); #endif /* _FT817_H */ hamlib-4.6.5/rigs/yaesu/ft920.h0000664000175000017500000000666515056640443011600 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft920.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003, 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2002 (fillods at users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-920 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT920_H #define _FT920_H 1 #define TRUE 1 #define FALSE 0 #define FT920_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT920_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_WFM) #define FT920_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT920_AM_RX_MODES (RIG_MODE_AM) #define FT920_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_WFM) /* TX caps */ #define FT920_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM ) /* 100 W class */ #define FT920_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ /* Other features */ #define FT920_ANTS 0 /* FIXME: declare Ant A & B and RX input */ #define FT920_FUNC_ALL (RIG_FUNC_TUNER | RIG_FUNC_LOCK) /* fix */ /* Returned data length in bytes */ #define FT920_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT920_STATUS_FLAGS_LENGTH 8 /* 0xfa return size */ #define FT920_VFO_DATA_LENGTH 28 /* 0x10 P1 = 02, 03 return size */ #define FT920_MEM_CHNL_DATA_LENGTH 14 /* 0x10 P1 = 04, P4 = 0x00-0x89 return size */ /* Delay sequential fast writes * * It is thought that it takes the rig about 60 mS to process a command * so a default of 80 mS should be long enough to prevent commands from * stacking up. */ #define FT920_POST_WRITE_DELAY 80 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte * in 2.2917 msec => 28 bytes in 64 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------- --------------------- * * 0 64 msec * 1 92 msec * 2 120 msec * 5 204 msec * 255 7.2 sec * */ /* Timing values in mS */ #define FT920_PACING_DEFAULT_VALUE 0 /* time between characters from 920 */ #define FT920_WRITE_DELAY 0 /* time between characters to 920 */ /* Rough safe value for default timeout */ #define FT920_DEFAULT_READ_TIMEOUT 28 * ( 5 + FT920_PACING_DEFAULT_VALUE) /* BCD coded frequency length */ #define FT920_BCD_DIAL 8 #define FT920_BCD_RIT 3 #endif /* _FT920_H */ hamlib-4.6.5/rigs/yaesu/ft100.c0000664000175000017500000010365015056640443011551 /* * hamlib - (C) Frank Singleton 2000-2003 * (C) Stephane Fillod 2000-2010 * * ft100.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-100 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft100.h" #include "misc.h" #include "bandplan.h" enum ft100_native_cmd_e { FT100_NATIVE_CAT_LOCK_ON = 0, FT100_NATIVE_CAT_LOCK_OFF, FT100_NATIVE_CAT_PTT_ON, FT100_NATIVE_CAT_PTT_OFF, FT100_NATIVE_CAT_SET_FREQ, FT100_NATIVE_CAT_SET_MODE_LSB, FT100_NATIVE_CAT_SET_MODE_USB, FT100_NATIVE_CAT_SET_MODE_CW, FT100_NATIVE_CAT_SET_MODE_CWR, FT100_NATIVE_CAT_SET_MODE_AM, FT100_NATIVE_CAT_SET_MODE_FM, FT100_NATIVE_CAT_SET_MODE_DIG, FT100_NATIVE_CAT_SET_MODE_WFM, FT100_NATIVE_CAT_CLAR_ON, FT100_NATIVE_CAT_CLAR_OFF, FT100_NATIVE_CAT_SET_CLAR_FREQ, FT100_NATIVE_CAT_SET_VFOAB, FT100_NATIVE_CAT_SET_VFOA, FT100_NATIVE_CAT_SET_VFOB, FT100_NATIVE_CAT_SPLIT_ON, FT100_NATIVE_CAT_SPLIT_OFF, FT100_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT100_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT100_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT100_NATIVE_CAT_SET_RPT_OFFSET, /* fix me */ FT100_NATIVE_CAT_SET_DCS_ON, FT100_NATIVE_CAT_SET_CTCSS_ENC_ON, FT100_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON, FT100_NATIVE_CAT_SET_CTCSS_DCS_OFF, /* em xif */ FT100_NATIVE_CAT_SET_CTCSS_FREQ, FT100_NATIVE_CAT_SET_DCS_CODE, FT100_NATIVE_CAT_GET_RX_STATUS, FT100_NATIVE_CAT_GET_TX_STATUS, FT100_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT100_NATIVE_CAT_PWR_WAKE, FT100_NATIVE_CAT_PWR_ON, FT100_NATIVE_CAT_PWR_OFF, FT100_NATIVE_CAT_READ_STATUS, FT100_NATIVE_CAT_READ_METERS, FT100_NATIVE_CAT_READ_FLAGS, FT100_NATIVE_SIZE /* end marker */ }; /* * we are able to get way more info * than we can set * */ typedef struct { unsigned char band_no; unsigned char freq[4]; unsigned char mode; unsigned char ctcss; unsigned char dcs; unsigned char flag1; unsigned char flag2; unsigned char clarifier[2]; unsigned char not_used; unsigned char step1; unsigned char step2; unsigned char filter; unsigned char stuffing[16]; } FT100_STATUS_INFO; typedef struct { unsigned char mic_switch_1; unsigned char tx_fwd_power; unsigned char tx_rev_power; unsigned char s_meter; unsigned char mic_level; unsigned char squelch_level; unsigned char mic_switch_2; unsigned char final_temp; unsigned char alc_level; } FT100_METER_INFO; typedef struct { unsigned char byte[8]; } FT100_FLAG_INFO; static int ft100_init(RIG *rig); static int ft100_open(RIG *rig); static int ft100_cleanup(RIG *rig); static int ft100_close(RIG *rig); static int ft100_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft100_set_vfo(RIG *rig, vfo_t vfo); static int ft100_get_vfo(RIG *rig, vfo_t *vfo); static int ft100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #if 0 static int ft100_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft100_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft100_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft100_set_parm(RIG *rig, setting_t parm, value_t val); static int ft100_get_parm(RIG *rig, setting_t parm, value_t *val); #endif static int ft100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft100_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft100_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft100_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift); static int ft100_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft100_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); static int ft100_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft100_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); //static int ft100_get_info(RIG *rig, FT100_STATUS_INFO *ft100_status, FT100_METER_INFO *ft100_meter, FT100_FLAG_INFO *ft100_flags); struct ft100_priv_data { /* TODO: make use of cached data */ FT100_STATUS_INFO status; FT100_FLAG_INFO flags; }; /* prototypes */ static int ft100_send_priv_cmd(RIG *rig, unsigned char cmd_index); /* Native ft100 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ /* kc2ivl - what works on a ft100 as of 02/27/2002 */ /* ptt on/off */ /* set mode AM,CW,USB,LSB,FM use PKTUSB for DIG mode*/ /* set split on/off */ /* set repeater +, - splx */ /* set frequency of current vfo */ static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set main LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set main USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* mode set main CW */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set main CWR */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set main AM */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* mode set main FM */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* mode set main DIG */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* mode set main WFM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set clar freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo a */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo b */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* set RPT shift MINUS */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* set RPT shift PLUS */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set RPT offset freq */ /* fix me */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x92 } }, /* set DCS on */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x92 } }, /* set CTCSS/DCS enc/dec on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x92 } }, /* set CTCSS/DCS enc on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x92 } }, /* set CTCSS/DCS off */ /* em xif */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x90 } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x91 } }, /* set DCS code */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get RX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get TX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* get FREQ and MODE status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr wakeup sequence */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* read status block */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* read meter block */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xfa } } /* read flags block */ }; static tone_t ft100_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, \ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, \ 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, \ 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, \ 2503, 0 }; static tone_t ft100_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, \ 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, \ 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, \ 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, \ 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, \ 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, \ 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, \ 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, \ 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, \ 0, }; #define FT100_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_FM) #define FT100_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT100_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT100_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_FM) #define FT100_AM_TX_MODES (RIG_MODE_AM) #define FT100_GET_RIG_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|\ RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_MICGAIN|RIG_LEVEL_SQL) #define FT100_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL) #define FT100_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* S-meter calibration, ascending order of RAW values */ #define FT100_STR_CAL { 9, \ { \ { 90, 60 }, /* +60 */ \ { 105, 40 }, /* +40 */ \ { 115, 20 }, /* +20 */ \ { 120, 0 }, /* S9 */ \ { 130, -6 }, /* S8 */ \ { 140, -12 }, /* S7 */ \ { 160, -18 }, /* S6 */ \ { 180, -24 }, /* S5 */ \ { 200, -54 } /* S0 */ \ } } struct rig_caps ft100_caps = { RIG_MODEL(RIG_MODEL_FT100), .model_name = "FT-100", .mfg_name = "Yaesu", .version = "20240910.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* ft100/d 4800 only */ .serial_rate_max = 4800, /* no others allowed */ .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT100_WRITE_DELAY, .post_write_delay = FT100_POST_WRITE_DELAY, .timeout = 100, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT100_FUNC_ALL, .has_get_level = FT100_GET_RIG_LEVELS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft100_ctcss_list, .dcs_list = ft100_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan .list = 78 */ .rx_range_list1 = { {kHz(100), MHz(56), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(108), MHz(154), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(420), MHz(470), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_HF(1, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(1, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(1, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(1, FT100_OTHER_TX_MODES, W(0.5), W(50), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(1, FT100_AM_TX_MODES, W(0.5), W(12.5), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(1, FT100_OTHER_TX_MODES, W(0.5), W(20), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(1, FT100_AM_TX_MODES, W(0.5), W(5), FT100_VFO_ALL, RIG_ANT_CURR), }, .rx_range_list2 = { {kHz(100), MHz(56), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(108), MHz(154), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(420), MHz(470), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_HF(2, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(2, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(2, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(2, FT100_OTHER_TX_MODES, W(0.5), W(50), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(2, FT100_AM_TX_MODES, W(0.5), W(12.5), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(2, FT100_OTHER_TX_MODES, W(0.5), W(20), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(2, FT100_AM_TX_MODES, W(0.5), W(5), FT100_VFO_ALL, RIG_ANT_CURR), RIG_FRNG_END, }, .tuning_steps = { /* FIXME */ {FT100_SSB_CW_RX_MODES, 10}, {FT100_SSB_CW_RX_MODES, 100}, {FT100_AM_FM_RX_MODES, 10}, {FT100_AM_FM_RX_MODES, 100}, {RIG_MODE_WFM, kHz(5)}, {RIG_MODE_WFM, kHz(50)}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, Hz(300)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, Hz(500)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = FT100_STR_CAL, .priv = NULL, .rig_init = ft100_init, .rig_cleanup = ft100_cleanup, .rig_open = ft100_open, .rig_close = ft100_close, .set_freq = ft100_set_freq, .get_freq = ft100_get_freq, .set_mode = ft100_set_mode, .get_mode = ft100_get_mode, .set_vfo = ft100_set_vfo, .get_vfo = ft100_get_vfo, .set_ptt = ft100_set_ptt, .get_ptt = ft100_get_ptt, .get_dcd = NULL, .set_rptr_shift = ft100_set_rptr_shift, .get_rptr_shift = ft100_get_rptr_shift, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = ft100_set_split_vfo, .get_split_vfo = ft100_get_split_vfo, .set_rit = NULL, .get_rit = NULL, .set_xit = NULL, .get_xit = NULL, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = ft100_set_dcs_code, .get_dcs_code = ft100_get_dcs_code, .set_ctcss_tone = ft100_set_ctcss_tone, .get_ctcss_tone = ft100_get_ctcss_tone, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_level = NULL, .get_level = ft100_get_level, .set_func = NULL, .get_func = NULL, .set_parm = NULL, .get_parm = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ft100_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct ft100_priv_data *) calloc(1, sizeof(struct ft100_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } int ft100_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft100_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft100_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. * */ static int ft100_send_priv_cmd(RIG *rig, unsigned char cmd_index) { rig_debug(RIG_DEBUG_VERBOSE, "%s called (%d)\n", __func__, cmd_index); if (!rig) { return -RIG_EINVAL; } return write_block(RIGPORT(rig), (unsigned char *) &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } static int ft100_read_status(RIG *rig) { struct ft100_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft100_priv_data *)STATE(rig)->priv; rig_flush(rp); ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_STATUS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->status, sizeof(FT100_STATUS_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read status=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } static int ft100_read_flags(RIG *rig) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rp); ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_FLAGS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->flags, sizeof(FT100_FLAG_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read flags=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } int ft100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft100: requested freq = %"PRIfreq" Hz \n", freq); cmd_index = FT100_NATIVE_CAT_SET_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* fixed 10Hz bug by OH2MMY */ freq = (int) freq / 10; to_bcd(p_cmd, freq, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; freq_t d1, d2; char freq_str[10]; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s:\n", __func__); if (!freq) { return -RIG_EINVAL; } ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq= %3i %3i %3i %3i \n", __func__, (int)priv->status.freq[0], (int)priv->status.freq[1], (int)priv->status.freq[2], (int)priv->status.freq[3]); /* now convert it .... */ SNPRINTF(freq_str, sizeof(freq_str), "%02X%02X%02X%02X", priv->status.freq[0], priv->status.freq[1], priv->status.freq[2], priv->status.freq[3]); d1 = strtol(freq_str, NULL, 16); d2 = (d1 * 1.25); /* fixed 10Hz bug by OH2MMY */ rig_debug(RIG_DEBUG_VERBOSE, "ft100: d1=%"PRIfreq" d2=%"PRIfreq"\n", d1, d2); // cppcheck-suppress * rig_debug(RIG_DEBUG_VERBOSE, "ft100: get_freq= %8"PRIll" \n", (int64_t)d2); *freq = d2; return RIG_OK; } int ft100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s, width %d\n", __func__, rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_AM: cmd_index = FT100_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: cmd_index = FT100_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_CWR: cmd_index = FT100_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_USB: cmd_index = FT100_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: cmd_index = FT100_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_FM: cmd_index = FT100_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_PKTUSB: cmd_index = FT100_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_WFM: cmd_index = FT100_NATIVE_CAT_SET_MODE_WFM; break; default: return -RIG_EINVAL; } ret = ft100_send_priv_cmd(rig, cmd_index); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } #if 1 if (mode != RIG_MODE_FM && mode != RIG_MODE_WFM && width <= kHz(6)) { unsigned char p_cmd[YAESU_CMD_LENGTH]; p_cmd[0] = 0x00; p_cmd[1] = 0x00; p_cmd[2] = 0x00; p_cmd[3] = 0x00; /* to be filled in */ p_cmd[4] = 0x8C; /* Op: filter selection */ if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= 300) { p_cmd[3] = 0x03; } else if (width <= 500) { p_cmd[3] = 0x02; } else if (width <= 2400) { p_cmd[3] = 0x00; } else { p_cmd[3] = 0x01; } ret = write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { return ret; } } #endif return RIG_OK; } /* ft100_get_mode fixed by OH2MMY * Still answers wrong if on AM. Bug in rig's firmware? * The rig answers something weird then, not what the manual says * and the answer is different every time. Other modes do work. */ int ft100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; if (!mode || !width) { return -RIG_EINVAL; } ret = ft100_read_status(rig); if (ret < 0) { return ret; } switch (priv->status.mode & 0x0f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x05: *mode = RIG_MODE_PKTUSB; break; case 0x06: *mode = RIG_MODE_FM; break; case 0x07: *mode = RIG_MODE_WFM; break; default: *mode = RIG_MODE_NONE; }; switch (priv->status.mode >> 4) { case 0x00: *width = Hz(6000); break; case 0x01: *width = Hz(2400); break; case 0x02: *width = Hz(500); break; case 0x03: *width = Hz(300); break; default: *width = RIG_PASSBAND_NORMAL; }; return RIG_OK; } /* Function ft100_set_vfo fixed by OH2MMY */ int ft100_set_vfo(RIG *rig, vfo_t vfo) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_SET_VFOA); if (ret != RIG_OK) { return ret; } break; case RIG_VFO_B: ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_SET_VFOB); if (ret != RIG_OK) { return ret; } break; default: return -RIG_EINVAL; } return RIG_OK; } /* Function ft100_get_vfo written again by OH2MMY * Tells the right answer if in VFO mode. * TODO: handle memory modes. */ int ft100_get_vfo(RIG *rig, vfo_t *vfo) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } if ((priv->flags.byte[1] & 0x04) == 0x04) { *vfo = RIG_VFO_B; } else { *vfo = RIG_VFO_A; } return RIG_OK; } int ft100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; int split = CACHE(rig)->split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: cmd_index = FT100_NATIVE_CAT_PTT_ON; // This was causing WSJT-X to assume reverse split //if (split) { rig_set_vfo(rig, RIG_VFO_B); } break; case RIG_PTT_OFF: cmd_index = FT100_NATIVE_CAT_PTT_OFF; if (split) { rig_set_vfo(rig, RIG_VFO_A); } hl_usleep(100 * 1000); // give ptt some time to do its thing -- fake it was not resetting freq after tx break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; if (!ptt) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } *ptt = (priv->flags.byte[0] & 0x80) == 0x80 ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * Rem: The FT-100(D) has no set_level ability */ int ft100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; int split = CACHE(rig)->split; int ptt = CACHE(rig)->ptt; FT100_METER_INFO ft100_meter; if (!rig) { return -RIG_EINVAL; } if (!val) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rig_strlevel(level)); // if in split have to switch to VFOB to read power and back to VFOA if (split && ptt) { rig_set_vfo(rig, RIG_VFO_B); } ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_METERS); if (split && ptt) { rig_set_vfo(rig, RIG_VFO_A); } if (ret != RIG_OK) { return ret; } ret = read_block(RIGPORT(rig), (unsigned char *) &ft100_meter, sizeof(FT100_METER_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read meters=%d\n", __func__, ret); if (ret < 0) { return ret; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = ft100_meter.s_meter; break; case RIG_LEVEL_RFPOWER: val->f = (float)ft100_meter.tx_fwd_power / 0xff; break; case RIG_LEVEL_SWR: if (ft100_meter.tx_fwd_power == 0) { val->f = 0; } else { float f; f = sqrt((float)ft100_meter.tx_rev_power / (float)ft100_meter.tx_fwd_power); val->f = (1 + f) / (1 - f); } break; case RIG_LEVEL_ALC: /* need conversion ? */ val->f = (float)ft100_meter.alc_level / 0xff; break; case RIG_LEVEL_MICGAIN: val->f = (float)ft100_meter.mic_level / 0xff; break; case RIG_LEVEL_SQL: val->f = (float)ft100_meter.squelch_level / 0xff; break; default: return -RIG_EINVAL; } return RIG_OK; } #if 0 /* TODO: all of this */ int ft100_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } int ft100_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { return -RIG_ENIMPL; } int ft100_set_parm(RIG *rig, setting_t parm, value_t val) { return -RIG_ENIMPL; } int ft100_get_parm(RIG *rig, setting_t parm, value_t *val) { return -RIG_ENIMPL; } #endif /* kc2ivl */ int ft100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_ON: cmd_index = FT100_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: cmd_index = FT100_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!split) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } *split = (priv->flags.byte[0] & 0x01) == 0x01 ? RIG_SPLIT_ON : RIG_SPLIT_OFF; return RIG_OK; } int ft100_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s:ft100_set_rptr_shift called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: + - 0 %3i %3i %3i %3i %c\n", __func__, RIG_RPT_SHIFT_PLUS, RIG_RPT_SHIFT_MINUS, RIG_RPT_SHIFT_NONE, shift, (char)shift); switch (shift) { case RIG_RPT_SHIFT_PLUS: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_PLUS; break; case RIG_RPT_SHIFT_MINUS: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_MINUS; break; case RIG_RPT_SHIFT_NONE: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX; break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *shift = RIG_RPT_SHIFT_NONE; if (priv->status.flag1 & (1 << 2)) { *shift = RIG_RPT_SHIFT_MINUS; } else if (priv->status.flag1 & (1 << 3)) { *shift = RIG_RPT_SHIFT_PLUS; } rig_debug(RIG_DEBUG_VERBOSE, "%s: flag1=0x%02x\n", __func__, priv->status.flag1); return RIG_OK; } /* * TODO: enable/disable encoding/decoding */ int ft100_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ int pcode; for (pcode = 0; pcode < 104 && ft100_dcs_list[pcode] != 0; pcode++) { if (ft100_dcs_list[pcode] == code) { break; } } /* there are 104 dcs codes available */ if (pcode >= 104 || ft100_dcs_list[pcode] == 0) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s = %03i, n=%d\n", __func__, code, pcode); cmd_index = FT100_NATIVE_CAT_SET_DCS_CODE; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); p_cmd[3] = (char)pcode; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *code = ft100_dcs_list[priv->status.dcs]; rig_debug(RIG_DEBUG_VERBOSE, "%s: P1=0x%02x, code=%d\n", __func__, priv->status.dcs, *code); return RIG_OK; } /* * TODO: enable/disable encoding/decoding */ int ft100_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ int ptone; for (ptone = 0; ptone < 39 && ft100_ctcss_list[ptone] != 0; ptone++) { if (ft100_ctcss_list[ptone] == tone) { break; } } /* there are 39 ctcss tones available */ if (ptone >= 39 || ft100_ctcss_list[ptone] == 0) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s = %.1f Hz, n=%d\n", __func__, (float)tone / 10, ptone); cmd_index = FT100_NATIVE_CAT_SET_CTCSS_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); p_cmd[3] = (char)ptone; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *tone = ft100_ctcss_list[priv->status.ctcss]; rig_debug(RIG_DEBUG_VERBOSE, "%s: P1=0x%02x, tone=%.1f\n", __func__, priv->status.ctcss, *tone / 10.0); return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft950.c0000664000175000017500000003113715056640443011566 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft950.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "yaesu.h" #include "newcat.h" #include "ft950.h" const struct newcat_priv_caps ft950_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ft950_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { RIG_CONF_END, NULL, } }; int ft950_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_BACKEND_NONE }; /* * FT-950 rig capabilities */ struct rig_caps ft950_caps = { RIG_MODEL(RIG_MODEL_FT950), .model_name = "FT-950", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT950_WRITE_DELAY, .post_write_delay = FT950_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT950_FUNCS, .has_set_func = FT950_FUNCS, .has_get_level = FT950_LEVELS, .has_set_level = RIG_LEVEL_SET(FT950_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_KEYSPD #define NO_LVL_NOTCHF #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_KEYSPD #undef NO_LVL_NOTCHF #undef NO_LVL_RFPOWER [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT950_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT950_RFPOWER_METER_CAL, .str_cal = FT950_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 125, 128, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channels U51-U54 or US1-US4, if available */ { 130, 130, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channel U55 or US5, if available */ { 131, 131, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* EU5, 5167.5 KHz Alaska Emergency Freq, if available */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(56), FT950_ALL_RX_MODES, -1, -1, FT950_VFO_ALL, FT950_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_HF(1, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ FRQ_RNG_6m(1, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_6m(1, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT950_ALL_RX_MODES, -1, -1, FT950_VFO_ALL, FT950_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_HF(2, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ FRQ_RNG_6m(2, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_6m(2, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT950_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT950_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT950_AM_RX_MODES, Hz(100)}, /* Normal */ {FT950_AM_RX_MODES, kHz(1)}, /* Fast */ {FT950_FM_RX_MODES, Hz(100)}, /* Normal */ {FT950_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT950_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(2000)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(1400)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(800)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(400)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(200)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(100)}, /* CW, RTTY, PKT */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2250)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1500)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FT950_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ {FT950_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ {FT950_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ft950_ext_tokens, .extlevels = ft950_ext_levels, .priv = &ft950_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ftdx101.h0000664000175000017500000001520415056640443012110 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D/MP) using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX101_H #define _FTDX101_H 1 #define FTDX101_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* Receiver caps */ #define FTDX101_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX101_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX101_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX101_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX101_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX101_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FTDX101_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FTDX101_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_TEMP_METER|\ RIG_LEVEL_BAND_SELECT|RIG_LEVEL_USB_AF) #define FTDX101_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|\ RIG_FUNC_SYNC) /* TBC */ #define FTDX101_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) #define FTDX101D_ALC_METER_CAL \ { \ 2, \ { \ {0, 0.0f}, \ {121, 1.0f} \ } \ } #define FTDX101D_RFPOWER_METER_CAL \ { \ 6, \ { \ {0, 0.0f}, \ {38, 0.5f}, \ {94, 0.25f}, \ {147, 0.50f}, \ {176, 0.75f}, \ {205, 1.0f}, \ } \ } #define FTDX101D_RFPOWER_METER_WATTS_CAL \ { \ 6, \ { \ {0, 0.0f}, \ {38, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } #define FTDX101MP_RFPOWER_METER_CAL \ { \ 11, \ { \ {0, 0.00f}, \ {69, 0.05f}, \ {111, 0.10f}, \ {129, 0.15f}, \ {143, 0.20f}, \ {158, 0.25f}, \ {184, 0.35f}, \ {200, 0.40f}, \ {211, 0.45f}, \ {222, 0.50f}, \ {255, 1.0f}, \ } \ } #define FTDX101MP_RFPOWER_METER_WATTS_CAL \ { \ 13, \ { \ {0, 0.0f}, \ {30, 5.0f}, \ {69, 20.0f}, \ {98, 40.0f}, \ {119, 60.0f}, \ {139, 80.0f}, \ {160, 100.0f}, \ {173, 120.0f}, \ {185, 140.0f}, \ {198, 160.0f}, \ {210, 180.0f}, \ {225, 200.0f}, \ {255, 210.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner #define FTDX101D_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } #define FTDX101D_STR_CAL { 12, \ { \ { 0, -60 }, /* S0 */ \ { 17, -54 }, /* S0 */ \ { 25, -48 }, \ { 34, -42 }, \ { 51, -36 }, \ { 68, -30 }, \ { 85, -24 }, \ { 102, -18 }, \ { 119, -12 }, \ { 136, -6 }, \ { 160, 0 }, /* S9 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) */ #define FTDX101_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define FTDX101_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX101_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX101_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX101_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX101_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX101_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX101_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX101_POST_WRITE_DELAY 5 #endif /* _FTDX101_H */ hamlib-4.6.5/rigs/yaesu/ft857.h0000664000175000017500000000452115056640443011576 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft857.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT857_H #define _FT857_H 1 /* * No need to wait between written characters. */ #define FT857_WRITE_DELAY 0 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT857_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT857_TIMEOUT 200 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT857_CACHE_TIMEOUT 50 int ft857_set_vfo(RIG *rig, vfo_t vfo); int ft857_get_vfo(RIG *rig, vfo_t *vfo); #endif /* _FT857_H */ hamlib-4.6.5/rigs/yaesu/ft1200.c0000664000175000017500000003065515056640443011637 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft1200.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * ft1200.c - (C) David Fannin 2015 (kk6df at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-1200 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft1200.h" #include "tones.h" const struct newcat_priv_caps ftdx1200_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ftdx1200_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx1200_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FTDX 1200 rig capabilities */ struct rig_caps ftdx1200_caps = { RIG_MODEL(RIG_MODEL_FTDX1200), .model_name = "FTDX-1200", .mfg_name = "Yaesu", .version = NEWCAT_VER ".7", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* found by testing with remote serial port */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX1200_WRITE_DELAY, .post_write_delay = FTDX1200_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX1200_FUNCS, .has_set_func = FTDX1200_FUNCS, .has_get_level = FTDX1200_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX1200_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_MICGAIN #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_MICGAIN #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX1200_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 1200 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX1200_RFPOWER_METER_CAL, .str_cal = FTDX1200_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_HF(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_6m(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_HF(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_6m(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX1200_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX1200_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX1200_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX1200_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX1200_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX1200_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FTDX1200_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX1200_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ {FTDX1200_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx1200_ext_tokens, .extlevels = ftdx1200_ext_levels, .priv = &ftdx1200_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft600.h0000664000175000017500000000263415056640443011563 /* * hamlib - (C) Frank Singleton 2000-2003 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft600.h -(C) Kārlis Millers YL3ALK 2019 * * This shared library provides an API for communicating * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT600_H #define _FT600_H 1 #define FT600_STATUS_UPDATE_DATA_LENGTH 19 #define FT600_METER_INFO_LENGTH 5 #define FT600_WRITE_DELAY 5 #define FT600_POST_WRITE_DELAY 200 #define FT600_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT600_H */ hamlib-4.6.5/rigs/yaesu/ft857.c0000664000175000017500000011627215056640443011600 /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- * * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft857.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-857 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-857: * * - DCS encoder/squelch ON/OFF, similar to RIG_FUNC_TONE/TSQL. * Needs frontend support. * * - RX status command returns info that is not used: * * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) * * - TX status command returns info that is not used: * * - high swr flag * * The manual also indicates that CTCSS and DCS codes can be set * separately for tx and rx, but this doesn't seem to work. It * doesn't work from front panel either. */ #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft857.h" #include "ft817.h" /* We use functions from the 817 code */ #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" enum ft857_native_cmd_e { FT857_NATIVE_CAT_LOCK_ON = 0, FT857_NATIVE_CAT_LOCK_OFF, FT857_NATIVE_CAT_PTT_ON, FT857_NATIVE_CAT_PTT_OFF, FT857_NATIVE_CAT_SET_FREQ, FT857_NATIVE_CAT_SET_MODE_LSB, FT857_NATIVE_CAT_SET_MODE_USB, FT857_NATIVE_CAT_SET_MODE_CW, FT857_NATIVE_CAT_SET_MODE_CWR, FT857_NATIVE_CAT_SET_MODE_AM, FT857_NATIVE_CAT_SET_MODE_FM, FT857_NATIVE_CAT_SET_MODE_FM_N, FT857_NATIVE_CAT_SET_MODE_DIG, FT857_NATIVE_CAT_SET_MODE_PKT, FT857_NATIVE_CAT_CLAR_ON, FT857_NATIVE_CAT_CLAR_OFF, FT857_NATIVE_CAT_SET_CLAR_FREQ, FT857_NATIVE_CAT_SET_VFOAB, FT857_NATIVE_CAT_SPLIT_ON, FT857_NATIVE_CAT_SPLIT_OFF, FT857_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT857_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT857_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT857_NATIVE_CAT_SET_RPT_OFFSET, FT857_NATIVE_CAT_SET_DCS_ON, FT857_NATIVE_CAT_SET_DCS_DEC_ON, FT857_NATIVE_CAT_SET_DCS_ENC_ON, FT857_NATIVE_CAT_SET_CTCSS_ON, FT857_NATIVE_CAT_SET_CTCSS_DEC_ON, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT857_NATIVE_CAT_SET_CTCSS_FREQ, FT857_NATIVE_CAT_SET_DCS_CODE, FT857_NATIVE_CAT_GET_RX_STATUS, FT857_NATIVE_CAT_GET_TX_STATUS, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT857_NATIVE_CAT_PWR_WAKE, FT857_NATIVE_CAT_PWR_ON, FT857_NATIVE_CAT_PWR_OFF, FT857_NATIVE_CAT_EEPROM_READ, FT857_NATIVE_SIZE /* end marker */ }; static int ft857_init(RIG *rig); static int ft857_open(RIG *rig); static int ft857_cleanup(RIG *rig); static int ft857_close(RIG *rig); static int ft857_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft857_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft857_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft857_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft857_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int ft857_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int ft857_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft857_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); // static int ft857_set_vfo(RIG *rig, vfo_t vfo); // static int ft857_get_vfo(RIG *rig, vfo_t *vfo); static int ft857_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft857_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); // static int ft857_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft857_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft857_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); // static int ft857_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); // static int ft857_set_parm(RIG *rig, setting_t parm, value_t val); // static int ft857_get_parm(RIG *rig, setting_t parm, value_t *val); static int ft857_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft857_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft857_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft857_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft857_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft857_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); // static int ft857_set_powerstat(RIG *rig, powerstat_t status); struct ft857_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[YAESU_CMD_LENGTH + 1]; }; /* Native ft857 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x0b, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS decoder on */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS encoder on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x3a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS decoder on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ }; enum ft857_digi { FT857_DIGI_RTTY_L = 0, FT857_DIGI_RTTY_U, FT857_DIGI_PSK_L, FT857_DIGI_PSK_U, FT857_DIGI_USER_L, FT857_DIGI_USER_U, }; #define FT857_PWR_CAL { 9, \ { \ { 0x00, 0.0f }, \ { 0x01, 10.0f }, \ { 0x02, 15.0f }, \ { 0x03, 20.0f }, \ { 0x04, 34.0f }, \ { 0x05, 50.0f }, \ { 0x06, 66.0f }, \ { 0x07, 82.f }, \ { 0x08, 100.0f } \ } } #define FT857_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT857_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT857_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT857_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT857_AM_TX_MODES (RIG_MODE_AM) #define FT857_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT857_ANTS 0 static int ft857_send_icmd(RIG *rig, int index, const unsigned char *data); struct rig_caps ft857_caps = { RIG_MODEL(RIG_MODEL_FT857), .model_name = "FT-857", .mfg_name = "Yaesu", .version = "20230206.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT857_WRITE_DELAY, .post_write_delay = FT857_POST_WRITE_DELAY, .timeout = FT857_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_RFPOWER_METER_WATTS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT857_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT857_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT857_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_6m(1, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_HF(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_6m(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_2m(1, FT857_OTHER_TX_MODES, W(5), W(50), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_2m(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_70cm(1, FT857_OTHER_TX_MODES, W(2), W(20), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT857_AM_TX_MODES, W(0.5), W(5), FT857_VFO_ALL, FT857_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT857_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT857_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT857_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_HF(2, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_2m(2, FT857_OTHER_TX_MODES, W(5), W(50), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_2m(2, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_70cm(2, FT857_OTHER_TX_MODES, W(2), W(20), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT857_AM_TX_MODES, W(0.5), W(5), FT857_VFO_ALL, FT857_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT857_SSB_CW_RX_MODES, 10}, {FT857_SSB_CW_RX_MODES, 100}, {FT857_AM_FM_RX_MODES, 10}, {FT857_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rfpower_meter_cal = FT857_PWR_CAL, .rig_init = ft857_init, .rig_cleanup = ft857_cleanup, .rig_open = ft857_open, .rig_close = ft857_close, .get_vfo = ft857_get_vfo, .set_vfo = ft857_set_vfo, .set_freq = ft857_set_freq, .get_freq = ft857_get_freq, .set_mode = ft857_set_mode, .get_mode = ft857_get_mode, .set_ptt = ft857_set_ptt, .get_ptt = ft857_get_ptt, .get_dcd = ft857_get_dcd, .set_rptr_shift = ft857_set_rptr_shift, .set_rptr_offs = ft857_set_rptr_offs, .set_split_freq_mode = ft857_set_split_freq_mode, .get_split_freq_mode = ft857_get_split_freq_mode, .set_split_vfo = ft857_set_split_vfo, .get_split_vfo = ft857_get_split_vfo, .set_rit = ft857_set_rit, .set_dcs_code = ft857_set_dcs_code, .set_ctcss_tone = ft857_set_ctcss_tone, .set_dcs_sql = ft857_set_dcs_sql, .set_ctcss_sql = ft857_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft857_get_level, .set_func = ft857_set_func, .vfo_op = ft857_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ int ft857_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft857_priv_data))) == NULL) { return -RIG_ENOMEM; } return RIG_OK; } int ft857_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int ft857_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft857_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s:called\n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT857_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "ft857: using cache (%ld ms)\n", t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "ft857: cache timed out (%ld ms)\n", t); return 1; } } static int ft857_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; hamlib_port_t *rp = RIGPORT(rig); int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); memcpy(data, (char *)ncmd[FT857_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xfe; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } *out = data[addr % 2]; return RIG_OK; } static int ft857_get_status(RIG *rig, int status) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (status) { case FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; len = YAESU_CMD_LENGTH; tv = &p->fm_status_tv; break; case FT857_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT857_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, len)) < 0) { return n; } if (n != len) { return -RIG_EIO; } if (status == FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS) { if ((n = ft857_read_eeprom(rig, 0x0078, &p->fm_status[5])) < 0) { return n; } p->fm_status[5] >>= 5; } gettimeofday(tv, NULL); return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft857_send_cmd(RIG *rig, int index) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: incomplete sequence\n", __func__); return -RIG_EINTERNAL; } write_block(RIGPORT(rig), ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft857_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ int ft857_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char c; static int ignore = 0; *vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); // Some 857's cannot read so we'll just return the cached value if we've seen an error if (ignore) { *vfo = CACHE(rig)->vfo; return RIG_OK; } if (ft857_read_eeprom(rig, 0x0068, &c) < 0) /* get vfo status */ { ignore = 1; *vfo = CACHE(rig)->vfo; return RIG_OK; } if ((c & 0x1) == 0) { *vfo = RIG_VFO_A; } return RIG_OK; } int ft857_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); ft857_get_vfo(rig, &curvfo); // retval is always RIG_OK so ignore it if (curvfo == vfo) { return RIG_OK; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); } int ft857_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } *freq = from_bcd_be(p->fm_status, 8) * 10; return -RIG_OK; } static void get_mode(RIG *rig, const struct ft857_priv_data *priv, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (priv->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (priv->fm_status[5]) { case FT857_DIGI_RTTY_L: *mode = RIG_MODE_RTTY; break; case FT857_DIGI_RTTY_U: *mode = RIG_MODE_RTTYR; break; case FT857_DIGI_PSK_L: *mode = RIG_MODE_PKTLSB; break; case FT857_DIGI_PSK_U: *mode = RIG_MODE_PKTUSB; break; case FT857_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT857_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; } break; case 0x0c: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (priv->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } } int ft857_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } get_mode(rig, p, mode, width); return RIG_OK; } int ft857_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retcode; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); retcode = ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); if (RIG_OK != retcode) { return retcode; } retcode = ft857_get_freq(rig, RIG_VFO_CURR, freq); if (RIG_OK == retcode) { get_mode(rig, (struct ft857_priv_data *)STATE(rig)->priv, mode, width); } ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); /* always try and return to orig VFO */ return retcode; } int ft857_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } if (p->tx_status & 0x80) { // TX status not valid when in RX unsigned char c; if ((n = ft857_read_eeprom(rig, 0x008d, &c)) < 0) /* get split status */ { return n; } *split = (c & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } return RIG_OK; } int ft857_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = ((p->tx_status & 0x80) == 0); return RIG_OK; } static int ft857_get_pometer_level(RIG *rig, value_t *val, const cal_table_float_t *cal, float divider) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: bars=%d\n", __func__, p->tx_status & 0x0F); // does rig have 10 bars or 15? val->f = rig_raw2val_float(p->tx_status & 0x0F, cal) / divider; } else { val->f = 0; // invalid value return } return RIG_OK; } static int ft857_get_smeter_level(RIG *rig, value_t *val) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } n = (p->rx_status & 0x0F); // S level returned if (n >= 9) { val->i = (n - 9) * 10; } else { val->i = n * 6 - 54; } return RIG_OK; } int ft857_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); freq_t freq; rmode_t mode; pbwidth_t width; int freq_ms, mode_ms, width_ms; switch (level) { case RIG_LEVEL_STRENGTH: return ft857_get_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: case RIG_LEVEL_RFPOWER_METER_WATTS: rig_get_cache(rig, vfo, &freq, &freq_ms, &mode, &mode_ms, &width, &width_ms); if (144000000.0f <= freq && 148000000.0f > freq) { return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 2.0); } else if (420000000.0f <= freq && 450000000.0f > freq) { return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 5.0); } return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 1.0); default: return -RIG_EINVAL; } return RIG_OK; } int ft857_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } int ft857_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; int i; ptt_t ptt = RIG_PTT_ON; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: requested freq = %"PRIfreq" Hz\n", freq); // cannot set freq while PTT is on for (i = 0; i < 10 && ptt == RIG_PTT_ON; ++i) { int retval = ft857_get_ptt(rig, vfo, &ptt); if (retval != RIG_OK) { return retval; } hl_usleep(100 * 1000); } /* fill in the frequency */ to_bcd_be(data, (freq + 5) / 10, 8); rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_FREQ, data); } int ft857_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT857_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT857_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT857_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT857_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: /* user has to have correct DIG mode setup on rig */ index = FT857_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_FM: index = FT857_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_WFM: index = FT857_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT857_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT857_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL) { return -RIG_EINVAL; } rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft857_send_cmd(rig, index); } int ft857_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retcode; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); retcode = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retcode != RIG_OK) { return retcode; } retcode = ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); if (RIG_OK != retcode) { return retcode; } retcode = ft857_set_freq(rig, RIG_VFO_CURR, freq); if (RIG_OK == retcode) { retcode = ft857_set_mode(rig, RIG_VFO_CURR, mode, width); } ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); /* always try and return to orig VFO */ return retcode; } int ft857_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (split) { case RIG_SPLIT_ON: index = FT857_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: index = FT857_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } n = ft857_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft857_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT857_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT857_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } n = ft857_send_cmd(rig, index); if (ptt == RIG_PTT_OFF) { hl_usleep(200 * 1000); } // FT857 takes a bit to come out of PTT rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft857_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_LOCK_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_OFF); } #if 0 case RIG_FUNC_CODE: /* this doesn't exist */ if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ENC_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } #endif default: return -RIG_EINVAL; } } int ft857_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set DCS code (%u)\n", code); if (code == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ENC_ON); } int ft857_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON); } int ft857_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set DCS sql (%u)\n", code); if (code == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ON); } int ft857_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ON); } int ft857_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set repeater shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } int ft857_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set repeater offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_RPT_OFFSET, data); } int ft857_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_OFF); } else { ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_ON); }*/ return RIG_OK; } int ft857_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (op) { case RIG_OP_TOGGLE: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); default: return -RIG_EINVAL; } return -RIG_EINVAL; } /* ---------------------------------------------------------------------- */ hamlib-4.6.5/rigs/yaesu/ft1000mp.c0000664000175000017500000015611615056640443012173 /* * ft1000.c - (C) Stephane Fillod 2002-2005 (fillods@users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-1000MP using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Right now, this FT-1000MP implementation is a big mess. * This is actually a fast copy past (from ft920.c), * just to make get_freq/set_freq and co to work for a friend of mine. * I wouldn't mind if someone could take over the maintenance * of this piece of code, and eventually rewrite it. * '02, Stephane */ #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft1000mp.h" /* * Native FT1000MP functions. More to come :-) * */ enum ft1000mp_native_cmd_e { FT1000MP_NATIVE_SPLIT_OFF = 0, FT1000MP_NATIVE_SPLIT_ON, // 1 FT1000MP_NATIVE_RECALL_MEM, // 2 FT1000MP_NATIVE_VFO_TO_MEM, // 3 FT1000MP_NATIVE_VFO_A, // 4 FT1000MP_NATIVE_VFO_B, // 5 FT1000MP_NATIVE_M_TO_VFO, // 6 FT1000MP_NATIVE_RIT_ON, // 7 FT1000MP_NATIVE_RIT_OFF, // 8 FT1000MP_NATIVE_XIT_ON, // 9 FT1000MP_NATIVE_XIT_OFF, // 10 FT1000MP_NATIVE_RXIT_SET, // 11 FT1000MP_NATIVE_FREQA_SET, // 12 FT1000MP_NATIVE_FREQB_SET, // 13 FT1000MP_NATIVE_MODE_SET_LSB, // 14 FT1000MP_NATIVE_MODE_SET_USB, // 15 FT1000MP_NATIVE_MODE_SET_CW, // 16 FT1000MP_NATIVE_MODE_SET_CWR, // 17 FT1000MP_NATIVE_MODE_SET_AM, // 18 FT1000MP_NATIVE_MODE_SET_AMS, // 19 FT1000MP_NATIVE_MODE_SET_FM, // 20 FT1000MP_NATIVE_MODE_SET_FMW, // 21 FT1000MP_NATIVE_MODE_SET_RTTY_LSB, // 22 FT1000MP_NATIVE_MODE_SET_RTTY_USB, // 23 FT1000MP_NATIVE_MODE_SET_DATA_LSB, // 24 FT1000MP_NATIVE_MODE_SET_DATA_FM, // 25 FT1000MP_NATIVE_MODE_SET_LSB_B, // 26 FT1000MP_NATIVE_MODE_SET_USB_B, // 27 FT1000MP_NATIVE_MODE_SET_CW_B, // 28 FT1000MP_NATIVE_MODE_SET_CWR_B, // 29 FT1000MP_NATIVE_MODE_SET_AM_B, // 30 FT1000MP_NATIVE_MODE_SET_AMS_B, // 31 FT1000MP_NATIVE_MODE_SET_FM_B, // 32 FT1000MP_NATIVE_MODE_SET_FMW_B, // 33 FT1000MP_NATIVE_MODE_SET_RTTY_LSB_B, // 34 FT1000MP_NATIVE_MODE_SET_RTTY_USB_B, // 35 FT1000MP_NATIVE_MODE_SET_DATA_LSB_B, // 36 FT1000MP_NATIVE_MODE_SET_DATA_FM_B, // 37 FT1000MP_NATIVE_PACING, // 38 FT1000MP_NATIVE_PTT_OFF, // 39 FT1000MP_NATIVE_PTT_ON, // 40 FT1000MP_NATIVE_VFO_UPDATE, // 41 FT1000MP_NATIVE_CURR_VFO_UPDATE, // 42 FT1000MP_NATIVE_UPDATE, // 43 FT1000MP_NATIVE_AB, // 44 FT1000MP_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * API local implementation * */ static int ft1000mp_init(RIG *rig); static int ft1000mp_cleanup(RIG *rig); static int ft1000mp_open(RIG *rig); //static int ft1000mp_close(RIG *rig); static int ft1000mp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft1000mp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000mp_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft1000mp_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft1000mp_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft1000mp_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int ft1000mp_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int ft1000mp_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft1000mp_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft1000mp_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft1000mp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft1000mp_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft1000mp_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft1000mp_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft1000mp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_set_rxit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_get_rxit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft1000mp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft1000mp_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft1000mp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft1000mp_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); /* * Differences between FT1000MP: * The FT1000MP MARK-V Field appears to be identical to FT1000MP, * whereas the FT1000MP MARK-V is a FT1000MP with 200W. TBC. */ /* Private helper function prototypes */ static int ft1000mp_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft1000mp_send_priv_cmd(RIG *rig, unsigned char ci); /* * Native ft1000mp cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 0 split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* 1 split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* 2 recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* 3 memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* 4 select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* 5 select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* 6 copy memory data to vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* 7 RX clarifier on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 8 RX clarifier off */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* 9 TX clarifier on */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* 10 TX clarifier off */ { 0, { 0x00, 0x00, 0x00, 0xFF, 0x09 } }, /* 11 set clarifier offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* 12 set VFOA freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* 13 set VFOB freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* 14 vfo A mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* 15 vfo A mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* 16 vfo A mode set CW-USB */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* 17 vfo A mode set CW-LSB */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* 18 vfo A mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* 19 vfo A mode set AM sync */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* 20 vfo A mode set FM */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* 21 vfo A mode set FMW? */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* 22 vfo A mode set RTTY-LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* 23 vfo A mode set RTTY-USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* 24 vfo A mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* 25 vfo A mode set DATA-FM */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x0c } }, /* 26 vfo B mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x0c } }, /* 27 vfo B mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x0c } }, /* 28 vfo B mode set CW-USB */ { 1, { 0x00, 0x00, 0x00, 0x83, 0x0c } }, /* 29 vfo B mode set CW-LSB */ { 1, { 0x00, 0x00, 0x00, 0x84, 0x0c } }, /* 30 vfo B mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x85, 0x0c } }, /* 31 vfo B mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x86, 0x0c } }, /* 32 vfo B mode set FM */ { 1, { 0x00, 0x00, 0x00, 0x87, 0x0c } }, /* 33 vfo B mode set FMN */ { 1, { 0x00, 0x00, 0x00, 0x88, 0x0c } }, /* 34 vfo B mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x89, 0x0c } }, /* 35 vfo B mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x8a, 0x0c } }, /* 36 vfo B mode set DATA-USB */ { 1, { 0x00, 0x00, 0x00, 0x8b, 0x0c } }, /* 37 vfo B mode set DATA-FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* 38 update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0F } }, /* 39 PTT OFF */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0F } }, /* 40 PTT ON */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* 41 status update VFO A & B update */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* 42 status update operating data */ // We only ask for the 1st 3 status bytes // The MARK-V was not recognizing the 6-byte request // This should be all we need as we're only getting the VFO { 1, { 0x00, 0x00, 0x00, 0x00, 0xFA } }, /* 43 Read status flags */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* 44 A>B */ /* { 0, { 0x00, 0x00, 0x00, 0x00, 0x70 } }, */ /* 45 keyer commands */ /* { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, */ /* 46 tuner off */ /* { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, */ /* 47 tuner on */ /* { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, */ /* 48 tuner start*/ }; #define FT1000MP_ALL_RX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) /* * TX caps */ #define FT1000MP_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* 100 W class */ #define FT1000MP_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT1000MP_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL \ |RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK \ |RIG_FUNC_RIT|RIG_FUNC_XIT \ /* |RIG_FUNC_TUNER */) /* FIXME */ #define FT1000MP_LEVEL_GET (RIG_LEVEL_RAWSTR|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER|RIG_LEVEL_COMP| \ RIG_LEVEL_MICGAIN|RIG_LEVEL_CWPITCH) #define FT1000MP_VFOS (RIG_VFO_A|RIG_VFO_B) #define FT1000MP_ANTS 0 /* FIXME: declare antenna connectors: ANT-A, ANT-B, RX ANT */ #define FT1000MP_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /** * 33 CTCSS sub-audible tones */ static tone_t ft1000mp_ctcss_list[] = { 670, 719, 770, 825, 885, 948, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; #define FT1000MP_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } #define FT1000MP_STR_CAL { 12, \ { \ { 0, -60 }, \ { 17, -54 }, /* S0 */ \ { 17, -48 }, \ { 34, -42 }, \ { 51, -36 }, \ { 68, -30 }, \ { 85, -24 }, \ { 102, -18 }, \ { 119, -12 }, \ { 136, -6 }, \ { 160, 0 }, /* S9 */ \ { 255, 60 } /* +60 */ \ } } /* * future - private data * */ struct ft1000mp_priv_data { unsigned char pacing; /* pacing value */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[2 * FT1000MP_STATUS_UPDATE_LENGTH]; /* returned data--max value, some are less */ }; /* * ft1000mp rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft1000mp_caps = { RIG_MODEL(RIG_MODEL_FT1000MP), .model_name = "FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, // was 2000 -- see https://github.com/Hamlib/Hamlib/issues/308 .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, Hz(100)}, /* Fast */ {RIG_MODE_AM, Hz(100)}, /* Normal */ {RIG_MODE_AM, kHz(1)}, /* Fast */ {RIG_MODE_FM, Hz(100)}, /* Normal */ {RIG_MODE_FM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, {RIG_MODE_AM, kHz(5)}, /* wide */ {RIG_MODE_FM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, /* TODO: the remaining ... */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft1000mpmkv_caps = { RIG_MODEL(RIG_MODEL_FT1000MPMKV), .model_name = "MARK-V FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(200), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(50), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(200), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(50), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(100)}, /* Fast */ {RIG_MODE_AM | RIG_MODE_SAL, Hz(100)}, /* Normal */ {RIG_MODE_AM | RIG_MODE_SAL, kHz(1)}, /* Fast */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(100)}, /* Normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_AM | RIG_MODE_SAL, kHz(5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS /* TODO: the remaining ... */ }; struct rig_caps ft1000mpmkvfld_caps = { RIG_MODEL(RIG_MODEL_FT1000MPMKVFLD), .model_name = "MARK-V Field FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(100)}, /* Fast */ {RIG_MODE_AM | RIG_MODE_SAL, Hz(100)}, /* Normal */ {RIG_MODE_AM | RIG_MODE_SAL, kHz(1)}, /* Fast */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(100)}, /* Normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_AM | RIG_MODE_SAL, kHz(5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS /* TODO: the remaining ... */ }; /* * _init * */ static int ft1000mp_init(RIG *rig) { struct ft1000mp_priv_data *priv; ENTERFUNC; STATE(rig)->priv = (struct ft1000mp_priv_data *) calloc(1, sizeof(struct ft1000mp_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT1000MP_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ RETURNFUNC(RIG_OK); } /* * ft1000mp_cleanup routine * the serial port is closed by the frontend * */ static int ft1000mp_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * ft1000mp_open routine * */ static int ft1000mp_open(RIG *rig) { struct rig_state *rig_s; hamlib_port_t *rp = RIGPORT(rig); struct ft1000mp_priv_data *p; unsigned char *cmd; /* points to sequence to send */ ENTERFUNC; rig_s = STATE(rig); p = (struct ft1000mp_priv_data *)rig_s->priv; rig_debug(RIG_DEBUG_TRACE, "%s: rig_open: write_delay = %i msec \n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: rig_open: post_write_delay = %i msec \n", __func__, rp->post_write_delay); /* * Copy native cmd PACING to private cmd storage area */ memcpy(&p->p_cmd, &ncmd[FT1000MP_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = p->pacing; /* get pacing value, and store in private cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, p->pacing); /* send PACING cmd to rig */ cmd = p->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); ft1000mp_get_vfo(rig, &rig_s->current_vfo); /* TODO */ RETURNFUNC(RIG_OK); } static int ft1000mp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft1000mp_priv_data *p; unsigned char *cmd; /* points to sequence to send */ int cmd_index = 0; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: requested freq on %s = %"PRIfreq" Hz \n", __func__, rig_strvfo(vfo), freq); if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } // round freq to 10Hz intervals due to rig restriction freq = round(freq / 10.0) * 10.0; switch (vfo) { case RIG_VFO_A: cmd_index = FT1000MP_NATIVE_FREQA_SET; CACHE(rig)->freqMainA = freq; break; case RIG_VFO_B: cmd_index = FT1000MP_NATIVE_FREQB_SET; CACHE(rig)->freqMainB = freq; break; case RIG_VFO_MEM: // we can set VFOA when VFO MEM is selected cmd_index = FT1000MP_NATIVE_FREQA_SET; break; default: rig_debug(RIG_DEBUG_WARN, "%s: unknown VFO %0x\n", __func__, vfo); RETURNFUNC(-RIG_EINVAL); } /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); to_bcd(p->p_cmd, freq / 10, 8); /* store bcd format in in p_cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz\n", __func__, (freq_t)from_bcd(p->p_cmd, 8) * 10); cmd = p->p_cmd; /* get native sequence */ write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } static int ft1000mp_get_vfo_data(RIG *rig, vfo_t vfo) { int cmd_index, len, retval; ENTERFUNC; if (vfo == RIG_VFO_A || vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_VFO_UPDATE; len = 2 * FT1000MP_STATUS_UPDATE_LENGTH; } else { /* RIG_VFO_CURR or RIG_VFO_MEM */ cmd_index = FT1000MP_NATIVE_CURR_VFO_UPDATE; len = FT1000MP_STATUS_UPDATE_LENGTH; } /* * get record from rig */ retval = ft1000mp_get_update_data(rig, cmd_index, len); RETURNFUNC(retval); } /* * Return Freq for a given VFO * */ static int ft1000mp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft1000mp_priv_data *priv; unsigned char *p; freq_t f; int retval; ENTERFUNC; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_FREQ]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_FREQ]; /* CURR_VFO has VFOA offset */ } /* big endian integer, kinda */ f = ((((((p[0] << 8) + p[1]) << 8) + p[2]) << 8) + p[3]) * 10 / 16; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for VFO [%x]\n", __func__, f, vfo); *freq = f; // return displayed frequency RETURNFUNC(RIG_OK); } /* * set mode : eg AM, CW etc for a given VFO * */ static int ft1000mp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index = 0; /* index of sequence to send */ ENTERFUNC; /* frontend sets VFO for us */ rig_debug(RIG_DEBUG_TRACE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } /* * translate mode from generic to ft1000mp specific */ switch (mode) { case RIG_MODE_AM: cmd_index = FT1000MP_NATIVE_MODE_SET_AM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_AM_B; } break; case RIG_MODE_CW: cmd_index = FT1000MP_NATIVE_MODE_SET_CWR; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_CWR_B; } break; case RIG_MODE_CWR: cmd_index = FT1000MP_NATIVE_MODE_SET_CW; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_CW_B; } break; case RIG_MODE_USB: cmd_index = FT1000MP_NATIVE_MODE_SET_USB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_USB_B; } break; case RIG_MODE_LSB: cmd_index = FT1000MP_NATIVE_MODE_SET_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_LSB_B; } break; case RIG_MODE_FM: cmd_index = FT1000MP_NATIVE_MODE_SET_FM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_FM_B; } break; case RIG_MODE_RTTY: cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_LSB_B; } break; case RIG_MODE_PKTUSB: case RIG_MODE_RTTYR: cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_USB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_USB_B; } break; case RIG_MODE_PKTLSB: cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_LSB_B; } break; case RIG_MODE_PKTFM: cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_FM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_FM_B; } break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong MODE * */ } /* * Now set width * FIXME: so far setting passband is buggy, only 0 is accepted */ /* * phew! now send cmd to rig */ ft1000mp_send_priv_cmd(rig, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_index = %i\n", __func__, cmd_index); RETURNFUNC(RIG_OK); /* good */ } /* * get mode : eg AM, CW etc for a given VFO * */ static int ft1000mp_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft1000mp_priv_data *priv; unsigned char mymode; /* ft1000mp mode */ unsigned char mymode_ext; /* ft1000mp extra mode bit mode */ int retval; struct rig_state *rs = STATE(rig); ENTERFUNC; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; } retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } priv = (struct ft1000mp_priv_data *)rs->priv; if (vfo == RIG_VFO_B) { mymode = priv->update_data[FT1000MP_SUMO_VFO_B_MODE]; mymode_ext = priv->update_data[FT1000MP_SUMO_VFO_B_IF] & IF_MODE_MASK; } else { mymode = priv->update_data[FT1000MP_SUMO_VFO_A_MODE]; /* CURR_VFO is VFOA offset */ mymode_ext = priv->update_data[FT1000MP_SUMO_VFO_A_IF] & IF_MODE_MASK; } rig_debug(RIG_DEBUG_TRACE, "%s: mymode = %x (before)\n", __func__, mymode); mymode &= MODE_MASK; rig_debug(RIG_DEBUG_TRACE, "%s: mymode = %x (after)\n", __func__, mymode); /* * translate mode from ft1000mp to generic. * TODO: Add DATA, and Narrow modes. CW on LSB? -N0NB */ switch (mymode) { case MODE_CW: *mode = mymode_ext ? RIG_MODE_CW : RIG_MODE_CWR; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_AM: *mode = mymode_ext ? RIG_MODE_SAL : RIG_MODE_AM; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_RTTY: *mode = mymode_ext ? RIG_MODE_RTTYR : RIG_MODE_RTTY; break; case MODE_PKT: *mode = mymode_ext ? RIG_MODE_PKTFM : RIG_MODE_PKTLSB; break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong mode */ break; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); /* TODO: set real IF filter selection */ *width = RIG_PASSBAND_NORMAL; RETURNFUNC(RIG_OK); } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft1000mp_set_vfo(RIG *rig, vfo_t vfo) { //unsigned char cmd_index = 0; /* index of sequence to send */ ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); /* * RIG_VFO_VFO/RIG_VFO_MEM are not available * so try to emulate them. * looks like there's no RIG_VFO_MEM, maybe setting mem# * switch to it automatically? */ if (vfo == RIG_VFO_VFO) { vfo = STATE(rig)->current_vfo; } #if 0 // seems switching VFOs like this changes the frequencies in the response switch (vfo) { case RIG_VFO_A: cmd_index = FT1000MP_NATIVE_VFO_A; STATE(rig)->current_vfo = vfo; /* update active VFO */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo == RIG_VFO_A\n", __func__); break; case RIG_VFO_B: cmd_index = FT1000MP_NATIVE_VFO_B; STATE(rig)->current_vfo = vfo; /* update active VFO */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo == RIG_VFO_B\n", __func__); break; case RIG_VFO_CURR: /* do nothing, we're already at it! */ RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unknown default VFO %d\n", __func__, vfo); RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } /* * phew! now send cmd to rig */ ft1000mp_send_priv_cmd(rig, cmd_index); #endif // we just store the requested vfo in our internal state STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } /* * get vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft1000mp_get_vfo(RIG *rig, vfo_t *vfo) { struct ft1000mp_priv_data *p; int retval; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ retval = ft1000mp_get_update_data(rig, FT1000MP_NATIVE_UPDATE, FT1000MP_STATUS_FLAGS_LENGTH); if (retval < 0) { RETURNFUNC(retval); } if (p->update_data[1] & 0x40) { *vfo = RIG_VFO_MEM; } else // we are emulating vfo status { *vfo = STATE(rig)->current_vfo; if (*vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: no get_vfo, defaulting to VFOA\n", __func__); *vfo = RIG_VFO_A; } } #if 0 else if (p->update_data[FT1000MP_SUMO_DISPLAYED_STATUS] & SF_VFOAB) { *vfo = STATE(rig)->current_vfo = RIG_VFO_B; } else { *vfo = STATE(rig)->current_vfo = RIG_VFO_A; } #endif rig_debug(RIG_DEBUG_TRACE, "%s: vfo status = %x %x\n", __func__, p->update_data[0], p->update_data[1]); RETURNFUNC(RIG_OK); } static int ft1000mp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct ft1000mp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char *cmd; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; switch (func) { case RIG_FUNC_RIT: if (status) { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RIT_ON].nseq, YAESU_CMD_LENGTH); } else { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RIT_OFF].nseq, YAESU_CMD_LENGTH); } cmd = priv->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); case RIG_FUNC_XIT: if (status) { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_XIT_ON].nseq, YAESU_CMD_LENGTH); } else { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_XIT_OFF].nseq, YAESU_CMD_LENGTH); } cmd = priv->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_func %s", __func__, rig_strfunc(func)); } RETURNFUNC(-RIG_EINVAL); } static int ft1000mp_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; struct ft1000mp_priv_data *priv; unsigned char *p; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; if (!status) { RETURNFUNC(-RIG_EINVAL); } switch (func) { case RIG_FUNC_RIT: { retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_MEM]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_MEM]; /* CURR_VFO has VFOA offset */ } *status = (*p & 2) ? 1 : 0; RETURNFUNC(RIG_OK); } case RIG_FUNC_XIT: { retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_MEM]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_MEM]; /* CURR_VFO has VFOA offset */ } *status = (*p & 1) ? 1 : 0; RETURNFUNC(RIG_OK); } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_func %s", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * set_rit only support vfo = RIG_VFO_CURR */ static int ft1000mp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; if (rit != 0) { ft1000mp_set_func(rig, vfo, RIG_FUNC_RIT, 1); } RETURNFUNC(ft1000mp_set_rxit(rig, vfo, rit)); } static int ft1000mp_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; RETURNFUNC(ft1000mp_set_rxit(rig, vfo, rit)); } static int ft1000mp_set_rxit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct rig_state *rs; struct ft1000mp_priv_data *priv; unsigned char *cmd; /* points to sequence to send */ int direction = 0; ENTERFUNC; rs = STATE(rig); priv = (struct ft1000mp_priv_data *)rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: requested freq = %d Hz\n", __func__, (int)rit); /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RXIT_SET].nseq, YAESU_CMD_LENGTH); if (rit < 0) { direction = 0xff; rit = -rit; } unsigned char rit_freq[10]; // yes, it really is this nasty and complicated! to_bcd_be(rit_freq, (rit - (rit / 1000) * 1000) / 10, 2); priv->p_cmd[0] = rit_freq[0]; // 10 hz to_bcd_be(rit_freq, rit / 1000, 2); priv->p_cmd[1] = rit_freq[0]; // Khz priv->p_cmd[2] = direction; cmd = priv->p_cmd; /* get native sequence */ write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } /* * Return RIT for a given VFO * */ static int ft1000mp_get_rxit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft1000mp_priv_data *priv; unsigned char *p; shortfreq_t f; int retval; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_CLAR]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_CLAR]; /* CURR_VFO has VFOA offset */ } f = (p[0] << 8) + p[1]; if (p[0] & 0x80) { f = ~(f - 1) & 0x7fff; // two's complement f = -f; } f = f * 10 / 16; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %d Hz for VFO [%s]\n", __func__, (int)f, rig_strvfo(vfo)); *rit = f; // return displayed frequency RETURNFUNC(RIG_OK); } static int ft1000mp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft1000mp_priv_data *priv; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); unsigned char lvl_data[YAESU_CMD_LENGTH]; int m; int retval; int retry = rp->retry; ENTERFUNC; rs = STATE(rig); priv = (struct ft1000mp_priv_data *)rs->priv; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } m = vfo == RIG_VFO_B ? 0x01 : 0x00; break; case RIG_LEVEL_RFPOWER: m = 0x80; break; case RIG_LEVEL_ALC: m = 0x81; break; case RIG_LEVEL_COMP: m = 0x83; break; case RIG_LEVEL_SWR: m = 0x85; break; case RIG_LEVEL_MICGAIN: /* not sure ... */ m = 0x86; break; case RIG_LEVEL_CWPITCH: m = 0xf1; break; case RIG_LEVEL_IF: /* not sure ... */ m = 0xf3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } memset(&priv->p_cmd, m, YAESU_CMD_LENGTH - 1); priv->p_cmd[4] = 0xf7; do { write_block(rp, priv->p_cmd, YAESU_CMD_LENGTH); retval = read_block(rp, lvl_data, YAESU_CMD_LENGTH); } while (retry-- && retval == -RIG_ETIMEOUT); if (retval != YAESU_CMD_LENGTH) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG %d", __func__, retval); RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_RAWSTR: val->i = lvl_data[0]; break; default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float)lvl_data[0] / 255; } else { val->i = lvl_data[0]; } } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %f\n", __func__, lvl_data[0], val->i, val->f); RETURNFUNC(RIG_OK); } static int ft1000mp_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: called %d\n", __func__, ptt); cmd_index = ptt ? FT1000MP_NATIVE_PTT_ON : FT1000MP_NATIVE_PTT_OFF; ft1000mp_send_priv_cmd(rig, cmd_index); RETURNFUNC(RIG_OK); } /* * private helper function. Retrieves update data from rig. * using buffer indicated in *priv struct. * Extended to be command agnostic as 1000mp has several ways to * get data and several ways to return it. * * need to use this when doing ft1000mp_get_* stuff * * Variables: ci = command index, rl = read length of returned data * */ static int ft1000mp_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft1000mp_priv_data *p; int n; /* for read_ */ ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; // timeout retries are done in read_block now // based on rig backed retry value /* send UPDATE command to fetch data*/ ft1000mp_send_priv_cmd(rig, ci); n = read_block(RIGPORT(rig), p->update_data, rl); if (n == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_TRACE, "%s: Timeout\n", __func__); } RETURNFUNC(n); } /* * private helper function to send a private command * sequence . Must only be complete sequences. * TODO: place variant of this in yaesu.c * */ static int ft1000mp_send_priv_cmd(RIG *rig, unsigned char ci) { ENTERFUNC; if (! ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: attempt to send incomplete sequence\n", __func__); RETURNFUNC(-RIG_EINVAL); } write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } static int ft1000mp_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index = 0; /* index of sequence to send */ struct rig_state *rs = STATE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s called rx_vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo)); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT1000MP_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT1000MP_NATIVE_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unknown split value = %d\n", __func__, split); RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } // manual says VFO_A=Tx and VFO_B=Rx but testing shows otherwise rs->current_vfo = RIG_VFO_A; rs->rx_vfo = RIG_VFO_B; rs->tx_vfo = RIG_VFO_B; ft1000mp_send_priv_cmd(rig, cmd_index); RETURNFUNC(RIG_OK); } /* * get split * */ static int ft1000mp_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft1000mp_priv_data *p; int retval; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; /* Get flags for split status */ retval = ft1000mp_get_update_data(rig, FT1000MP_NATIVE_UPDATE, FT1000MP_STATUS_FLAGS_LENGTH); if (retval < 0) { RETURNFUNC(retval); } if (p->update_data[0] & 0x01) { *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; } else { *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; } RETURNFUNC(RIG_OK); } static int ft1000mp_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { ENTERFUNC; int retval = rig_set_split_vfo(rig, vfo, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(ft1000mp_set_freq(rig, RIG_VFO_B, tx_freq)); } static int ft1000mp_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int retval; ENTERFUNC; retval = rig_set_mode(rig, RIG_VFO_B, tx_mode, tx_width); RETURNFUNC(retval); } static int ft1000mp_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int retval; ENTERFUNC; retval = rig_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); RETURNFUNC(retval); } static int ft1000mp_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; ENTERFUNC; retval = rig_set_mode(rig, RIG_VFO_B, mode, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } retval = ft1000mp_set_split_freq(rig, vfo, freq); if (retval == RIG_OK) { CACHE(rig)->freqMainB = freq; CACHE(rig)->modeMainB = mode; } RETURNFUNC(retval); } static int ft1000mp_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; retval = rig_get_mode(rig, RIG_VFO_B, mode, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } retval = ft1000mp_get_split_freq(rig, vfo, freq); if (retval == RIG_OK) { CACHE(rig)->freqMainB = *freq; CACHE(rig)->modeMainB = *mode; } RETURNFUNC(retval); } static int ft1000mp_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { ENTERFUNC; RETURNFUNC(ft1000mp_get_freq(rig, RIG_VFO_B, tx_freq)); } hamlib-4.6.5/rigs/yaesu/ft767gx.c0000664000175000017500000013732315056640443012137 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft767gx.c - (C) Steve Conklin 2007 * adapted from ft757gx.c by Stephane Fillod 2004 * This shared library provides an API for communicating * via serial interface to an FT-767GX using the "CAT" interface * box (FIF-232C) or similar * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO * * 1. Allow cached reads * 2. set_mem/get_mem, get_channel, set_split/get_split, * set_func/get_func * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft767gx.h" static int ft767_init(RIG *rig); static int ft767_cleanup(RIG *rig); static int ft767_open(RIG *rig); static int ft767_close(RIG *rig); static int ft767_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft767_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft767_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft767_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft767_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft767_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft767_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft767_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft767_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int ft767_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft767_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int ft767_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft767_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft767_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft767_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft767_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft767_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); /* Private helper function prototypes */ static int ft767_send_block_and_ack(RIG *rig, unsigned char *cmd, size_t length); static int ft767_get_update_data(RIG *rig); static int ft767_enter_CAT(RIG *rig); static int ft767_leave_CAT(RIG *rig); static int ft767_set_split(RIG *rig, unsigned int split); static unsigned char vfo2rig(RIG *rig, vfo_t vfo); static vfo_t rig2vfo(unsigned char status); static int mode2rig(RIG *rig, rmode_t mode); static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); /* static int ctcss2rig(RIG *rig, tone_t tone); */ static int rig2ctcss(RIG *rig, unsigned char tn, tone_t *tone); /* * On the rig used by the author of this software, the values returned * by the rig for the CTCSS tones are different than those in the Yaesu * documentation. This could possibly be because he tone module in that * rig is an aftermarket board sold by the piexx company. Leaving the * following undefined uses the values discovered by experimentation. For * The original values defined in the Yaesu documentation, uncomment it. */ /* #define USE_YAESU_PUBLISHED_TONES */ #define FT767GX_VFOS (RIG_VFO_A|RIG_VFO_B) /* Valid command codes */ #define CMD_CAT_SW 0x00 #define CMD_CHECK 0x01 #define CMD_UP10HZ 0x02 #define CMD_DN10HZ 0x03 #define CMD_PROG_UP 0x04 #define CMD_PROG_DN 0x05 #define CMD_BAND_UP 0x06 #define CMD_BAND_DN 0x07 #define CMD_FREQ_SET 0x08 #define CMD_VFOMR 0x09 #define CMD_MULTICMD 0x0A /* This command code overloaded */ #define CMD_TONE_SET 0x0C #define CMD_ACK 0x0B /* subcommands for command code 0x0A */ /* values 0 - 9 select memories */ #define SUBCMD_MEM0 0x00 /* 8 bytes returned */ #define SUBCMD_MEM1 0x01 /* 8 bytes returned */ #define SUBCMD_MEM2 0x02 /* 8 bytes returned */ #define SUBCMD_MEM3 0x03 /* 8 bytes returned */ #define SUBCMD_MEM4 0x04 /* 8 bytes returned */ #define SUBCMD_MEM5 0x05 /* 8 bytes returned */ #define SUBCMD_MEM6 0x06 /* 8 bytes returned */ #define SUBCMD_MEM7 0x07 /* 8 bytes returned */ #define SUBCMD_MEM8 0x08 /* 8 bytes returned */ #define SUBCMD_MEM9 0x09 /* 8 bytes returned */ #define SUBCMD_MODE_LSB 0x10 /* 8 bytes returned */ #define SUBCMD_MODE_USB 0x11 /* 8 bytes returned */ #define SUBCMD_MODE_CW 0x12 /* 8 bytes returned */ #define SUBCMD_MODE_AM 0x13 /* 8 bytes returned */ #define SUBCMD_MODE_FM 0x14 /* 8 bytes returned */ #define SUBCMD_MODE_FSK 0x15 /* 8 bytes returned */ #define SUBCMD_HG_HAM 0x20 /* ham coverage */ #define SUBCMD_HG_GEN 0x21 /* general coverage */ #define SUBCMD_SPLIT 0x30 /* toggle split */ #define SUBCMD_CLAR 0x40 /* toggle clarifier */ #define SUBCMD_MTOV 0x50 /* memory to VFO */ #define SUBCMD_VTOM 0x60 /* VFO to memory */ #define SUBCMD_SWAP 0x70 /* swap VFO, memory */ #define SUBCMD_ACLR 0x80 /* turn off SPLIT, CLAR< OFFSET */ /* * Some useful offsets in the status update map (offset) * * Status Update Chart, FT767GXII */ #define STATUS_FLAGS 0 #define STATUS_CURR_FREQ 1 /* Operating Frequency */ #define STATUS_CURR_TONE 5 #define STATUS_CURR_MODE 6 #define STATUS_VFOA_FREQ 14 #define STATUS_VFOA_MODE 19 #define STATUS_VFOB_FREQ 20 #define STATUS_VFOB_MODE 25 /* Status bit masks */ #define STATUS_MASK_PTT 0x01 #define STATUS_MASK_HG 0x02 #define STATUS_MASK_TXINH 0x04 #define STATUS_MASK_SPLIT 0x08 #define STATUS_MASK_VFO 0x10 #define STATUS_MASK_MEM 0x20 #define STATUS_MASK_CLAR 0x40 #define STATUS_MASK_CAT 0x80 /* mode byte */ #define MODE_LSB 0x0 #define MODE_USB 0x1 #define MODE_CW 0x2 #define MODE_AM 0x3 #define MODE_FM 0x4 #define MODE_FSK 0x5 /* * Things that I need to figure out how to fit in */ //#define VFO_OPERATIONS_LIST (RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_TOGGLE) /* These VFO OPS can only be applied to the current VFO */ // RIG_OP_UP = (1<<5), /*!< UP increment VFO freq by tuning step*/ // RIG_OP_DOWN = (1<<6), /*!< DOWN decrement VFO freq by tuning step*/ // RIG_OP_BAND_UP = (1<<7), /*!< Band UP */ /* #define FT767_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, .ctcss_tone = 1 \ } */ /* * End of things not put in yet */ /* * Receiver caps */ #define FT767GX_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT767GX_HF_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) /* * TX caps */ #define FT767GX_ALL_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT767GX_HF_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) #define CTCSS_TONE_LIST \ 670, 710, 747, 770, 797, 825, 854, 885, 915, 948, \ 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, \ 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, \ 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 /* * future - private data * */ struct ft767_priv_data { unsigned char pacing; /* pacing value */ unsigned char current_vfo; /* active VFO from last cmd , can be either RIG_VFO_A or RIG_VFO_B only */ unsigned char update_data[FT767GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ unsigned char rx_data[FT767GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ unsigned char ack_cmd[5]; }; tone_t static_767gx_ctcss_list[] = { CTCSS_TONE_LIST }; /* * ft767gx rigs capabilities. * Also this struct is READONLY! */ struct rig_caps ft767gx_caps = { RIG_MODEL(RIG_MODEL_FT767), .model_name = "FT-767GX", .mfg_name = "Yaesu", .version = "20230523.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT767GX_WRITE_DELAY, .post_write_delay = FT767GX_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = static_767gx_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = {RIG_CHAN_END, }, /* TODO need memory channel capabilities here */ // .chan_list = {0, 9, RIG_MTYPE_MEM, RIG_CHAN_END, }, /* TODO need memory channel capabilities here */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(100), .endf = 29999999, .modes = FT767GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1500), 1999900, FT767GX_HF_TX_MODES, .low_power = 5000, .high_power = 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(3500), 3999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(7000), 7499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(10), 10499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(14), 14499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(18), 18499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(21), 21499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(24500), 24999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(28), 29999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(50), 59999900, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(144), 147999900, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(430), 449999990, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, RIG_FRNG_END, }, .tuning_steps = { {FT767GX_ALL_RX_MODES, 10}, {FT767GX_ALL_RX_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* private data */ .rig_init = ft767_init, .rig_cleanup = ft767_cleanup, .rig_open = ft767_open, /* port opened */ .rig_close = ft767_close, /* port closed */ .set_freq = ft767_set_freq, /* set freq */ .get_freq = ft767_get_freq, /* get freq */ .set_mode = ft767_set_mode, /* set mode */ .get_mode = ft767_get_mode, /* get mode */ .set_vfo = ft767_set_vfo, /* set vfo */ .get_vfo = ft767_get_vfo, /* get vfo */ .set_ptt = NULL, /* set ptt */ .get_ptt = ft767_get_ptt, /* get ptt */ .set_ctcss_tone = ft767_set_ctcss_tone, .get_ctcss_tone = ft767_get_ctcss_tone, .set_ctcss_sql = ft767_set_ctcss_sql, .get_ctcss_sql = ft767_get_ctcss_sql, .set_split_freq = ft767_set_split_freq, .get_split_freq = ft767_get_split_freq, .set_split_mode = ft767_set_split_mode, .get_split_mode = ft767_get_split_mode, .set_split_vfo = ft767_set_split_vfo, .get_split_vfo = ft767_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ int ft767_init(RIG *rig) { struct ft767_priv_data *priv; if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft767_priv_data *) calloc(1, sizeof(struct ft767_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* TODO: read pacing from preferences */ priv->pacing = FT767GX_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A ? */ priv->ack_cmd[0] = 00; priv->ack_cmd[1] = 00; priv->ack_cmd[2] = 00; priv->ack_cmd[3] = 00; priv->ack_cmd[4] = 0x0B; return RIG_OK; } /* * ft767_cleanup routine * the serial port is closed by the frontend */ int ft767_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft767_open routine * */ int ft767_open(RIG *rig) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; rig_flush(RIGPORT(rig)); /* send 0 delay PACING cmd to rig */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); memset(priv->update_data, 0, FT767GX_STATUS_UPDATE_DATA_LENGTH); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); memset(priv->update_data, 0, FT767GX_STATUS_UPDATE_DATA_LENGTH); return retval; } STATE(rig)->vfo_list = RIG_VFO_A | RIG_VFO_B; return RIG_OK; } /* * ft767_close routine * */ int ft767_close(RIG *rig) { int retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } return RIG_OK; } /* * This command only functions when operating on a vfo. * */ int ft767_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_FREQ_SET}; int retval; /* should the vfo be tested? */ /* fill in first four bytes */ to_bcd(cmd, freq / 10, 8); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_MULTICMD}; int retval; /* fill in p1 */ cmd[3] = mode2rig(rig, mode); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } /* * Return Freq */ int ft767_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* grab freq and convert */ switch (vfo) { case RIG_VFO_CURR: *freq = from_bcd_be(priv->update_data + STATUS_CURR_FREQ, 8); break; case RIG_VFO_A: *freq = from_bcd_be(priv->update_data + STATUS_VFOA_FREQ, 8); break; case RIG_VFO_B: *freq = from_bcd_be(priv->update_data + STATUS_VFOB_FREQ, 8); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } *freq *= 10.0; /* rig reads in 10 Hz increments*/ return RIG_OK; } int ft767_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE( rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } switch (vfo) { case RIG_VFO_CURR: retval = rig2mode(rig, priv->update_data[STATUS_CURR_MODE], mode, width); break; case RIG_VFO_A: retval = rig2mode(rig, priv->update_data[STATUS_VFOA_MODE], mode, width); break; case RIG_VFO_B: retval = rig2mode(rig, priv->update_data[STATUS_VFOB_MODE], mode, width); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return retval; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int ft767_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: cmd[3] = 0x00; break; case RIG_VFO_B: cmd[3] = 0x01; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } priv->current_vfo = vfo; retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); return RIG_OK; } int ft767_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *ptt = (priv->update_data[STATUS_FLAGS] & 0x01) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* on this rig, only one tone can be set per VFO or memory, * and it's active for both tx and receive. */ int ft767_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_TONE_SET}; int retval; /* determine whether we have to send high-Q */ switch (tone) { case 747: case 797: case 854: case 915: cmd[1] = 1; /* High Q */ break; default: break; } /* fill in p2 and p1 with bcd tone value */ to_bcd(&cmd[2], tone, 4); /* cmd[3] = tone2rig(rig, tone); */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } retval = rig2ctcss(rig, priv->update_data[STATUS_CURR_TONE], tone); return retval; } int ft767_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { return ft767_set_ctcss_tone(rig, vfo, tone); } int ft767_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { return ft767_get_ctcss_tone(rig, vfo, tone); } /* split functions */ int ft767_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char freq_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_FREQ_SET}; unsigned char vfo_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; vfo_t curr_vfo; vfo_t change_vfo; unsigned char curr_split; int retval; retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { return retval; } /* This appears to always pass in VFO_CURR as the vfo */ /* My decision is to only update the xmit VFO if we're in split mode */ retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out how we're currently configured */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to set something */ case RIG_VFO_A: change_vfo = RIG_VFO_B; break; case RIG_VFO_B: change_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* fill in first four bytes */ to_bcd(freq_cmd, tx_freq / 10, 8); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* change to the xmit VFO */ vfo_cmd[3] = vfo2rig(rig, change_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } /* change the freq */ retval = ft767_send_block_and_ack(rig, freq_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } /* change back to the rcv VFO */ vfo_cmd[3] = vfo2rig(rig, curr_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return RIG_OK; } int ft767_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int offset; vfo_t curr_vfo; unsigned char curr_split; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to get something */ case RIG_VFO_A: offset = STATUS_VFOB_FREQ; break; case RIG_VFO_B: offset = STATUS_VFOA_FREQ; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } *tx_freq = from_bcd_be(priv->update_data + offset, 8); return RIG_OK; } int ft767_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char mode_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_MULTICMD}; unsigned char vfo_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; vfo_t curr_vfo; vfo_t change_vfo; unsigned char curr_split; int retval; /* This appears to always pass in VFO_CURR as the vfo */ /* My decision is to only update the xmit mode if we're in split mode */ retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out how we're currently configured */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to set something */ case RIG_VFO_A: change_vfo = RIG_VFO_B; break; case RIG_VFO_B: change_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* fill in p1 */ mode_cmd[3] = mode2rig(rig, tx_mode); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* change to the xmit VFO */ vfo_cmd[3] = vfo2rig(rig, change_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send vfo change 1 command: status %d\n", __func__, retval); return retval; } /* change the mode */ retval = ft767_send_block_and_ack(rig, mode_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send mode command: status %d\n", __func__, retval); return retval; } /* change back to the rcv VFO */ vfo_cmd[3] = vfo2rig(rig, curr_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send vfo change 2command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return RIG_OK; } int ft767_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int offset; vfo_t curr_vfo; unsigned char curr_split; retval = ft767_get_update_data(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to get something */ case RIG_VFO_A: offset = STATUS_VFOB_MODE; break; case RIG_VFO_B: offset = STATUS_VFOA_MODE; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* get the actual mode */ retval = rig2mode(rig, priv->update_data[offset], tx_mode, tx_width); return retval; } int ft767_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; int retval; vfo_t curr_vfo; vfo_t future_vfo; unsigned char curr_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); if ((tx_vfo != RIG_VFO_A) && (tx_vfo != RIG_VFO_B)) { return -RIG_EINVAL; } retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out which VFO we're currently using */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); /* * If split is enabled, Set the current VFO to the opposite of * the one specified in tx_vfo. If split is not enabled, then don't change anything. */ switch (split) { case RIG_SPLIT_OFF: /* turn off split, leave everything else alone */ return ft767_set_split(rig, 0); break; case RIG_SPLIT_ON: switch (tx_vfo) { case RIG_VFO_CURR: // we need to switch VFOs if (curr_vfo == RIG_VFO_A) { future_vfo = RIG_VFO_B; } else if (curr_vfo == RIG_VFO_B) { future_vfo = RIG_VFO_B; } else { /* Currently using memory! */ rig_debug(RIG_DEBUG_ERR, "%s: RIG_VFO_CURR requested when it is a memory\n", __func__); return -RIG_EINVAL; } break; case RIG_VFO_A: future_vfo = RIG_VFO_B; break; case RIG_VFO_B: future_vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_flush(RIGPORT(rig)); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* See whether we need to toggle the split state */ curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { curr_split = RIG_SPLIT_ON; } if (curr_split != split) { cmd[3] = SUBCMD_SPLIT; cmd[4] = CMD_MULTICMD; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send split command: status %d\n", __func__, retval); return retval; } } /* now set the rx vfo if needed */ if (curr_vfo != future_vfo) { cmd[3] = vfo2rig(rig, future_vfo); cmd[4] = CMD_VFOMR; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send set vfo command: status %d\n", __func__, retval); return retval; } } /* Make sure clarifier is off */ if (priv->update_data[STATUS_FLAGS] & STATUS_MASK_CLAR) { cmd[3] = SUBCMD_CLAR; cmd[4] = CMD_MULTICMD; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send set clar command: status %d\n", __func__, retval); return retval; } } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } break; default: return -RIG_EINVAL; } return RIG_OK; } int ft767_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE( rig)->priv; int retval; vfo_t curr_vfo; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } /* TODO if SPLIT is enabled, return which VFO is the transmit VFO!! */ if (priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT) { *split = RIG_SPLIT_ON; } else { *split = RIG_SPLIT_OFF; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); switch (curr_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; default: /* we don't know how to deal with MEM, anything else is an error */ /* TODO make sure this is what we want to do here */ rig_debug(RIG_DEBUG_ERR, "%s: current vfo is %s with split\n", __func__, rig_strvfo(curr_vfo)); return -RIG_EINVAL; break; } return RIG_OK; } /* End of hamlib API-mapped functions */ /* * This function puts the radio in CAT mode */ int ft767_enter_CAT(RIG *rig) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_CAT_SW}; rig_debug(RIG_DEBUG_TRACE, "%s: Entered\n", __func__); return ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); } /* * This function takes the radio out of CAT mode */ int ft767_leave_CAT(RIG *rig) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, CMD_CAT_SW}; rig_debug(RIG_DEBUG_TRACE, "%s: Entered\n", __func__); return ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); } /* * The Yaesu interface is convoluted and braindead. * * Private helper function. The 767GX has a handshaking system that works like this: * * 5 byte command block sent to rig * (5 to 20 mS delay) * Rig echos 5 byte command block back * Send a 5 byte ACK block to the rig * (5 to 20 mS delay) * * Rig sends back a status update block (5-86 bytes) * The status update block is received in reverse byte order from the way it's structured * * In addition, You must send a command to enable CAT mode, and disable when done. * When in CAT mode, the front panel of the radio is locked out. * * There is an error in the manual, the response length for a TONE SET command * is 26 bytes, not 5. */ int ft767_send_block_and_ack(RIG *rig, unsigned char *cmd, size_t length) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); size_t replylen, cpycnt; unsigned char cmd_echo_buf[5]; int retval; unsigned char *src, *dst; /* Validate command and set length of data returned */ switch (cmd[4]) { case CMD_CHECK: case CMD_CAT_SW: replylen = 86; break; case CMD_UP10HZ: case CMD_DN10HZ: case CMD_PROG_UP: case CMD_PROG_DN: case CMD_BAND_UP: case CMD_BAND_DN: case CMD_FREQ_SET: case CMD_VFOMR: case CMD_ACK: replylen = 5; break; case CMD_TONE_SET: replylen = 26; /* the manual is wrong */ break; case CMD_MULTICMD: if (cmd[3] <= 0x15) { replylen = 8; } else { switch (cmd[3]) { case SUBCMD_HG_HAM: case SUBCMD_HG_GEN: case SUBCMD_SPLIT: case SUBCMD_CLAR: case SUBCMD_MTOV: replylen = 26; break; case SUBCMD_VTOM: replylen = 68; break; case SUBCMD_SWAP: case SUBCMD_ACLR: replylen = 5; break; default: /* invalid or unknown sub-command */ rig_debug(RIG_DEBUG_ERR, "%s: invalid sub-command 0x%x for command 0x%x\n", __func__, cmd[3], cmd[4]); return -RIG_EINVAL; } } break; default: /* invalid or unknown command */ rig_debug(RIG_DEBUG_ERR, "%s: invalid command 0x%x\n", __func__, cmd[4]); return -RIG_EINVAL; } /* send the command block */ write_block(rp, cmd, YAESU_CMD_LENGTH); /* read back the command block echo */ retval = read_block(rp, cmd_echo_buf, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_block failed: %s\n", __func__, rigerror(retval)); return retval; } /* see if it matches the command we sent */ if (memcmp(cmd_echo_buf, cmd, YAESU_CMD_LENGTH)) { rig_debug(RIG_DEBUG_ERR, "%s: Command echo doesn't match\n", __func__); return -RIG_EINVAL; } /* send the ACK */ write_block(rp, priv->ack_cmd, YAESU_CMD_LENGTH); /* read back the response (status bytes) */ retval = read_block(rp, priv->rx_data, replylen); // update data if (retval != replylen) { rig_debug(RIG_DEBUG_ERR, "%s: Got unexpected number of bytes %d in response\n", __func__, retval); return -RIG_EINVAL; } /* reverse the data buffer returned from the rig */ src = &priv->rx_data[0]; dst = &priv->update_data[replylen - 1]; cpycnt = replylen; while (cpycnt--) { *dst-- = *src++; } return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * * need to use this when doing ft767_get_* stuff */ int ft767_get_update_data(RIG *rig) { /* unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, CMD_CHECK}; */ struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; rig_flush(RIGPORT(rig)); /* Entering CAT updates our data structures */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: status = 0x%02x\n", __func__, priv->update_data[STATUS_FLAGS]); return RIG_OK; } int ft767_set_split(RIG *rig, unsigned int split) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int curr_split; rig_flush(RIGPORT(rig)); /* Entering CAT updates our data structures */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* See whether we need to toggle */ curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s called curr_split = %u, split = %u\n", __func__, curr_split, split); if (curr_split ^ split) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, SUBCMD_SPLIT, CMD_MULTICMD}; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } return RIG_OK; } unsigned char vfo2rig(RIG *rig, vfo_t vfo) { switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: return 0x00; break; case RIG_VFO_B: return 0x01; break; case RIG_VFO_MEM: return 0x02; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } } vfo_t rig2vfo(unsigned char status) { if (status & 0x20) { return RIG_VFO_MEM; } else if (status & 0x10) { return RIG_VFO_B; } else { return RIG_VFO_A; } } int mode2rig(RIG *rig, rmode_t mode) { int md; /* * translate mode from generic to ft767 specific */ switch (mode) { case RIG_MODE_LSB: md = SUBCMD_MODE_LSB; break; case RIG_MODE_USB: md = SUBCMD_MODE_USB; break; case RIG_MODE_CW: md = SUBCMD_MODE_CW; break; case RIG_MODE_AM: md = SUBCMD_MODE_AM; break; case RIG_MODE_FM: md = SUBCMD_MODE_FM; break; case RIG_MODE_PKTFM: md = SUBCMD_MODE_FSK; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { /* * translate mode from ft767 specific to generic */ switch (md & 0x07) { case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_CW: *mode = RIG_MODE_CW; break; case MODE_AM: *mode = RIG_MODE_AM; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_FSK: *mode = RIG_MODE_PKTFM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return RIG_OK; } int rig2ctcss(RIG *rig, unsigned char tn, tone_t *tone) { /* * translate tone from ft767 specific to generic */ switch (tn) { #ifdef USE_YAESU_PUBLISHED_TONES /* Yaesu documentation */ case 0x3E: *tone = 670; break; case 0x1D: *tone = 670; break; /* High Q */ case 0x3D: *tone = 719; break; case 0x1C: *tone = 719; break; /* High Q */ case 0x1B: *tone = 747; break; /* High Q */ case 0x3C: *tone = 770; break; case 0x1A: *tone = 770; break; /* High Q */ case 0x19: *tone = 797; break; /* High Q */ case 0x3B: *tone = 825; break; case 0x18: *tone = 825; break; /* High Q */ case 0x17: *tone = 854; break; /* High Q */ case 0x3A: *tone = 885; break; case 0x16: *tone = 885; break; /* High Q */ case 0x15: *tone = 915; break; /* High Q */ case 0x39: *tone = 948; break; case 0x38: *tone = 1000; break; case 0x37: *tone = 1035; break; case 0x36: *tone = 1072; break; case 0x35: *tone = 1109; break; case 0x34: *tone = 1148; break; case 0x33: *tone = 1188; break; case 0x32: *tone = 1230; break; case 0x31: *tone = 1273; break; case 0x30: *tone = 1318; break; case 0x2F: *tone = 1365; break; case 0x2E: *tone = 1413; break; case 0x2D: *tone = 1462; break; case 0x2C: *tone = 1514; break; case 0x2B: *tone = 1567; break; case 0x2A: *tone = 1622; break; case 0x29: *tone = 1679; break; case 0x28: *tone = 1738; break; case 0x27: *tone = 1799; break; case 0x26: *tone = 1862; break; case 0x25: *tone = 1928; break; case 0x24: *tone = 2035; break; case 0x23: *tone = 2107; break; case 0x22: *tone = 2181; break; case 0x21: *tone = 2257; break; case 0x20: *tone = 2336; break; case 0x1F: *tone = 2418; break; case 0x1E: *tone = 2503; break; #else /* values found by experimentation */ case 0: *tone = 670; break; case 33: *tone = 670; break; /* High Q */ case 01: *tone = 719; break; case 34: *tone = 719; break; /* High Q */ case 35: *tone = 747; break; /* High Q */ case 2: *tone = 770; break; case 36: *tone = 770; break; /* High Q */ case 37: *tone = 797; break; /* High Q */ case 3: *tone = 825; break; case 38: *tone = 825; break; /* High Q */ case 39: *tone = 854; break; /* High Q */ case 4: *tone = 885; break; case 40: *tone = 885; break; /* High Q */ case 41: *tone = 915; break; /* High Q */ case 5: *tone = 948; break; case 6: *tone = 1000; break; case 7: *tone = 1035; break; case 8: *tone = 1072; break; case 9: *tone = 1109; break; case 10: *tone = 1148; break; case 11: *tone = 1188; break; case 12: *tone = 1230; break; case 13: *tone = 1273; break; case 14: *tone = 1318; break; case 15: *tone = 1365; break; case 16: *tone = 1413; break; case 17: *tone = 1462; break; case 18: *tone = 1514; break; case 19: *tone = 1567; break; case 20: *tone = 1622; break; case 21: *tone = 1679; break; case 22: *tone = 1738; break; case 23: *tone = 1799; break; case 24: *tone = 1862; break; case 25: *tone = 1928; break; case 26: *tone = 2035; break; case 27: *tone = 2107; break; case 28: *tone = 2181; break; case 29: *tone = 2257; break; case 30: *tone = 2336; break; case 31: *tone = 2418; break; case 32: *tone = 2503; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid tone value from rig: 0x%02x\n", __func__, tn); return -RIG_EINVAL; /* sorry, wrong TONE */ break; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft710.c0000664000175000017500000002663015056640443011562 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft710.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2023 * * This shared library provides an API for communicating * via serial interface to an FT-710 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ft710.h" const struct newcat_priv_caps ft710_priv_caps = { .roofing_filter_count = 0, .roofing_filters = {} }; const struct confparams ft710_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft710_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ft710_caps = { RIG_MODEL(RIG_MODEL_FT710), .model_name = "FT-710", .mfg_name = "Yaesu", .version = NEWCAT_VER ".7", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 3, .has_get_func = FT710_FUNCS, .has_set_func = FT710_FUNCS, .has_get_level = FT710_LEVELS, .has_set_level = RIG_LEVEL_SET(FT710_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT710_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the FT-710 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT710_RFPOWER_METER_CAL, .swr_cal = FT710_SWR_CAL, .str_cal = FT710_STR_CAL, .id_meter_cal = FT710_ID_CAL, .vd_meter_cal = FT710_VD_CAL, .comp_meter_cal = FT710_COMP_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FT710_ALL_RX_MODES, -1, -1, FT710_VFO_ALL, FT710_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_HF(1, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_6m(1, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FT710_ALL_RX_MODES, -1, -1, FT710_VFO_ALL, FT710_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_HF(2, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_6m(2, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_4m_REGION2(FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT710_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT710_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT710_AM_RX_MODES, Hz(100)}, /* Normal */ {FT710_AM_RX_MODES, kHz(1)}, /* Fast */ {FT710_FM_RX_MODES, Hz(100)}, /* Normal */ {FT710_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FT710_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FT710_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ft710_ext_tokens, .extlevels = ft710_ext_levels, .priv = &ft710_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_clarifier_frequency, .get_rit = newcat_get_clarifier_frequency, .set_xit = newcat_set_clarifier_frequency, .get_xit = newcat_get_clarifier_frequency, .set_ant = NULL, .get_ant = NULL, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft1000d.c0000664000175000017500000034760215056640443012004 /* * hamlib - (C) Stephane Fillod 2002-2009 (fillods at users.sourceforge.net) * * ft1000d.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * (C) 2016 Sean Sharkey (g0oan at icloud.com) * * This shared library provides an API for communicating * via serial interface to an FT-1000D using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Code separated out from ft990.c and ft990.h in December 2016. Added several * extra functions to expand level of support for the FT1000/D. Sean G0OAN. * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft1000d.h" // FT1000D native commands enum FT1000D_native_cmd_e { FT1000D_NATIVE_SPLIT_OFF = 0, FT1000D_NATIVE_SPLIT_ON, FT1000D_NATIVE_RECALL_MEM, FT1000D_NATIVE_VFO_TO_MEM, FT1000D_NATIVE_LOCK_OFF, FT1000D_NATIVE_LOCK_ON, FT1000D_NATIVE_VFO_A, FT1000D_NATIVE_VFO_B, FT1000D_NATIVE_MEM_TO_VFO, FT1000D_NATIVE_VFO_STEP_UP, FT1000D_NATIVE_VFO_STEP_UP_FAST, FT1000D_NATIVE_VFO_STEP_DOWN, FT1000D_NATIVE_VFO_STEP_DOWN_FAST, FT1000D_NATIVE_RX_CLARIFIER_OFF, FT1000D_NATIVE_RX_CLARIFIER_ON, FT1000D_NATIVE_TX_CLARIFIER_OFF, FT1000D_NATIVE_TX_CLARIFIER_ON, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET, FT1000D_NATIVE_CLARIFIER_OPS, FT1000D_NATIVE_FREQ_SET, FT1000D_NATIVE_MODE_SET_LSB, FT1000D_NATIVE_MODE_SET_USB, FT1000D_NATIVE_MODE_SET_CW_W, FT1000D_NATIVE_MODE_SET_CW_N, FT1000D_NATIVE_MODE_SET_AM_W, FT1000D_NATIVE_MODE_SET_AM_N, FT1000D_NATIVE_MODE_SET_FM, FT1000D_NATIVE_MODE_SET_RTTY_LSB, FT1000D_NATIVE_MODE_SET_RTTY_USB, FT1000D_NATIVE_MODE_SET_PKT_LSB, FT1000D_NATIVE_MODE_SET_PKT_FM, FT1000D_NATIVE_MODE_SUB_VFOB_SET_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_USB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_W, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_N, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_USB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM, /* Added December 2016 */ FT1000D_NATIVE_PACING, FT1000D_NATIVE_PTT_OFF, FT1000D_NATIVE_PTT_ON, FT1000D_NATIVE_UPDATE_ALL_DATA, FT1000D_NATIVE_UPDATE_MEM_CHNL, FT1000D_NATIVE_UPDATE_OP_DATA, FT1000D_NATIVE_UPDATE_VFO_DATA, FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA, FT1000D_NATIVE_TUNER_OFF, FT1000D_NATIVE_TUNER_ON, FT1000D_NATIVE_TUNER_START, FT1000D_NATIVE_RPTR_SHIFT_NONE, FT1000D_NATIVE_RPTR_SHIFT_MINUS, FT1000D_NATIVE_RPTR_SHIFT_PLUS, FT1000D_NATIVE_VFO_TO_VFO, FT1000D_NATIVE_SET_SUB_VFO_FREQ, FT1000D_NATIVE_BANDWIDTH, FT1000D_NATIVE_OP_FREQ_STEP_UP, FT1000D_NATIVE_OP_FREQ_STEP_DOWN, FT1000D_NATIVE_READ_METER, FT1000D_NATIVE_DIM_LEVEL, FT1000D_NATIVE_RPTR_OFFSET, FT1000D_NATIVE_READ_FLAGS, FT1000D_NATIVE_SIZE }; static int ft1000d_init(RIG *rig); static int ft1000d_cleanup(RIG *rig); static int ft1000d_open(RIG *rig); static int ft1000d_close(RIG *rig); static int ft1000d_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft1000d_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000d_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft1000d_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft1000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft1000d_set_vfo(RIG *rig, vfo_t vfo); static int ft1000d_get_vfo(RIG *rig, vfo_t *vfo); static int ft1000_get_vfo(RIG *rig, vfo_t *vfo); static int ft1000d_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft1000d_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft1000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft1000d_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft1000d_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft1000d_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft1000d_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); /* Added December 2016 */ static int ft1000d_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); /* Added December 2016 */ static int ft1000d_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft1000d_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft1000d_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); /* Added December 2016 */ static int ft1000d_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); /* Added December 2016 */ static int ft1000d_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000d_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft1000d_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft1000d_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft1000d_set_parm(RIG *rig, setting_t parm, value_t val); static int ft1000d_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft1000d_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft1000d_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value); static int ft1000d_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft1000d_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft1000d_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft1000d_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft1000d_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft1000d_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft1000d_send_static_cmd(RIG *rig, unsigned char ci); static int ft1000d_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft1000d_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft1000d_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* OP Mode Set PKT FM */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x0c } }, /* Sub VFOB OP Mode Set LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x0c } }, /* Sub VFOB OP Mode Set USB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x0c } }, /* Sub VFOB OP Mode Set CW 2.4KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x83, 0x0c } }, /* Sub VFOB OP Mode Set CW 500Hz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x84, 0x0c } }, /* Sub VFOB OP Mode Set AM 6KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x85, 0x0c } }, /* Sub VFOB OP Mode Set AM 2.4KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x86, 0x0c } }, /* Sub VFOB OP Mode Set FM Added December 2016*/ { 1, { 0x00, 0x00, 0x00, 0x88, 0x0c } }, /* Sub VFOB OP Mode Set RTTY LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x89, 0x0c } }, /* Sub VFOB OP Mode Set RTTY USB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x8a, 0x0c } }, /* Sub VFOB OP Mode Set PKT LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x8b, 0x0c } }, /* Sub VFOB OP Mode Set PKT FM Added December 2016 */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* Update All Data (1636 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Update Memory Ch Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8A } }, /* Set Sub VFO Frequency Added December 2016 */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct ft1000d_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ vfo_t split_vfo; /* TX VFO in split mode Added on 16 Dec 2016 to include FT1000D function */ split_t split; /* split active or not Added on 16 Dec 2016 to include FT1000D function */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft1000d_update_data_t update_data; /* returned data */ }; /* * FT1000D rigs capabilities. */ #define FT1000D_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } struct rig_caps ft1000d_caps = { RIG_MODEL(RIG_MODEL_FT1000D), .model_name = "FT-1000D", .mfg_name = "Yaesu", .version = "20240228.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000D_WRITE_DELAY, .post_write_delay = FT1000D_POST_WRITE_DELAY, .timeout = 500, .retry = 2, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT1000D_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(1, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(2, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT1000D_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT1000D_AM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_AM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_FM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_FM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft1000d_init, .rig_cleanup = ft1000d_cleanup, .rig_open = ft1000d_open, /* port opened */ .rig_close = ft1000d_close, /* port closed */ .set_freq = ft1000d_set_freq, .get_freq = ft1000d_get_freq, .set_mode = ft1000d_set_mode, .get_mode = ft1000d_get_mode, .set_vfo = ft1000d_set_vfo, .get_vfo = ft1000d_get_vfo, .set_ptt = ft1000d_set_ptt, .get_ptt = ft1000d_get_ptt, .set_rptr_shift = ft1000d_set_rptr_shift, .get_rptr_shift = ft1000d_get_rptr_shift, .set_rptr_offs = ft1000d_set_rptr_offs, .set_split_freq = ft1000d_set_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ .get_split_freq = ft1000d_get_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ .set_split_mode = ft1000d_set_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ .get_split_mode = ft1000d_get_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ .set_split_vfo = ft1000d_set_split_vfo, /* Changed in December 2016 so that vfos toggle back and forth like pressing Split button on rig */ .get_split_vfo = ft1000d_get_split_vfo, .set_rit = ft1000d_set_rit, .get_rit = ft1000d_get_rit, .set_xit = ft1000d_set_xit, .get_xit = ft1000d_get_xit, .set_func = ft1000d_set_func, .get_func = ft1000d_get_func, .set_parm = ft1000d_set_parm, .get_level = ft1000d_get_level, .set_mem = ft1000d_set_mem, .get_mem = ft1000d_get_mem, .vfo_op = ft1000d_vfo_op, .set_channel = ft1000d_set_channel, .get_channel = ft1000d_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft1000_caps = { RIG_MODEL(RIG_MODEL_FT1000), .model_name = "FT-1000", .mfg_name = "Yaesu", .version = "20231124.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000D_WRITE_DELAY, .post_write_delay = FT1000D_POST_WRITE_DELAY, .timeout = 500, .retry = 2, // .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, // .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, // .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, // .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, // .has_set_parm = RIG_PARM_BACKLIGHT, // .level_gran = // { //#include "level_gran_yaesu.h" // }, // .parm_gran = { // [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, // }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), // .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | // RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, // .chan_list = { // {1, 90, RIG_MTYPE_MEM, FT1000D_MEM_CAP}, // RIG_CHAN_END, // }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(1, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(2, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT1000D_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT1000D_AM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_AM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_FM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_FM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft1000d_init, .rig_cleanup = ft1000d_cleanup, .rig_open = ft1000d_open, /* port opened */ .rig_close = ft1000d_close, /* port closed */ .set_freq = ft1000d_set_freq, .get_freq = ft1000_get_freq, .set_mode = ft1000d_set_mode, .get_mode = ft1000_get_mode, .set_vfo = ft1000d_set_vfo, .get_vfo = ft1000_get_vfo, .set_ptt = ft1000d_set_ptt, .get_ptt = ft1000_get_ptt, // .set_rptr_shift = ft1000d_set_rptr_shift, // .get_rptr_shift = ft1000d_get_rptr_shift, // .set_rptr_offs = ft1000d_set_rptr_offs, // .set_split_freq = ft1000d_set_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ // .get_split_freq = ft1000d_get_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ // .set_split_mode = ft1000d_set_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ // .get_split_mode = ft1000d_get_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ // .set_split_vfo = ft1000d_set_split_vfo, /* Changed in December 2016 so that vfos toggle back and forth like pressing Split button on rig */ // .get_split_vfo = ft1000d_get_split_vfo, // .set_rit = ft1000d_set_rit, // .get_rit = ft1000d_get_rit, // .set_xit = ft1000d_set_xit, // .get_xit = ft1000d_get_xit, // .set_func = ft1000d_set_func, // .get_func = ft1000d_get_func, // .set_parm = ft1000d_set_parm, // .get_level = ft1000d_get_level, // .set_mem = ft1000d_set_mem, // .get_mem = ft1000d_get_mem, // .vfo_op = ft1000d_vfo_op, // .set_channel = ft1000d_set_channel, // .get_channel = ft1000d_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ static int ft1000d_init(RIG *rig) { struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft1000d_priv_data *) calloc(1, sizeof(struct ft1000d_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT1000D_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO changed from RIG_VFO_MAIN to RIG_VFO_A December 2016 priv->current_vfo = RIG_VFO_A; return RIG_OK; } /* * rig_cleanup */ static int ft1000d_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ static int ft1000d_open(RIG *rig) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status if (rig->caps->rig_model != RIG_MODEL_FT1000) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_close */ static int ft1000d_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft1000d_send_dial_freq(rig, FT1000D_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft1000d_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update data structure to obtain get frequency err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft1000d_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT1000D_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT1000D_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ static int ft1000d_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT1000D_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ static int ft1000d_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft1000d_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT1000D_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT1000D_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT1000D_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT1000D_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ static int ft1000d_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft1000d_priv_data *priv; ft1000d_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT1000D_MODE_FM) { *rptr_shift = (p->status & FT1000D_RPT_MASK) >> 2; } else { rig_debug(RIG_DEBUG_TRACE, "%s: Rig not in FM mode = 0x%02x\n", __func__, *rptr_shift); } return -RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ static int ft1000d_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT1000D_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT1000D_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ static int ft1000d_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft1000d_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT1000D_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT1000D_NATIVE_SPLIT_OFF; /* added below line to force VFOA in simplex operation */ // priv->current_vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) /* ; */ { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ static int ft1000d_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Read status flags err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT1000D_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Added in December 2016 to ensure get split vfo only works if Spilt function is active. // FT1000D_SF_VFOB which is data bit 4 of flag byte 1 on the FT1000D does not work. Added the code below // to check that the Split function is active on the FT1000D. if (priv->update_data.flag1 & FT1000D_SF_SPLIT) // Added 15 Dec 2016. // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT1000D_SF_SPLIT) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Split not set on rig = 0x%02x\n", __func__, *tx_vfo); } return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ static int ft1000d_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT1000D_CLAR_TX_EN) == 0) { err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft1000d_send_rit_freq(rig, FT1000D_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft1000d_priv_data *priv; unsigned char ci; ft1000d_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT1000D_NATIVE_UPDATE_OP_DATA; p = (ft1000d_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT1000D_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ static int ft1000d_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT1000D_CLAR_RX_EN) == 0) { err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft1000d_send_rit_freq(rig, FT1000D_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft1000d_priv_data *priv; unsigned char ci; ft1000d_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT1000D_NATIVE_UPDATE_OP_DATA; p = (ft1000d_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT1000D_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ static int ft1000d_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT1000D_NATIVE_LOCK_ON; } else { ci = FT1000D_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT1000D_NATIVE_TUNER_ON; } else { ci = FT1000D_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ static int ft1000d_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT1000D_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT1000D_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT1000D_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ static int ft1000d_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft1000d_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT1000D_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT1000D_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT1000D_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT1000D_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT1000D_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT1000D_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT1000D_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT1000D_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT1000D_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT1000D_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT1000D_NATIVE_MODE_SET_AM_N || ci == FT1000D_NATIVE_MODE_SET_AM_W || ci == FT1000D_NATIVE_MODE_SET_FM || ci == FT1000D_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT1000D_BW_F250; } else if (width <= 500) { bw = FT1000D_BW_F500; } else if (width <= 2000) { bw = FT1000D_BW_F2000; } else { bw = FT1000D_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft1000d_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, RIG_VFO_CURR); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: p = &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT1000D_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT1000D_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: *mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: *mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: *mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: *mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (*fl & FT1000D_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (*fl & FT1000D_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT1000D firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT1000D firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT1000D_BW_F2000: *width = 2000; break; case FT1000D_BW_F500: *width = 500; break; case FT1000D_BW_F250: *width = 250; break; case FT1000D_BW_F6000: *width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_vfo(RIG *rig, vfo_t vfo) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO STATE(rig)->priv = 0x%02x\n", __func__, RIG_VFO_CURR); // if (vfo == RIG_VFO_CURR) { if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT1000D_NATIVE_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO VFO A = 0x%02x\n", __func__, RIG_VFO_CURR); break; case RIG_VFO_B: ci = FT1000D_NATIVE_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO VFO B = 0x%02x\n", __func__, RIG_VFO_CURR); break; case RIG_VFO_MEM: ci = FT1000D_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft1000d_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ static int ft1000d_get_vfo(RIG *rig, vfo_t *vfo) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *vfo = RIG_VFO_CURR; if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } if (priv->update_data.flag2 & FT1000D_SF_MEM || priv->update_data.flag2 & FT1000D_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT1000D_SF_VFOB_INUSE) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft1000d_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT1000D_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %sn", __func__, rig_strvfop(op)); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT1000D_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT1000D_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT1000D_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT1000D_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT1000D_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT1000D_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT1000D_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT1000D_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft1000d_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ static int ft1000d_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ static int ft1000d_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ static int ft1000d_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ static int ft1000d_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft1000d_priv_data *priv; ft1000d_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %i\n", __func__, chan->vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft1000d_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft1000d_op_data_t *) &priv->update_data.vfoa; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft1000d_op_data_t *) &priv->update_data.vfob; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft1000d_op_data_t *) &priv->update_data.current_front; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft1000d_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft1000d_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT1000D_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT1000D_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(p->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT1000D firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT1000D firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT1000D_BW_F2000: chan->width = 2000; break; case FT1000D_BW_F500: chan->width = 500; break; case FT1000D_BW_F250: chan->width = 250; break; case FT1000D_BW_F6000: chan->width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT1000D_SF_SPLIT); if (priv->update_data.flag1 & FT1000D_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT1000D_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT1000D_SF_ANT_TUNER_ACTIVE) { if (chan->mode & (FT1000D_AM_RX_MODES | FT1000D_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT1000D_AM_RX_MODES | FT1000D_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT1000D_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft1000d_op_data_t *) &priv->update_data.current_rear; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { p = (ft1000d_op_data_t *) &priv->update_data.vfob; } chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT1000D_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT1000D firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT1000D firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT1000D_BW_F2000: chan->tx_width = 2000; break; case FT1000D_BW_F500: chan->tx_width = 500; break; case FT1000D_BW_F250: chan->tx_width = 250; break; case FT1000D_BW_F6000: chan->tx_width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } /* For now commented this out to better understand what's going on */ if (priv->update_data.flag1 & FT1000D_SF_DUAL) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT1000D_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT1000D_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT1000D_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing FT1000D_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { hamlib_port_t *rp = RIGPORT(rig); struct ft1000d_priv_data *priv; int n; int err; int rl; int retry; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; retry = rp->retry; do { if (ci == FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { err = ft1000d_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); } else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } switch (ci) { case FT1000D_NATIVE_UPDATE_ALL_DATA: p = (unsigned char *) &priv->update_data; rl = FT1000D_ALL_DATA_LENGTH; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { return RIG_OK; } break; case FT1000D_NATIVE_UPDATE_MEM_CHNL: p = (unsigned char *) &priv->update_data.channelnumber; rl = FT1000D_MEM_CHNL_LENGTH; break; case FT1000D_NATIVE_UPDATE_OP_DATA: p = (unsigned char *) &priv->update_data.current_front; rl = FT1000D_OP_DATA_LENGTH; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { rl = FT1000D_OP_DATA_LENGTH; } break; case FT1000D_NATIVE_UPDATE_VFO_DATA: p = (unsigned char *) &priv->update_data.vfoa; rl = FT1000D_VFO_DATA_LENGTH; break; case FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA: p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT1000D_MEM_CHNL_DATA_LENGTH; break; case FT1000D_NATIVE_READ_FLAGS: p = temp; rl = FT1000D_STATUS_FLAGS_LENGTH; break; default: return -RIG_EINVAL; } n = read_block(rp, p, rl); } while (n < 0 && retry-- >= 0); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); if (ci == FT1000D_NATIVE_READ_FLAGS) { memcpy(&priv->update_data, p, FT1000D_STATUS_FLAGS_LENGTH - 2); } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_static_cmd(RIG *rig, unsigned char ci) { int err; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: ci = 0x%02x\n", __func__, ci); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(rp, ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT1000D_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT1000D_BCD_DIAL) * 10); err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT1000D_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT1000D_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT1000D_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT1000D_BCD_RIT); err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* COMMANDS ADDED IN DECEMBER 2016 TO INCLUDE EXTRA FUNCTIONS OF THE FT1000D */ /* rig_set_split_freq* * * Set the FT1000D split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_freq | input | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: The FT1000D is capable of setting the Sub VFO's frequency * regardless of whether or not the rig is in Split or Dual mode. * */ static int ft1000d_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int err; // struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, tx_freq); err = rig_set_split_vfo(rig, vfo, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } // priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_send_dial_freq(rig, FT1000D_NATIVE_SET_SUB_VFO_FREQ, tx_freq); if (err != RIG_OK) { return err; } // Get current rig settings and status err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_freq* * * Get the 'FT1000D split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_freq | output | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the FT1000D is in split mode, if so it * checks which VFO is set for TX and then gets the * frequency of that VFO and stores it into *tx_freq. * If not in split mode returns 0 Hz. * */ static int ft1000d_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; err = ft1000d_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* FT1000D is in split mode */ err = ft1000d_get_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: *tx_freq = 0; break; } return RIG_OK; } /* * rig_set_split_mode * * Set the FT1000D split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Sends mode commands directly to Sub VFOB whether or not radio is in * Split or Dual modes. * */ static int ft1000d_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int err; unsigned char bw; unsigned char ci; // struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); // priv = (struct ft1000d_priv_data *)STATE(rig)->priv; switch (tx_mode) { case RIG_MODE_AM: if (tx_width == rig_passband_narrow(rig, tx_mode)) { ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N; } else if (tx_width == rig_passband_normal(rig, tx_mode)) { ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_W; break; case RIG_MODE_USB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_USB; break; case RIG_MODE_LSB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_LSB; break; case RIG_MODE_RTTY: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: ci = 0x%02x\n", __func__, ci); err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM) { return RIG_OK; } if (tx_width <= 250) { bw = FT1000D_BW_F250; } else if (tx_width <= 500) { bw = FT1000D_BW_F500; } else if (tx_width <= 2000) { bw = FT1000D_BW_F2000; } else { bw = FT1000D_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_mode* * * Get the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft1000d_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* FT1000D is in split mode */ err = ft1000d_get_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: *tx_mode = RIG_MODE_NONE; *tx_width = 0; break; } return RIG_OK; } static int ft1000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_A) { *freq = CACHE(rig)->freqMainA; } else { *freq = CACHE(rig)->freqMainB; } return RIG_OK; } static int ft1000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { if (vfo == RIG_VFO_A) { *mode = CACHE(rig)->modeMainA; } else { *mode = CACHE(rig)->modeMainB; } return RIG_OK; } static int ft1000_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = STATE(rig)->current_vfo; return RIG_OK; } static int ft1000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { *ptt = CACHE(rig)->ptt; return RIG_OK; } hamlib-4.6.5/rigs/yaesu/Android.mk0000664000175000017500000000112015056640443012451 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ft100.c ft747.c ft817.c ft847.c ft890.c ft900.c ft920.c \ ft1000mp.c ft857.c ft897.c ft990.c frg8800.c \ ft757gx.c ft736.c frg100.c frg9600.c ft1000d.c \ vr5000.c ft767gx.c ft840.c ft980.c vx1700.c \ newcat.c ft450.c ft950.c ft2000.c ft9000.c ft5000.c \ ft1200.c ft991.c ft600.c ft3000.c ftdx101.c ftdx101mp.c \ ft891.c ftdx10.c \ yaesu.c LOCAL_MODULE := yaesu LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/yaesu/ft900.h0000664000175000017500000000676315056640443011575 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft900.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-900 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT900_H #define _FT900_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT900_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT900_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT900_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT900_AM_RX_MODES (RIG_MODE_AM) #define FT900_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT900_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT900_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT900_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT900_ANTS 0 /* Returned data length in bytes */ #define FT900_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT900_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT900_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT900_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT900_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT900_ALL_DATA_LENGTH 1941 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT900_PACING_INTERVAL 5 #define FT900_PACING_DEFAULT_VALUE 0 #define FT900_WRITE_DELAY 5 /* Delay sequential fast writes */ #define FT900_POST_WRITE_DELAY 50 /* Rough safe value for default timeout */ #define FT900_DEFAULT_READ_TIMEOUT 1941 * ( 5 + (FT900_PACING_INTERVAL * FT900_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT900_BCD_DIAL 8 #define FT900_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 1941 bytes in 4448 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 1941 bytes * ------------ ---------------------- * * 0 4448 msec (backend default) * 1 6389 msec * 2 8330 msec * 5 14153 msec * 255 499.4 sec * */ #endif /* _FT900_H */ hamlib-4.6.5/rigs/yaesu/ft950.h0000664000175000017500000001155715056640443011577 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft950.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT950_H #define _FT950_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT950_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT950_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FT950_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT950_AM_RX_MODES (RIG_MODE_AM) #define FT950_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT950_FM_RX_MODES (FT950_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT950_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT950_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB) /* 100 W class */ #define FT950_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT950_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_BAND_SELECT) #define FT950_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER) #define FT950_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT950_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT950_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT950_ANTS (RIG_ANT_1|RIG_ANT_2) #define FT950_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT950_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT950_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT950_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT950_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT950_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT950_PACING_INTERVAL 5 // #define FT950_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-950 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT950_WRITE_DELAY 0 /* Delay sequential fast writes */ //#define FT950_POST_WRITE_DELAY 5 #define FT950_POST_WRITE_DELAY 50 #endif /* _FT950_H */ hamlib-4.6.5/rigs/yaesu/newcat.h0000664000175000017500000002273215056640443012206 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * and the Hamlib Group (hamlib-developer at lists.sourceforge.net) * * newcat.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Terry Embry 2008-2010 * * This shared library provides the backend API for communicating * via serial interface to any Yaesu radio using the new "CAT" * interface commands that are similar to the Kenwood command set. * * Models this code aims to support are FTDX-9000*, FT-2000, * FT-950, FT-450. Much testing remains. -N0NB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _NEWCAT_H #define _NEWCAT_H 1 #include #include /* Handy constants */ #ifndef TRUE #define TRUE 1 #endif #define ON TRUE #ifndef FALSE #define FALSE 0 #endif #define OFF FALSE typedef char ncboolean; /* shared function version */ #define NEWCAT_VER "20241118" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 /* arbitrary value for now. 11 bits (8N2+1) == 2.2917 mS @ 4800 bps */ #define NEWCAT_DEFAULT_READ_TIMEOUT (NEWCAT_DATA_LEN * 5) #define NEWCAT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1,\ .ctcss_sql = 1,\ } #define YAESU_DEFAULT_VD_METER_200W_CAL \ { \ 3, \ { \ {0, 0.0f}, \ {196, 50.0f}, \ {255, 65.0f}, \ } \ } extern const struct confparams newcat_cfg_params[]; /* * Private caps for newcat rigs */ #define NEWCAT_ROOFING_FILTER_COUNT 12 struct newcat_roofing_filter { /* Index of the roofing filter in the ext level combo */ int index; /* Value to set the selected roofing filter, must be 0 for a get-only choice */ char set_value; /* Value returned by the rig for this roofing filter, must be 0 for a set-only choice */ char get_value; /* Width of the filter in Hz */ int width; /* 0 = Always available, 1 = Optional filter */ int optional; }; struct newcat_priv_caps { int roofing_filter_count; struct newcat_roofing_filter roofing_filters[NEWCAT_ROOFING_FILTER_COUNT]; }; /* * Private state for newcat rigs */ struct newcat_priv_data { char cmd_str[NEWCAT_DATA_LEN]; /* command string buffer */ char ret_data[NEWCAT_DATA_LEN]; /* returned data--max value, most are less */ int current_mem; /* private memory channel number */ int rig_id; /* rig id from CAT Command ID; */ int trn_state; /* AI state found at startup */ int fast_set_commands; /* do not check for ACK/NAK; needed for high throughput > 100 commands/s */ int width_frequency; /* found at startup */ struct timespec cache_start; char last_if_response[NEWCAT_DATA_LEN]; int poweron; /* to prevent powering on more than once */ int question_mark_response_means_rejected; /* the question mark response has multiple meanings */ char front_rear_status; /* e.g. FTDX5000 EX103 status */ int split_st_command_missing; /* is ST command gone? assume not until proven otherwise */ int band_index; }; /* * Functions considered to be Stable: * * Functions considered to be Beta: * * Functions considered to be Alpha: * newcat_set_freq * newcat_get_freq * newcat_set_vfo * newcat_get_vfo * newcat_get_rit * newcat_set_rit * newcat_get_xit * newcat_set_xit * power2mW * mW2power * newcat_get_ant * newcat_set_ant * newcat_get_ptt * Functions not yet implemented * most everything at this time. * * At this time, CAT documentation for the FT-450 can be obtained from * the Yaesu website at: http://www.yaesu.com/downloadFile.cfm?FileID=2600&FileCatID=158&FileName=FT%2D450%5FCAT%5FOperation%5FReference%5FBook.pdf&FileContentType=application%2Fpdf * */ /* * newcat function definitions. * */ int newcat_get_cmd(RIG *rig); int newcat_set_cmd(RIG *rig); int newcat_init(RIG *rig); int newcat_cleanup(RIG *rig); int newcat_open(RIG *rig); int newcat_close(RIG *rig); int newcat_set_conf(RIG *rig, hamlib_token_t token, const char *val); int newcat_get_conf(RIG *rig, hamlib_token_t token, char *val); int newcat_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); int newcat_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int newcat_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int newcat_set_vfo(RIG *rig, vfo_t vfo); int newcat_get_vfo(RIG *rig, vfo_t *vfo); int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo); int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo); int newcat_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int newcat_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int newcat_get_ptt(RIG * rig, vfo_t vfo, ptt_t * ptt); int newcat_set_ant(RIG * rig, vfo_t vfo, ant_t ant, value_t option); int newcat_get_ant(RIG * rig, vfo_t vfo, ant_t dummy, value_t * option, ant_t * ant_curr, ant_t * ant_tx, ant_t *ant_rx); int newcat_set_level(RIG * rig, vfo_t vfo, setting_t level, value_t val); int newcat_get_level(RIG * rig, vfo_t vfo, setting_t level, value_t * val); int newcat_set_func(RIG * rig, vfo_t vfo, setting_t func, int status); int newcat_get_func(RIG * rig, vfo_t vfo, setting_t func, int *status); int newcat_set_parm(RIG * rig, setting_t parm, value_t val); int newcat_get_parm(RIG * rig, setting_t parm, value_t *val); int newcat_set_mem(RIG * rig, vfo_t vfo, int ch); int newcat_get_mem(RIG * rig, vfo_t vfo, int *ch); int newcat_vfo_op(RIG * rig, vfo_t vfo, vfo_op_t op); const char *newcat_get_info(RIG * rig); int newcat_get_rit(RIG * rig, vfo_t vfo, shortfreq_t * rit); int newcat_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int newcat_get_xit(RIG * rig, vfo_t vfo, shortfreq_t * xit); int newcat_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit); int newcat_get_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t *freq); int newcat_set_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t freq); int newcat_power2mW(RIG * rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); int newcat_mW2power(RIG * rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); int newcat_set_split_vfo(RIG * rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int newcat_get_split_vfo(RIG * rig, vfo_t vfo, split_t * split, vfo_t *tx_vfo); int newcat_set_rptr_shift(RIG * rig, vfo_t vfo, rptr_shift_t rptr_shift); int newcat_get_rptr_shift(RIG * rig, vfo_t vfo, rptr_shift_t * rptr_shift); int newcat_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); int newcat_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs); int newcat_set_ctcss_tone(RIG * rig, vfo_t vfo, tone_t tone); int newcat_get_ctcss_tone(RIG * rig, vfo_t vfo, tone_t * tone); int newcat_set_ctcss_sql(RIG * rig, vfo_t vfo, tone_t tone); int newcat_get_ctcss_sql(RIG * rig, vfo_t vfo, tone_t * tone); int newcat_set_powerstat(RIG * rig, powerstat_t status); int newcat_get_powerstat(RIG * rig, powerstat_t * status); int newcat_set_ts(RIG * rig, vfo_t vfo, shortfreq_t ts); int newcat_get_ts(RIG * rig, vfo_t vfo, shortfreq_t * ts); int newcat_set_trn(RIG * rig, int trn); int newcat_get_trn(RIG * rig, int *trn); int newcat_set_channel(RIG * rig, vfo_t vfo, const channel_t * chan); int newcat_get_channel(RIG * rig, vfo_t vfo, channel_t * chan, int read_only); rmode_t newcat_rmode(char mode); char newcat_modechar(rmode_t rmode); rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width); int newcat_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int newcat_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg); int newcat_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int newcat_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int newcat_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int newcat_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); #define TOKEN_BACKEND(t) (t) #define TOK_ROOFING_FILTER TOKEN_BACKEND(100) #define TOK_KEYER TOKEN_BACKEND(101) #define TOK_APF_FREQ TOKEN_BACKEND(102) #define TOK_APF_WIDTH TOKEN_BACKEND(103) #define TOK_CONTOUR TOKEN_BACKEND(104) #define TOK_CONTOUR_FREQ TOKEN_BACKEND(105) #define TOK_CONTOUR_LEVEL TOKEN_BACKEND(106) #define TOK_CONTOUR_WIDTH TOKEN_BACKEND(107) #define TOK_MAXPOWER_HF TOKEN_BACKEND(108) #define TOK_MAXPOWER_6M TOKEN_BACKEND(109) #define TOK_MAXPOWER_4M TOKEN_BACKEND(110) #define TOK_MAXPOWER_AM TOKEN_BACKEND(111) #define TOK_MAXPOWER_VHF TOKEN_BACKEND(112) #define TOK_MAXPOWER_UHF TOKEN_BACKEND(113) #endif /* _NEWCAT_H */ hamlib-4.6.5/rigs/yaesu/ft990v12.c0000664000175000017500000030637615056640443012135 /* * hamlib - (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * (C) Terry Embry 2009 * * ft990.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* THIS FILE WAS MODIFIED IN DECEMBER 2016 TO REMOVE ANY REFERENCE TO THE FT-1000/D. SEPARATE ft1000d.c and .h FILES * WERE CREATED TO HANDLE FT-1000/D COMMANDS AND PROVIDE THE FULL RANGE OF FUNCTIONS AVAILABLE ON THE FT-1000/D * TO MAXIMISE COMPATIBILITY WITH RIGCTL. * G0OAN */ /* MODIFIED VERSION for FT-990 with ROM v1.2 : June 2022 * The standard version was written for FT-990 with ROM v1.3 and as the CAT spec was different to ROM v1.2 CAT * would not work with the older ROM. This version enables ROM v1.2 to work although it is necessary to accept * that frequent polling functionality is not feasible with this older ROM. With ROM v1.2 polling fetches 1492 * bytes which at 4800 Baud takes about 3.8 seconds during which the FT-990 has a CAT blackout. The longest poll * interval available in WSJT-X is 99 seconds. * Collaboration between M0EZP David Brewerton and K1MMI Edmund Hajjar */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft990v12.h" // FT990 native commands enum ft990v12_native_cmd_e { FT990_NATIVE_SPLIT_OFF = 0, FT990_NATIVE_SPLIT_ON, FT990_NATIVE_RECALL_MEM, FT990_NATIVE_VFO_TO_MEM, FT990_NATIVE_LOCK_OFF, FT990_NATIVE_LOCK_ON, FT990_NATIVE_VFO_A, FT990_NATIVE_VFO_B, FT990_NATIVE_MEM_TO_VFO, FT990_NATIVE_VFO_STEP_UP, FT990_NATIVE_VFO_STEP_UP_FAST, FT990_NATIVE_VFO_STEP_DOWN, FT990_NATIVE_VFO_STEP_DOWN_FAST, FT990_NATIVE_RX_CLARIFIER_OFF, FT990_NATIVE_RX_CLARIFIER_ON, FT990_NATIVE_TX_CLARIFIER_OFF, FT990_NATIVE_TX_CLARIFIER_ON, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET, FT990_NATIVE_CLARIFIER_OPS, FT990_NATIVE_FREQ_SET, FT990_NATIVE_MODE_SET_LSB, FT990_NATIVE_MODE_SET_USB, FT990_NATIVE_MODE_SET_CW_W, FT990_NATIVE_MODE_SET_CW_N, FT990_NATIVE_MODE_SET_AM_W, FT990_NATIVE_MODE_SET_AM_N, FT990_NATIVE_MODE_SET_FM, FT990_NATIVE_MODE_SET_RTTY_LSB, FT990_NATIVE_MODE_SET_RTTY_USB, FT990_NATIVE_MODE_SET_PKT_LSB, FT990_NATIVE_MODE_SET_PKT_FM, FT990_NATIVE_PACING, FT990_NATIVE_PTT_OFF, FT990_NATIVE_PTT_ON, FT990_NATIVE_UPDATE_ALL_DATA, FT990_NATIVE_UPDATE_MEM_CHNL, FT990_NATIVE_UPDATE_OP_DATA, FT990_NATIVE_UPDATE_VFO_DATA, FT990_NATIVE_UPDATE_MEM_CHNL_DATA, FT990_NATIVE_TUNER_OFF, FT990_NATIVE_TUNER_ON, FT990_NATIVE_TUNER_START, FT990_NATIVE_RPTR_SHIFT_NONE, FT990_NATIVE_RPTR_SHIFT_MINUS, FT990_NATIVE_RPTR_SHIFT_PLUS, FT990_NATIVE_VFO_TO_VFO, FT990_NATIVE_BANDWIDTH, FT990_NATIVE_OP_FREQ_STEP_UP, FT990_NATIVE_OP_FREQ_STEP_DOWN, FT990_NATIVE_READ_METER, FT990_NATIVE_DIM_LEVEL, FT990_NATIVE_RPTR_OFFSET, FT990_NATIVE_READ_FLAGS, FT990_NATIVE_SIZE }; /* HAMLIB API implementation */ static int ft990v12_init(RIG *rig); static int ft990v12_cleanup(RIG *rig); static int ft990v12_open(RIG *rig); static int ft990v12_close(RIG *rig); static int ft990v12_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft990v12_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft990v12_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft990v12_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft990v12_set_vfo(RIG *rig, vfo_t vfo); static int ft990v12_get_vfo(RIG *rig, vfo_t *vfo); static int ft990v12_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft990v12_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft990v12_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft990v12_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft990v12_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft990v12_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft990v12_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft990v12_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft990v12_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft990v12_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft990v12_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft990v12_set_parm(RIG *rig, setting_t parm, value_t val); static int ft990v12_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft990v12_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft990v12_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft990v12_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft990v12_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft990v12_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft990v12_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft990v12_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft990v12_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft990v12_send_static_cmd(RIG *rig, unsigned char ci); static int ft990v12_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft990v12_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft990v12_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { /* ci */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 00 00 Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* 01 01 Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* 02 02 Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* 03 03 Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* 04 04 Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* 05 05 Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* 06 06 Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* 07 07 Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* 08 08 Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* 09 09 OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* 10 0a OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* 11 0b OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* 12 0c OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 13 0d RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* 14 0e RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* 15 0f TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* 16 10 TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* 17 11 Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 18 12 Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* 19 13 Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* 20 14 OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* 21 15 OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* 22 16 OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* 23 17 OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* 24 18 OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* 25 19 OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* 26 1a OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* 27 1b OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* 28 1c OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* 29 1d OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* 30 1e OP Mode Set PKT FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* 31 1f Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* 32 20 PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* 33 21 PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* 34 22 Update All Data (1492 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* 35 23 Update Memory Ch Number M0EZP: 2ndByte was 0x01 */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* 36 24 Update Op Data M0EZP: 2ndByte was 0x02 */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* 37 25 Update VFO Data M0EZP: 2ndByte was 0x03 */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* 38 26 Update Memory Ch Data M0EZP: 2ndByte was 0x04 */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* 39 27 Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* 40 28 Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* 41 29 Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* 42 2a Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* 43 2b Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* 44 2c Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* 45 2d Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* 46 2e Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* 47 2f Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* 48 30 Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* 49 31 Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* 50 32 DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* 51 33 Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* 52 34 Read Status Flags */ }; /* * Private data */ // M0EZP: status 0=uni first call, 1=uni after first call int ft990uni_get_freq_state = 0; struct ft990v12_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft990v12_update_data_t update_data; /* returned data */ }; /* * ft990 rigs capabilities. */ #define FT990_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } // Old FT990 ROM has to read all 1492 to get frequency // So for this model we just use the cache to read freq struct rig_caps ft990uni_caps = { RIG_MODEL(RIG_MODEL_FT990UNI), .model_name = "FT-990 Old Rom", .mfg_name = "Yaesu", .version = "20220628.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT990_WRITE_DELAY, .post_write_delay = FT990_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT990_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(1, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(2, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT990_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT990_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT990_AM_RX_MODES, Hz(100)}, /* Normal */ {FT990_AM_RX_MODES, kHz(1)}, /* Fast */ {FT990_FM_RX_MODES, Hz(100)}, /* Normal */ {FT990_FM_RX_MODES, kHz(1)}, /* Fast */ {FT990_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT990_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft990v12_init, .rig_cleanup = ft990v12_cleanup, .rig_open = ft990v12_open, /* port opened */ .rig_close = ft990v12_close, /* port closed */ .set_freq = ft990v12_set_freq, .get_freq = ft990v12_get_freq, .set_mode = ft990v12_set_mode, .get_mode = ft990v12_get_mode, .set_vfo = ft990v12_set_vfo, .get_vfo = ft990v12_get_vfo, .set_ptt = ft990v12_set_ptt, .get_ptt = ft990v12_get_ptt, .set_rptr_shift = ft990v12_set_rptr_shift, .get_rptr_shift = ft990v12_get_rptr_shift, .set_rptr_offs = ft990v12_set_rptr_offs, .set_split_vfo = ft990v12_set_split_vfo, .get_split_vfo = ft990v12_get_split_vfo, .set_rit = ft990v12_set_rit, .get_rit = ft990v12_get_rit, .set_xit = ft990v12_set_xit, .get_xit = ft990v12_get_xit, .set_func = ft990v12_set_func, .get_func = ft990v12_get_func, .set_parm = ft990v12_set_parm, .get_level = ft990v12_get_level, .set_mem = ft990v12_set_mem, .get_mem = ft990v12_get_mem, .vfo_op = ft990v12_vfo_op, .set_channel = ft990v12_set_channel, .get_channel = ft990v12_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ int ft990v12_init(RIG *rig) { struct ft990v12_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft990v12_priv_data *) calloc(1, sizeof(struct ft990v12_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT990_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * rig_cleanup */ int ft990v12_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ int ft990v12_open(RIG *rig) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status // err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); // M0EZP read flags instead of update err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close */ int ft990v12_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft990v12_priv_data *priv; int err; vfo_t vfo_save; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; vfo_save = priv->current_vfo; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != vfo_save) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990v12_send_dial_freq(rig, FT990_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } if (vfo != vfo_save) { err = ft990v12_set_vfo(rig, vfo_save); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft990v12_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: ft990uni_get_freq_state = 0x%02x\n", __func__, ft990uni_get_freq_state); if (ft990uni_get_freq_state < 2) { // M0EZP: UNI first call needs UPDATE_ALL ft990uni_get_freq_state = ft990uni_get_freq_state + 1; if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } ci = FT990_NATIVE_UPDATE_ALL_DATA; /* M0EZP: inserted to override CI */ err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } else { // M0EZP: Uni use cache // *freq = vfo == RIG_VFO_A ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; return (RIG_OK); } } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft990v12_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT990_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT990_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ int ft990v12_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT990_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ int ft990v12_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft990v12_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT990_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT990_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT990_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT990_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ int ft990v12_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft990v12_priv_data *priv; ft990v12_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT990_MODE_FM) { *rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } else { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ int ft990v12_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT990_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT990_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ int ft990v12_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft990v12_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT990_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT990_NATIVE_SPLIT_OFF; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ int ft990v12_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Read status flags err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT990_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT990_SF_VFOB) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ int ft990v12_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_TX_EN) == 0) { err = ft990v12_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft990v12_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft990v12_priv_data *priv; unsigned char ci; ft990v12_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990v12_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ int ft990v12_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_RX_EN) == 0) { err = ft990v12_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft990v12_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft990v12_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft990v12_priv_data *priv; unsigned char ci; ft990v12_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990v12_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ int ft990v12_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT990_NATIVE_LOCK_ON; } else { ci = FT990_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT990_NATIVE_TUNER_ON; } else { ci = FT990_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ int ft990v12_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT990_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT990_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT990_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ int ft990v12_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft990v12_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT990_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT990_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT990_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT990_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT990_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT990_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT990_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT990_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT990_NATIVE_MODE_SET_AM_N || ci == FT990_NATIVE_MODE_SET_AM_W || ci == FT990_NATIVE_MODE_SET_FM || ci == FT990_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT990_BW_F250; } else if (width <= 500) { bw = FT990_BW_F500; } else if (width <= 2000) { bw = FT990_BW_F2000; } else { bw = FT990_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft990v12_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT990_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT990_MODE_USB: *mode = RIG_MODE_USB; break; case FT990_MODE_CW: *mode = RIG_MODE_CW; break; case FT990_MODE_AM: *mode = RIG_MODE_AM; break; case FT990_MODE_FM: *mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT990 firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT990 firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT990_BW_F2000: *width = 2000; break; case FT990_BW_F500: *width = 500; break; case FT990_BW_F250: *width = 250; break; case FT990_BW_F6000: *width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_vfo(RIG *rig, vfo_t vfo) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_A; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_B; break; case RIG_VFO_MEM: ci = FT990_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft990v12_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft990v12_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ int ft990v12_get_vfo(RIG *rig, vfo_t *vfo) { struct ft990v12_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; /* Get flags for VFO status err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } */ if (priv->update_data.flag2 & FT990_SF_MEM || priv->update_data.flag2 & FT990_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT990_SF_VFOB) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft990v12_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990v12_send_static_cmd(rig, FT990_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT990_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %s\n", __func__, rig_strvfop(op)); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT990_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT990_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT990_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT990_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT990_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT990_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft990v12_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft990v12_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ int ft990v12_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ int ft990v12_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ int ft990v12_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ int ft990v12_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft990v12_priv_data *priv; ft990v12_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %s\n", __func__, rig_strvfo(chan->vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft990v12_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft990v12_op_data_t *) &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft990v12_op_data_t *) &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft990v12_op_data_t *) &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft990v12_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft990v12_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT990_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = 0x%02x\n", __func__, p->mode); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT990_BW_F2000: chan->width = 2000; break; case FT990_BW_F500: chan->width = 500; break; case FT990_BW_F250: chan->width = 250; break; case FT990_BW_F6000: chan->width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT990_SF_SPLIT); if (priv->update_data.flag1 & FT990_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT990_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT990_SF_FAST) { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT990_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft990v12_op_data_t *) &priv->update_data.current_front; /* M0EZP: was current_rear */ /* FT1000D * if (RIG_MODEL_FT1000D == rig->caps->rig_model) * p = (ft990v12_op_data_t *) &priv->update_data.vfob; * chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + * p->basefreq[2]) * 10; * * THIS SECTION WAS REMOVED IN DECEMBER 2016. SEE SEPARATE ft1000d.c and .h FILES */ /* Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT990_BW_F2000: chan->tx_width = 2000; break; case FT990_BW_F500: chan->tx_width = 500; break; case FT990_BW_F250: chan->tx_width = 250; break; case FT990_BW_F6000: chan->tx_width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } if (priv->update_data.flag1 & FT990_SF_VFOB) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing ft990_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { struct ft990v12_priv_data *priv; int n; int err = -RIG_EINTERNAL; int rl; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } n = 0; // K1MMI: Initialise as the only time n will be updated is for the FT990_NATIVE_ALL_DATA AND FT990_READ_FLAGS priv = (struct ft990v12_priv_data *)STATE(rig)->priv; switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: case FT990_NATIVE_UPDATE_MEM_CHNL: case FT990_NATIVE_UPDATE_OP_DATA: case FT990_NATIVE_UPDATE_VFO_DATA: case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: if (ft990uni_get_freq_state < 2) { // if (ci == FT990_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { /* err = ft990v12_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); M0EZP: dont send command, rely on the assignment from memory below*/ } else { // err = RIG_OK; K1MMI err = ft990v12_send_static_cmd(rig, ci); // K1MMI: only send for ALL DATA 1492 bytes or READ FLAGS 5 bytes } if (err != RIG_OK) { return err; } switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: rl = FT990_ALL_DATA_LENGTH; // K1MMI: prepare to receive 1492 bytes back p = (unsigned char *) &priv->update_data; // K1MMI: This seems like 1492 will be saved here n = read_block(RIGPORT(rig), p, rl); /* M0EZP: copied here from below */ return RIG_OK; break; case FT990_NATIVE_UPDATE_MEM_CHNL: // we already have the channelnumber in the previously saved 1492 bytes p = (unsigned char *) &priv->update_data.channelnumber; rl = FT990_MEM_CHNL_LENGTH; // 1 break; case FT990_NATIVE_UPDATE_OP_DATA: // we already have the current OP and VFOA in the 1492 bytes p = (unsigned char *) &priv->update_data.current_front; rl = FT990_OP_DATA_LENGTH; // 32 break; case FT990_NATIVE_UPDATE_VFO_DATA: // we already have the VFOA and VFOB in the 1492 bytes p = (unsigned char *) &priv->update_data.vfoa; rl = FT990_VFO_DATA_LENGTH; // 32 break; case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: // we already have the 16 structure for the memory channel number p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT990_MEM_CHNL_DATA_LENGTH; // 16 break; default: // M0EZP: shouldn't be here! rig_debug(RIG_DEBUG_TRACE, "%s: Default clause ci 0x%02x\n", __func__, ci); // M0EZP return -RIG_EINVAL; } ft990uni_get_freq_state = ft990uni_get_freq_state + 1; if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); memcpy(&priv->update_data, p, FT990_ALL_DATA_LENGTH); return RIG_OK; } else { return RIG_OK; } case FT990_NATIVE_READ_FLAGS: rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); err = ft990v12_send_static_cmd(rig, ci); // K1MMI: only send for ALL DATA 1492 bytes if (err != RIG_OK) { return err; } p = (unsigned char *)&priv->update_data; rl = FT990_STATUS_FLAGS_LENGTH; // 5 n = read_block(RIGPORT(rig), (unsigned char *)&temp, rl); /* M0EZP: copied here from below */ if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); memcpy(&priv->update_data, p, FT990_STATUS_FLAGS_LENGTH - 2); /* just overwrite first 3 bytes */ return RIG_OK; break; default: // M0EZP: shouldn't be here! rig_debug(RIG_DEBUG_TRACE, "%s: Default clause ci 0x%02x\n", __func__, ci); // M0EZP return -RIG_EINVAL; } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft990v12_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT990_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT990_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT990_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT990_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT990_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT990_BCD_RIT); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/frg100.h0000664000175000017500000000236215056640443011721 /* * frg100.h - (C) Michael Black 2016 * * This shared library provides an API for communicating * via serial interface to an FRG-100 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #define FRG100_OP_DATA_LENGTH 19 /* 0x10 p1=02 return size */ #define FRG100_CMD_UPDATE 0x10 #define FRG100_MIN_CHANNEL 1 #define FRG100_MAX_CHANNEL 200 // Return codes #define FRG100_CMD_RETCODE_OK 0x00 #define FRG100_CMD_RETCODE_ERROR 0xF0 hamlib-4.6.5/rigs/yaesu/ft757gx.c0000664000175000017500000006113015056640443012126 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft757gx.c - (C) Stephane Fillod 2004 * (C) Nate Bargmann 2008 * * This shared library provides an API for communicating * via serial interface to an FT-757GX/FT-757GXII using the * "CAT" interface box (FIF-232C) or similar. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO * * 1. Allow cached reads * 2. set_mem/get_mem, vfo_op, get_channel, set_split/get_split, * set_func/get_func * */ #include #include /* String function definitions */ #include #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft757gx.h" #define FT757GX_VFOS (RIG_VFO_A|RIG_VFO_B) /* Backend function prototypes. These map to frontend functions. */ static int ft757_init(RIG *rig); static int ft757_cleanup(RIG *rig); static int ft757_open(RIG *rig); static int ft757gx_get_conf(RIG *rig, hamlib_token_t token, char *val); static int ft757gx_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int ft757_set_freq(RIG *rig, vfo_t vfo, freq_t freq); //static int ft757_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft757gx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft757_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft757_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft757_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft757_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft757gx_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft757_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft757_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* Private helper function prototypes */ static int ft757_get_update_data(RIG *rig); static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width); static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); /* * future - private data * */ struct ft757_priv_data { unsigned char pacing; /* pacing value */ unsigned char current_vfo; /* active VFO from last cmd , can be either RIG_VFO_A or RIG_VFO_B only */ unsigned char update_data[FT757GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ double curfreq; /* for fake get_freq on 757G */ char fakefreq; /* 0=no fake, 1=fake get freq */ }; #define TOKEN_BACKEND(t) (t) #define TOK_FAKEFREQ TOKEN_BACKEND(1) const struct confparams ft757gx_cfg_params[] = { { TOK_FAKEFREQ, "fakefreq", "Fake get-freq", "Fake getting freq", "0", RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; /* * ft757gx rig capabilities. * Also this struct is READONLY! */ struct rig_caps ft757gx_caps = { RIG_MODEL(RIG_MODEL_FT757), .model_name = "FT-757GX", .mfg_name = "Yaesu", .version = "20220429.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT757GX_WRITE_DELAY, .post_write_delay = FT757GX_POST_WRITE_DELAY, .timeout = FT757GX_DEFAULT_READ_TIMEOUT, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list:20 */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(500), .endf = 29999990, .modes = FT757GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1500), 1999900, FT757GX_ALL_TX_MODES, .low_power = 5000, .high_power = 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(3500), 3999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(7000), 7499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(10), 10499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(14), 14499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(18), 18499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(21), 21499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(24500), 24999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(28), 29999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {FT757GX_ALL_RX_MODES, 10}, {FT757GX_ALL_RX_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* private data */ .rig_init = ft757_init, .rig_cleanup = ft757_cleanup, .rig_open = ft757_open, /* port opened */ .rig_close = NULL, /* port closed */ .set_freq = ft757_set_freq, /* set freq */ .get_freq = ft757gx_get_freq, /* get freq */ .set_mode = NULL, /* set mode */ .get_mode = NULL, /* get mode */ .get_vfo = ft757gx_get_vfo, /* set vfo */ .set_vfo = ft757_set_vfo, /* set vfo */ .set_ptt = NULL, /* set ptt */ .get_ptt = NULL, /* get ptt */ .cfgparams = ft757gx_cfg_params, .set_conf = ft757gx_set_conf, .get_conf = ft757gx_get_conf, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft757gx2 rig capabilities. * Also this struct is READONLY! */ struct rig_caps ft757gx2_caps = { RIG_MODEL(RIG_MODEL_FT757GXII), .model_name = "FT-757GXII", .mfg_name = "Yaesu", .version = "20240927.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_SERIAL_DTR, /* CAT port pin 4 per manual */ .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT757GX_WRITE_DELAY, .post_write_delay = FT757GX_POST_WRITE_DELAY, .timeout = FT757GX_DEFAULT_READ_TIMEOUT, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 9, RIG_MTYPE_MEM, FT757_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = 29999990, .modes = FT757GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ /* FIXME: 10m is "less" and AM is 25W carrier */ .tx_range_list2 = { {kHz(1500), 1999900, FT757GX_ALL_TX_MODES, .low_power = 5000, .high_power = 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(3500), 3999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(7000), 7499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(10), 10499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(14), 14499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(18), 18499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(21), 21499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(24500), 24999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(28), 29999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {FT757GX_ALL_RX_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_CW, Hz(600)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT757GXII_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft757_init, .rig_cleanup = ft757_cleanup, .rig_open = ft757_open, /* port opened */ .rig_close = NULL, /* port closed */ .set_freq = ft757_set_freq, /* set freq */ .get_freq = ft757gx_get_freq, /* get freq */ .set_mode = ft757_set_mode, /* set mode */ .get_mode = ft757_get_mode, /* get mode */ .set_vfo = ft757_set_vfo, /* set vfo */ .get_vfo = ft757_get_vfo, /* get vfo */ .get_level = ft757_get_level, .get_ptt = ft757_get_ptt, /* get ptt */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ static int ft757_init(RIG *rig) { struct ft757_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft757_priv_data *) calloc(1, sizeof(struct ft757_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->curfreq = 1e6; /* TODO: read pacing from preferences */ priv->pacing = FT757GX_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A ? */ return RIG_OK; } /* * ft757_cleanup routine * the serial port is closed by the frontend */ static int ft757_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft757_open routine * */ static int ft757_open(RIG *rig) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); priv->fakefreq = 1; // turn this on by default /* FT757GX has a write-only serial port: don't try to read status data */ if (rig->caps->rig_model == RIG_MODEL_FT757) { int retval; memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH); retval = rig_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_vfo error: %s\n", __func__, rigerror(retval)); } } else { /* read back the 75 status bytes from FT757GXII */ int retval = ft757_get_update_data(rig); if (retval < 0) { memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH); return retval; } } return RIG_OK; } /* * This command only functions when operating on a vfo. * TODO: test Status Update Byte 1 * */ static int ft757_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0a}; rig_debug(RIG_DEBUG_VERBOSE, "%s called. Freq=%"PRIfreq"\n", __func__, freq); /* fill in first four bytes */ to_bcd(cmd, freq / 10, BCD_LEN); priv->curfreq = freq; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } static int ft757_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0c}; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s, width = %d\n", __func__, rig_strrmode(mode), (int)width); if (mode == RIG_MODE_NONE) { return -RIG_EINVAL; } /* fill in p1 */ cmd[3] = mode2rig(rig, mode, width); return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } static int ft757gx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called. fakefreq=%d\n", __func__, priv->fakefreq); if (priv->fakefreq) // only return last freq set when fakeit is turned on { *freq = priv->curfreq; return RIG_OK; } return RIG_ENAVAIL; } /* * Return Freq */ #if 0 static int ft757_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* grab freq (little endian format) and convert */ switch (vfo) { case RIG_VFO_CURR: *freq = 10 * from_bcd(priv->update_data + STATUS_CURR_FREQ, BCD_LEN); break; case RIG_VFO_A: *freq = 10 * from_bcd(priv->update_data + STATUS_VFOA_FREQ, BCD_LEN); break; case RIG_VFO_B: *freq = 10 * from_bcd(priv->update_data + STATUS_VFOB_FREQ, BCD_LEN); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_VERBOSE, "%s returning: Freq=%"PRIfreq"\n", __func__, *freq); return RIG_OK; } #endif static int ft757_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } switch (vfo) { case RIG_VFO_CURR: retval = rig2mode(rig, priv->update_data[STATUS_CURR_MODE], mode, width); break; case RIG_VFO_A: retval = rig2mode(rig, priv->update_data[STATUS_VFOA_MODE], mode, width); break; case RIG_VFO_B: retval = rig2mode(rig, priv->update_data[STATUS_VFOB_MODE], mode, width); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return retval; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft757_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x05}; struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (vfo) { case RIG_VFO_CURR: RETURNFUNC(RIG_OK); case RIG_VFO_A: cmd[3] = 0x00; /* VFO A */ break; case RIG_VFO_B: cmd[3] = 0x01; /* VFO B */ break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } priv->current_vfo = vfo; RETURNFUNC(write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH)); } static int ft757gx_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; // we'll just use the cached vfo for the 757GX since we can't read it *vfo = priv->current_vfo; return RIG_OK; } static int ft757_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } if (priv->update_data[0] & 0x10) { (*vfo) = RIG_VFO_MEM; } else if (priv->update_data[0] & 0x08) { (*vfo) = RIG_VFO_B; } else { (*vfo) = RIG_VFO_A; } return RIG_OK; } static int ft757_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *ptt = (priv->update_data[0] & 0x20) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } static int ft757_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, 0x10}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d.\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * * need to use this when doing ft757_get_* stuff */ static int ft757_get_update_data(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x10}; struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval = 0; long nbtries; /* Maximum number of attempts to ask/read the data. */ int maxtries = rp->retry ; rig_debug(RIG_DEBUG_VERBOSE, "%s called Timeout=%d ms, Retry=%d\n", __func__, rp->timeout, maxtries); /* At least on one model, returns erratically a timeout. Increasing the timeout does not fix things. So we restart the read from scratch, it works most of times. */ for (nbtries = 0 ; nbtries < maxtries ; nbtries++) { rig_flush(rp); /* send READ STATUS cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 75 status bytes */ retval = read_block(rp, priv->update_data, FT757GX_STATUS_UPDATE_DATA_LENGTH); if (retval == FT757GX_STATUS_UPDATE_DATA_LENGTH) { break ; } rig_debug(RIG_DEBUG_ERR, "%s: read update_data failed, %d octets of %d read, retry %ld out of %d\n", __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH, nbtries, maxtries); /* The delay is quadratic. */ hl_usleep(nbtries * nbtries * 1000000); } if (retval != FT757GX_STATUS_UPDATE_DATA_LENGTH) { rig_debug(RIG_DEBUG_ERR, "%s: read update_data failed, %d octets of %d read.\n", __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH); return retval < 0 ? retval : -RIG_EIO; } return RIG_OK; } static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width) { int md; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * translate mode from generic to ft757 specific */ switch (mode) { case RIG_MODE_AM: md = MODE_AM; break; case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_FM: md = MODE_FM; break; case RIG_MODE_CW: if (RIG_PASSBAND_NOCHANGE == width || width == RIG_PASSBAND_NORMAL || width >= rig_passband_normal(rig, mode)) { md = MODE_CWW; } else { md = MODE_CWN; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * translate mode from ft757 specific to generic */ switch (md) { case MODE_AM: *mode = RIG_MODE_AM; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_CWW: case MODE_CWN: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (md == MODE_CWN) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ft757gx_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct ft757_priv_data *priv; struct rig_state *rs; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); rs = STATE(rig); priv = (struct ft757_priv_data *)rs->priv; switch (token) { case TOK_FAKEFREQ: SNPRINTF(val, val_len, "%d", priv->fakefreq); break; default: *val = 0; return -RIG_EINVAL; } return RIG_OK; } static int ft757gx_get_conf(RIG *rig, hamlib_token_t token, char *val) { return ft757gx_get_conf2(rig, token, val, 128); } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ft757gx_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct ft757_priv_data *priv; struct rig_state *rs; rig_debug(RIG_DEBUG_VERBOSE, "%s called. val=%s\n", __func__, val); rs = STATE(rig); priv = (struct ft757_priv_data *)rs->priv; switch (token) { case TOK_FAKEFREQ: priv->fakefreq = 0; // should only be 0 or 1 -- default to 0 if (val[0] != '0') { priv->fakefreq = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: fakefreq=%d\n", __func__, priv->fakefreq); break; default: return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft920.c0000664000175000017500000023247115056640443011567 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft920.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Nate Bargmann 2002-2005 (n0nb at arrl.net) * (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-920 using the "CAT" interface * Documentation can be found online at: * http://www.yaesu.com/amateur/pdf/manuals/ft_920.pdf * pages 86 to 90 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft920.h" /* * Functions considered to be Stable (2010-01-29): * set_vfo * get_vfo * set_freq * get_freq * set_mode * get_mode * set_split * get_split * set_split_freq * get_split_freq * set_split_mode * get_split_mode * set_rit * get_rit * set_xit * get_xit * set_ptt * get_ptt */ /* * Native FT920 functions. More to come :-) * */ enum ft920_native_cmd_e { FT920_NATIVE_SPLIT_OFF = 0, FT920_NATIVE_SPLIT_ON, FT920_NATIVE_RECALL_MEM, FT920_NATIVE_VFO_TO_MEM, FT920_NATIVE_VFO_A, FT920_NATIVE_VFO_B, FT920_NATIVE_MEM_TO_VFO, FT920_NATIVE_CLARIFIER_OPS, FT920_NATIVE_VFO_A_FREQ_SET, FT920_NATIVE_MODE_SET, FT920_NATIVE_PACING, FT920_NATIVE_PTT_OFF, FT920_NATIVE_PTT_ON, FT920_NATIVE_MEM_CHNL, FT920_NATIVE_OP_DATA, FT920_NATIVE_VFO_DATA, FT920_NATIVE_MEM_CHNL_DATA, FT920_NATIVE_TUNER_BYPASS, FT920_NATIVE_TUNER_INLINE, FT920_NATIVE_TUNER_START, FT920_NATIVE_VFO_B_FREQ_SET, FT920_NATIVE_VFO_A_PASSBAND_WIDE, FT920_NATIVE_VFO_A_PASSBAND_NAR, FT920_NATIVE_VFO_B_PASSBAND_WIDE, FT920_NATIVE_VFO_B_PASSBAND_NAR, FT920_NATIVE_STATUS_FLAGS, FT920_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * Internal MODES - when setting modes via FT920_NATIVE_MODE_SET * */ /* VFO A */ #define MODE_SET_A_LSB 0x00 #define MODE_SET_A_USB 0x01 #define MODE_SET_A_CW_U 0x02 #define MODE_SET_A_CW_L 0x03 #define MODE_SET_A_AM_W 0x04 #define MODE_SET_A_AM_N 0x05 #define MODE_SET_A_FM_W 0x06 #define MODE_SET_A_FM_N 0x07 #define MODE_SET_A_DATA_L 0x08 #define MODE_SET_A_DATA_U 0x0a #define MODE_SET_A_DATA_F 0x0b /* VFO B */ #define MODE_SET_B_LSB 0x80 #define MODE_SET_B_USB 0x81 #define MODE_SET_B_CW_U 0x82 #define MODE_SET_B_CW_L 0x83 #define MODE_SET_B_AM_W 0x84 #define MODE_SET_B_AM_N 0x85 #define MODE_SET_B_FM_W 0x86 #define MODE_SET_B_FM_N 0x87 #define MODE_SET_B_DATA_L 0x88 #define MODE_SET_B_DATA_U 0x8a #define MODE_SET_B_DATA_F 0x8b /* * Internal Clarifier parms - when setting clarifier via * FT920_NATIVE_CLARIFIER_OPS * */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_TX_OFF 0x80 #define CLAR_TX_ON 0x81 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* Tuner status values used to set the * tuner state and indicate tuner status. */ #define TUNER_BYPASS 0 #define TUNER_INLINE 1 #define TUNER_TUNING 2 /* * Local VFO CMD's, according to spec * */ //#define FT920_VFO_A 0x00 //#define FT920_VFO_B 0x01 /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA, P1 = 01 requests the FT-920 to return its status flags. * These flags consist of 8 bytes and are documented in the FT-920 manual * on page 89. * */ #define FT920_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_VFOA 0x00 /* bits 0 & 1, VFO A TX/RX == 0 */ #define SF_SPLITA (1<<0) /* Split operation with VFO-B on TX */ #define SF_SPLITB (1<<1) /* Split operation with VFO-B on RX */ #define SF_VFOB (SF_SPLITA|SF_SPLITB) /* bits 0 & 1, VFO B TX/RX == 3 */ #define SF_TUNER_TUNE (1<<2) /* Antenna tuner On and Tuning for match*/ #define SF_PTT_OFF (0<<7) /* Receive mode (PTT line open) */ #define SF_PTT_ON (1<<7) /* Transmission in progress (PTT line grounded) */ #define SF_PTT_MASK (SF_PTT_ON) #define FT920_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define SF_QMB (1<<3) /* Quick Memory Bank (QMB) selected */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_VFO (1<<5) /* VFO operation selected */ #define SF_MR (1<<6) /* Memory Mode selected */ #define SF_GC (1<<7) /* General Coverage Reception selected */ #define SF_VFO_MASK (SF_QMB|SF_MT|SF_VFO|SF_MR) #define FT920_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 2 */ #define SF_TUNER_INLINE (1<<1) /* Antenna tuner is inline or bypass */ #define SF_VFOB_LOCK (1<<2) /* VFO B tuning lock status */ #define SF_VFOA_LOCK (1<<3) /* VFO A tuning lock status */ /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03 * * The FT-920 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (28 bytes) * CAT command 0x10, P1 = 03 returns VFO A data and the sub display data (sub display is always VFO B) (28 bytes) * CAT command 0x10, P1 = 04, P4 = 0x00-0x89 returns memory channel data (14 bytes) * In all cases the format is (from the FT-920 manual page 90): * * Offset Value * 0x00 Band Selection (not documented!) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x05 Clarifier Offset (Hex value) * 0x07 Mode Data * 0x08 Flag * 0x09 Filter Data 1 * 0x0a Filter Data 2 * 0x0b CTCSS Encoder Data * 0x0c CTCSS Decoder Data * 0x0d Memory recall Flag * * Memory Channel data has the same layout and offsets * VFO B data has the same layout, but the offset starts at 0x0e and * continues through 0x1b * */ #define FT920_SUMO_DISPLAYED_FREQ 0x01 /* Current main display, can be VFO A, Memory data, Memory tune */ #define FT920_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT920_SUMO_DISPLAYED_CLAR 0x05 /* RIT/XIT offset -- current display */ #define FT920_SUMO_VFO_A_CLAR 0x05 /* RIT/XIT offset -- VFO A */ #define FT920_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT920_SUMO_VFO_A_MODE 0x07 /* VFO A mode, not necessarily currently displayed! */ #define FT920_SUMO_VFO_B_FREQ 0x0f /* Current sub display && VFO B */ #define FT920_SUMO_VFO_B_CLAR 0x13 /* RIT/XIT offset -- VFO B */ #define FT920_SUMO_VFO_B_MODE 0x15 /* Current sub display && VFO B */ /* * Mode Bitmap from offset 0x07 or 0x16 in VFO Record. * Bits 5 and 6 ignored * used when READING modes from FT-920 * */ #define MODE_LSB 0x00 #define MODE_CW_L 0x01 /* CW listening on LSB */ #define MODE_AM 0x02 #define MODE_FM 0x03 #define MODE_DATA_L 0x04 /* DATA on LSB */ #define MODE_DATA_U 0x05 /* DATA on USB (who does that? :) */ #define MODE_DATA_F 0x06 /* DATA on FM */ #define MODE_USB 0x40 #define MODE_CW_U 0x41 /* CW listening on USB */ /* Narrow filter selected */ #define MODE_LSBN 0x80 /* Not sure this actually exists */ #define MODE_CW_LN 0x81 #define MODE_AMN 0x82 #define MODE_FMN 0x83 #define MODE_DATA_LN 0x84 #define MODE_DATA_UN 0x85 #define MODE_DATA_FN 0x86 #define MODE_USBN 0xc0 /* Not sure this actually exists */ #define MODE_CW_UN 0xc1 /* All relevant bits */ #define MODE_MASK 0xc7 /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * API local implementation * */ static int ft920_init(RIG *rig); static int ft920_cleanup(RIG *rig); static int ft920_open(RIG *rig); static int ft920_close(RIG *rig); static int ft920_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft920_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft920_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft920_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft920_set_vfo(RIG *rig, vfo_t vfo); static int ft920_get_vfo(RIG *rig, vfo_t *vfo); static int ft920_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft920_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft920_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft920_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft920_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft920_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft920_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft920_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft920_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft920_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); /* not documented in my FT-920 manual, but it works! - N0NB */ static int ft920_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft920_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft920_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft920_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); /* Private helper function prototypes */ static int ft920_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft920_send_static_cmd(RIG *rig, unsigned char ci); static int ft920_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft920_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft920_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft920 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set vfo A freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (28 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (28 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (14 bytes) P4 = 0x00-0x89 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner bypass */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner inline */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner start tuning for match */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* set vfo B frequency */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8c } }, /* VFO A wide filter */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x8c } }, /* VFO A narrow filter */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x8c } }, /* VFO B wide filter */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x8c } }, /* VFO B narrow filter */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xFA } }, /* Read status flags */ /* { 0, { 0x00, 0x00, 0x00, 0x00, 0x70 } }, */ /* keyer commands */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft920_caps.priv? I'm guessing not as it's private to the backend. -N0NB */ struct ft920_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ vfo_t split_vfo; /* TX VFO in split mode */ split_t split; /* split active or not */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT920_VFO_DATA_LENGTH]; /* returned data--max value, some are less */ }; /* * ft920 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft920_caps = { RIG_MODEL(RIG_MODEL_FT920), .model_name = "FT-920", .mfg_name = "Yaesu", .version = "20220060.0", /* YYYYMMDD */ .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT920_WRITE_DELAY, .post_write_delay = FT920_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = FT920_FUNC_ALL, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .announces = RIG_ANN_NONE, .vfo_ops = RIG_OP_NONE, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 122 (!) */ .rx_range_list1 = { {kHz(100), MHz(30), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, /* General coverage + ham */ {MHz(48), MHz(56), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, /* 6m! */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_HF(1, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ FRQ_RNG_6m(1, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_6m(1, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, {MHz(48), MHz(56), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_HF(2, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ FRQ_RNG_6m(2, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_6m(2, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT920_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT920_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT920_AM_RX_MODES, Hz(100)}, /* Normal */ {FT920_AM_RX_MODES, kHz(1)}, /* Fast */ {FT920_FM_RX_MODES, Hz(100)}, /* Normal */ {FT920_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-920 has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.4)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(15)}, /* normal AM filter (stock radio has no AM filter!) */ {RIG_MODE_AM, kHz(2.4)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM with optional FM unit */ {RIG_MODE_WFM, kHz(12)}, /* WideFM, with optional FM unit. */ {RIG_MODE_PKTLSB, kHz(1.8)},/* Alias of MODE_DATA_L */ {RIG_MODE_PKTLSB, kHz(0.5)},/* Alias of MODE_DATA_LN */ {RIG_MODE_PKTUSB, kHz(2.4)}, /* Alias for MODE DATA_U */ {RIG_MODE_PKTUSB, kHz(0.5)},/* Alias of MODE_DATA_UN */ {RIG_MODE_PKTFM, kHz(12)}, /* Alias for MODE_DATA _F */ {RIG_MODE_PKTFM, kHz(6)}, /* Alias for MODE_DATA_FN */ RIG_FLT_END, }, .str_cal = EMPTY_STR_CAL, .cfgparams = NULL, .priv = NULL, /* private data FIXME: ?? */ .rig_init = ft920_init, .rig_cleanup = ft920_cleanup, .rig_open = ft920_open, /* port opened */ .rig_close = ft920_close, /* port closed */ .set_freq = ft920_set_freq, .get_freq = ft920_get_freq, .set_mode = ft920_set_mode, .get_mode = ft920_get_mode, .set_vfo = ft920_set_vfo, .get_vfo = ft920_get_vfo, .set_ptt = ft920_set_ptt, .get_ptt = ft920_get_ptt, .get_dcd = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = ft920_set_split_freq, .get_split_freq = ft920_get_split_freq, .set_split_mode = ft920_set_split_mode, .get_split_mode = ft920_get_split_mode, .set_split_vfo = ft920_set_split_vfo, .get_split_vfo = ft920_get_split_vfo, .set_rit = ft920_set_rit, .get_rit = ft920_get_rit, .set_xit = ft920_set_xit, .get_xit = ft920_get_xit, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = NULL, .get_dcs_code = NULL, .set_tone = NULL, .get_tone = NULL, .set_ctcss_tone = NULL, .get_ctcss_tone = NULL, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_tone_sql = NULL, .get_tone_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .power2mW = NULL, .mW2power = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_level = NULL, .get_level = NULL, .set_func = ft920_set_func, .get_func = ft920_get_func, .set_parm = NULL, .get_parm = NULL, .set_ext_level = NULL, .get_ext_level = NULL, .set_ext_parm = NULL, .get_ext_parm = NULL, .set_conf = NULL, .get_conf = NULL, .send_dtmf = NULL, .recv_dtmf = NULL, .send_morse = NULL, .set_bank = NULL, .set_mem = NULL, .get_mem = NULL, .vfo_op = NULL, .scan = NULL, .set_trn = NULL, .get_trn = NULL, .decode_event = NULL, .set_channel = NULL, .get_channel = NULL, .get_info = NULL, .set_chan_all_cb = NULL, .get_chan_all_cb = NULL, .set_mem_all_cb = NULL, .get_mem_all_cb = NULL, .clone_combo_set = NULL, .clone_combo_get = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init* * */ static int ft920_init(RIG *rig) { struct ft920_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft920_priv_data *) calloc(1, sizeof(struct ft920_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; /* whoops! memory shortage! */ } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT920_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A */ return RIG_OK; } /* * rig_cleanup* * * the serial port is closed by the frontend * */ static int ft920_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open* * */ static int ft920_open(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); /* Copy native cmd PACING to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[FT920_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); /* get pacing value, and store in private cmd */ priv->p_cmd[P1] = priv->pacing; rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = write_block(rp, priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } /* TODO: more initialization as necessary */ return RIG_OK; } /* * rig_close* * */ static int ft920_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set freq for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * freq | input | frequency to passed VFO * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: If vfo is set to RIG_VFO_CUR then vfo from * priv_data is used. * */ static int ft920_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft920_priv_data *priv; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: /* force main display to VFO */ case RIG_VFO_VFO: err = ft920_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_FREQ_SET; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_FREQ_SET; break; default: return -RIG_EINVAL; /* sorry, unsupported VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = 0x%02x\n", __func__, cmd_index); err = ft920_send_dial_freq(rig, cmd_index, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq* * * Return Freq for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * *freq | output | displayed frequency based on passed VFO * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft920_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_A_FREQ; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_VFO_B_FREQ; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_FREQ; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (((((p[0] << 8) + p[1]) << 8) + p[2]) << 8) + p[3]; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode* * * Set mode and passband: eg AM, CW etc for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * mode | input | supported modes (see ft920.h) * width | input | supported widths (see ft920.h) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: If vfo is set to RIG_VFO_CUR then vfo from * priv_data is used. * */ static int ft920_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft920_priv_data *priv; unsigned char cmd_index = FT920_NATIVE_VFO_A_PASSBAND_WIDE; /* index of sequence to send */ unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft920 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft920_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_A_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_A_CW_U; break; case RIG_MODE_USB: mode_parm = MODE_SET_A_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_A_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_A_FM_W; break; case RIG_MODE_RTTY: mode_parm = MODE_SET_A_DATA_L; break; case RIG_MODE_PKTLSB: mode_parm = MODE_SET_A_DATA_L; break; case RIG_MODE_PKTUSB: mode_parm = MODE_SET_A_DATA_U; break; case RIG_MODE_PKTFM: mode_parm = MODE_SET_A_DATA_F; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } break; /* Now VFO B */ case RIG_VFO_B: case RIG_VFO_SUB: switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_B_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_B_CW_U; break; case RIG_MODE_USB: mode_parm = MODE_SET_B_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_B_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_B_FM_W; break; case RIG_MODE_RTTY: mode_parm = MODE_SET_B_DATA_L; break; case RIG_MODE_PKTLSB: mode_parm = MODE_SET_B_DATA_L; break; case RIG_MODE_PKTUSB: mode_parm = MODE_SET_B_DATA_U; break; case RIG_MODE_PKTFM: mode_parm = MODE_SET_B_DATA_F; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-920 doesn't appear to support narrow width in USB or LSB modes * * Yeah, it's ugly... -N0NB * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL || width == rig_passband_normal(rig, mode)) { switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_PASSBAND_WIDE; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_PASSBAND_WIDE; break; } } else { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_RTTY: switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_PASSBAND_NAR; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_PASSBAND_NAR; break; } break; default: return -RIG_EINVAL; /* Invalid mode; how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width; how can caller know? */ } } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; /* Whew! */ } /* * rig_get_mode* * * Get mode and passband: eg AM, CW etc for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * *mode | output | supported modes (see ft920.h) * *width | output | supported widths (see ft920.h) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft920_priv_data *priv; unsigned char mymode, offset; /* ft920 mode, flag offset */ int err, cmd_index, norm; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_DISPLAYED_MODE; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_B_MODE; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_MODE; break; default: return -RIG_EINVAL; } err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } mymode = priv->update_data[offset]; mymode &= MODE_MASK; rig_debug(RIG_DEBUG_TRACE, "%s: mymode = 0x%02x\n", __func__, mymode); /* * translate mode from ft920 to generic. * * FIXME: FT-920 has 3 DATA modes, LSB, USB, and FM * do we need more bit fields in rmode_t? -N0NB * */ switch (mymode) { case MODE_USBN: /* not sure this even exists */ *mode = RIG_MODE_USB; norm = FALSE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_LSBN: /* not sure this even exists */ *mode = RIG_MODE_LSB; norm = FALSE; break; case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_CW_UN: case MODE_CW_LN: *mode = RIG_MODE_CW; norm = FALSE; break; case MODE_CW_U: case MODE_CW_L: *mode = RIG_MODE_CW; norm = TRUE; break; case MODE_AMN: *mode = RIG_MODE_AM; norm = FALSE; break; case MODE_AM: *mode = RIG_MODE_AM; norm = TRUE; break; case MODE_FMN: *mode = RIG_MODE_FM; norm = FALSE; break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; case MODE_DATA_LN: *mode = RIG_MODE_PKTLSB; norm = FALSE; break; case MODE_DATA_L: *mode = RIG_MODE_PKTLSB; norm = TRUE; break; case MODE_DATA_UN: *mode = RIG_MODE_PKTUSB; norm = FALSE; break; case MODE_DATA_U: *mode = RIG_MODE_PKTUSB; norm = TRUE; break; case MODE_DATA_F: *mode = RIG_MODE_PKTFM; norm = TRUE; break; case MODE_DATA_FN: *mode = RIG_MODE_PKTFM; norm = FALSE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo* * * Get active VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Set vfo and store requested vfo for later * RIG_VFO_CURR requests. * */ static int ft920_set_vfo(RIG *rig, vfo_t vfo) { struct ft920_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B; priv->current_vfo = vfo; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo* * * Get active VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * *vfo | output | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested * vfo/mem back to the frontend. * */ static int ft920_get_vfo(RIG *rig, vfo_t *vfo) { struct ft920_priv_data *priv; unsigned char status_0; /* ft920 status flag 0 */ unsigned char status_1; /* ft920 status flag 1 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; status_0 &= SF_VFOB; /* get VFO B (sub display) active bits */ status_1 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_1]; status_1 &= SF_VFO_MASK; /* get VFO/MEM (main display) active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, status_1); /* * translate vfo status from ft920 to generic. * * Figuring out whether VFO B is the active RX vfo is tough as * Status Flag 0 bits 0 & 1 contain this information. Testing * Status Flag 1 only gives us the state of the main display. * */ switch (status_0) { case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; case SF_SPLITB: /* Split operation, RX on VFO B */ *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; } /* * Okay now test for the active MEM/VFO status of the main display * */ switch (status_1) { case SF_QMB: case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; break; case SF_VFO: switch (status_0) { case SF_SPLITA: /* Split operation, RX on VFO A */ *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; } break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_split_vfo* * * Set the '920 into split TX/RX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | not used * split | input | RIG_SPLIT_ON, RIG_SPLIT_OFF * tx_vfo | input | VFO to use for TX (not used) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: VFO cannot be set as the set split_on command only * changes the TX to the sub display. Setting split off * returns the TX to the main display. * */ static int ft920_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); switch (tx_vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: case RIG_VFO_VFO: break; case RIG_VFO_B: case RIG_VFO_SUB: break; default: return -RIG_EINVAL; } switch (split) { case RIG_SPLIT_OFF: cmd_index = FT920_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT920_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get whether the '920 is in split mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | not used * *split | output | RIG_SPLIT_ON, RIG_SPLIT_OFF * *tx_vfo | output | not used * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft920_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; status_0 &= SF_VFOB; /* get VFO B (sub display) active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLITA: /* VFOB (sub display) is TX Got that? */ *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; break; case SF_SPLITB: /* VFOA is TX */ *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_ON; break; case SF_VFOA: *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; break; case SF_VFOB: *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_OFF; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_split_freq* * * Set the '920 split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_freq | input | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if 920 is in split mode and if so sets * the frequency of the TX VFO. If not in split mode * does nothing and returns. * */ static int ft920_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, tx_freq); err = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_set_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: break; } return RIG_OK; } /* * rig_get_split_freq* * * Get the '920 split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_freq | output | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * frequency of that VFO and stores it into *tx_freq. * If not in split mode returns 0 Hz. * */ static int ft920_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_get_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: *tx_freq = 0; break; } return RIG_OK; } /* * rig_set_split_mode * * Set the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if 920 is in split mode and if so sets * the mode and passband of the TX VFO. If not in split mode * does nothing and returns. * */ static int ft920_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_set_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: break; } return RIG_OK; } /* * rig_get_split_mode* * * Get the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft920_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_get_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: *tx_mode = RIG_MODE_NONE; *tx_width = 0; break; } return RIG_OK; } /* * rig_set_rit* * * Set the RIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is ignored as RIT cannot be changed on sub VFO * * FIXME: Should rig be forced into VFO mode if RIG_VFO_A * or RIG_VFO_VFO is received? * * VFO and MEM rit values are independent. The sub display * carries an RIT value only if A<>B button is pressed or * set_vfo is called with RIG_VFO_B and the main display has * an RIT value. */ static int ft920_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); if (rit == 0) { offset = CLAR_RX_OFF; } else { offset = CLAR_RX_ON; } rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_CLARIFIER_OPS, offset, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_rit_freq(rig, FT920_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit* * * Get the RIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *rit | output | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Value of vfo is ignored as it's not needed. * * Rig returns offset as hex from 0x0000 to 0x270f for * 0 to +9999 Hz and 0xffff to 0xd8f1 for -1 to -9999 Hz * * VFO and MEM rit values are independent. The sub display * carries an RIT value only if A<>B button is pressed or * set_vfo is called with RIG_VFO_B and the main display has * an RIT value. */ static int ft920_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft920_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_CLAR; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_A_CLAR; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_B_CLAR; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; if (f > 0xd8f0) /* 0xd8f1 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f); *rit = f; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_xit * * Set the XIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is ignored as XIT cannot be changed on sub VFO * * FIXME: Should rig be forced into VFO mode if RIG_VFO_A * or RIG_VFO_VFO is received? */ static int ft920_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed xit = %li\n", __func__, xit); if (xit == 0) { offset = CLAR_TX_OFF; } else { offset = CLAR_TX_ON; } rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_CLARIFIER_OPS, offset, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_rit_freq(rig, FT920_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_xit* * * Get the XIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *xit | output | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Value of vfo is ignored as it's not needed * * Rig returns offset as hex from 0x0000 to 0x270f for * 0 to +9999 Hz and 0xffff to 0xd8f1 for -1 to -9999 Hz */ static int ft920_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } err = ft920_get_rit(rig, vfo, xit); /* abuse get_rit and store in *xit */ if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_ptt* * * Set the '920 into TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | RIG_PTT_OFF, RIG_PTT_ON * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is respected by calling ft920_set_vfo if * passed vfo != priv->current_vfo * * This command is not documented in my '920 manual, * but it works! -N0NB * */ static int ft920_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft920_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT920_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT920_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } hl_usleep(200 * 1000); // give the rig some time before we try set_freq return RIG_OK; } /* * rig_get_ptt* * * Get current PTT status * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *ptt | output | RIG_PTT_OFF, RIG_PTT_ON * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Get the PTT state */ static int ft920_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft920_priv_data *priv; unsigned char stat_0; /* ft920 status flag 0 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* * The FT-920 status gives two flags for PTT, one if the PTT * line is grounded externally and the other if the PTT line * is grounded as the result of a CAT command. However, the * 7th bit of status byte 0 is set or cleared in each case * and gives an accurate state of the PTT line. */ stat_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; stat_0 &= SF_PTT_MASK; /* get external PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: stat_0 = 0x%02x\n", __func__, stat_0); switch (stat_0) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | TUNER * status | input | 0 = bypass, 1 =inline, 2 = start tuning * | | (toggle) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Set the tuner to on, off, or start */ static int ft920_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct ft920_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s, func = %s, status = %d\n", __func__, rig_strvfo(vfo), rig_strfunc(func), status); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } switch (func) { case RIG_FUNC_TUNER: switch (status) { case TUNER_BYPASS: cmd_index = FT920_NATIVE_TUNER_BYPASS; break; case TUNER_INLINE: cmd_index = FT920_NATIVE_TUNER_INLINE; break; case TUNER_TUNING: cmd_index = FT920_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; /* wrong tuner status! */ } break; default: return -RIG_EINVAL; /* wrong function! */ } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get rig function * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | TUNER * *status | output | 0 = bypass, 1 = inline, 2 = tuning * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Read the tuner status from status flags */ static int ft920_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft920_priv_data *priv; unsigned char stat_0, stat_2; /* ft920 status flags 0, 2 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s, func = %s\n", __func__, rig_strvfo(vfo), rig_strfunc(func)); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* * The FT-920 status gives three flags for the tuner state, * one if the tuner is On/tuning, another if the tuner is * "inline" and the last if the "WAIT" light is on. * * Currently, will only check if tuner is tuning and inline. */ stat_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; // stat_0 &= SF_TUNER_TUNE; /* get tuning state */ stat_2 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_2]; // stat_2 &= SF_TUNER_INLINE; /* get tuner inline state */ rig_debug(RIG_DEBUG_TRACE, "%s: stat_0 = 0x%02x, stat_2 = 0x%02x\n", __func__, stat_0, stat_2); switch (func) { case RIG_FUNC_TUNER: if (stat_0 & SF_TUNER_TUNE) { *status = TUNER_TUNING; } else if (stat_2 & SF_TUNER_INLINE) { *status = TUNER_INLINE; } else { *status = TUNER_BYPASS; } break; case RIG_FUNC_LOCK: switch (vfo) { case RIG_VFO_A: if (stat_2 & SF_VFOA_LOCK) { *status = TRUE; } else { *status = FALSE; } break; case RIG_VFO_B: if (stat_2 & SF_VFOB_LOCK) { *status = TRUE; } else { *status = FALSE; } break; } break; default: return -RIG_EINVAL; /* wrong function! */ } return RIG_OK; } /* * ************************************ * * Private functions to ft920 backend * * ************************************ */ /* * Private helper function to retrieve update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 920 has several ways to * get data and several ways to return it. * * Need to use this when doing ft920_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft920_priv_data *priv; int n; /* for read_ */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * If we've been passed a command index (ci) that is marked * as dynamic (0), then bail out. */ if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempted to modify a complete command sequence: %i\n", __func__, ci); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the Main or Sub display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft920_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT920_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT920_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT/XIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft920_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft920_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT920_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %d Hz\n", __func__, (int)from_bcd(priv->p_cmd, FT920_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ftdx101mp.c0000664000175000017500000002733115056640443012444 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101md.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * (C) Michael Black W9MDB 2021 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D) using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx101.h" const struct newcat_priv_caps ftdx101mp_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 }, } }; const struct confparams ftdx101mp_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } } }, { RIG_CONF_END, NULL, } }; int ftdx101mp_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_4M, TOK_MAXPOWER_AM, TOK_ROOFING_FILTER, TOK_BACKEND_NONE }; struct rig_caps ftdx101mp_caps = { RIG_MODEL(RIG_MODEL_FTDX101MP), .model_name = "FTDX-101MP", .mfg_name = "Yaesu", .version = NEWCAT_VER ".12", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX101_WRITE_DELAY, .post_write_delay = FTDX101_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX101_FUNCS, .has_set_func = FTDX101_FUNCS, .has_get_level = FTDX101_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX101_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .025 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 200.0f } }, [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = FTDX101_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX101 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX101MP_RFPOWER_METER_WATTS_CAL, .vd_meter_cal = YAESU_DEFAULT_VD_METER_200W_CAL, .str_cal = FTDX101D_STR_CAL, .swr_cal = FTDX101D_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 501, 510, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(1, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(1, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(2, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(2, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX101_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX101_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX101_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX101_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX101_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx101mp_ext_tokens, .extlevels = ftdx101mp_ext_levels, .priv = &ftdx101mp_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ftdx10.c0000664000175000017500000003054215056640443012024 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx10.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX10(D/MP) using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx10.h" const struct newcat_priv_caps ftdx10_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, // { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 500, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 0 }, } }; const struct confparams ftdx10_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "500 Hz", "300 Hz (optional)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx10_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ftdx10_caps = { RIG_MODEL(RIG_MODEL_FTDX10), .model_name = "FTDX-10", .mfg_name = "Yaesu", .version = NEWCAT_VER ".9", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX10_WRITE_DELAY, .post_write_delay = FTDX10_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX10_FUNCS, .has_set_func = FTDX10_FUNCS, .has_get_level = FTDX10_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX10_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX10_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX10 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX10_RFPOWER_METER_CAL, .swr_cal = FTDX10_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 501, 510, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channels, 5-01 - 5-10, if available */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX10_ALL_RX_MODES, -1, -1, FTDX10_VFO_ALL, FTDX10_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_HF(1, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_6m(1, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX10_ALL_RX_MODES, -1, -1, FTDX10_VFO_ALL, FTDX10_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_HF(2, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_6m(2, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX10_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX10_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX10_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX10_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX10_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX10_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX10_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx10_ext_tokens, .extlevels = ftdx10_ext_levels, .priv = &ftdx10_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = NULL, .get_ant = NULL, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft891.c0000664000175000017500000005242415056640443011574 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft891.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * (C) Michael Black W9MDB 2016 -- taken from ft991c * * The FT891 is very much like the FT991 * So most of this code is a duplicate of the FT991 * * This shared library provides an API for communicating * via serial interface to an FT-891 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "newcat.h" #include "yaesu.h" #include "ft891.h" /* Prototypes */ static int ft891_init(RIG *rig); static int ft891_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft891_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft891_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft891_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft891_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); const struct confparams ft891_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft891_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FT-891 rig capabilities */ struct rig_caps ft891_caps = { RIG_MODEL(RIG_MODEL_FT891), .model_name = "FT-891", .mfg_name = "Yaesu", .version = NEWCAT_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT891_WRITE_DELAY, .post_write_delay = FT891_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT891_FUNCS, .has_set_func = FT891_FUNCS, .has_get_level = FT891_LEVELS, .has_set_level = RIG_LEVEL_SET(FT891_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_RF #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_RF #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0f / 30.0f } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDRGEN,BANDMW"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC */ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT891_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT891_RFPOWER_METER_CAL, .str_cal = FT891_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(470), FT891_ALL_RX_MODES, -1, -1, FT891_VFO_ALL, FT891_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_HF(1, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ FRQ_RNG_6m(1, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_6m(1, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(470), FT891_ALL_RX_MODES, -1, -1, FT891_VFO_ALL, FT891_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_HF(2, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ FRQ_RNG_6m(2, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_6m(2, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT891_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT891_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT891_AM_RX_MODES, Hz(100)}, /* Normal */ {FT891_AM_RX_MODES, kHz(1)}, /* Fast */ {FT891_FM_RX_MODES, Hz(100)}, /* Normal */ {FT891_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT891_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(2000)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(1400)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(800)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(400)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(200)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(100)}, /* CW, RTTY, PKT */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2250)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1500)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {FT891_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY }, {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FT891_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FT891_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft891_ext_tokens, .extlevels = ft891_ext_levels, .priv = NULL, /* private data FIXME: */ .rig_init = ft891_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = ft891_set_mode, .get_mode = newcat_get_mode, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = ft891_set_split_vfo, .get_split_vfo = ft891_get_split_vfo, .get_split_mode = ft891_get_split_mode, .set_split_mode = ft891_set_split_mode, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ static int ft891_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct newcat_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct newcat_priv_data *)STATE(rig)->priv; // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if ((split == RIG_SPLIT_ON && (vfo == tx_vfo)) || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } switch (split) { case RIG_SPLIT_ON: ci = '1'; break; case RIG_SPLIT_OFF: ci = '0'; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ST%c;", ci); if (RIG_OK != (err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err = %d\n", __func__, err); return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since can only split one way */ static int ft891_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct newcat_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct newcat_priv_data *)STATE(rig)->priv; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ST;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } // Get split mode status *split = priv->ret_data[2] != '0'; // 1=split, 2=split + 5khz rig_debug(RIG_DEBUG_TRACE, "%s: get split = 0x%02x\n", __func__, *split); *tx_vfo = RIG_VFO_A; if (*split) { *tx_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_TRACE, "%s: get tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_get_split_mode* * * Get the '891 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 891 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft891_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct newcat_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct newcat_priv_data *)STATE(rig)->priv; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "OI;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } *tx_mode = priv->ret_data[22]; return RIG_OK; } /* * rig_set_split_mode * * Set the '891 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Passsband is not set here. * FT891 apparently cannot set VFOB mode directly * So we'll just set A and swap A into B * */ static int ft891_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct newcat_priv_data *priv; freq_t b_freq; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct newcat_priv_data *)STATE(rig)->priv; // Remember VFOB frequency if (RIG_OK != (err = newcat_get_freq(rig, RIG_VFO_B, &b_freq))) { return err; } // Change mode on VFOA and make VFOB match VFOA if (RIG_OK != (err = newcat_set_mode(rig, RIG_VFO_A, tx_mode, tx_width))) { return err; } // Copy A to B SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB;"); if (RIG_OK != (err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d write_block err = %d\n", __func__, __LINE__, err); return err; } // Restore VFOB frequency if (RIG_OK != (err = newcat_set_freq(rig, RIG_VFO_B, b_freq))) { return err; } #if 0 if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } #endif return RIG_OK; } static int ft891_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv; int err; // FT891 can't set VFOB mode directly so we always set VFOA // We will always make VFOB match VFOA mode newcat_set_mode(rig, RIG_VFO_A, mode, width); priv = (struct newcat_priv_data *)STATE(rig)->priv; // Copy A to B SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB;"); if (RIG_OK != (err = newcat_set_cmd(rig))) { return err; } return RIG_OK; } static int ft891_init(RIG *rig) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s\n", __func__, rig->caps->version); ret = newcat_init(rig); if (ret != RIG_OK) { return ret; } STATE(rig)->current_vfo = RIG_VFO_A; return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft890.h0000664000175000017500000000675615056640443011607 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft890.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-890 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT890_H #define _FT890_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT890_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT890_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT890_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT890_AM_RX_MODES (RIG_MODE_AM) #define FT890_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT890_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT890_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT890_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT890_ANTS 0 /* Returned data length in bytes */ #define FT890_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT890_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT890_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT890_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT890_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT890_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT890_PACING_INTERVAL 5 #define FT890_PACING_DEFAULT_VALUE 0 #define FT890_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT890_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT890_DEFAULT_READ_TIMEOUT 649 * ( 5 + (FT890_PACING_INTERVAL * FT890_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT890_BCD_DIAL 8 #define FT890_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 649 bytes in 1487 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------ ---------------------- * * 0 1487 msec * 1 2136 msec (backend default) * 2 2785 msec * 5 4732 msec * 255 167 sec * */ #endif /* _FT890_H */ hamlib-4.6.5/rigs/yaesu/Makefile.in0000664000175000017500000007221115056640453012617 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/yaesu ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_yaesu_la_LIBADD = am__objects_1 = ft100.lo ft747.lo ft817.lo ft847.lo ft890.lo ft900.lo \ ft920.lo ft1000mp.lo ft857.lo ft897.lo ft990.lo ft990v12.lo \ frg8800.lo ft757gx.lo ft600.lo ft736.lo frg100.lo frg9600.lo \ ft1000d.lo vr5000.lo ft767gx.lo ft840.lo ft980.lo vx1700.lo \ ft710.lo pmr171.lo am__objects_2 = newcat.lo ft450.lo ft950.lo ft991.lo ft2000.lo \ ft9000.lo ft5000.lo ft1200.lo ft891.lo ftdx101.lo ftdx101mp.lo \ ft3000.lo ftdx10.lo am_libhamlib_yaesu_la_OBJECTS = yaesu.lo $(am__objects_1) \ $(am__objects_2) libhamlib_yaesu_la_OBJECTS = $(am_libhamlib_yaesu_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/frg100.Plo ./$(DEPDIR)/frg8800.Plo \ ./$(DEPDIR)/frg9600.Plo ./$(DEPDIR)/ft100.Plo \ ./$(DEPDIR)/ft1000d.Plo ./$(DEPDIR)/ft1000mp.Plo \ ./$(DEPDIR)/ft1200.Plo ./$(DEPDIR)/ft2000.Plo \ ./$(DEPDIR)/ft3000.Plo ./$(DEPDIR)/ft450.Plo \ ./$(DEPDIR)/ft5000.Plo ./$(DEPDIR)/ft600.Plo \ ./$(DEPDIR)/ft710.Plo ./$(DEPDIR)/ft736.Plo \ ./$(DEPDIR)/ft747.Plo ./$(DEPDIR)/ft757gx.Plo \ ./$(DEPDIR)/ft767gx.Plo ./$(DEPDIR)/ft817.Plo \ ./$(DEPDIR)/ft840.Plo ./$(DEPDIR)/ft847.Plo \ ./$(DEPDIR)/ft857.Plo ./$(DEPDIR)/ft890.Plo \ ./$(DEPDIR)/ft891.Plo ./$(DEPDIR)/ft897.Plo \ ./$(DEPDIR)/ft900.Plo ./$(DEPDIR)/ft9000.Plo \ ./$(DEPDIR)/ft920.Plo ./$(DEPDIR)/ft950.Plo \ ./$(DEPDIR)/ft980.Plo ./$(DEPDIR)/ft990.Plo \ ./$(DEPDIR)/ft990v12.Plo ./$(DEPDIR)/ft991.Plo \ ./$(DEPDIR)/ftdx10.Plo ./$(DEPDIR)/ftdx101.Plo \ ./$(DEPDIR)/ftdx101mp.Plo ./$(DEPDIR)/newcat.Plo \ ./$(DEPDIR)/pmr171.Plo ./$(DEPDIR)/vr5000.Plo \ ./$(DEPDIR)/vx1700.Plo ./$(DEPDIR)/yaesu.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_yaesu_la_SOURCES) DIST_SOURCES = $(libhamlib_yaesu_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ YAESUSRC = ft100.c ft100.h ft747.c ft747.h ft817.c ft817.h ft847.c ft847.h \ ft890.c ft890.h ft900.c ft900.h ft920.c ft920.h ft1000mp.c ft1000mp.h \ ft857.c ft857.h ft897.c ft897.h ft990.c ft990.h ft990v12.c ft990v12.h frg8800.c ft757gx.c \ ft757gx.h ft600.h ft600.c ft736.c frg100.c frg100.h frg9600.c ft1000d.c \ ft1000d.h vr5000.c ft767gx.c ft767gx.h ft840.c ft840.h ft980.c ft980.h \ vx1700.c vx1700.h ftdx10.h ft710.c pmr171.c NEWCATSRC = newcat.c newcat.h ft450.c ft450.h ft950.c ft950.h ft991.c ft991.h \ ft2000.c ft2000.h ft9000.c ft9000.h ft5000.c ft5000.h ft1200.c ft1200.h \ ft891.c ft891.h ftdx101.c ftdx101.h ftdx101mp.c ft3000.c ftdx10.c ft710.h noinst_LTLIBRARIES = libhamlib-yaesu.la libhamlib_yaesu_la_SOURCES = yaesu.c yaesu.h level_gran_yaesu.h $(YAESUSRC) $(NEWCATSRC) EXTRA_DIST = README.ft890 README.ft920 Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/yaesu/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/yaesu/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-yaesu.la: $(libhamlib_yaesu_la_OBJECTS) $(libhamlib_yaesu_la_DEPENDENCIES) $(EXTRA_libhamlib_yaesu_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_yaesu_la_OBJECTS) $(libhamlib_yaesu_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg8800.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg9600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1000d.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1000mp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft3000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft450.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft736.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft747.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft757gx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft767gx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft817.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft840.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft847.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft857.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft890.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft891.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft897.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft900.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft9000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft920.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft980.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft990.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft990v12.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft991.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx101.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx101mp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newcat.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmr171.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vr5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vx1700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaesu.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/frg100.Plo -rm -f ./$(DEPDIR)/frg8800.Plo -rm -f ./$(DEPDIR)/frg9600.Plo -rm -f ./$(DEPDIR)/ft100.Plo -rm -f ./$(DEPDIR)/ft1000d.Plo -rm -f ./$(DEPDIR)/ft1000mp.Plo -rm -f ./$(DEPDIR)/ft1200.Plo -rm -f ./$(DEPDIR)/ft2000.Plo -rm -f ./$(DEPDIR)/ft3000.Plo -rm -f ./$(DEPDIR)/ft450.Plo -rm -f ./$(DEPDIR)/ft5000.Plo -rm -f ./$(DEPDIR)/ft600.Plo -rm -f ./$(DEPDIR)/ft710.Plo -rm -f ./$(DEPDIR)/ft736.Plo -rm -f ./$(DEPDIR)/ft747.Plo -rm -f ./$(DEPDIR)/ft757gx.Plo -rm -f ./$(DEPDIR)/ft767gx.Plo -rm -f ./$(DEPDIR)/ft817.Plo -rm -f ./$(DEPDIR)/ft840.Plo -rm -f ./$(DEPDIR)/ft847.Plo -rm -f ./$(DEPDIR)/ft857.Plo -rm -f ./$(DEPDIR)/ft890.Plo -rm -f ./$(DEPDIR)/ft891.Plo -rm -f ./$(DEPDIR)/ft897.Plo -rm -f ./$(DEPDIR)/ft900.Plo -rm -f ./$(DEPDIR)/ft9000.Plo -rm -f ./$(DEPDIR)/ft920.Plo -rm -f ./$(DEPDIR)/ft950.Plo -rm -f ./$(DEPDIR)/ft980.Plo -rm -f ./$(DEPDIR)/ft990.Plo -rm -f ./$(DEPDIR)/ft990v12.Plo -rm -f ./$(DEPDIR)/ft991.Plo -rm -f ./$(DEPDIR)/ftdx10.Plo -rm -f ./$(DEPDIR)/ftdx101.Plo -rm -f ./$(DEPDIR)/ftdx101mp.Plo -rm -f ./$(DEPDIR)/newcat.Plo -rm -f ./$(DEPDIR)/pmr171.Plo -rm -f ./$(DEPDIR)/vr5000.Plo -rm -f ./$(DEPDIR)/vx1700.Plo -rm -f ./$(DEPDIR)/yaesu.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/frg100.Plo -rm -f ./$(DEPDIR)/frg8800.Plo -rm -f ./$(DEPDIR)/frg9600.Plo -rm -f ./$(DEPDIR)/ft100.Plo -rm -f ./$(DEPDIR)/ft1000d.Plo -rm -f ./$(DEPDIR)/ft1000mp.Plo -rm -f ./$(DEPDIR)/ft1200.Plo -rm -f ./$(DEPDIR)/ft2000.Plo -rm -f ./$(DEPDIR)/ft3000.Plo -rm -f ./$(DEPDIR)/ft450.Plo -rm -f ./$(DEPDIR)/ft5000.Plo -rm -f ./$(DEPDIR)/ft600.Plo -rm -f ./$(DEPDIR)/ft710.Plo -rm -f ./$(DEPDIR)/ft736.Plo -rm -f ./$(DEPDIR)/ft747.Plo -rm -f ./$(DEPDIR)/ft757gx.Plo -rm -f ./$(DEPDIR)/ft767gx.Plo -rm -f ./$(DEPDIR)/ft817.Plo -rm -f ./$(DEPDIR)/ft840.Plo -rm -f ./$(DEPDIR)/ft847.Plo -rm -f ./$(DEPDIR)/ft857.Plo -rm -f ./$(DEPDIR)/ft890.Plo -rm -f ./$(DEPDIR)/ft891.Plo -rm -f ./$(DEPDIR)/ft897.Plo -rm -f ./$(DEPDIR)/ft900.Plo -rm -f ./$(DEPDIR)/ft9000.Plo -rm -f ./$(DEPDIR)/ft920.Plo -rm -f ./$(DEPDIR)/ft950.Plo -rm -f ./$(DEPDIR)/ft980.Plo -rm -f ./$(DEPDIR)/ft990.Plo -rm -f ./$(DEPDIR)/ft990v12.Plo -rm -f ./$(DEPDIR)/ft991.Plo -rm -f ./$(DEPDIR)/ftdx10.Plo -rm -f ./$(DEPDIR)/ftdx101.Plo -rm -f ./$(DEPDIR)/ftdx101mp.Plo -rm -f ./$(DEPDIR)/newcat.Plo -rm -f ./$(DEPDIR)/pmr171.Plo -rm -f ./$(DEPDIR)/vr5000.Plo -rm -f ./$(DEPDIR)/vx1700.Plo -rm -f ./$(DEPDIR)/yaesu.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/yaesu/ft897.h0000664000175000017500000000444015056640443011602 /* * ft897.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT897_H #define _FT897_H 1 /* * No need to wait between written characters. */ #define FT897_WRITE_DELAY 5 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT897_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT897_TIMEOUT 200 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT897_CACHE_TIMEOUT 50 extern int ft857_set_vfo(RIG *rig, vfo_t vfo); extern int ft857_get_vfo(RIG *rig, vfo_t *vfo); #endif /* _FT897_H */ hamlib-4.6.5/rigs/yaesu/ft900.c0000664000175000017500000015416615056640443011571 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft900.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2005 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-900 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "cal.h" #include "yaesu.h" #include "ft900.h" /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* * Native FT900 functions. More to come :-) * */ enum ft900_native_cmd_e { FT900_NATIVE_SPLIT_OFF = 0, FT900_NATIVE_SPLIT_ON, FT900_NATIVE_RECALL_MEM, FT900_NATIVE_VFO_TO_MEM, FT900_NATIVE_VFO_A, FT900_NATIVE_VFO_B, FT900_NATIVE_MEM_TO_VFO, FT900_NATIVE_CLARIFIER_OPS, FT900_NATIVE_FREQ_SET, FT900_NATIVE_MODE_SET, FT900_NATIVE_PACING, FT900_NATIVE_PTT_OFF, FT900_NATIVE_PTT_ON, FT900_NATIVE_MEM_CHNL, FT900_NATIVE_OP_DATA, FT900_NATIVE_VFO_DATA, FT900_NATIVE_MEM_CHNL_DATA, FT900_NATIVE_TUNER_OFF, FT900_NATIVE_TUNER_ON, FT900_NATIVE_TUNER_START, FT900_NATIVE_READ_METER, FT900_NATIVE_READ_FLAGS, FT900_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft900_native_cmd_e ft900_native_cmd_t; /* * Internal MODES - when setting modes via FT900_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT900_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-900 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-900 manual on page 33. * */ #define FT900_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT900_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT900_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-900 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-900 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT900_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT900_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT900_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT900_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT900_SUMO_DISPLAYED_FLAG 0x09 #define FT900_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT900_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT900_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT900_SUMO_VFO_A_FLAG 0x08 #define FT900_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT900_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT900_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT900_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-900 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT900_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-900 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-900 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * Two calibration sets for the smeter/power readings */ #define FT900_STR_CAL_SMETER { 3, \ { \ { 0, -54 }, /* S0 */ \ {0x44, 0 }, /* S9 */ \ {0x9d, 60 }, /* +60dB */ \ } } #define FT900_STR_CAL_POWER { 5, \ { \ { 0, 0 }, /* 0W */ \ {0x44, 10 }, /* 10W */ \ {0x69, 25 }, /* 25W */ \ {0x92, 50 }, /* 50W */ \ {0xCE, 100 }, /* 100W */ \ } } /* * API local implementation * */ static int ft900_init(RIG *rig); static int ft900_cleanup(RIG *rig); static int ft900_open(RIG *rig); static int ft900_close(RIG *rig); static int ft900_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft900_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft900_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft900_set_vfo(RIG *rig, vfo_t vfo); static int ft900_get_vfo(RIG *rig, vfo_t *vfo); static int ft900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft900_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft900_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft900_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft900_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft900_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft900_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft900_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft900_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft900_send_static_cmd(RIG *rig, unsigned char ci); static int ft900_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft900_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft900_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft900 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft900_caps.priv? -N0NB */ struct ft900_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT900_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ int ptt; /* ptt status needed for meter reading */ }; /* * ft900 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft900_caps = { RIG_MODEL(RIG_MODEL_FT900), .model_name = "FT-900", .mfg_name = "Yaesu", .version = "20241122.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT900_WRITE_DELAY, .post_write_delay = FT900_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 32 */ .rx_range_list1 = { {kHz(100), MHz(30), FT900_ALL_RX_MODES, -1, -1, FT900_VFO_ALL, FT900_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT900_OTHER_TX_MODES, W(5), W(100), FT900_VFO_ALL, FT900_ANTS), FRQ_RNG_HF(1, FT900_AM_TX_MODES, W(2), W(25), FT900_VFO_ALL, FT900_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT900_ALL_RX_MODES, -1, -1, FT900_VFO_ALL, FT900_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT900_OTHER_TX_MODES, W(5), W(100), FT900_VFO_ALL, FT900_ANTS), FRQ_RNG_HF(2, FT900_AM_TX_MODES, W(2), W(25), FT900_VFO_ALL, FT900_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT900_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT900_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT900_AM_RX_MODES, Hz(100)}, /* Normal */ {FT900_AM_RX_MODES, kHz(1)}, /* Fast */ {FT900_FM_RX_MODES, Hz(100)}, /* Normal */ {FT900_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft900_init, .rig_cleanup = ft900_cleanup, .rig_open = ft900_open, /* port opened */ .rig_close = ft900_close, /* port closed */ .set_freq = ft900_set_freq, .get_freq = ft900_get_freq, .set_mode = ft900_set_mode, .get_mode = ft900_get_mode, .set_vfo = ft900_set_vfo, .get_vfo = ft900_get_vfo, .set_ptt = ft900_set_ptt, .get_ptt = ft900_get_ptt, .set_split_vfo = ft900_set_split_vfo, .get_split_vfo = ft900_get_split_vfo, .set_rit = ft900_set_rit, .get_rit = ft900_get_rit, .set_func = ft900_set_func, .get_level = ft900_get_level, .vfo_op = ft900_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft900_init(RIG *rig) { struct ft900_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft900_priv_data *) calloc(1, sizeof(struct ft900_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT900_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft900_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft900_open(RIG *rig) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft900_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft900_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft900_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft900_send_dial_freq(rig, FT900_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft900_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft900_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_A_FREQ; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_B_FREQ; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT900_NATIVE_OP_DATA; offset = FT900_SUMO_DISPLAYED_FREQ; count = FT900_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft900_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft900_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft900_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %li Hz\n", __func__, width); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft900 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft900_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft900_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: mode %s not supported by FT900\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-900 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft900_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft900_priv_data *priv; unsigned char my_mode, m_offset; /* ft900 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; m_offset = FT900_SUMO_VFO_A_MODE; f_offset = FT900_SUMO_VFO_A_FLAG; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; m_offset = FT900_SUMO_VFO_B_MODE; f_offset = FT900_SUMO_VFO_B_FLAG; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT900_NATIVE_OP_DATA; m_offset = FT900_SUMO_DISPLAYED_MODE; f_offset = FT900_SUMO_DISPLAYED_FLAG; count = FT900_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft900_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft900 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft900_set_vfo(RIG *rig, vfo_t vfo) { struct ft900_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT900_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft900_get_vfo(RIG *rig, vfo_t *vfo) { struct ft900_priv_data *priv; unsigned char status_0; /* ft900 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT900_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft900 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-900 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft900_get_update_data(rig, FT900_NATIVE_MEM_CHNL, FT900_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT900_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '900 into TX mode * * vfo is respected by calling ft900_set_vfo if * passed vfo != priv->current_vfo * */ static int ft900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft900_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft900_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT900_NATIVE_PTT_OFF; priv->ptt = 0; break; case RIG_PTT_ON: cmd_index = FT900_NATIVE_PTT_ON; priv->ptt = 1; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ static int ft900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft900_priv_data *priv; unsigned char status_2; /* ft900 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT900_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } priv->ptt = *ptt; return RIG_OK; } /* * rig_set_split_vfo * * set the '900 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft900_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT900_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT900_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '900 is in split mode * * vfo value is not used * */ static int ft900_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft900_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT900_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ static int ft900_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft900_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft900_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft900_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: clarifier off error: %s\n", __func__, rigerror(err)); } return err; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft900_send_rit_freq(rig, FT900_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft900_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft900_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT900_NATIVE_OP_DATA; offset = FT900_SUMO_DISPLAYED_CLAR; length = FT900_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_A_CLAR; length = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_B_CLAR; length = FT900_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft900_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '900 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft900_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %i\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT900_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT900_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '900 meter level * * vfo is ignored for now * * Meter level returned from FT-900 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft900_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft900_priv_data *priv; unsigned char *p; int err; cal_table_t cal = FT900_STR_CAL_SMETER; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft900_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft900_get_update_data(rig, FT900_NATIVE_READ_METER, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT900_SUMO_METER]; /* * My FT-900 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (priv->ptt) { cal = (cal_table_t)FT900_STR_CAL_POWER; } val->i = (int)rig_raw2val(*p, &cal); rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft900_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT900_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft900 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 900 has several ways to * get data and several ways to return it. * * Need to use this when doing ft900_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft900_priv_data *priv; int err; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; err = ft900_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft900_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT900_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT900_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft900_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft900_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT900_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %ld Hz\n", __func__, (long)from_bcd(priv->p_cmd, FT900_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/vx1700.c0000664000175000017500000011431615056640443011665 /* * Copyright (c) 2010-2011 by Mikhail Kshevetskiy (mikhail.kshevetskiy@gmail.com) * * Code based on VX-1700 CAT manual: * http://www.vertexstandard.com/downloadFile.cfm?FileID=3397&FileCatID=135&FileName=VX-1700_CAT_MANUAL_10_14_2008.pdf&FileContentType=application%2Fpdf * * WARNING: this manual has two errors * 1) Status Update Command (10h), U=01 returns 0..199 for channels 1..200 * 2) Frequency Data (bytes 1--4 of 9-Byte VFO Data Assignment, Status Update * Command (10h), U=02 and U=03) uses bytes 1--3 for frequency, byte 4 is * not used and always zero. Thus bytes 0x15,0xBE,0x68,0x00 means * frequency = 10 * 0x15BE68 = 10 * 1425000 = 14.25 MHz * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "vx1700.h" // VX-1700 native commands typedef enum vx1700_native_cmd_e { VX1700_NATIVE_RECALL_MEM = 0, /* 0x02, p1=ch */ VX1700_NATIVE_VFO_TO_MEM, /* 0x03, p1=ch, p2=0 */ VX1700_NATIVE_MEM_HIDE, /* 0x03, p1=ch, p2=1 */ VX1700_NATIVE_VFO_A, /* 0x05 */ VX1700_NATIVE_FREQ_SET, /* 0x0a, p1:4=freq */ VX1700_NATIVE_MODE_SET_LSB, /* 0x0c, p1=0x00 */ VX1700_NATIVE_MODE_SET_USB, /* 0x0c, p1=0x01 */ VX1700_NATIVE_MODE_SET_CW_W, /* 0x0c, p1=0x02 */ VX1700_NATIVE_MODE_SET_CW_N, /* 0x0c, p1=0x03 */ VX1700_NATIVE_MODE_SET_AM, /* 0x0c, p1=0x04 */ VX1700_NATIVE_MODE_SET_RTTY_LSB_W, /* 0x0c, p1=0x08 */ VX1700_NATIVE_MODE_SET_RTTY_USB_W, /* 0x0c, p1=0x09 */ VX1700_NATIVE_MODE_SET_H3E, /* 0x0c, p1=0x0d */ VX1700_NATIVE_MODE_SET_RTTY_LSB_N, /* 0x0c, p1=0x0e */ VX1700_NATIVE_MODE_SET_RTTY_USB_N, /* 0x0c, p1=0x0f */ VX1700_NATIVE_PTT_OFF, /* 0x0f, p1=0 */ VX1700_NATIVE_PTT_ON, /* 0x0f, p1=1 */ VX1700_NATIVE_UPDATE_MEM_CHNL, /* 0x10, p1=1 */ VX1700_NATIVE_UPDATE_OP_DATA, /* 0x10, p1=2 */ VX1700_NATIVE_UPDATE_VFO_DATA, /* 0x10, p1=3 */ VX1700_NATIVE_TX_POWER_LOW, /* 0x18 */ VX1700_NATIVE_TX_POWER_MID, /* 0x28 */ VX1700_NATIVE_TX_POWER_HI, /* 0x48 */ VX1700_NATIVE_CPY_RX_TO_TX, /* 0x85 */ VX1700_NATIVE_TX_FREQ_SET, /* 0x8a, p1:4=freq */ VX1700_NATIVE_OP_FREQ_STEP_UP, /* 0x8e, p1=0 */ VX1700_NATIVE_OP_FREQ_STEP_DOWN, /* 0x8e, p1=1 */ VX1700_NATIVE_READ_METER, /* 0xf7 */ VX1700_NATIVE_READ_FLAGS, /* 0xfa */ VX1700_NATIVE_SIZE } vx1700_native_cmd_t; // OpCode Declarations #define VX1700_CMD_RECALLMEM 0x02 #define VX1700_CMD_VFO2MEM 0x03 #define VX1700_CMD_SEL_VFOA 0x05 #define VX1700_CMD_SET_VFOA 0x0a #define VX1700_CMD_SEL_OP_MODE 0x0c #define VX1700_CMD_PTT 0x0f #define VX1700_CMD_UPDATE 0x10 #define VX1700_CMD_RX2TX 0x85 #define VX1700_CMD_STEP_VFO 0x8e #define VX1700_CMD_RD_METER 0xf7 #define VX1700_CMD_RD_FLAGS 0xfa // Return codes #define VX1700_CMD_RETCODE_OK 0x00 #define VX1700_CMD_RETCODE_ERROR 0xF0 // Operating Mode Status #define VX1700_MODE_LSB 0x00 #define VX1700_MODE_USB 0x01 #define VX1700_MODE_CW_W 0x02 #define VX1700_MODE_CW_N 0x03 #define VX1700_MODE_AM 0x04 #define VX1700_MODE_RTTY 0x05 // Operation Mode Selection #define VX1700_OP_MODE_LSB 0x00 #define VX1700_OP_MODE_USB 0x01 #define VX1700_OP_MODE_CW_W 0x02 #define VX1700_OP_MODE_CW_N 0x03 #define VX1700_OP_MODE_AM 0x04 #define VX1700_OP_MODE_RTTY_LSB_W 0x08 #define VX1700_OP_MODE_RTTY_USB_W 0x09 #define VX1700_OP_MODE_H3E 0x0d #define VX1700_OP_MODE_RTTY_LSB_N 0x0e #define VX1700_OP_MODE_RTTY_USB_N 0x0f // Status Flag 1 Masks #define VX1700_SF_LOCKED 0x01 /* LOCK is activated */ #define VX1700_SF_MEM 0x20 /* Memory Mode */ #define VX1700_SF_VFO 0x80 /* VFO Mode */ // Status Flag 2 Masks #define VX1700_SF_PTT_BY_CAT 0x01 /* PTT closed by CAT */ #define VX1700_SF_MEM_SCAN_PAUSE 0x02 /* Scanning paused */ #define VX1700_SF_MEM_SCAN 0x04 /* Scanning enabled */ #define VX1700_SF_RTTY_FILTER_NARROW 0x08 /* Narrow RTTY filter selected */ #define VX1700_SF_CW_FILTER_NARROW 0x10 /* Narrow CW filter selected */ #define VX1700_SF_RTTY_USB 0x20 /* USB selected for RTTY */ // Status Flag 3 Masks #define VX1700_SF_10W_TX 0x20 /* 10 Watt TX output selected */ #define VX1700_SF_TUNER_ON 0x20 /* Antenna Tuner working */ #define VX1700_SF_TRANSMISSION_ON 0x80 /* Transmission in progress */ /* HAMLIB API implementation */ static int vx1700_init(RIG *rig); static int vx1700_open(RIG *rig); static int vx1700_cleanup(RIG *rig); static const char *vx1700_get_info(RIG *rig); static int vx1700_set_vfo(RIG *rig, vfo_t vfo); static int vx1700_get_vfo(RIG *rig, vfo_t *vfo); static int vx1700_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int vx1700_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int vx1700_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int vx1700_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int vx1700_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int vx1700_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int vx1700_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int vx1700_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int vx1700_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int vx1700_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int vx1700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int vx1700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int vx1700_set_mem(RIG *rig, vfo_t vfo, int ch); static int vx1700_get_mem(RIG *rig, vfo_t vfo, int *ch); static int vx1700_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* VFO to MEM */ { 0, { 0x00, 0x00, 0x01, 0x00, 0x03 } }, /* Hide Memory Channel */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW-W */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW-N */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB-W */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB-W */ { 1, { 0x00, 0x00, 0x00, 0x0d, 0x0c } }, /* OP Mode Set H3E */ { 1, { 0x00, 0x00, 0x00, 0x0e, 0x0c } }, /* OP Mode Set RTTY LSB-N */ { 1, { 0x00, 0x00, 0x00, 0x0f, 0x0c } }, /* OP Mode Set RTTY USB-N */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x18 } }, /* Set TX power low */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x28 } }, /* Set TX power mid */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x48 } }, /* Set TX power hi */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy RX to TX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* Set TX Freq only */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8e } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct vx1700_priv_data { unsigned char ch; /* memory channel */ }; /* * vx1700 rigs capabilities. */ #define VX1700_MEM_CAP { \ .freq = 1, \ .tx_freq = 1, \ .mode = 1, \ .width = 1, \ } struct rig_caps vx1700_caps = { RIG_MODEL(RIG_MODEL_VX1700), .model_name = "VX-1700", .mfg_name = "Vertex Standard", .version = "20210221.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_NONE, /* we have DCD pin in DATA Jack, but get_dcd() is unavailable (yet?) */ .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 600, .retry = 3, .has_get_func = (RIG_FUNC_LOCK | RIG_FUNC_TUNER), .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_RFPOWER, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RFPOWER] = { .min = { .i = 0 }, .max = { .i = 2 } }, }, .parm_gran = {}, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = VX1700_VFO_OPS, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { VX1700_MIN_CHANNEL, VX1700_MAX_CHANNEL, RIG_MTYPE_MEM, VX1700_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { { kHz(30), MHz(30), VX1700_MODES, -1, -1, VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1600), MHz(4) - 1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS }, { kHz(4000), MHz(30), VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .rx_range_list2 = { { kHz(30), MHz(30), VX1700_MODES, -1, -1, VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(1600), MHz(4) - 1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS }, { kHz(4000), MHz(30), VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tuning_steps = { { VX1700_MODES, 100 }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_AM, VX1700_FILTER_WIDTH_AM }, { RIG_MODE_SSB, VX1700_FILTER_WIDTH_SSB }, { RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_WIDE }, { RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_NARROW }, RIG_FLT_END, }, .priv = NULL, .rig_init = vx1700_init, .rig_open = vx1700_open, .rig_cleanup = vx1700_cleanup, .set_vfo = vx1700_set_vfo, .get_vfo = vx1700_get_vfo, .set_freq = vx1700_set_freq, .get_freq = vx1700_get_freq, .set_split_freq = vx1700_set_split_freq, .get_split_freq = vx1700_get_split_freq, .set_mode = vx1700_set_mode, .get_mode = vx1700_get_mode, .get_ptt = vx1700_get_ptt, .set_ptt = vx1700_set_ptt, .get_info = vx1700_get_info, .set_func = vx1700_set_func, .get_func = vx1700_get_func, .set_level = vx1700_set_level, .get_level = vx1700_get_level, .set_mem = vx1700_set_mem, .get_mem = vx1700_get_mem, .vfo_op = vx1700_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static inline freq_t vx1700_read_freq_from_buf(const unsigned char p[]) { /* WARNING: documentation bug, actually frequency stored in bytes 0..2 only, byte 3 is not used and contain zero */ return ((((((unsigned)p[0]) << 8) + p[1]) << 8) + p[2]) * 10.0; } static inline int vx1700_channel_is_ok(unsigned char channel) { return ((channel >= VX1700_MIN_CHANNEL) && (channel <= VX1700_MAX_CHANNEL)) ? 1 : 0; } /* * Function definitions below */ static int vx1700_do_transaction(RIG *rig, const unsigned char cmd[YAESU_CMD_LENGTH], unsigned char *retbuf, size_t retbuf_len) { hamlib_port_t *rp = RIGPORT(rig); unsigned char default_retbuf[1]; int retval; if (retbuf == NULL) { retbuf = default_retbuf; retbuf_len = sizeof(default_retbuf); } memset(retbuf, 0, retbuf_len); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } retval = read_block(rp, retbuf, retbuf_len); if (retval != retbuf_len) { if ((retval == 1) && (retbuf[0] == VX1700_CMD_RETCODE_ERROR)) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retval == 1) { if ((cmd[4] == VX1700_CMD_UPDATE) && (cmd[3] == 0x01)) { /* read memory channel number */ if (vx1700_channel_is_ok(retbuf[0] + 1)) { /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ return RIG_OK; } if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retbuf[0] == VX1700_CMD_RETCODE_OK) { return RIG_OK; } if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int vx1700_do_static_cmd(RIG *rig, unsigned char ci) { if (rig == NULL) { return -RIG_EINVAL; } if (! ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[ci].nseq, NULL, 0); } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the cmd struct * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int vx1700_do_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { unsigned char cmd[YAESU_CMD_LENGTH]; if (rig == NULL) { return -RIG_EINVAL; } if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); cmd[3] = p1; cmd[2] = p2; cmd[1] = p3; cmd[0] = p4; return vx1700_do_transaction(rig, cmd, NULL, 0); } static int vx1700_do_freq_cmd(RIG *rig, unsigned char ci, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH]; if (rig == NULL) { return -RIG_EINVAL; } if ((ci != VX1700_NATIVE_FREQ_SET) && (ci != VX1700_NATIVE_TX_FREQ_SET)) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to use non frequency sequence\n", __func__); return -RIG_EINVAL; } memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); to_bcd(cmd, freq / 10, VX1700_BCD_DIAL); return vx1700_do_transaction(rig, cmd, NULL, 0); } static inline int vx1700_read_mem_channel_number(RIG *rig, unsigned char *channel) { int ret; unsigned char reply[VX1700_MEM_CHNL_LENGTH]; ret = vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_MEM_CHNL].nseq, reply, VX1700_MEM_CHNL_LENGTH); if (ret == -RIG_ERJCTED) { /* we are on VFO mode, so memory channel is not available at the moment */ *channel = VX1700_MIN_CHANNEL - 1; return RIG_OK; } if (ret != RIG_OK) { return ret; } /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ *channel = VX1700_MIN_CHANNEL + reply[0]; return RIG_OK; } static inline int vx1700_read_status_flags(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_FLAGS].nseq, reply, VX1700_STATUS_FLAGS_LENGTH); } static inline int vx1700_read_meter(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_METER].nseq, reply, VX1700_READ_METER_LENGTH); } static inline int vx1700_read_vfo_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_VFO_DATA].nseq, reply, VX1700_VFO_DATA_LENGTH); } static inline int vx1700_read_op_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_OP_DATA].nseq, reply, VX1700_OP_DATA_LENGTH); } #if 0 /* unused; re-enabled as needed. */ static int vx1700_read_vfo_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[VX1700_VFO_DATA_LENGTH]; if ((ret = vx1700_read_vfo_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[6]; } if (rx_freq != NULL) { *rx_freq = vx1700_read_freq_from_buf(reply + 1); } if (tx_freq != NULL) { *tx_freq = vx1700_read_freq_from_buf(reply + 10); } return RIG_OK; } #endif /* unused */ static int vx1700_read_op_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[VX1700_OP_DATA_LENGTH]; if ((ret = vx1700_read_op_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[7]; } if (rx_freq != NULL) { *rx_freq = vx1700_read_freq_from_buf(reply + 2); } if (tx_freq != NULL) { *tx_freq = vx1700_read_freq_from_buf(reply + 11); } return RIG_OK; } static const char *vx1700_get_hwmode_str(unsigned char hwmode) { switch (hwmode) { case VX1700_MODE_AM: return "AM (A3E)"; case VX1700_MODE_LSB: return "LSB (J3E)"; case VX1700_MODE_USB: return "USB (J3E)"; case VX1700_MODE_CW_W: return "CW (A1A-W)"; case VX1700_MODE_CW_N: return "CW (A1A-N)"; case VX1700_MODE_RTTY: return "RTTY[R] (J2B)"; default: return "unknown"; } } static void vx1700_parse_vfo_data(const char *func, const unsigned char buf[VX1700_VFO_DATA_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.band_data=0x%02d\n", func, buf[0]); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 1)); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.mode=0x%02d, %s\n", func, buf[6], vx1700_get_hwmode_str(buf[6])); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.band_data=0x%02d\n", func, buf[9]); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 10)); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.mode=0x%02d, %s\n", func, buf[15], vx1700_get_hwmode_str(buf[15])); } static void vx1700_parse_op_data(const char *func, const unsigned char buf[VX1700_OP_DATA_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Semi Duplex Memory Channel: %s\n", func, (buf[0] & 0x20) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Alpha Numeric Channel: %s\n", func, (buf[0] & 0x40) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Erased Memory Channel: %s\n", func, (buf[0] & 0x80) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.band_data=0x%02d\n", func, buf[1]); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 2)); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.mode=0x%02d, %s\n", func, buf[7], vx1700_get_hwmode_str(buf[7])); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.band_data=0x%02d\n", func, buf[10]); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 11)); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.mode=0x%02d, %s\n", func, buf[16], vx1700_get_hwmode_str(buf[16])); } static void vx1700_parse_status_flags(const char *func, const unsigned char buf[VX1700_STATUS_FLAGS_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: flags: Lock: %s\n", func, (buf[0] & VX1700_SF_LOCKED) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Memory Mode: %s\n", func, (buf[0] & VX1700_SF_MEM) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: VFO Mode: %s\n", func, (buf[0] & VX1700_SF_VFO) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: PTT closed by CAT: %s\n", func, (buf[1] & VX1700_SF_PTT_BY_CAT) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning paused: %s\n", func, (buf[1] & VX1700_SF_MEM_SCAN_PAUSE) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning enabled: %s\n", func, (buf[1] & VX1700_SF_MEM_SCAN) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow RTTY filter: %s\n", func, (buf[1] & VX1700_SF_RTTY_FILTER_NARROW) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow CW filter: %s\n", func, (buf[1] & VX1700_SF_CW_FILTER_NARROW) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: USB for RTTY: %s\n", func, (buf[1] & VX1700_SF_RTTY_USB) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: 10 Watt TX output: %s\n", func, (buf[2] & VX1700_SF_10W_TX) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Antenna Tuner: %s\n", func, (buf[2] & VX1700_SF_TUNER_ON) ? "on" : "off"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Transmission: %s\n", func, (buf[2] & VX1700_SF_TRANSMISSION_ON) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: end bytes (0x06, 0x04): 0x%02x, 0x%02x\n", func, buf[3], buf[4]); } static void vx1700_parse_meter(const char *func, const unsigned char buf[VX1700_READ_METER_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: meter: data: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", __func__, buf[0], buf[1], buf[2], buf[3]); rig_debug(RIG_DEBUG_TRACE, "%s: meter: end byte (0xF7): 0x%02x\n", __func__, buf[4]); } static void dump_radio_state(RIG *rig) { unsigned char channel = 0; unsigned char reply[VX1700_OP_DATA_LENGTH]; if (rig == NULL) { return; } if (vx1700_read_mem_channel_number(rig, &channel) != RIG_OK) { return; } if (vx1700_channel_is_ok(channel)) { rig_debug(RIG_DEBUG_TRACE, "%s: Current Memory Channel %d\n", __func__, (int)channel); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Memory Channel number is not available at the moment\n", __func__); } if (vx1700_read_op_data_raw(rig, reply) != RIG_OK) { return; } vx1700_parse_op_data(__func__, reply); if (vx1700_read_vfo_data_raw(rig, reply) != RIG_OK) { return; } vx1700_parse_vfo_data(__func__, reply); if (vx1700_read_status_flags(rig, reply) != RIG_OK) { return; } vx1700_parse_status_flags(__func__, reply); if (vx1700_read_meter(rig, reply) != RIG_OK) { return; } vx1700_parse_meter(__func__, reply); } static int vx1700_init(RIG *rig) { struct vx1700_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct vx1700_priv_data)); if (STATE(rig)->priv == NULL) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->ch = 1; return RIG_OK; } static int vx1700_open(RIG *rig) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; struct rig_state *state = STATE(rig); int ret; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_get_vfo(rig, &state->current_vfo)) != RIG_OK) { return ret; } if ((ret = vx1700_get_mode(rig, RIG_VFO_CURR, &state->current_mode, &state->current_width)) != RIG_OK) { return ret; } if ((ret = vx1700_read_op_data(rig, NULL, &state->current_freq, NULL)) != RIG_OK) { return ret; } if ((ret = vx1700_read_mem_channel_number(rig, &priv->ch)) != RIG_OK) { return ret; } return RIG_OK; } static int vx1700_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (STATE(rig)->priv != NULL) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } static const char *vx1700_get_info(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); dump_radio_state(rig); return "NO_INFO"; } static int vx1700_set_vfo(RIG *rig, vfo_t vfo) { const struct vx1700_priv_data *priv = (struct vx1700_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s, vfo=%s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: return vx1700_do_static_cmd(rig, VX1700_NATIVE_VFO_A); case RIG_VFO_MEM: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0); default: return -RIG_EINVAL; } } static int vx1700_get_vfo(RIG *rig, vfo_t *vfo) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *vfo = (reply[0] & VX1700_SF_MEM) ? RIG_VFO_MEM : RIG_VFO_A; return RIG_OK; } static int vx1700_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, freq); return vx1700_do_freq_cmd(rig, VX1700_NATIVE_FREQ_SET, freq); } static int vx1700_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { (void) vfo; return vx1700_read_op_data(rig, NULL, freq, NULL); } static int vx1700_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, tx_freq); int err = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } return vx1700_do_freq_cmd(rig, VX1700_NATIVE_TX_FREQ_SET, tx_freq); } static int vx1700_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return vx1700_read_op_data(rig, NULL, NULL, tx_freq); } static int vx1700_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%04x, width=%d\n", __func__, (int) mode, (int) width); if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } switch (mode) { case RIG_MODE_AM: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_AM); case RIG_MODE_LSB: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_LSB); case RIG_MODE_USB: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_USB); case RIG_MODE_CW: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_N); } case RIG_MODE_RTTY: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_N); } case RIG_MODE_RTTYR: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_N); } default: return -RIG_EINVAL; } } static int vx1700_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; unsigned char hwmode; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_op_data(rig, &hwmode, NULL, NULL)) != RIG_OK) { return ret; } switch (hwmode) { case VX1700_MODE_AM: *mode = RIG_MODE_AM; *width = VX1700_FILTER_WIDTH_AM; return RIG_OK; case VX1700_MODE_LSB: *mode = RIG_MODE_LSB; *width = VX1700_FILTER_WIDTH_SSB; return RIG_OK; case VX1700_MODE_USB: *mode = RIG_MODE_USB; *width = VX1700_FILTER_WIDTH_SSB; return RIG_OK; case VX1700_MODE_CW_W: *mode = RIG_MODE_CW; *width = VX1700_FILTER_WIDTH_WIDE; return RIG_OK; case VX1700_MODE_CW_N: *mode = RIG_MODE_CW; *width = VX1700_FILTER_WIDTH_NARROW; return RIG_OK; case VX1700_MODE_RTTY: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *mode = (reply[1] & VX1700_SF_RTTY_USB) ? RIG_MODE_RTTYR : RIG_MODE_RTTY; *width = (reply[1] & VX1700_SF_RTTY_FILTER_NARROW) ? VX1700_FILTER_WIDTH_NARROW : VX1700_FILTER_WIDTH_WIDE; return RIG_OK; default: return -RIG_EPROTO; } } static int vx1700_set_ptt_gps_jack(ptt_t ptt) { (void) ptt; /* * FIXME * * We are using GPIO to manage PTT pin in GPS/Data jack. * This highly bound to our specific device, so it makes * no sense to put our code here. * On regular PC this should be managed in another way, * probably via DTR/RTS. */ return -RIG_EINVAL; } static int vx1700_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { rmode_t mode; pbwidth_t width; int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s, ptt=%d\n", __func__, ptt); /* * We have 3 PTT source on Vertex Standard VX-1700: * 1) ptt on radio garniture (not checked, FIXME) * 2) PTT commands inside CAT operation protocol * - select radio garniture as audio input/output source * - does not work in RTTY/RTTYR modes * 3) PTT pin in GPS/Data jack * - select GPS/Data jack as input/output source * - does not work in CW/AM modes */ if ((ret = vx1700_get_mode(rig, vfo, &mode, &width)) != RIG_OK) { return ret; } switch (mode) { case RIG_MODE_AM: case RIG_MODE_CW: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_ON); case RIG_PTT_OFF: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_OFF); default: return -RIG_EINVAL; } case RIG_MODE_LSB: case RIG_MODE_USB: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_ON); case RIG_PTT_ON_DATA: return vx1700_set_ptt_gps_jack(RIG_PTT_ON); case RIG_PTT_OFF: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } if (reply[1] & VX1700_SF_PTT_BY_CAT) { /* PTT was turned on by CAT command, turn it off accordingly */ return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_OFF); } /* PTT was turned on via special pin on GPS/DATA jack */ return vx1700_set_ptt_gps_jack(RIG_PTT_OFF); default: return -RIG_EINVAL; } case RIG_MODE_RTTY: case RIG_MODE_RTTYR: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_DATA: return vx1700_set_ptt_gps_jack(RIG_PTT_ON); case RIG_PTT_OFF: return vx1700_set_ptt_gps_jack(RIG_PTT_OFF); default: return -RIG_EINVAL; } default: return -RIG_EINVAL; } } static int vx1700_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *ptt = (reply[2] & VX1700_SF_TRANSMISSION_ON) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } static int vx1700_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: func=%s, status=%d\n", __func__, rig_strfunc(func), status); return -RIG_EINVAL; } static int vx1700_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: func=%s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_LOCK: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *status = (reply[0] & VX1700_SF_LOCKED) ? 1 : 0; return RIG_OK; case RIG_FUNC_TUNER: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *status = (reply[2] & VX1700_SF_TUNER_ON) ? 1 : 0; return RIG_OK; default: return -RIG_EINVAL; } } static int vx1700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: level=%s, val=???\n", __func__, rig_strlevel(level)); switch (level) { case RIG_LEVEL_RFPOWER: if ((val.f < 0.0) || (val.f > 1.0)) { return -RIG_EINVAL; } if (val.f < (1.0 / 3.0)) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_LOW); } if (val.f < (2.0 / 3.0)) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_MID); } return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_HI); default: return -RIG_EINVAL; } } static int vx1700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: level=%s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } static int vx1700_set_mem(RIG *rig, vfo_t vfo, int ch) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; const struct rig_state *state = STATE(rig); if (! vx1700_channel_is_ok(ch)) { return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = state->current_vfo; } if (vfo == RIG_VFO_MEM) { int ret; ret = vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (ret == RIG_OK) { priv->ch = ch; } return ret; } priv->ch = ch; return RIG_OK; } static int vx1700_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; const struct rig_state *state = STATE(rig); unsigned char channel = 0; if (vfo == RIG_VFO_CURR) { vfo = state->current_vfo; } if (vfo == RIG_VFO_MEM) { int ret; ret = vx1700_read_mem_channel_number(rig, &channel); if (ret != RIG_OK) { return ret; } if (vx1700_channel_is_ok(channel)) { *ch = priv->ch = channel; return RIG_OK; } return -RIG_ERJCTED; } if (! vx1700_channel_is_ok(priv->ch)) { return -RIG_ERJCTED; } *ch = priv->ch; return RIG_OK; } static int vx1700_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct vx1700_priv_data *priv = (struct vx1700_priv_data *) STATE(rig)->priv; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: op=0x%04x\n", __func__, (int) op); switch (op) { case RIG_OP_TO_VFO: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0); case RIG_OP_FROM_VFO: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_VFO_TO_MEM, priv->ch, 0, 0, 0); case RIG_OP_UP: return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_UP); case RIG_OP_DOWN: return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_DOWN); default: return -RIG_EINVAL; } } hamlib-4.6.5/rigs/yaesu/yaesu.c0000664000175000017500000001476715056640443012057 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * yaesu.c - (C) Stephane Fillod 2001-2010 * * This shared library provides an API for communicating * via serial interface to a Yaesu rig * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "yaesu.h" struct yaesu_id { rig_model_t model; int id1, id2; }; #define UNKNOWN_ID -1 /* * Identification number as returned by 0xFA opcode. * Note: On the FT736R, the 0xFA opcode sets CTCSS tone code * * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF */ static const struct yaesu_id yaesu_id_list[] = { { RIG_MODEL_FT1000D, 0x10, 0x21 }, /* or 0x10, 0x00 ? */ { RIG_MODEL_FT990, 0x09, 0x90 }, { RIG_MODEL_FT990UNI, 0x09, 0x90 }, { RIG_MODEL_FT890, 0x08, 0x41 }, { RIG_MODEL_FRG100, 0x03, 0x92 }, /* TBC, inconsistency in manual */ { RIG_MODEL_FT1000MP, 0x03, 0x93 }, { RIG_MODEL_FT1000MPMKV, 0x03, 0x93 }, /* or 0x10, 0x00 ? */ { RIG_MODEL_FT1000MPMKVFLD, 0x03, 0x93 }, { RIG_MODEL_VX1700, 0x06, 0x04 }, { RIG_MODEL_NONE, UNKNOWN_ID, UNKNOWN_ID }, /* end marker */ }; /* * initrigs_yaesu is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(yaesu) { rig_debug(RIG_DEBUG_VERBOSE, "yaesu: %s called\n", __func__); ft450d_caps = ft450_caps; ft450d_caps.rig_model = RIG_MODEL_FT450D; ft450d_caps.model_name = "FT-450D"; ft450d_caps.level_gran[LVL_RFPOWER].min.f = .05; ft450d_caps.level_gran[LVL_RFPOWER].step.f = 1.0f / 100.0f; rig_register(&ft100_caps); rig_register(&ft450_caps); rig_register(&ft450d_caps); rig_register(&ft736_caps); rig_register(&ft747_caps); rig_register(&ft757gx_caps); rig_register(&ft757gx2_caps); rig_register(&ft600_caps); rig_register(&ft767gx_caps); rig_register(&ft817_caps); rig_register(&ft847_caps); rig_register(&ft857_caps); rig_register(&ft897_caps); rig_register(&ft840_caps); rig_register(&ft890_caps); rig_register(&ft900_caps); rig_register(&ft920_caps); rig_register(&ft950_caps); rig_register(&ft980_caps); rig_register(&ft990_caps); rig_register(&ft990uni_caps); rig_register(&ft1000_caps); rig_register(&ft1000d_caps); rig_register(&ft1000mp_caps); rig_register(&ft1000mpmkv_caps); rig_register(&ft1000mpmkvfld_caps); rig_register(&ft2000_caps); rig_register(&ftdx3000_caps); rig_register(&ftdx5000_caps); rig_register(&ft9000_caps); rig_register(&ft9000Old_caps); rig_register(&frg100_caps); rig_register(&frg8800_caps); rig_register(&frg9600_caps); rig_register(&vr5000_caps); rig_register(&vx1700_caps); rig_register(&ftdx1200_caps); rig_register(&ft991_caps); rig_register(&ft891_caps); rig_register(&ft847uni_caps); rig_register(&ftdx101d_caps); rig_register(&ft818_caps); rig_register(&ftdx10_caps); rig_register(&ft897d_caps); rig_register(&ftdx101mp_caps); rig_register(&mchfqrp_caps); rig_register(&ft650_caps); rig_register(&ft710_caps); rig_register(&q900_caps); rig_register(&pmr171_caps); return RIG_OK; } /* * proberigs_yaesu * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_yaesu(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(yaesu) { unsigned char idbuf[YAESU_CMD_LENGTH + 1]; static const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xfa}; int id_len = -1, i, id1, id2; int retval = -1; static const int rates[] = { 4800, 57600, 9600, 38400, 0 }; /* possible baud rates */ int rates_idx; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 20; port->parm.serial.stop_bits = 2; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } /* send READ STATUS cmd to rig */ retval = write_block(port, cmd, YAESU_CMD_LENGTH); id_len = read_block(port, idbuf, YAESU_CMD_LENGTH); close(port->fd); if (retval == RIG_OK && id_len > 0) { break; } } if (retval != RIG_OK || id_len < 0) { return RIG_MODEL_NONE; } /* * reply should be [Flag1,Flag2,Flag3,ID1,ID2] */ if (id_len != 5 && id_len != 6) { idbuf[YAESU_CMD_LENGTH] = '\0'; rig_debug(RIG_DEBUG_WARN, "probe_yaesu: protocol error," " expected %d, received %d: %s\n", 6, id_len, idbuf); return RIG_MODEL_NONE; } id1 = idbuf[3]; id2 = idbuf[4]; for (i = 0; yaesu_id_list[i].model != RIG_MODEL_NONE; i++) { if (id1 == yaesu_id_list[i].id1 && id2 == yaesu_id_list[i].id2) { rig_debug(RIG_DEBUG_VERBOSE, "probe_yaesu: " "found ID %02xH %02xH\n", id1, id2); if (cfunc) { (*cfunc)(port, yaesu_id_list[i].model, data); } return yaesu_id_list[i].model; } } /* * not found in known table.... * update yaesu_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_yaesu: found unknown device " "with ID %02xH %02xH, please report to Hamlib " "developers.\n", id1, id2); return RIG_MODEL_NONE; } hamlib-4.6.5/rigs/yaesu/ftdx101.c0000664000175000017500000003354315056640443012111 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D/MP) using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx101.h" const struct newcat_priv_caps ftdx101d_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 }, } }; const struct confparams ftdx101d_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { TOK_MAXPOWER_HF, "MAXPOWER_HF", "Maxpower HF", "Maxpower HF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_6M, "MAXPOWER_6M", "Maxpower 6m", "Maxpower 6m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_4M, "MAXPOWER_4M", "Maxpower 4m", "Maxpower 4m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { TOK_MAXPOWER_AM, "MAXPOWER_AM", "Maxpower AM", "Maxpower AM", NULL, RIG_CONF_NUMERIC, { .n = { .min = 5, .max = 25, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx101d_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_4M, TOK_MAXPOWER_AM, TOK_BACKEND_NONE }; struct rig_caps ftdx101d_caps = { RIG_MODEL(RIG_MODEL_FTDX101D), .model_name = "FTDX-101D", .mfg_name = "Yaesu", .version = NEWCAT_VER ".22", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX101_WRITE_DELAY, .post_write_delay = FTDX101_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX101_FUNCS, .has_set_func = FTDX101_FUNCS, .has_get_level = FTDX101_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX101_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX101_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX101 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX101D_RFPOWER_METER_WATTS_CAL, .alc_cal = FTDX101D_ALC_METER_CAL, .str_cal = FTDX101D_STR_CAL, .swr_cal = FTDX101D_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 501, 510, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(1, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(1, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(2, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(2, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX101_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX101_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX101_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX101_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX101_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx101d_ext_tokens, .extlevels = ftdx101d_ext_levels, .priv = &ftdx101d_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/pmr171.c0000664000175000017500000011103115056640443011736 /* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * pmr171.c - borrowed from ft817.c * (C) Michael Black W9MDB 2024 * This shared library provides an API for communicating * via serial interface to an Guohe PMR-171 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817 which has then been borrowed * for the PMR-171. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" //#include "pmr171.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" struct pmr171_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* Raw data from rig. Highest bit 0 = PTT */ /* tx levels */ struct timeval tx_level_tv; unsigned char swr_level; unsigned char alc_level; unsigned char mod_level; unsigned char pwr_level; /* TX power level */ /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[5]; /* 5 bytes, NOT related to YAESU_CMD_LENGTH */ /* Digi mode is not part of regular fm_status response. * So keep track of it in a separate variable. */ unsigned char dig_mode; }; static int pmr171_init(RIG *rig); static int pmr171_open(RIG *rig); static int pmr171_cleanup(RIG *rig); static int pmr171_close(RIG *rig); static int pmr171_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int pmr171_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int pmr171_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int pmr171_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int pmr171_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int pmr171_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int pmr171_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int pmr171_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int pmr171_set_powerstat(RIG *rig, powerstat_t status); #if 0 static int pmr171_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int pmr171_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int pmr171_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int pmr171_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int pmr171_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int pmr171_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int pmr171_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int pmr171_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int pmr171_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int pmr171_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int pmr171_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int pmr171_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int pmr171_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); #endif #define FT817_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTFM|\ RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY) #define FT817_CWN_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY) #define FT817_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT817_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_AM_TX_MODES (RIG_MODE_AM) #define FT817_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT817_ANT_FRONT (RIG_ANT_1) #define FT817_ANT_REAR (RIG_ANT_2) #define FT817_ANTS (FT817_ANT_FRONT | FT817_ANT_REAR) #define FT817_STR_CAL { 16, \ { \ { 0x00, -54 }, /* S0 */ \ { 0x01, -48 }, \ { 0x02, -42 }, \ { 0x03, -36 }, \ { 0x04, -30 }, \ { 0x05, -24 }, \ { 0x06, -18 }, \ { 0x07, -12 }, \ { 0x08, -6 }, \ { 0x09, 0 }, /* S9 */ \ { 0x0A, 10 }, /* +10 */ \ { 0x0B, 20 }, /* +20 */ \ { 0x0C, 30 }, /* +30 */ \ { 0x0D, 40 }, /* +40 */ \ { 0x0E, 50 }, /* +50 */ \ { 0x0F, 60 } /* +60 */ \ } } // Thanks to Olivier Schmitt sc.olivier@gmail.com for these tables #define FT817_PWR_CAL { 9, \ { \ { 0x00, 0 }, \ { 0x01, 10 }, \ { 0x02, 14 }, \ { 0x03, 20 }, \ { 0x04, 34 }, \ { 0x05, 50 }, \ { 0x06, 66 }, \ { 0x07, 82 }, \ { 0x08, 100 } \ } } #define FT817_ALC_CAL { 6, \ { \ { 0x00, 0 }, \ { 0x01, 20 }, \ { 0x02, 40 }, \ { 0x03, 60 }, \ { 0x04, 80 }, \ { 0x05, 100 } \ } } #define FT817_SWR_CAL { 2, \ { \ { 0, 0 }, \ { 15, 100 } \ } } // similar to FT817 but with header and CRC check struct rig_caps pmr171_caps = { RIG_MODEL(RIG_MODEL_PMR171), .model_name = "PMR-171", .mfg_name = "Guohe", .version = "20240704.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 2, .has_get_func = RIG_FUNC_NONE, // .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, // .has_get_level = // RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | // RIG_LEVEL_ALC | RIG_LEVEL_SWR, // .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = pmr171_init, .rig_cleanup = pmr171_cleanup, .rig_open = pmr171_open, .rig_close = pmr171_close, // .get_vfo = pmr171_get_vfo, // .set_vfo = pmr171_set_vfo, .set_freq = pmr171_set_freq, .get_freq = pmr171_get_freq, // using cache for now until we determine timing .set_mode = pmr171_set_mode, .get_mode = pmr171_get_mode, // using cache for now until we determine timing .set_ptt = pmr171_set_ptt, .get_ptt = pmr171_get_ptt, .set_split_vfo = pmr171_set_split_vfo, .get_split_vfo = pmr171_get_split_vfo, // TBD .set_powerstat = pmr171_set_powerstat, #if 0 .get_dcd = pmr171_get_dcd, .set_rptr_shift = pmr171_set_rptr_shift, .set_rptr_offs = pmr171_set_rptr_offs, .set_rit = pmr171_set_rit, .set_dcs_code = pmr171_set_dcs_code, .set_ctcss_tone = pmr171_set_ctcss_tone, .set_dcs_sql = pmr171_set_dcs_sql, .set_ctcss_sql = pmr171_set_ctcss_sql, .power2mW = pmr171_power2mW, .mW2power = pmr171_mW2power, .get_level = pmr171_get_level, .set_func = pmr171_set_func, .vfo_op = pmr171_vfo_op, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //**************************************************** //** Function name: CRC16Check -- from the PMR-171 manual //** Input: buf The data to verify; //** len The length of the data to verify //** Output: Check value //** Function description: CRC16 cyclic redundancy check //** Note: The check mode is CRC16/CCITT-FALSE, pay attention to the variable type //*****************************************************/ #include uint16_t CRC16Check(const unsigned char *buf, int len) { uint16_t crc = 0xFFFF; // Initial value uint16_t polynomial = 0x1021; // Polynomial x^16 + x^12 + x^5 + 1 for (int i = 0; i < len; i++) { crc ^= ((uint16_t)buf[i] << 8); // XOR byte into the upper 8 bits of crc for (int j = 0; j < 8; j++) { if (crc & 0x8000) { crc = (crc << 1) ^ polynomial; } else { crc = crc << 1; } } } return crc; } #if 0 // manual's method does not compute the correct CRC // some day when I'm bored I'll debug this unsigned int CRC16Checkx(unsigned char *buf, unsigned char len) { unsigned char i, j; unsigned int uncrcReg = 0xFFFF; unsigned int uncur; for (i = 0; i < len; i++) { uncur = buf[i] << 8; printf("buf[%d]=x%04x\n", i, uncur); for (j = 0; j < 8; j++) { if ((int)(uncrcReg ^ uncur) < 0) { uncrcReg = (uncrcReg << 1) ^ 0x1021; } else { uncrcReg <<= 1; } uncur <<= 1; } } printf("CRC=%04x\n", uncrcReg); return uncrcReg; } #endif /* ---------------------------------------------------------------------- */ static int pmr171_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called, version %s\n", __func__, rig->caps->version); if ((STATE(rig)->priv = calloc(1, sizeof(struct pmr171_priv_data))) == NULL) { return -RIG_ENOMEM; } CACHE(rig)->freqMainA = 14999000; CACHE(rig)->freqMainB = 14999000; return RIG_OK; } static int pmr171_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } static int pmr171_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } static int pmr171_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ #if 0 static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } #endif static int pmr171_send_cmd1(RIG *rig, unsigned char cmd, unsigned char *reply) { hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); unsigned char buf[8] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x03, 0x00, 0x00, 0x00 }; buf[5] = cmd; unsigned int crc = CRC16Check(&buf[4], 2); buf[6] = crc >> 8; buf[7] = crc & 0xff; rig_flush(rp); write_block(rp, buf, 8); return RIG_OK; } #define GUOHE_MODE_TABLE_MAX 9 rmode_t pmr171_modes[GUOHE_MODE_TABLE_MAX] = { RIG_MODE_USB, RIG_MODE_LSB, RIG_MODE_CWR, RIG_MODE_CW, RIG_MODE_AM, RIG_MODE_FM, RIG_MODE_FMN, RIG_MODE_PKTUSB, RIG_MODE_RTTY // not functioning }; rmode_t guohe2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=0x%02x\n", __func__, mode); if (mode >= GUOHE_MODE_TABLE_MAX) { return (RIG_MODE_NONE); } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning %s\n", __func__, rig_strrmode(mode_table[mode])); return (mode_table[mode]); } unsigned char rmode2guohe(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); if (mode != RIG_MODE_NONE) { unsigned char i; for (i = 0; i < GUOHE_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: returning 0x%02x\n", __func__, i); return (i); } } } return (-1); } /** * Converting to Big-endian bytes */ unsigned char *to_be(unsigned char data[], unsigned long long freq, unsigned int byte_len) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = byte_len - 1; i >= 0; i--) { unsigned char a = freq & 0xFF; freq >>= 8; data[i] = a; } return data; } unsigned long long from_be(const unsigned char data[], unsigned int byte_len) { int i; unsigned long long f = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; i < byte_len; i++) { f = (f << 8) + data[i]; } return f; } static int pmr171_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); unsigned char reply[80]; freq_t vfoa, vfob; // probably already read VFO_A so just return cache for VFO_B for now if (vfo == RIG_VFO_B) { *freq = cachep->freqMainB; return RIG_OK; } pmr171_send_cmd1(rig, 0x0b, 0); read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); vfoa = from_be(&reply[9], 4); vfob = from_be(&reply[13], 4); cachep->freqMainA = vfoa; cachep->freqMainB = vfob; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfoa=%.0f, vfob=%.0f\n", __func__, vfoa, vfob); // Now grab the ptt status cachep->ptt = (reply[6] == 1); // And the mode cachep->modeMainA = guohe2rmode(reply[7], pmr171_modes); cachep->modeMainB = guohe2rmode(reply[8], pmr171_modes); if (vfo == RIG_VFO_A) { *freq = cachep->freqMainA; } else { *freq = cachep->freqMainB; } return RIG_OK; } static int pmr171_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct rig_cache *cachep = CACHE(rig); if (vfo == RIG_VFO_B) { *mode = cachep->modeMainA; } else { *mode = cachep->modeMainB; } *width = 2400; return RIG_OK; } static int pmr171_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { *split = CACHE(rig)->split; if (*split) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } return RIG_OK; } static int pmr171_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { //struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *ptt = CACHE(rig)->ptt; return RIG_OK; } #if 0 static int pmr171_get_tx_level(RIG *rig, value_t *val, unsigned char *tx_level, const cal_table_float_t *cal) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_level_tv)) { int n; ptt_t ptt; /* Default to not keyed */ *tx_level = 0; /* TX metering is special; it sends 1 byte if not keyed and 2 if keyed. * To handle this properly we first verify the rig is keyed. * Otherwise we experience at least a full timeout and * perhaps pointless retries + timeouts. */ n = pmr171_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } if (ptt == RIG_PTT_OFF) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not keyed\n", __func__); return -RIG_ERJCTED; //Or return OK? } n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_TX_METERING); if (n != RIG_OK) { return n; } } val->f = rig_raw2val_float(*tx_level, cal); rig_debug(RIG_DEBUG_VERBOSE, "%s: level %f\n", __func__, val->f); return RIG_OK; } /* frontend will always use RAWSTR+cal_table */ static int pmr171_get_smeter_level(RIG *rig, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } //n = (p->rx_status & 0x0F) - 9; //val->i = n * ((n > 0) ? 10 : 6); /* S-meter value is returned in the lower 4 bits. 0x00 = S0 (-54dB) 0x01 = S1 0x02 = S2 ... 0x09 = S9 (0dB) 0x0A = S9+10 (10dB) 0x0B = S9+20 and so on */ n = (p->rx_status & 0x0F); if (n < 0x0A) { val->i = (6 * n) - 54; } else { val->i = 10 * (n - 9); } return RIG_OK; } static int pmr171_get_raw_smeter_level(RIG *rig, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int pmr171_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: /* The front-end will always call for RAWSTR and use the cal_table */ return pmr171_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return pmr171_get_raw_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: return pmr171_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); case RIG_LEVEL_ALC: return pmr171_get_tx_level(rig, val, &p->alc_level, &rig->caps->alc_cal); case RIG_LEVEL_SWR: return pmr171_get_tx_level(rig, val, &p->swr_level, &rig->caps->swr_cal); default: return -RIG_EINVAL; } return RIG_OK; } static int pmr171_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } #endif /* ---------------------------------------------------------------------- */ static int pmr171_read_ack(RIG *rig) { unsigned char dummy; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (rp->post_write_delay == 0) { if (read_block(rp, &dummy, 1) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error reading ack\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: adjusting post_write_delay to avoid ack\n", __func__); rp->post_write_delay = 10; // arbitrary choice right now of max 100 cmds/sec return RIG_OK; // let it continue without checking for ack now } rig_debug(RIG_DEBUG_TRACE, "%s: ack value=0x%x\n", __func__, dummy); } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete 2-byte sequences. */ static int pmr171_send_cmd2(RIG *rig, unsigned char cmd, unsigned char value, int response) { unsigned char reply[256]; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; buf[5] = cmd; buf[6] = value; unsigned int crc = CRC16Check(&buf[4], 3); buf[7] = crc >> 8; buf[8] = crc & 0xff; rig_flush(rp); write_block(rp, buf, 9); if (response) { read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); } return pmr171_read_ack(rig); } /* * The same for incomplete commands. */ #if 0 static int pmr171_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return pmr171_read_ack(rig); } #endif static int pmr171_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[16] = { 0xa5, 0xa5, 0xa5, 0xa5, 11, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char reply[16]; //int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "pmr171: requested freq = %"PRIfreq" Hz\n", freq); /* fill in the frequency */ if (vfo == RIG_VFO_B) { to_be(&cmd[6], CACHE(rig)->freqMainA, 4); to_be(&cmd[10], freq, 4); } else { to_be(&cmd[6], freq, 4); to_be(&cmd[10], CACHE(rig)->freqMainB, 4); } unsigned int crc = CRC16Check(&cmd[4], 10); cmd[14] = crc >> 8; cmd[15] = crc & 0xff; rig_flush(rp); write_block(rp, cmd, 16); read_block(rp, reply, 16); dump_hex(reply, 16); return RIG_OK; } static int pmr171_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd[10] = { 0xa5, 0xa5, 0xa5, 0xa5, 5, 0x0a, 0x00, 0x00, 0x00, 0x00 }; unsigned char reply[10]; int crc; unsigned char i = rmode2guohe(mode, pmr171_modes); if (i != (-1)) { if (vfo == RIG_VFO_B) { cmd[6] = rmode2guohe(CACHE(rig)->modeMainA, pmr171_modes); cmd[7] = i; } else { cmd[6] = i; cmd[7] = rmode2guohe(CACHE(rig)->modeMainB, pmr171_modes); } crc = CRC16Check(&cmd[4], 4); cmd[8] = crc >> 8; cmd[9] = crc & 0xff; rig_flush(rp); write_block(rp, cmd, 10); read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); dump_hex(reply, reply[4] + 5); /* // Grab the modes CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); */ return RIG_OK; } rig_debug(RIG_DEBUG_ERR, "%s: invalid mode=%s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } static int pmr171_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char reply[9]; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); // According to the manual, sending 0 means PTT ON. // TODO: How to process ack messages? switch (ptt) { case RIG_PTT_ON: return pmr171_send_cmd2(rig, 0x07, 0x00, 1); case RIG_PTT_OFF: return pmr171_send_cmd2(rig, 0x07, 0x01, 1); default: return -RIG_EINVAL; } read_block(rp, reply, 9); dump_hex(reply, 9); } #if 0 static int pmr171_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_LOCK_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } default: return -RIG_EINVAL; } } static int pmr171_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; /* int n; */ rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set DCS code (%u)\n", code); if (code == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); /* FT-817 does not have the DCS_ENC_ON command, so we just set the tone here */ /* if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) */ /* return n; */ /* return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ENC_ON); */ return pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data); } static int pmr171_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set DCS sql (%u)\n", code); if (code == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } static int pmr171_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } static int pmr171_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } static int pmr171_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { /* Note: this doesn't have effect unless FT817 is in FM mode although the command is accepted in any mode. */ rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set repeater shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } static int pmr171_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set repeater offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_RPT_OFFSET, data); } static int pmr171_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } else { pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } */ return RIG_OK; } #endif static int pmr171_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case RIG_POWER_OFF: return pmr171_send_cmd2(rig, 0x0c, 0x00, 0); case RIG_POWER_ON: return pmr171_send_cmd2(rig, 0x0c, 0x01, 0); case RIG_POWER_STANDBY: default: return -RIG_EINVAL; } } #if 0 static int pmr171_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { int n; case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct pmr171_priv_data *) STATE(rig)->priv)->fm_status_tv); n = pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(100 * 1000); // rig needs a little time to do this return n; default: return -RIG_EINVAL; } } #endif /* FIXME: this function silently ignores the vfo args and just turns split ON or OFF. */ static int pmr171_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_ON: pmr171_send_cmd2(rig, 0x07, 0x1c, 1); break; case RIG_SPLIT_OFF: pmr171_send_cmd2(rig, 0x07, 0x1c, 0); break; default: return -RIG_EINVAL; } CACHE(rig)->split = split; return RIG_OK; } #if 0 /* FIXME: currently ignores mode and freq */ /* No documentation on how to interpret it but the max number of bars on the display is 10 and I measure: 8 bars = 5W 5 bars = 2.5W 3 bars = 1W 1 bar = 0.5W */ static int pmr171_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mwpower = (int)(power * 6000); return RIG_OK; } /* FIXME: currently ignores mode and freq */ static int pmr171_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *power = mwpower / 6000.0; return RIG_OK; } #endif /* ---------------------------------------------------------------------- */ hamlib-4.6.5/rigs/yaesu/ft9000.c0000664000175000017500000004121615056640443011640 /* * hamlib - (C) Frank Singleton 9000 (javabear at users.sourceforge.net) * * ft9000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-9000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "yaesu.h" #include "newcat.h" #include "ft9000.h" #include "tones.h" /* * ft9000 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft9000_caps = { RIG_MODEL(RIG_MODEL_FT9000), .model_name = "FTDX-9000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT9000_WRITE_DELAY, .post_write_delay = FT9000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT9000_FUNCS, .has_set_func = FT9000_FUNCS, .has_get_level = FT9000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT9000_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT9000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_ANT | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 9000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT9000_RFPOWER_METER_CAL, .str_cal = FT9000_STR_CAL, .chan_list = { /* TBC */ { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham */ {kHz(30), MHz(60), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT9000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT9000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT9000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT9000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT9000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT9000_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT9000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft9000Old_caps = { RIG_MODEL(RIG_MODEL_FT9000OLD), .model_name = "FTDX-9000 Old", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT9000_WRITE_DELAY, .post_write_delay = FT9000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT9000_FUNCS, .has_set_func = FT9000_FUNCS, .has_get_level = FT9000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT9000_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT9000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_ANT | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 9000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT9000_RFPOWER_METER_CAL, .str_cal = FT9000_STR_CAL, .chan_list = { /* TBC */ { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham */ {kHz(30), MHz(60), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT9000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT9000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT9000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT9000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT9000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT9000_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT9000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, // .set_vfo = newcat_set_vfo, // old FTDX9000 does not have VS command // .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft847.c0000664000175000017500000016500315056640443011573 /* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft847.c - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * This shared library provides an API for communicating * via serial interface to an FT-847 using the "CAT" interface. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO - Remove static stuff, see ft747 for new style [started] * - create yaesu.h for common command structure etc..[started] * - add mode set before freq set to avoid prior mode offset (eg: CW) * */ /* * Notes on limitations in RIG control capabilities. These are * related to the Yaesu's FT847 design, not my program :-) * * 1. Rig opcodes allow only 10Hz resolution. * 2. Cannot select VFO B * 3. Using CAT and Tuner controls simultaneously can * cause problems. * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft847.h" #include "misc.h" #include "bandplan.h" #include "tones.h" /* * Native FT847 functions. This is what I have to work with :-) * */ enum ft847_native_cmd_e { /* Set commands to the rig */ FT_847_NATIVE_CAT_ON = 0, FT_847_NATIVE_CAT_OFF, FT_847_NATIVE_CAT_PTT_ON, FT_847_NATIVE_CAT_PTT_OFF, FT_847_NATIVE_CAT_SAT_MODE_ON, FT_847_NATIVE_CAT_SAT_MODE_OFF, FT_847_NATIVE_CAT_SET_FREQ_MAIN, FT_847_NATIVE_CAT_SET_FREQ_SAT_RX_VFO, FT_847_NATIVE_CAT_SET_FREQ_SAT_TX_VFO, FT_847_NATIVE_CAT_SET_MODE_MAIN_LSB, /* MAIN VFO */ FT_847_NATIVE_CAT_SET_MODE_MAIN_USB, FT_847_NATIVE_CAT_SET_MODE_MAIN_CW, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWR, FT_847_NATIVE_CAT_SET_MODE_MAIN_AM, FT_847_NATIVE_CAT_SET_MODE_MAIN_FM, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWN, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWRN, FT_847_NATIVE_CAT_SET_MODE_MAIN_AMN, FT_847_NATIVE_CAT_SET_MODE_MAIN_FMN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_LSB, /* SAT RX VFO */ FT_847_NATIVE_CAT_SET_MODE_SAT_RX_USB, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CW, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWR, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_AM, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_FM, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWRN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_AMN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_FMN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_LSB, /* SAT TX VFO */ FT_847_NATIVE_CAT_SET_MODE_SAT_TX_USB, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CW, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWR, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_AM, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_FM, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWRN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_AMN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_FMN, FT_847_NATIVE_CAT_SET_DCS_ON_MAIN, /* MAIN CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_MAIN, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_MAIN, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN, FT_847_NATIVE_CAT_SET_DCS_ON_SAT_RX, /* SAT RX CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_SAT_RX, FT_847_NATIVE_CAT_SET_DCS_ON_SAT_TX, /* SAT TX CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_MAIN, /* CTCSS Freq */ FT_847_NATIVE_CAT_SET_CTCSS_FREQ_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_SAT_TX, FT_847_NATIVE_CAT_SET_DCS_CODE_MAIN, /* DCS code */ FT_847_NATIVE_CAT_SET_DCS_CODE_SAT_RX, FT_847_NATIVE_CAT_SET_DCS_CODE_SAT_TX, FT_847_NATIVE_CAT_SET_RPT_SHIFT_MINUS, /* RPT SHIFT */ FT_847_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT_847_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT_847_NATIVE_CAT_SET_RPT_OFFSET, /* RPT Offset frequency */ /* Get info from the rig */ FT_847_NATIVE_CAT_GET_RX_STATUS, FT_847_NATIVE_CAT_GET_TX_STATUS, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_MAIN, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_SAT_RX, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_SAT_TX, FT_847_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft847_native_cmd_e ft847_native_cmd_t; /* * API local implementation */ static int ft847_init(RIG *rig); static int ft847_open(RIG *rig); static int ft847_cleanup(RIG *rig); static int ft847_close(RIG *rig); static int ft847_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft847_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft847_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft847_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft847_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft847_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft847_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft847_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft847_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft847_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft847_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft847_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft847_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft847_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft847_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft847_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft847_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft847_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft847_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft847_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs); /* * ft847 instance - private data * */ struct ft847_priv_data { split_t sat_mode; unsigned char rx_status; /* tx returned data */ unsigned char tx_status; /* rx returned data */ /* for early ft847's we keep our own memory items */ /* Early rigs are one-way com to the rig */ freq_t freqA, freqB; mode_t mode; pbwidth_t width; ptt_t ptt; }; /* prototypes */ static int ft847_send_priv_cmd(RIG *rig, int cmd_index); /* Native ft847 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* CAT = On */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* CAT = Off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x88 } }, /* ptt off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x4e } }, /* sat mode on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* sat mode off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x11 } }, /* set freq sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x21 } }, /* set freq sat tx */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FMN */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx FMN */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx FMN */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on, main */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS enc/dec on, main */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS enc on, main */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off, main */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x1a } }, /* set DCS on, sat rx */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS enc/dec on, sat rx */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS enc on, sat rx */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS off, sat rx */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x2a } }, /* set DCS on, sat tx */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS enc/dec on, sat tx */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS enc on, sat tx */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS off, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS freq, main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x1b } }, /* set CTCSS freq, sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x2b } }, /* set CTCSS freq, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code, main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x1c } }, /* set DCS code, sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x2c } }, /* set DCS code, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x49 } }, /* set RPT shift PLUS */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x89 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status, main */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x13 } }, /* get FREQ and MODE status, sat rx */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x23 } }, /* get FREQ and MODE status, sat tx */ }; /* * Receiver caps */ #define UNIDIRECTIONAL (rig->caps->rig_model == RIG_MODEL_FT847UNI || rig->caps->rig_model == RIG_MODEL_FT650) #define FT847_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM) #define FT847_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB) #define FT847_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) /* tx doesn't have WFM. * 100W in 160-6m (25 watts AM carrier) * 50W in 2m/70cm (12.5 watts AM carrier) */ #define FT847_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define FT847_AM_TX_MODES (RIG_MODE_AM) #define FT847_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL) #define FT847_LEVEL_ALL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ALC) #define FT847_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB) /* FT-847 has different antennas connectors, but no rig_set_ant() ability */ #define FT847_ANTS RIG_ANT_1 #define FT847_STR_CAL { 3, \ { \ { 0, -60 }, /* S0 */ \ { 16, 0 }, /* S9 */ \ { 31, 60 }, /* +60 dB */ \ } } /* * 39 CTCSS sub-audible tones * c.f. ft847_set_ctcss_tone() */ static tone_t ft847_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; #if 0 static tone_t ft650_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; #endif /* * ft847 rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ft847_caps = { RIG_MODEL(RIG_MODEL_FT847), .model_name = "FT-847", .mfg_name = "Yaesu", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft600 rigs capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ft650_caps = { RIG_MODEL(RIG_MODEL_FT650), .model_name = "FT-650", .mfg_name = "Yaesu", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, //.has_get_level = FT847_LEVEL_ALL, //.has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, //.ctcss_list = ft847_ctcss_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {MHz(24.5), MHz(56), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {MHz(24.5), MHz(56), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { {kHz(24500), kHz(25000), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(24500), kHz(25000), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(28000), kHz(29700), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(28000), kHz(29700), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(50000), kHz(54000), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(50000), kHz(54000), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_CW, Hz(1200)}, {RIG_MODE_CW, Hz(600)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ // .set_split_vfo = ft847_set_split_vfo, // .get_split_vfo = ft847_get_split_vfo, // .set_split_freq = ft847_set_split_freq, // .get_split_freq = ft847_get_split_freq, // .set_split_mode = ft847_set_split_mode, // .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ // .get_dcd = ft847_get_dcd, /* get dcd */ // .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, // .set_ctcss_sql = ft847_set_ctcss_sql, // .set_dcs_sql = ft847_set_dcs_sql, // .set_rptr_shift = ft847_set_rptr_shift, // .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps mchfqrp_caps = { RIG_MODEL(RIG_MODEL_MCHFQRP), .model_name = "mcHF QRP", .mfg_name = "M0NKA", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ // {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, // {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, // {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ // {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, // {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, // {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft847uni rigs capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! Yaesu appears to use the following format for serial numbers on their amateur products: Year of manufacture-Month of manufacture-Production Run-Individual Unit number, where the month of manufacture is offset by 2, so "C" means January, "D" means February, "E" means March, and so forth. Example: 8G051234 = 1998, May (fifth month, or "G"), Production Run 05, unit #1234 in this run. One key serial number range is 8G05. This seems to be the point at which Yaesu had corrected the bi-directional CAT issue and made some other improvements. This version was made in May 1998. Later serial numbers (e.g., 8L09nnnn) all seem to have incorporated the earlier improvements plus new ones...." */ struct rig_caps ft847uni_caps = { RIG_MODEL(RIG_MODEL_FT847UNI), .model_name = "FT-847UNI", .mfg_name = "Yaesu", .version = "20230511.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * setup *priv * serial port is already open (STATE(rig)->fd) */ static int ft847_init(RIG *rig) { struct ft847_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called \n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft847_priv_data *) calloc(1, sizeof(struct ft847_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->sat_mode = RIG_SPLIT_OFF; /* for early FT-847's we have our own memory items due to one way comm*/ /* until these are set we won't know what the values are */ priv->freqA = 1; /* 1Hz default */ priv->freqB = 1; /* 1Hz default */ priv->mode = RIG_MODE_USB; /* mode USB by default to avoid users not setting mode */ priv->width = 1; /* 1Hz default */ return RIG_OK; } /* * ft847_cleanup routine * the serial port is closed by the frontend */ static int ft847_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* * ft847_open routine * */ static int ft847_open(RIG *rig) { int retval; /* Good time to set CAT ON */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); retval = ft847_send_priv_cmd(rig, FT_847_NATIVE_CAT_ON); RETURNFUNC2(retval); } /* * ft847_close routine * */ static int ft847_close(RIG *rig) { /* Good time to set CAT OFF */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* don't care about return value */ ft847_send_priv_cmd(rig, FT_847_NATIVE_CAT_OFF); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. * */ static int ft847_send_priv_cmd(RIG *rig, int cmd_index) { if (! ncmd[cmd_index].ncomp) { rig_debug(RIG_DEBUG_VERBOSE, "%s: attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return write_block(RIGPORT(rig), ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } /* * opcode_vfo() copy into cmd the 5 byte command designated by cmd_index, * and patch the opcode with VFO targeting (MAIN 0x0-, SAT RX 0x1-, SAT TX 0x2-) */ static int opcode_vfo(RIG *rig, unsigned char *cmd, int cmd_index, vfo_t vfo) { struct ft847_priv_data *p = (struct ft847_priv_data *)STATE(rig)->priv; memcpy(cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* If the sat_mode is not enabled, * then leave the OpCode untouched (MAIN VFO) */ if (p->sat_mode == RIG_SPLIT_ON || vfo == RIG_VFO_SUB) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_MAIN: cmd[4] &= 0x0f; cmd[4] |= 0x10; /* MAIN VFO -> SAT RX VFO */ break; case RIG_VFO_SUB: case RIG_VFO_TX: cmd[4] &= 0x0f; cmd[4] |= 0x20; /* SAT TX VFO */ break; default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; /* sorry, wrong VFO */ } } return RIG_OK; } /* * Set frequency to freq Hz. Note 10 Hz resolution -- YUK -- FS * */ static int ft847_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz \n"; if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft847: requested freq = %"PRIfreq" Hz, vfo=%s\n", freq, rig_strvfo(vfo)); ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_FREQ_MAIN, vfo); if (ret != RIG_OK) { return ret; } to_bcd_be(p_cmd, freq / 10, 8); /* store bcd format in in p_cmd */ rig_debug(RIG_DEBUG_VERBOSE, fmt, __func__, (int64_t)from_bcd_be(p_cmd, 8) * 10); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_MAIN) { priv->freqA = freq; rig_debug(RIG_DEBUG_TRACE, "%s: freqA=%"PRIfreq"\n", __func__, priv->freqA); } else { priv->freqB = freq; rig_debug(RIG_DEBUG_TRACE, "%s: freqB=%"PRIfreq"\n", __func__, priv->freqB); } } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } #define MD_LSB 0x00 #define MD_USB 0x01 #define MD_CW 0x02 #define MD_CWR 0x03 #define MD_AM 0x04 #define MD_FM 0x08 #define MD_CWN 0x82 #define MD_CWNR 0x83 #define MD_AMN 0x84 #define MD_FMN 0x88 static int get_freq_and_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { hamlib_port_t *rp = RIGPORT(rig); unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ unsigned char cmd_index; /* index of sequence to send */ unsigned char data[8]; int n; struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo =%s \n", __func__, rig_strvfo(vfo)); if (UNIDIRECTIONAL) { if (vfo == RIG_VFO_MAIN) { *freq = priv->freqA; rig_debug(RIG_DEBUG_TRACE, "%s: freqA=%"PRIfreq"\n", __func__, priv->freqA); } else { *freq = priv->freqB; rig_debug(RIG_DEBUG_TRACE, "%s: freqB=%"PRIfreq"\n", __func__, priv->freqB); } *mode = priv->mode; *width = priv->width; return RIG_OK; } cmd_index = FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_MAIN; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* change opcode according to vfo */ n = opcode_vfo(rig, p_cmd, cmd_index, vfo); if (n != RIG_OK) { return n; } n = write_block(rp, p_cmd, YAESU_CMD_LENGTH); if (n < 0) { return n; } n = read_block(rp, data, YAESU_CMD_LENGTH); if (n != YAESU_CMD_LENGTH) { rig_debug(RIG_DEBUG_ERR, "ft847: read_block returned %d\n", n); return n < 0 ? n : -RIG_EPROTO; } /* Remember, this is 10Hz resolution */ *freq = 10 * from_bcd_be(data, 8); *width = RIG_PASSBAND_NORMAL; switch (data[4]) { case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_CWN: *width = rig_passband_narrow(rig, RIG_MODE_CW); case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWNR: *width = rig_passband_narrow(rig, RIG_MODE_CW); case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_AMN: *width = rig_passband_narrow(rig, RIG_MODE_AM); case MD_AM: *mode = RIG_MODE_AM; break; case MD_FMN: *width = rig_passband_narrow(rig, RIG_MODE_FM); case MD_FM: *mode = RIG_MODE_FM; break; default: *mode = RIG_MODE_NONE; rig_debug(RIG_DEBUG_VERBOSE, "ft847: Unknown mode %02x\n", data[4]); } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * Note taken from http://www.supercontrol.de/cat/ft847faq/page4.htm#pollingcodes * The FT-847, as originally delivered, could not poll the radio for frequency * and mode information. This was added beginning with the 8G05 production * runs. The Operating Manual does not show the codes for polling the radio. * Note that you cannot query the sub-VFO, nor can you swap VFOs via software. */ static int ft847_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rmode_t mode; pbwidth_t width; return get_freq_and_mode(rig, vfo, freq, &mode, &width); } static int ft847_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; /* * translate mode from generic to ft847 specific */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; priv->mode = mode; priv->width = width; } switch (mode) { case RIG_MODE_AM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_AM; break; case RIG_MODE_CW: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CW; break; case RIG_MODE_CWR: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWR; break; case RIG_MODE_USB: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_USB; break; case RIG_MODE_LSB: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_LSB; break; case RIG_MODE_FM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_AM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_AMN; break; case RIG_MODE_FM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_FMN; break; case RIG_MODE_CW: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWN; break; case RIG_MODE_CWR: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWRN; break; case RIG_MODE_USB: case RIG_MODE_LSB: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode/width: %s/%d, narrow: %d\n", __func__, rig_strrmode(mode), (int)width, (int)rig_passband_narrow(rig, mode)); return -RIG_EINVAL; /* sorry, wrong MODE/WIDTH combo */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode/width: %s/%d, narrow: %d\n", __func__, rig_strrmode(mode), (int)width, (int)rig_passband_narrow(rig, mode)); return -RIG_EINVAL; /* sorry, wrong MODE/WIDTH combo */ } } } /* * Now send the command */ ret = opcode_vfo(rig, p_cmd, cmd_index, vfo); if (ret != RIG_OK) { return ret; } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { freq_t freq; return get_freq_and_mode(rig, vfo, &freq, mode, width); } /* * Not exactly Split mode, this will set *SAT* Mode */ static int ft847_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_ON: cmd_index = FT_847_NATIVE_CAT_SAT_MODE_ON; break; case RIG_SPLIT_OFF: cmd_index = FT_847_NATIVE_CAT_SAT_MODE_OFF; break; default: return -RIG_EINVAL; /* sorry, wrong split range */ } ret = ft847_send_priv_cmd(rig, cmd_index); if (ret == RIG_OK) { priv->sat_mode = split; } return ret; } static int ft847_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *split = priv->sat_mode; *tx_vfo = RIG_VFO_SUB; return RIG_OK; } static int ft847_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { RETURNFUNC2(retval); } return ft847_set_freq(rig, RIG_VFO_TX, freq); } static int ft847_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq) { return ft847_get_freq(rig, RIG_VFO_TX, freq); } static int ft847_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return ft847_set_mode(rig, RIG_VFO_TX, mode, width); } static int ft847_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { return ft847_get_mode(rig, RIG_VFO_TX, mode, width); } /* * _set_ptt * */ static int ft847_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; priv->ptt = ptt; } switch (ptt) { case RIG_PTT_ON: cmd_index = FT_847_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: cmd_index = FT_847_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; /* sorry, wrong ptt range */ } /* * phew! now send cmd to rig */ return ft847_send_priv_cmd(rig, cmd_index); } static int ft847_get_status(RIG *rig, int status_ci) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char *data; int len; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } switch (status_ci) { case FT_847_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; break; case FT_847_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); n = write_block(rp, ncmd[status_ci].nseq, YAESU_CMD_LENGTH); if (n < 0) { return n; } n = read_block(rp, data, len); if (n < 0) { return n; } if (n != len) { return -RIG_EPROTO; } return RIG_OK; } static int ft847_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; *ptt = priv->ptt; return RIG_OK; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_TX_STATUS); if (n < 0) { return n; } *ptt = (p->tx_status & 0x80) ? RIG_PTT_OFF : RIG_PTT_ON; /* The CAT query above lies when PTT is asserted via the PTT pin on the rear PACKET socket, it always returns Rx status. Given that CAT PTT does not take audio from DATA IN on the rear PACKET socket DTR or RTS PTT on the rear PACKET PTT pin is likely. So we override if we know PTT was asserted via rig_set_ptt for any type of PTT */ if (RIG_PTT_OFF == *ptt && STATE(rig)->transmit) { *ptt = RIG_PTT_ON; } return RIG_OK; } static int ft847_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_RX_STATUS); if (n < 0) { return n; } *dcd = (p->rx_status & 0x80) ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * Get the 'raw' signal strength * This number corresponds to the number of 'dots' in * the FT-847 display */ static int ft847_get_rawstr_level(RIG *rig, value_t *val) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_RX_STATUS); if (n < 0) { return n; } n = (p->rx_status & 0x1F); val->i = n; return RIG_OK; } /* * Get S-meter reading (in dB) */ static int ft847_get_smeter_level(RIG *rig, value_t *val) { int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_rawstr_level(rig, val); if (n < 0) { return n; } /* * The FT-847 S-meter readings over CAT returns * an integer that corresponds to the number of * 'dots' lit in the display. Use a conversion * function to convert the raw signal strength to dB */ n = val->i; if (n < 4) /* <= S1 */ { val->i = -54 + (n * 2); } else if (n < 20) /* S1 - S9 */ { val->i = -48 + ((n - 3) * 3); } else /* > S9 */ { n -= 19; val->i = (n * 5); } return RIG_OK; } /* * Get the PO/ALC Meter Data */ static int ft847_get_alc_level(RIG *rig, value_t *val) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_TX_STATUS); if (n < 0) { return n; } n = (p->tx_status & 0x1F); val->f = (float)n / 0x1F; return RIG_OK; } /* * Get "level" data from rig. * The 847 supports S-meter readings in receive mode * and PO/ALC in transmit mode. There is no way * to determine whether it's PO or ALC, unfortunately. */ static int ft847_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } switch (level) { case RIG_LEVEL_STRENGTH: return ft847_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft847_get_rawstr_level(rig, val); case RIG_LEVEL_ALC: return ft847_get_alc_level(rig, val); default: return -RIG_EINVAL; } return RIG_OK; } static int ft847_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; ft847_native_cmd_t fcmd; if (!rig) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TONE: fcmd = status ? FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_MAIN : FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN; break; case RIG_FUNC_TSQL: fcmd = status ? FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_MAIN : FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN; break; default: return -RIG_EINVAL; } ret = opcode_vfo(rig, p_cmd, fcmd, vfo); if (ret != RIG_OK) { return ret; } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int i, ret; /* * 39 CTCSS CAT codes corresponding to ft847_ctcss_list */ static const unsigned char ft847_ctcss_cat[] = { 0x3F, 0x39, 0x1F, 0x3E, 0x0F, 0x3D, 0x1E, 0x3C, 0x0E, 0x3B, 0x1D, 0x3A, 0x0D, 0x1C, 0x0C, 0x1B, 0x0B, 0x1A, 0x0A, 0x19, 0x09, 0x18, 0x08, 0x17, 0x07, 0x16, 0x06, 0x15, 0x05, 0x14, 0x04, 0x13, 0x03, 0x12, 0x02, 0x11, 0x01, 0x10, 0x00, }; ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_MAIN, vfo); if (ret != RIG_OK) { return ret; } #define FT847_CTCSS_NB 39 for (i = 0; i < FT847_CTCSS_NB; i++) { if (ft847_ctcss_list[i] == tone) { break; } } if (i == FT847_CTCSS_NB) { return -RIG_EINVAL; } /* get associated CAT code */ p_cmd[0] = ft847_ctcss_cat[i]; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { /* same opcode as tone */ return ft847_set_ctcss_tone(rig, vfo, tone); } static int ft847_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_DCS_CODE_MAIN, vfo); if (ret != RIG_OK) { return ret; } /* TODO: FT_847_NATIVE_CAT_SET_DCS_ON_MAIN here or with new RIG_FUNC_DCS? */ /* DCS Code # (i.e. 07, 54=DCS Code 754) */ to_bcd_be(p_cmd, code, 4); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { unsigned char cmd_index; /* index of sequence to send */ switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX; break; case RIG_RPT_SHIFT_MINUS: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_PLUS; break; default: return -RIG_EINVAL; /* sorry, wrong shift */ } return ft847_send_priv_cmd(rig, cmd_index); } static int ft847_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } memcpy(p_cmd, &ncmd[FT_847_NATIVE_CAT_SET_RPT_OFFSET].nseq, YAESU_CMD_LENGTH); to_bcd_be(p_cmd, rptr_offs / 10, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } hamlib-4.6.5/rigs/yaesu/level_gran_yaesu.h0000664000175000017500000001014415056640443014243 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ #if !defined(LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, #endif [LVL_IF] = { .min = { .i = -1200 }, .max = { .i = 1200 }, .step = { .i = 20 } }, #if !defined(NO_LVL_NOTCHF) [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, #endif /* levels with time units */ [LVL_VOXDELAY] = { .min = { .i = 3 }, .max = { .i = 300 }, .step = { .i = 1 } }, [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, /* levels with watt units */ [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, // most recent rigs seem to have 15 as the maximum -- other values can be set in the backend #if !defined(NO_LVL_NR) [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/15.0f } }, #endif /* levels with 0-1 values -- increment based on rig's range */ #if !defined(NO_LVL_AF) [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RF) [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RFPOWER) [LVL_RFPOWER] = { .min = { .f = 5.0/255.0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif [LVL_RFPOWER_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #if !defined(NO_LVL_SQL) [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_MICGAIN) [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_MONITOR_GAIN) [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_COMP) [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif #if !defined(NO_LVL_VOXGAIN) [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_ANTIVOX] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, hamlib-4.6.5/rigs/yaesu/ft450.c0000664000175000017500000002155615056640443011565 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft450.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-450 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft450.h" /* * FT-450 rig capabilities */ struct rig_caps ft450_caps = { RIG_MODEL(RIG_MODEL_FT450), .model_name = "FT-450", .mfg_name = "Yaesu", .version = NEWCAT_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT450_WRITE_DELAY, .post_write_delay = FT450_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT450_FUNCS, .has_set_func = FT450_FUNCS, .has_get_level = FT450_LEVELS, .has_set_level = RIG_LEVEL_SET(FT450_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_VOXGAIN #define NO_LVL_NR #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_VOXGAIN #undef NO_LVL_NR [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 800 }, .step = { .i = 100 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 11.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(1000), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT450_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 450 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT450_RFPOWER_METER_CAL, .str_cal = FT450_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 501, 504, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 1, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), FT450_ALL_RX_MODES, -1, -1, FT450_VFO_ALL, FT450_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_HF(1, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ FRQ_RNG_6m(1, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_6m(1, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT450_ALL_RX_MODES, -1, -1, FT450_VFO_ALL, FT450_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_HF(2, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ FRQ_RNG_6m(2, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_6m(2, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT450_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT450_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT450_AM_RX_MODES, Hz(100)}, /* Normal */ {FT450_AM_RX_MODES, kHz(1)}, /* Fast */ {FT450_FM_RX_MODES, Hz(100)}, /* Normal */ {FT450_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT450_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT450_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT450_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT450_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT450_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 40, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft450d_caps; hamlib-4.6.5/rigs/yaesu/ft990v12.h0000775000175000017500000002363715056640443012141 /* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft990.h - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* MODIFIED VERSION for FT-990 with ROM v1.2 : June 2022 * The standard version was written for FT-990 with ROM v1.3 and as the CAT spec was different to ROM v1.2 CAT * would not work with the older ROM. This version enables ROM v1.2 to work although it is necessary to accept * that frequent polling functionality is not feasible with this older ROM. With ROM v1.2 polling fetches 1492 * bytes which at 4800 Baud takes about 3.8 seconds during which the FT-990 has a CAT blackout. The longest poll * interval available in WSJT-X is 99 seconds. * Collaboration between M0EZP David Brewerton and K1MMI Edmund Hajjar */ #ifndef _FT990UNI_H #define _FT990UNI_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT990_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT990_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT990_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT990_AM_RX_MODES (RIG_MODE_AM) #define FT990_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT990_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT990_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT990_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT990_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT990_ANTS 0 #define FT990_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /* Returned data length in bytes */ #define FT990_ALL_DATA_LENGTH 1492 /* 0x10 P1 = 00 return size */ #define FT990_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT990_OP_DATA_LENGTH 32 /* 0x10 P1 = 02 return size */ #define FT990_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT990_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT990_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT990_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT990_BCD_DIAL 8 #define FT990_BCD_RIT 3 #define FT990_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT990_PACING_INTERVAL 5 #define FT990_PACING_DEFAULT_VALUE 0 #define FT990_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT990_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT990_DEFAULT_READ_TIMEOUT FT990_ALL_DATA_LENGTH * ( 5 + (FT990_PACING_INTERVAL * FT990_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kft990 * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT990_CMD_SPLIT 0x01 #define FT990_CMD_RECALLMEM 0x02 #define FT990_CMD_VFO2MEM 0x03 #define FT990_CMD_LOCK 0x04 #define FT990_CMD_SELVFOAB 0x05 #define FT990_CMD_MEM2VFO 0x06 #define FT990_CMD_UP 0x07 #define FT990_CMD_DOWN 0x08 #define FT990_CMD_CLARIFIER 0x09 #define FT990_CMD_SETVFOA 0x0a #define FT990_CMD_SELOPMODE 0x0c #define FT990_CMD_PACING 0x0e #define FT990_CMD_PTT 0x0f #define FT990_CMD_UPDATE 0x10 #define FT990_CMD_TUNER 0x81 #define FT990_CMD_START 0x82 #define FT990_CMD_RPT 0x84 #define FT990_CMD_VFOA2B 0x85 #define FT990_CMD_BW 0x8c #define FT990_CMD_MEMSCANSKIP 0x8d #define FT990_CMD_STEPVFO 0x8e #define FT990_CMD_RDMETER 0xf7 #define FT990_CMD_DIMLEVEL 0xf8 #define FT990_CMD_RPTROFFSET 0xf9 #define FT990_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT990_BW_F2400 0x00 #define FT990_BW_F2000 0x01 #define FT990_BW_F500 0x02 #define FT990_BW_F250 0x03 #define FT990_BW_F6000 0x04 #define FT990_BW_FMPKTRTTY 0x80 // Operating Mode Status #define FT990_MODE_LSB 0x00 #define FT990_MODE_USB 0x01 #define FT990_MODE_CW 0x02 #define FT990_MODE_AM 0x03 #define FT990_MODE_FM 0x04 #define FT990_MODE_RTTY 0x05 #define FT990_MODE_PKT 0x06 // Operation Mode Selection #define FT990_OP_MODE_LSB 0x00 #define FT990_OP_MODE_USB 0x01 #define FT990_OP_MODE_CW2400 0x02 #define FT990_OP_MODE_CW500 0x03 #define FT990_OP_MODE_AM6000 0x04 #define FT990_OP_MODE_AM2400 0x05 #define FT990_OP_MODE_FM 0x06 #define FT990_OP_MODE_RTTYLSB 0x08 #define FT990_OP_MODE_RTTYUSB 0x09 #define FT990_OP_MODE_PKTLSB 0x0a #define FT990_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT990_CLAR_TX_EN 0x01 #define FT990_CLAR_RX_EN 0x02 #define FT990_CLAR_RX_OFF 0x00 #define FT990_CLAR_RX_ON 0x01 #define FT990_CLAR_TX_OFF 0x80 #define FT990_CLAR_TX_ON 0x81 #define FT990_CLAR_CLEAR 0xff #define FT990_CLAR_TUNE_UP 0x00 #define FT990_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT990_RPT_POS_EN 0x04 #define FT990_RPT_NEG_EN 0x08 #define FT990_RPT_MASK 0x0C // Status Flag 1 Masks #define FT990_SF_SPLIT 0x01 #define FT990_SF_VFOB 0x02 #define FT990_SF_FAST 0x04 #define FT990_SF_CAT 0x08 #define FT990_SF_TUNING 0x10 #define FT990_SF_KEY_ENTRY 0x20 #define FT990_SF_MEM_EMPTY 0x40 #define FT990_SF_XMIT 0x80 // Status Flag 2 Masks #define FT990_SF_MEM_SCAN_PAUSE 0x01 #define FT990_SF_MEM_CHECK 0x02 #define FT990_SF_MEM_SCAN 0x04 #define FT990_SF_LOCKED 0x08 #define FT990_SF_MTUNE 0x10 #define FT990_SF_VFO 0x20 #define FT990_SF_MEM 0x40 #define FT990_SF_GEN 0x80 // Status Flag 3 Masks #define FT990_SF_PTT 0x01 #define FT990_SF_TX_INHIBIT 0x02 #define FT990_SF_KEY_TIMER 0x04 #define FT990_SF_MEM_TIMER 0x08 #define FT990_SF_PTT_INHIBIT 0x10 #define FT990_SF_XMIT_MON 0x20 #define FT990_SF_TUNER_ON 0x40 #define FT990_SF_SIDETONE 0x80 #define FT990_EMPTY_MEM 0x80 #define FT990_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft990v12_flags1_t { unsigned split: 1; unsigned vfob: 1; unsigned fast: 1; unsigned cat: 1; unsigned tuning: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft990v12_flags1_t; // Flags Byte 2 typedef struct _ft990v12_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft990v12_flags2_t; // Flags Byte 3 typedef struct _ft990v12_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned sidetone: 1; } ft990v12_flags3_t; typedef union _ft990v12_flags1_u { ft990v12_flags1_t bits; unsigned char byte; } ft990v12_flags1_u; typedef union _ft990v12_flags2_u { ft990v12_flags2_t bits; unsigned char byte; } ft990v12_flags2_u; typedef union _ft990v12_flags3_u { ft990v12_flags3_t bits; unsigned char byte; } ft990v12_flags3_u; typedef struct _ft990v12_status_data_t { ft990v12_flags1_u flags1; ft990v12_flags2_u flags2; ft990v12_flags3_u flags3; unsigned char id1; unsigned char id2; } ft990v12_status_data_t; typedef struct _ft990v12_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft990v12_meter_data_t; typedef struct _ft990v12_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft990v12_op_data_t; // Update Data Structure typedef struct _ft990v12_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft990v12_op_data_t current_front; /* ft990_op_data_t current_rear; M0EZP: field not valid for FT990 ROM v1.2 */ ft990v12_op_data_t vfoa; ft990v12_op_data_t vfob; ft990v12_op_data_t channel[90]; } ft990v12_update_data_t; // Command Structure typedef struct _ft990v12_command_t { unsigned char data[4]; unsigned char opcode; } ft990v12_command_t; #endif /* _FT990UNI_H */ hamlib-4.6.5/rigs/yaesu/ft2000.c0000664000175000017500000003005015056640443011623 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft2000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-2000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "yaesu.h" #include "newcat.h" #include "ft2000.h" #include "tones.h" const struct newcat_priv_caps ft2000_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ft2000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft2000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FT-2000 rig capabilities */ struct rig_caps ft2000_caps = { RIG_MODEL(RIG_MODEL_FT2000), .model_name = "FT-2000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT2000_WRITE_DELAY, .post_write_delay = FT2000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT2000_FUNCS, .has_set_func = FT2000_FUNCS, .has_get_level = FT2000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT2000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDRGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .vfo_ops = FT2000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 2000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT2000D_RFPOWER_METER_CAL, .str_cal = FT2000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FT2000_ALL_RX_MODES, -1, -1, FT2000_VFO_ALL, FT2000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_HF(1, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_6m(1, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FT2000_ALL_RX_MODES, -1, -1, FT2000_VFO_ALL, FT2000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_HF(2, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_6m(2, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT2000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT2000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT2000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT2000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT2000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT2000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, /* Narrow CW, RTTY, PKT/USER */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* Normal RTTY */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, /* Narrow RTTY */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(2400)}, /* Wide RTTY */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FT2000_PKTSSB_RX_MODES, Hz(500)}, /* Normal PKTSSB */ {FT2000_PKTSSB_RX_MODES, Hz(200)}, /* Narrow PKTSSB */ {FT2000_PKTSSB_RX_MODES, Hz(2400)}, /* Wide PKTSSB */ {FT2000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FT2000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FT2000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FT2000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft2000_ext_tokens, .extlevels = ft2000_ext_levels, .priv = &ft2000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft600.c0000664000175000017500000004313015056640443011552 /* * hamlib - (C) Frank Singleton 2000-2003 * (C) Stephane Fillod 2000-2010 * * ft600.c -(C) Kārlis Millers YL3ALK 2019 * * This shared library provides an API for communicating * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft600.h" #include "misc.h" #include "bandplan.h" enum ft600_native_cmd_e { FT600_NATIVE_CAT_LOCK_ON = 0, FT600_NATIVE_CAT_LOCK_OFF, FT600_NATIVE_CAT_PTT_ON, FT600_NATIVE_CAT_PTT_OFF, FT600_NATIVE_CAT_SET_FREQ, FT600_NATIVE_CAT_SET_MODE_LSB, FT600_NATIVE_CAT_SET_MODE_USB, FT600_NATIVE_CAT_SET_MODE_DIG, FT600_NATIVE_CAT_SET_MODE_CW, FT600_NATIVE_CAT_SET_MODE_AM, FT600_NATIVE_CAT_CLAR_ON, FT600_NATIVE_CAT_CLAR_OFF, FT600_NATIVE_CAT_SET_CLAR_FREQ, FT600_NATIVE_CAT_SET_VFOAB, FT600_NATIVE_CAT_SET_VFOA, FT600_NATIVE_CAT_SET_VFOB, FT600_NATIVE_CAT_SPLIT_ON, FT600_NATIVE_CAT_SPLIT_OFF, FT600_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT600_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT600_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT600_NATIVE_CAT_SET_RPT_OFFSET, /* fix me */ FT600_NATIVE_CAT_SET_DCS_ON, FT600_NATIVE_CAT_SET_CTCSS_ENC_ON, FT600_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON, FT600_NATIVE_CAT_SET_CTCSS_DCS_OFF, /* em xif */ FT600_NATIVE_CAT_SET_CTCSS_FREQ, FT600_NATIVE_CAT_SET_DCS_CODE, FT600_NATIVE_CAT_GET_RX_STATUS, FT600_NATIVE_CAT_GET_TX_STATUS, FT600_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT600_NATIVE_CAT_PWR_WAKE, FT600_NATIVE_CAT_PWR_ON, FT600_NATIVE_CAT_PWR_OFF, FT600_NATIVE_CAT_READ_STATUS, FT600_NATIVE_CAT_READ_METERS, FT600_NATIVE_CAT_READ_FLAGS }; /* * we are able to get way more info * than we can set * */ typedef struct { // unsigned char band_no; unsigned char freq[16]; // unsigned char mode; // unsigned char ctcss; // unsigned char dcs; // unsigned char flag1; // unsigned char flag2; // unsigned char clarifier[2]; // unsigned char not_used; // unsigned char step1; // unsigned char step2; // unsigned char filter; // cppcheck-suppress * unsigned char stuffing[16]; } FT600_STATUS_INFO; static int ft600_init(RIG *rig); static int ft600_open(RIG *rig); static int ft600_cleanup(RIG *rig); static int ft600_close(RIG *rig); static int ft600_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft600_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft600_get_vfo(RIG *rig, vfo_t *vfo); static int ft600_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct ft600_priv_data { FT600_STATUS_INFO status; unsigned char s_meter; }; /* prototypes */ static int ft600_send_priv_cmd(RIG *rig, unsigned char cmd_index); static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set main LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set main USB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* mode set main DIG */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set main CW */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set main AM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set clar freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo a */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo b */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* set RPT shift MINUS */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* set RPT shift PLUS */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set RPT offset freq */ /* fix me */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x92 } }, /* set DCS on */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x92 } }, /* set CTCSS/DCS enc/dec on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x92 } }, /* set CTCSS/DCS enc on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x92 } }, /* set CTCSS/DCS off */ /* em xif */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x90 } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x91 } }, /* set DCS code */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get RX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get TX status */ { 0, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* get FREQ and MODE status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr wakeup sequence */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr off */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* read status block */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* read meter block */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xfa } } /* read flags block */ }; #define FT600_GET_RIG_LEVELS (RIG_LEVEL_RAWSTR) #define FT600_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_PKTUSB|RIG_MODE_CW|RIG_MODE_AM) #define FT600_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT600_OTHER_TX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_PKTUSB|RIG_MODE_CW) #define FT600_AM_TX_MODES (RIG_MODE_AM) #define FT600_VFO_ALL (RIG_VFO_A) #define FT600_ANT (RIG_ANT_1) #define FT600_DUMMY_S_METER_VALUE 0; //FOR TESTS /* S-meter calibration, ascending order of RAW values */ #define FT600_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ }} struct rig_caps ft600_caps = { RIG_MODEL(RIG_MODEL_FT600), .model_name = "FT-600", .mfg_name = "Yaesu", .version = "20231001.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT600_WRITE_DELAY, .post_write_delay = FT600_POST_WRITE_DELAY, .timeout = 100, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = FT600_GET_RIG_LEVELS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = RIG_FUNC_NONE, .dcs_list = RIG_FUNC_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan .list = 78 */ .rx_range_list1 = { {kHz(50), kHz(29999), FT600_ALL_RX_MODES, -1, -1, FT600_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT600_OTHER_TX_MODES, W(40), W(100), FT600_VFO_ALL, FT600_ANT), FRQ_RNG_HF(1, FT600_AM_TX_MODES, W(25), W(25), FT600_VFO_ALL, FT600_ANT), }, .tuning_steps = { {FT600_ALL_RX_MODES, 10}, {FT600_ALL_RX_MODES, 100}, {FT600_ALL_RX_MODES, 1000}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .str_cal = FT600_STR_CAL, .priv = NULL, .rig_init = ft600_init, .rig_cleanup = ft600_cleanup, .rig_open = ft600_open, .rig_close = ft600_close, .set_freq = ft600_set_freq, .get_freq = ft600_get_freq, .set_mode = ft600_set_mode, .get_mode = ft600_get_mode, .set_vfo = NULL, .get_vfo = ft600_get_vfo, .set_ptt = ft600_set_ptt, .get_ptt = NULL, .get_level = ft600_get_level, .set_level = NULL, .get_dcd = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = NULL, .get_split_vfo = NULL, .set_rit = NULL, .get_rit = NULL, .set_xit = NULL, .get_xit = NULL, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = NULL, .get_dcs_code = NULL, .set_ctcss_tone = NULL, .get_ctcss_tone = NULL, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_func = NULL, .get_func = NULL, .set_parm = NULL, .get_parm = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int ft600_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct ft600_priv_data *) calloc(1, sizeof(struct ft600_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } static int ft600_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } static int ft600_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } static int ft600_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s:called\n", __func__); return RIG_OK; } static int ft600_send_priv_cmd(RIG *rig, unsigned char cmd_index) { rig_debug(RIG_DEBUG_VERBOSE, "%s called (%d)\n", __func__, cmd_index); if (!rig) { return -RIG_EINVAL; } return write_block(RIGPORT(rig), (unsigned char *) &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } static int ft600_read_status(RIG *rig) { struct ft600_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft600_priv_data *)STATE(rig)->priv; rig_flush(rp); ret = ft600_send_priv_cmd(rig, FT600_NATIVE_CAT_READ_STATUS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->status, FT600_STATUS_UPDATE_DATA_LENGTH); rig_debug(RIG_DEBUG_VERBOSE, "%s: read status=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } static int ft600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft600_priv_data *priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft600_priv_data *)STATE(rig)->priv; ret = ft600_send_priv_cmd(rig, FT600_NATIVE_CAT_READ_METERS); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: read tx status=%i \n", __func__, ret); ret = read_block(RIGPORT(rig), &priv->s_meter, 5); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "S_METER: %u ", priv->s_meter); //val->i = FT600_DUMMY_S_METER_VALUE; //DUMMY val->i = priv->s_meter; return RIG_OK; } static int ft600_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft600: requested freq = %"PRIfreq" Hz \n", freq); cmd_index = FT600_NATIVE_CAT_SET_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); freq = (int)freq / 10; to_bcd(p_cmd, freq, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft600_priv_data *priv = (struct ft600_priv_data *)STATE(rig)->priv; freq_t f; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq\n", __func__); if (!freq) { return -RIG_EINVAL; } ret = ft600_read_status(rig); if (ret != RIG_OK) { return ret; } f = ((((priv->status.freq[1] << 8) + priv->status.freq[2]) << 8) + priv->status.freq[3]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz\n", __func__, f); *freq = f; return RIG_OK; } static int ft600_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: cmd_index = FT600_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: cmd_index = FT600_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } return ft600_send_priv_cmd(rig, cmd_index); } static int ft600_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft600_priv_data *priv = (struct ft600_priv_data *)STATE(rig)->priv; int ret; if (!mode) { return -RIG_EINVAL; } *width = RIG_PASSBAND_NORMAL; ret = ft600_read_status(rig); if (ret < 0) { return ret; } switch (priv->status.freq[6]) { case 0x00: *mode = RIG_MODE_LSB; *width = Hz(5000); break; case 0x01: *mode = RIG_MODE_USB; *width = Hz(5000); break; case 0x02: *mode = RIG_MODE_CW; *width = Hz(1200); break; case 0x04: *mode = RIG_MODE_AM; *width = Hz(6000); break; case 0x05: *mode = RIG_MODE_PKTUSB; *width = Hz(5000); break; default: *mode = RIG_MODE_NONE; *width = RIG_PASSBAND_NORMAL; }; return RIG_OK; } static int ft600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s, width %d\n", __func__, rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_LSB: cmd_index = FT600_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_USB: cmd_index = FT600_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_PKTUSB: cmd_index = FT600_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_CW: cmd_index = FT600_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_AM: cmd_index = FT600_NATIVE_CAT_SET_MODE_AM; break; default: return -RIG_EINVAL; } ret = ft600_send_priv_cmd(rig, cmd_index); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } #if 1 if (mode != RIG_MODE_FM && mode != RIG_MODE_WFM && width <= kHz(6)) { unsigned char p_cmd[YAESU_CMD_LENGTH]; p_cmd[0] = 0x00; p_cmd[1] = 0x00; p_cmd[2] = 0x00; p_cmd[3] = 0x00; /* to be filled in */ p_cmd[4] = 0x8C; /* Op: filter selection */ if (width <= 300) { p_cmd[3] = 0x03; } else if (width <= 500) { p_cmd[3] = 0x02; } else if (width <= 2400) { p_cmd[3] = 0x00; } else { p_cmd[3] = 0x01; } ret = write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { return ret; } } #endif return RIG_OK; } static int ft600_get_vfo(RIG *rig, vfo_t *vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } *vfo = RIG_VFO_A; return RIG_OK; } hamlib-4.6.5/rigs/yaesu/ft847.h0000664000175000017500000000263315056640443011577 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft847.h - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * This shared library provides an API for communicating * via serial interface to an FT-847 using the "CAT" interface. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT847_H #define _FT847_H 1 #define FT847_WRITE_DELAY 50 /* Sequential fast writes may confuse FT847 without this delay */ #define FT847_POST_WRITE_DELAY 50 /* Rough safe value for default timeout */ #define FT847_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT847_H */ hamlib-4.6.5/rigs/yaesu/ft897.c0000664000175000017500000012534715056640443011607 /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- * * ft897.c - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * (C) Stephane Fillod 2009 * * ...derived but heavily modified from: * * ft817.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-897 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-897: * * - DCS encoder/squelch ON/OFF, similar to RIG_FUNC_TONE/TSQL. * Needs frontend support. * * - RX status command returns info that is not used: * * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) * * The manual also indicates that CTCSS and DCS codes can be set * separately for tx and rx, but this doesn't seem to work. It * doesn't work from front panel either. * * DONE (--sf): * * - VFO A/B toggle. Needs frontend support (RIG_OP_TOGGLE) * * - Split ON/OFF. Maybe some sort of split operation could * be supported with this and the above??? * * - TX status command returns info that is not used: * * - split on/off flag * - high swr flag */ #include #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft897.h" #include "ft817.h" /* We use functions from the 817 code */ #include "ft857.h" //Needed for ft857_set_vfo, ft857_get_vfo #include "misc.h" #include "tones.h" #include "bandplan.h" enum ft897_native_cmd_e { FT897_NATIVE_CAT_LOCK_ON = 0, FT897_NATIVE_CAT_LOCK_OFF, FT897_NATIVE_CAT_PTT_ON, FT897_NATIVE_CAT_PTT_OFF, FT897_NATIVE_CAT_SET_FREQ, FT897_NATIVE_CAT_SET_MODE_LSB, FT897_NATIVE_CAT_SET_MODE_USB, FT897_NATIVE_CAT_SET_MODE_CW, FT897_NATIVE_CAT_SET_MODE_CWR, FT897_NATIVE_CAT_SET_MODE_AM, FT897_NATIVE_CAT_SET_MODE_FM, FT897_NATIVE_CAT_SET_MODE_FM_N, FT897_NATIVE_CAT_SET_MODE_DIG, FT897_NATIVE_CAT_SET_MODE_PKT, FT897_NATIVE_CAT_CLAR_ON, FT897_NATIVE_CAT_CLAR_OFF, FT897_NATIVE_CAT_SET_CLAR_FREQ, FT897_NATIVE_CAT_SET_VFOAB, FT897_NATIVE_CAT_SPLIT_ON, FT897_NATIVE_CAT_SPLIT_OFF, FT897_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT897_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT897_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT897_NATIVE_CAT_SET_RPT_OFFSET, FT897_NATIVE_CAT_SET_DCS_ON, FT897_NATIVE_CAT_SET_DCS_DEC_ON, FT897_NATIVE_CAT_SET_DCS_ENC_ON, FT897_NATIVE_CAT_SET_CTCSS_ON, FT897_NATIVE_CAT_SET_CTCSS_DEC_ON, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT897_NATIVE_CAT_SET_CTCSS_FREQ, FT897_NATIVE_CAT_SET_DCS_CODE, FT897_NATIVE_CAT_GET_RX_STATUS, FT897_NATIVE_CAT_GET_TX_STATUS, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT897_NATIVE_CAT_PWR_WAKE, FT897_NATIVE_CAT_PWR_ON, FT897_NATIVE_CAT_PWR_OFF, FT897_NATIVE_CAT_EEPROM_READ, FT897_NATIVE_CAT_GET_TX_METER, FT897_NATIVE_SIZE /* end marker */ }; struct ft897_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[YAESU_CMD_LENGTH + 1]; /* tx meter status */ struct timeval tm_status_tv; unsigned char tm_status[3]; }; static int ft897_init(RIG *rig); static int ft897_open(RIG *rig); static int ft897_cleanup(RIG *rig); static int ft897_close(RIG *rig); static int ft897_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft897_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft897_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft897_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft897_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft897_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft897_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft897_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft897_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); // static int ft897_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft897_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft897_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); // static int ft897_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); // static int ft897_set_parm(RIG *rig, setting_t parm, value_t val); // static int ft897_get_parm(RIG *rig, setting_t parm, value_t *val); static int ft897_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft897_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft897_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft897_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft897_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); /* Native ft897 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x0b, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS decoder on */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS encoder on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x3a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS decoder on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xbd } }, /* tx meter status, i.e ALC, MOD, PWR, SWR */ }; enum ft897_digi { FT897_DIGI_RTTY_L = 0, FT897_DIGI_RTTY_U, FT897_DIGI_PSK_L, FT897_DIGI_PSK_U, FT897_DIGI_USER_L, FT897_DIGI_USER_U, }; #define FT897_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT897_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT897_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT897_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT897_AM_TX_MODES (RIG_MODE_AM) #define FT897_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT897_ANTS RIG_ANT_CURR struct rig_caps ft897_caps = { RIG_MODEL(RIG_MODEL_FT897), .model_name = "FT-897", .mfg_name = "Yaesu", .version = "20220404.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT897_WRITE_DELAY, .post_write_delay = FT897_POST_WRITE_DELAY, .timeout = FT897_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR | RIG_LEVEL_RAWSTR | RIG_LEVEL_ALC, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(1, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(1, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(2, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(2, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT897_SSB_CW_RX_MODES, 10}, {FT897_SSB_CW_RX_MODES, 100}, {FT897_AM_FM_RX_MODES, 10}, {FT897_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rig_init = ft897_init, .rig_cleanup = ft897_cleanup, .rig_open = ft897_open, .rig_close = ft897_close, // .get_vfo = ft857_get_vfo, // set_vfo not working on serial# 5n660296 // .set_vfo = ft857_set_vfo, .set_vfo = NULL, .set_freq = ft897_set_freq, .get_freq = ft897_get_freq, .set_mode = ft897_set_mode, .get_mode = ft897_get_mode, .set_ptt = ft897_set_ptt, .get_ptt = ft897_get_ptt, .get_dcd = ft897_get_dcd, .set_rptr_shift = ft897_set_rptr_shift, .set_rptr_offs = ft897_set_rptr_offs, .set_split_vfo = ft897_set_split_vfo, .get_split_vfo = ft897_get_split_vfo, .set_rit = ft897_set_rit, .set_dcs_code = ft897_set_dcs_code, .set_ctcss_tone = ft897_set_ctcss_tone, .set_dcs_sql = ft897_set_dcs_sql, .set_ctcss_sql = ft897_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft897_get_level, .set_func = ft897_set_func, .vfo_op = ft897_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft897d_caps = { RIG_MODEL(RIG_MODEL_FT897D), .model_name = "FT-897D", .mfg_name = "Yaesu", .version = "20220407.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT897_WRITE_DELAY, .post_write_delay = FT897_POST_WRITE_DELAY, .timeout = FT897_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR | RIG_LEVEL_RAWSTR | RIG_LEVEL_ALC, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(1, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(1, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(2, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(2, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT897_SSB_CW_RX_MODES, 10}, {FT897_SSB_CW_RX_MODES, 100}, {FT897_AM_FM_RX_MODES, 10}, {FT897_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rig_init = ft897_init, .rig_cleanup = ft897_cleanup, .rig_open = ft897_open, .rig_close = ft897_close, .get_vfo = ft857_get_vfo, .set_vfo = ft857_set_vfo, .set_freq = ft897_set_freq, .get_freq = ft897_get_freq, .set_mode = ft897_set_mode, .get_mode = ft897_get_mode, .set_ptt = ft897_set_ptt, .get_ptt = ft897_get_ptt, .get_dcd = ft897_get_dcd, .set_rptr_shift = ft897_set_rptr_shift, .set_rptr_offs = ft897_set_rptr_offs, .set_split_vfo = ft897_set_split_vfo, .get_split_vfo = ft897_get_split_vfo, .set_rit = ft897_set_rit, .set_dcs_code = ft897_set_dcs_code, .set_ctcss_tone = ft897_set_ctcss_tone, .set_dcs_sql = ft897_set_dcs_sql, .set_ctcss_sql = ft897_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft897_get_level, .set_func = ft897_set_func, .vfo_op = ft897_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ int ft897_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft897_priv_data))) == NULL) { return -RIG_ENOMEM; } return RIG_OK; } int ft897_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int ft897_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft897_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT897_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: using cache (%ld ms)\n", __func__, t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache timed out (%ld ms)\n", __func__, t); return 1; } } static int ft897_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; int n; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); memcpy(data, (char *)ncmd[FT897_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xfe; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } *out = data[addr % 2]; return RIG_OK; } static int ft897_get_status(RIG *rig, int status) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; len = YAESU_CMD_LENGTH; tv = &p->fm_status_tv; break; case FT897_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT897_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; case FT897_NATIVE_CAT_GET_TX_METER: data = p->tm_status; len = 2; tv = &p->tm_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, len)) < 0) { return n; } if (n != len) { return -RIG_EIO; } if (status == FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS) { if ((n = ft897_read_eeprom(rig, 0x0078, &p->fm_status[5])) < 0) { return n; } p->fm_status[5] >>= 5; } gettimeofday(tv, NULL); return RIG_OK; } /* ---------------------------------------------------------------------- */ int ft897_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } *freq = from_bcd_be(p->fm_status, 8) * 10; return RIG_OK; } int ft897_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } switch (p->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (p->fm_status[5]) { case FT897_DIGI_RTTY_L: *mode = RIG_MODE_RTTY; break; case FT897_DIGI_RTTY_U: *mode = RIG_MODE_RTTYR; break; case FT897_DIGI_PSK_L: *mode = RIG_MODE_PKTLSB; break; case FT897_DIGI_PSK_U: *mode = RIG_MODE_PKTUSB; break; case FT897_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT897_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; } break; case 0x0c: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (p->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } int ft897_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = ((p->tx_status & 0x80) == 0); return RIG_OK; } static int ft897_get_pometer_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { val->f = ((p->tx_status & 0x0F) / 15.0); } else { val->f = 0.0; } return RIG_OK; } static int ft897_get_swr_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { val->f = (p->tx_status & 0x40) ? 30.0 : 1.0; /* or infinity? */ } else { val->f = 0.0; } return RIG_OK; } static int ft897_get_smeter_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } n = (p->rx_status & 0x0F) - 9; val->i = n * ((n > 0) ? 10 : 6); return RIG_OK; } static int ft897_get_rawstr_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int ft897_get_alc_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* have to check PTT first - only 1 byte (0xff) returned in RX and two bytes returned in TX */ if ((p->tx_status & 0x80) == 0) { if (check_cache_timeout(&p->tm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_METER)) < 0) { return n; } } /* returns 2 bytes when in TX mode: byte[0]: bits 7:4 --> power byte[0]: bits 3:0 --> ALC byte[1]: bits 7:4 --> SWR byte[1]: bits 3:0 --> MOD */ val->f = p->tm_status[0] >> 4; } else { val->f = 0; } return RIG_OK; } int ft897_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (level) { case RIG_LEVEL_STRENGTH: return ft897_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft897_get_rawstr_level(rig, val); case RIG_LEVEL_RFPOWER: return ft897_get_pometer_level(rig, val); case RIG_LEVEL_SWR: return ft897_get_swr_level(rig, val); case RIG_LEVEL_ALC: return ft897_get_alc_level(rig, val); default: return -RIG_EINVAL; } return RIG_OK; } int ft897_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft897_send_cmd(RIG *rig, int index) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: incomplete sequence\n", __func__); return -RIG_EINTERNAL; } write_block(RIGPORT(rig), ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft897_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ int ft897_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: requested freq = %"PRIfreq" Hz\n", __func__, freq); /* fill in the frequency */ to_bcd_be(data, (freq + 5) / 10, 8); /*invalidate frequency cache*/ rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_FREQ, data); } int ft897_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT897_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT897_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT897_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT897_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: /* user has to have correct DIG mode setup on rig */ index = FT897_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_FM: index = FT897_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT897_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT897_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL) { return -RIG_EINVAL; } rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft897_send_cmd(rig, index); } int ft897_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT897_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT897_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); index = FT897_NATIVE_CAT_SET_VFOAB; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_OFF: index = FT897_NATIVE_CAT_SPLIT_OFF; break; case RIG_SPLIT_ON: index = FT897_NATIVE_CAT_SPLIT_ON; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } if (p->tx_status & 0x80) { // TX status not valid when in RX unsigned char c; if ((n = ft897_read_eeprom(rig, 0x008d, &c)) < 0) /* get split status */ { return n; } *split = (c & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } return RIG_OK; } int ft897_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_LOCK_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_OFF); } #if 0 case RIG_FUNC_CODE: /* this doesn't exist */ if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ENC_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } #endif default: return -RIG_EINVAL; } } int ft897_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set DCS code (%u)\n", code); if (code == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ENC_ON); } int ft897_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON); } int ft897_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set DCS sql (%u)\n", code); if (code == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ON); } int ft897_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ON); } int ft897_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set repeater shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } int ft897_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set repeater offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_RPT_OFFSET, data); } int ft897_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_OFF); } else { ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_ON); }*/ return RIG_OK; } /* ---------------------------------------------------------------------- */ hamlib-4.6.5/rigs/yaesu/ft757gx.h0000664000175000017500000000520315056640443012132 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * * ft757gx.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-757GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT757GX_H #define _FT757GX_H 1 #define FT757GX_STATUS_UPDATE_DATA_LENGTH 75 #define FT757GX_PACING_INTERVAL 0 #define FT757GX_PACING_DEFAULT_VALUE 0 #define FT757GX_WRITE_DELAY 50 /* number of BCD digits--2 digits per octet */ #define BCD_LEN 8 /* Sequential fast writes confuse my FT757GX without this delay */ #define FT757GX_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT757GX_DEFAULT_READ_TIMEOUT FT757GX_STATUS_UPDATE_DATA_LENGTH * (5 + (FT757GX_PACING_INTERVAL * FT757GX_PACING_DEFAULT_VALUE)) /* * Some useful offsets in the status update map (offset = book byte value - 1) * * Status Update Chart, FT757GXII */ #define STATUS_CURR_FREQ 5 /* Operating Frequency */ #define STATUS_CURR_MODE 9 #define STATUS_VFOA_FREQ 10 #define STATUS_VFOA_MODE 14 #define STATUS_VFOB_FREQ 15 #define STATUS_VFOB_MODE 19 /* Mode values for both set and get */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CWW 0x02 #define MODE_CWN 0x03 #define MODE_AM 0x04 #define MODE_FM 0x05 /* TODO: get better measure numbers */ #define FT757GXII_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 15, 60 } /* +60 */ \ } } #define FT757_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1 \ } /* * Receiver caps */ #define FT757GX_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * TX caps */ #define FT757GX_ALL_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #endif /* _FT757GX_H */ hamlib-4.6.5/rigs/yaesu/ft5000.c0000664000175000017500000003070415056640443011634 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft5000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-DX5000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft5000.h" #include "tones.h" const struct newcat_priv_caps ftdx5000_priv_caps = { .roofing_filter_count = 11, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, }, }; const struct confparams ftdx5000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz (Main)", "300 Hz (Main)", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz (Main)", "AUTO - 300 Hz (Main)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "S. Narrow", "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx5000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ftdx5000_caps = { RIG_MODEL(RIG_MODEL_FTDX5000), .model_name = "FTDX-5000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX5000_WRITE_DELAY, .post_write_delay = FTDX5000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX5000_FUNCS, .has_set_func = FTDX5000_FUNCS, .has_get_level = FTDX5000_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX5000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING, .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT5000_RFPOWER_METER_CAL, .str_cal = FTDX5000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m_REGION1(FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m_REGION1(FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m_REGION2(FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m_REGION2(FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx5000_ext_tokens, .extlevels = ftdx5000_ext_levels, .priv = &ftdx5000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft990.c0000775000175000017500000027307015056640443011601 /* * hamlib - (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * (C) Terry Embry 2009 * * ft990.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* THIS FILE WAS MODIFIED IN DECEMBER 2016 TO REMOVE ANY REFERENCE TO THE FT-1000/D. SEPARATE ft1000d.c and .h FILES * WERE CREATED TO HANDLE FT-1000/D COMMANDS AND PROVIDE THE FULL RANGE OF FUNCTIONS AVAILABLE ON THE FT-1000/D * TO MAXIMISE COMPATIBILITY WITH RIGCTL. * G0OAN */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft990.h" // FT990 native commands enum ft990_native_cmd_e { FT990_NATIVE_SPLIT_OFF = 0, FT990_NATIVE_SPLIT_ON, FT990_NATIVE_RECALL_MEM, FT990_NATIVE_VFO_TO_MEM, FT990_NATIVE_LOCK_OFF, FT990_NATIVE_LOCK_ON, FT990_NATIVE_VFO_A, FT990_NATIVE_VFO_B, FT990_NATIVE_MEM_TO_VFO, FT990_NATIVE_VFO_STEP_UP, FT990_NATIVE_VFO_STEP_UP_FAST, FT990_NATIVE_VFO_STEP_DOWN, FT990_NATIVE_VFO_STEP_DOWN_FAST, FT990_NATIVE_RX_CLARIFIER_OFF, FT990_NATIVE_RX_CLARIFIER_ON, FT990_NATIVE_TX_CLARIFIER_OFF, FT990_NATIVE_TX_CLARIFIER_ON, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET, FT990_NATIVE_CLARIFIER_OPS, FT990_NATIVE_FREQ_SET, FT990_NATIVE_MODE_SET_LSB, FT990_NATIVE_MODE_SET_USB, FT990_NATIVE_MODE_SET_CW_W, FT990_NATIVE_MODE_SET_CW_N, FT990_NATIVE_MODE_SET_AM_W, FT990_NATIVE_MODE_SET_AM_N, FT990_NATIVE_MODE_SET_FM, FT990_NATIVE_MODE_SET_RTTY_LSB, FT990_NATIVE_MODE_SET_RTTY_USB, FT990_NATIVE_MODE_SET_PKT_LSB, FT990_NATIVE_MODE_SET_PKT_FM, FT990_NATIVE_PACING, FT990_NATIVE_PTT_OFF, FT990_NATIVE_PTT_ON, FT990_NATIVE_UPDATE_ALL_DATA, FT990_NATIVE_UPDATE_MEM_CHNL, FT990_NATIVE_UPDATE_OP_DATA, FT990_NATIVE_UPDATE_VFO_DATA, FT990_NATIVE_UPDATE_MEM_CHNL_DATA, FT990_NATIVE_TUNER_OFF, FT990_NATIVE_TUNER_ON, FT990_NATIVE_TUNER_START, FT990_NATIVE_RPTR_SHIFT_NONE, FT990_NATIVE_RPTR_SHIFT_MINUS, FT990_NATIVE_RPTR_SHIFT_PLUS, FT990_NATIVE_VFO_TO_VFO, FT990_NATIVE_BANDWIDTH, FT990_NATIVE_OP_FREQ_STEP_UP, FT990_NATIVE_OP_FREQ_STEP_DOWN, FT990_NATIVE_READ_METER, FT990_NATIVE_DIM_LEVEL, FT990_NATIVE_RPTR_OFFSET, FT990_NATIVE_READ_FLAGS, FT990_NATIVE_SIZE }; /* HAMLIB API implementation */ static int ft990_init(RIG *rig); static int ft990_cleanup(RIG *rig); static int ft990_open(RIG *rig); static int ft990_close(RIG *rig); static int ft990_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft990_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft990_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft990_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft990_set_vfo(RIG *rig, vfo_t vfo); static int ft990_get_vfo(RIG *rig, vfo_t *vfo); static int ft990_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft990_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft990_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft990_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft990_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft990_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft990_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft990_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft990_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft990_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft990_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft990_set_parm(RIG *rig, setting_t parm, value_t val); static int ft990_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft990_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft990_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft990_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft990_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft990_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft990_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft990_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft990_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft990_send_static_cmd(RIG *rig, unsigned char ci); static int ft990_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft990_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft990_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* OP Mode Set PKT FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* Update All Data (1508 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Update Memory Ch Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct ft990_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft990_update_data_t update_data; /* returned data */ }; /* * ft990 rigs capabilities. */ #define FT990_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } struct rig_caps ft990_caps = { RIG_MODEL(RIG_MODEL_FT990), .model_name = "FT-990", .mfg_name = "Yaesu", .version = "20211231.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT990_WRITE_DELAY, .post_write_delay = FT990_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT990_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(1, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(2, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT990_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT990_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT990_AM_RX_MODES, Hz(100)}, /* Normal */ {FT990_AM_RX_MODES, kHz(1)}, /* Fast */ {FT990_FM_RX_MODES, Hz(100)}, /* Normal */ {FT990_FM_RX_MODES, kHz(1)}, /* Fast */ {FT990_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT990_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft990_init, .rig_cleanup = ft990_cleanup, .rig_open = ft990_open, /* port opened */ .rig_close = ft990_close, /* port closed */ .set_freq = ft990_set_freq, .get_freq = ft990_get_freq, .set_mode = ft990_set_mode, .get_mode = ft990_get_mode, .set_vfo = ft990_set_vfo, .get_vfo = ft990_get_vfo, .set_ptt = ft990_set_ptt, .get_ptt = ft990_get_ptt, .set_rptr_shift = ft990_set_rptr_shift, .get_rptr_shift = ft990_get_rptr_shift, .set_rptr_offs = ft990_set_rptr_offs, .set_split_vfo = ft990_set_split_vfo, .get_split_vfo = ft990_get_split_vfo, .set_rit = ft990_set_rit, .get_rit = ft990_get_rit, .set_xit = ft990_set_xit, .get_xit = ft990_get_xit, .set_func = ft990_set_func, .get_func = ft990_get_func, .set_parm = ft990_set_parm, .get_level = ft990_get_level, .set_mem = ft990_set_mem, .get_mem = ft990_get_mem, .vfo_op = ft990_vfo_op, .set_channel = ft990_set_channel, .get_channel = ft990_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ int ft990_init(RIG *rig) { struct ft990_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft990_priv_data *) calloc(1, sizeof(struct ft990_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT990_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * rig_cleanup */ int ft990_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ int ft990_open(RIG *rig) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close */ int ft990_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft990_priv_data *priv; int err; vfo_t vfo_save; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; vfo_save = priv->current_vfo; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != vfo_save) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990_send_dial_freq(rig, FT990_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } if (vfo != vfo_save) { err = ft990_set_vfo(rig, vfo_save); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft990_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update data structure to obtain get frequency err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft990_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT990_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT990_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ int ft990_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT990_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ int ft990_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft990_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT990_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT990_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT990_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT990_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ int ft990_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft990_priv_data *priv; ft990_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT990_MODE_FM) { *rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } else { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ int ft990_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT990_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT990_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ int ft990_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft990_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT990_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT990_NATIVE_SPLIT_OFF; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ int ft990_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Read status flags err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT990_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT990_SF_VFOB) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ int ft990_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_TX_EN) == 0) { err = ft990_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft990_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft990_priv_data *priv; unsigned char ci; ft990_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ int ft990_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_RX_EN) == 0) { err = ft990_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft990_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft990_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft990_priv_data *priv; unsigned char ci; ft990_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ int ft990_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT990_NATIVE_LOCK_ON; } else { ci = FT990_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT990_NATIVE_TUNER_ON; } else { ci = FT990_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ int ft990_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft990_priv_data *)STATE(rig)->priv; err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT990_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT990_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT990_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ int ft990_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft990_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft990_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT990_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT990_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT990_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT990_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT990_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT990_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT990_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT990_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT990_NATIVE_MODE_SET_AM_N || ci == FT990_NATIVE_MODE_SET_AM_W || ci == FT990_NATIVE_MODE_SET_FM || ci == FT990_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT990_BW_F250; } else if (width <= 500) { bw = FT990_BW_F500; } else if (width <= 2000) { bw = FT990_BW_F2000; } else { bw = FT990_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft990_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT990_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT990_MODE_USB: *mode = RIG_MODE_USB; break; case FT990_MODE_CW: *mode = RIG_MODE_CW; break; case FT990_MODE_AM: *mode = RIG_MODE_AM; break; case FT990_MODE_FM: *mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT990 firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT990 firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT990_BW_F2000: *width = 2000; break; case FT990_BW_F500: *width = 500; break; case FT990_BW_F250: *width = 250; break; case FT990_BW_F6000: *width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_vfo(RIG *rig, vfo_t vfo) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_A; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_B; break; case RIG_VFO_MEM: ci = FT990_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft990_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ int ft990_get_vfo(RIG *rig, vfo_t *vfo) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } if (priv->update_data.flag2 & FT990_SF_MEM || priv->update_data.flag2 & FT990_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT990_SF_VFOB) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft990_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990_send_static_cmd(rig, FT990_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT990_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %s\n", __func__, rig_strvfop(op)); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT990_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT990_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT990_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT990_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT990_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT990_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft990_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ int ft990_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ int ft990_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ int ft990_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ int ft990_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft990_priv_data *priv; ft990_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %s\n", __func__, rig_strvfo(chan->vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft990_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft990_op_data_t *) &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft990_op_data_t *) &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft990_op_data_t *) &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft990_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft990_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT990_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = 0x%02x\n", __func__, p->mode); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT990_BW_F2000: chan->width = 2000; break; case FT990_BW_F500: chan->width = 500; break; case FT990_BW_F250: chan->width = 250; break; case FT990_BW_F6000: chan->width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT990_SF_SPLIT); if (priv->update_data.flag1 & FT990_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT990_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT990_SF_FAST) { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT990_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft990_op_data_t *) &priv->update_data.current_rear; /* FT1000D * if (RIG_MODEL_FT1000D == rig->caps->rig_model) * p = (ft990_op_data_t *) &priv->update_data.vfob; * chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + * p->basefreq[2]) * 10; * * THIS SECTION WAS REMOVED IN DECEMBER 2016. SEE SEPARATE ft1000d.c and .h FILES */ /* Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT990_BW_F2000: chan->tx_width = 2000; break; case FT990_BW_F500: chan->tx_width = 500; break; case FT990_BW_F250: chan->tx_width = 250; break; case FT990_BW_F6000: chan->tx_width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } if (priv->update_data.flag1 & FT990_SF_VFOB) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing ft990_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { struct ft990_priv_data *priv; int n; int err; int rl; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ci == FT990_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { err = ft990_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); } else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: return RIG_OK; break; case FT990_NATIVE_UPDATE_MEM_CHNL: p = (unsigned char *) &priv->update_data.channelnumber; rl = FT990_MEM_CHNL_LENGTH; break; case FT990_NATIVE_UPDATE_OP_DATA: p = (unsigned char *) &priv->update_data.current_front; rl = FT990_OP_DATA_LENGTH; break; case FT990_NATIVE_UPDATE_VFO_DATA: p = (unsigned char *) &priv->update_data.vfoa; rl = FT990_VFO_DATA_LENGTH; break; case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT990_MEM_CHNL_DATA_LENGTH; break; case FT990_NATIVE_READ_FLAGS: p = temp; rl = FT990_STATUS_FLAGS_LENGTH; break; default: return -RIG_EINVAL; } n = read_block(RIGPORT(rig), p, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); if (ci == FT990_NATIVE_READ_FLAGS) { memcpy(&priv->update_data, p, FT990_STATUS_FLAGS_LENGTH - 2); } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft990_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT990_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT990_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT990_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT990_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT990_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT990_BCD_RIT); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.5/rigs/yaesu/frg100.c0000664000175000017500000004107115056640443011714 /* * frg100.c - (C) Stephane Fillod 2002-2005 * * This shared library provides an API for communicating * via serial interface to an FRG-100 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "frg100.h" enum frg100_native_cmd_e { FRG100_NATIVE_RECALL_MEM = 0, /* 0x02, p1=ch */ FRG100_NATIVE_VFO_TO_MEM, /* 0x03, p1=ch, p2=0 */ FRG100_NATIVE_MEM_HIDE, /* 0x03, p1=ch, p2=1 */ FRG100_NATIVE_VFO_A, /* 0x05 */ FRG100_NATIVE_FREQ_SET, /* 0x0a, p1:4=freq */ FRG100_NATIVE_MODE_SET_LSB, /* 0x0c, p1=0x00 */ FRG100_NATIVE_MODE_SET_USB, /* 0x0c, p1=0x01 */ FRG100_NATIVE_MODE_SET_CW_W, /* 0x0c, p1=0x02 */ FRG100_NATIVE_MODE_SET_CW_N, /* 0x0c, p1=0x03 */ FRG100_NATIVE_MODE_SET_AM, /* 0x0c, p1=0x04 */ FRG100_NATIVE_MODE_SET_RTTY_LSB_W, /* 0x0c, p1=0x08 */ FRG100_NATIVE_MODE_SET_RTTY_USB_W, /* 0x0c, p1=0x09 */ FRG100_NATIVE_MODE_SET_H3E, /* 0x0c, p1=0x0d */ FRG100_NATIVE_MODE_SET_RTTY_LSB_N, /* 0x0c, p1=0x0e */ FRG100_NATIVE_MODE_SET_RTTY_USB_N, /* 0x0c, p1=0x0f */ FRG100_NATIVE_PTT_OFF, /* 0x0f, p1=0 */ FRG100_NATIVE_PTT_ON, /* 0x0f, p1=1 */ FRG100_NATIVE_UPDATE_MEM_CHNL, /* 0x10, p1=1 */ FRG100_NATIVE_UPDATE_OP_DATA, /* 0x10, p1=2 */ FRG100_NATIVE_UPDATE_VFO_DATA, /* 0x10, p1=3 */ FRG100_NATIVE_TX_POWER_LOW, /* 0x18 */ FRG100_NATIVE_TX_POWER_MID, /* 0x28 */ FRG100_NATIVE_TX_POWER_HI, /* 0x48 */ FRG100_NATIVE_CPY_RX_TO_TX, /* 0x85 */ FRG100_NATIVE_TX_FREQ_SET, /* 0x8a, p1:4=freq */ FRG100_NATIVE_OP_FREQ_STEP_UP, /* 0x8e, p1=0 */ FRG100_NATIVE_OP_FREQ_STEP_DOWN, /* 0x8e, p1=1 */ FRG100_NATIVE_READ_METER, /* 0xf7 */ FRG100_NATIVE_READ_FLAGS, /* 0xfa */ FRG100_NATIVE_SIZE }; #define FRG100_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM) #define FRG100_VFOS (RIG_VFO_A) #define FRG100_ANTS 0 /* TODO: get real measure numbers */ #define FRG100_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 60, 60 } /* +60 */ \ } } #define FRG100_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1 \ } static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* VFO to MEM */ { 0, { 0x00, 0x00, 0x01, 0x00, 0x03 } }, /* Hide Memory Channel */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW-W */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW-N */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB-W */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB-W */ { 1, { 0x00, 0x00, 0x00, 0x0d, 0x0c } }, /* OP Mode Set H3E */ { 1, { 0x00, 0x00, 0x00, 0x0e, 0x0c } }, /* OP Mode Set RTTY LSB-N */ { 1, { 0x00, 0x00, 0x00, 0x0f, 0x0c } }, /* OP Mode Set RTTY USB-N */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x18 } }, /* Set TX power low */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x28 } }, /* Set TX power mid */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x48 } }, /* Set TX power hi */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy RX to TX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* Set TX Freq only */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8e } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* Private helper function prototypes */ static int frg100_open(RIG *rig); static int frg100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int frg100_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int frg100_set_vfo(RIG *rig, vfo_t vfo); static int frg100_set_powerstat(RIG *rig, powerstat_t status); static int frg100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #if 0 static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); #endif static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width); /* * frg100 rigs capabilities. * Also this struct is READONLY! * * TODO: * - Memory recall * - VFO->M & M->VFO * - Lock, Up/Down * - Status update * - Clock set, Timer * - Scan skip * - Step Frequency Size * - Dim */ struct rig_caps frg100_caps = { RIG_MODEL(RIG_MODEL_FRG100), .model_name = "FRG-100", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 20, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 0x32, RIG_MTYPE_MEM, FRG100_MEM_CAP }, { 0x33, 0x34, RIG_MTYPE_EDGE }, }, .rx_range_list1 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, Hz(10)}, {RIG_MODE_FM | RIG_MODE_AM, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = FRG100_STR_CAL, .rig_open = frg100_open, .get_freq = frg100_get_freq, .set_freq = frg100_set_freq, .set_mode = frg100_set_mode, .set_vfo = frg100_set_vfo, .get_level = frg100_get_level, .set_powerstat = frg100_set_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static inline int frg100_channel_is_ok(unsigned char channel) { return ((channel >= FRG100_MIN_CHANNEL) && (channel <= FRG100_MAX_CHANNEL)) ? 1 : 0; } static int frg100_do_transaction(RIG *rig, const unsigned char cmd[YAESU_CMD_LENGTH], unsigned char *retbuf, size_t retbuf_len) { hamlib_port_t *rp = RIGPORT(rig); unsigned char default_retbuf[1]; int retval; if (retbuf == NULL) { retbuf = default_retbuf; retbuf_len = sizeof(default_retbuf); } memset(retbuf, 0, retbuf_len); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } retval = read_block(rp, retbuf, retbuf_len); if (retval != retbuf_len) { if ((retval == 1) && (retbuf[0] == FRG100_CMD_RETCODE_ERROR)) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retval == 1) { if ((cmd[4] == FRG100_CMD_UPDATE) && (cmd[3] == 0x01)) { /* read memory channel number */ if (frg100_channel_is_ok(retbuf[0] + 1)) { /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ return RIG_OK; } if (retbuf[0] == FRG100_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retbuf[0] == FRG100_CMD_RETCODE_OK) { return RIG_OK; } if (retbuf[0] == FRG100_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } return RIG_OK; } static inline freq_t frg100_read_freq_from_buf(const unsigned char p[]) { /* WARNING: documentation bug, actually frequency stored in bytes 0..2 only, byte 3 is not used and contain zero */ return ((((((unsigned)p[2]) << 8) + p[1]) << 8) + p[0]) * 10.0; } static inline int frg100_read_op_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return frg100_do_transaction(rig, ncmd[FRG100_NATIVE_UPDATE_OP_DATA].nseq, reply, FRG100_OP_DATA_LENGTH); } static int frg100_read_op_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[FRG100_OP_DATA_LENGTH]; if ((ret = frg100_read_op_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[7]; } if (rx_freq != NULL) { *rx_freq = frg100_read_freq_from_buf(reply + 2); } if (tx_freq != NULL) { *tx_freq = frg100_read_freq_from_buf(reply + 11); } return RIG_OK; } /* * frg100_open routine * */ int frg100_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0e}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send 0 delay pacing */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { (void) vfo; return frg100_read_op_data(rig, NULL, freq, NULL); } int frg100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0a}; /* store bcd format in cmd (LSB) */ to_bcd(cmd, freq / 10, 8); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0c}; /* fill in p1 */ cmd[3] = mode2rig(rig, mode, width); return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } /* * Actually, this is tape relay, 0xfe=on */ int frg100_set_powerstat(RIG *rig, powerstat_t status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x20}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cmd[3] = status == RIG_POWER_OFF ? 0x00 : 0x01; /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: cmd[4] = 0x05; break; case RIG_VFO_MEM: /* TODO: cmd[3] = priv->current_mem_chan; */ cmd[4] = 0x02; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CWW 0x02 #define MODE_CWN 0x03 #define MODE_AMW 0x04 #define MODE_AMN 0x05 #define MODE_FMW 0x06 #define MODE_FMN 0x07 int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width) { int md; /* * translate mode from generic to frg100 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_AMN; } else { md = MODE_AMW; } break; case RIG_MODE_FM: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_FMN; } else { md = MODE_FMW; } break; case RIG_MODE_CW: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_CWN; } else { md = MODE_CWW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } /* function not used */ #if 0 int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { /* * translate mode from frg100 specific to generic */ switch (md) { case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_AMW: case MODE_AMN: *mode = RIG_MODE_AM; break; case MODE_FMW: case MODE_FMN: *mode = RIG_MODE_FM; break; case MODE_CWW: case MODE_CWN: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (md == MODE_CWN || md == MODE_AMN || md == MODE_FMN) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } #endif hamlib-4.6.5/rigs/yaesu/ft840.h0000664000175000017500000002247515056640443011576 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft840.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2009 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-840 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT840_H #define _FT840_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT840_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT840_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT840_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT840_AM_RX_MODES (RIG_MODE_AM) #define FT840_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT840_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT840_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT840_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT840_ANTS 0 /* Returned data length in bytes */ #define FT840_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT840_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT840_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT840_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT840_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT840_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT840_PACING_INTERVAL 5 #define FT840_PACING_DEFAULT_VALUE 0 #define FT840_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT840_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT840_DEFAULT_READ_TIMEOUT 649 * ( 5 + (FT840_PACING_INTERVAL * FT840_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT840_BCD_DIAL 8 #define FT840_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 649 bytes in 1487 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------ ---------------------- * * 0 1487 msec * 1 2136 msec (backend default) * 2 2785 msec * 5 4732 msec * 255 167 sec * */ /* * Internal MODES - when setting modes via FT840_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT840_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-840 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-840 manual on page 33. * */ #define FT840_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT840_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT840_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-840 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-840 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT840_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT840_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT840_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT840_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT840_SUMO_DISPLAYED_FLAG 0x09 #define FT840_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT840_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT840_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT840_SUMO_VFO_A_FLAG 0x08 #define FT840_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT840_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT840_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT840_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-840 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT840_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-840 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-840 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 #endif /* _FT840_H */ hamlib-4.6.5/rigs/yaesu/frg8800.c0000664000175000017500000001560615056640443012020 /* * frg8800.c - (C) Stephane Fillod 2002-2004 * * This shared library provides an API for communicating * via serial interface to an FRG-8800 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" /* Private helper function prototypes */ #define FRG8800_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define FRG8800_VFOS (RIG_VFO_A) #define FRG8800_ANTS 0 static int frg8800_open(RIG *rig); static int frg8800_close(RIG *rig); static int frg8800_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg8800_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int frg8800_set_powerstat(RIG *rig, powerstat_t status); /* * frg8800 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps frg8800_caps = { RIG_MODEL(RIG_MODEL_FRG8800), .model_name = "FRG-8800", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(29.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, {MHz(118), MHz(173.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(150), MHz(29.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, {MHz(118), MHz(173.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {FRG8800_MODES, Hz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_WFM, kHz(230)}, /* optional unit */ RIG_FLT_END, }, .rig_open = frg8800_open, .rig_close = frg8800_close, .set_freq = frg8800_set_freq, .set_mode = frg8800_set_mode, .set_powerstat = frg8800_set_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #define MODE_SET_AM 0x00 #define MODE_SET_LSB 0x01 #define MODE_SET_USB 0x02 #define MODE_SET_CW 0x03 #define MODE_SET_FM 0x0c #define MODE_SET_FMW 0x04 /* * frg8800_open routine * */ int frg8800_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send Ext Cntl ON: Activate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x80, 0x00}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send Ext Cntl OFF: Deactivate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* store bcd format in cmd (LSB) */ to_bcd(cmd, freq / 10, 8); /* Byte1: 100Hz's and 25Hz step code */ cmd[0] = (cmd[0] & 0xf0) | (1 << ((((long long)freq) % 100) / 25)); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; unsigned char md; rig_debug(RIG_DEBUG_TRACE, "%s: frg8800_set_mode called %s\n", __func__, rig_strrmode(mode)); /* * translate mode from generic to frg8800 specific */ switch (mode) { case RIG_MODE_AM: md = MODE_SET_AM; break; case RIG_MODE_CW: md = MODE_SET_CW; break; case RIG_MODE_USB: md = MODE_SET_USB; break; case RIG_MODE_LSB: md = MODE_SET_LSB; break; case RIG_MODE_FM: md = MODE_SET_FM; break; case RIG_MODE_WFM: md = MODE_SET_FMW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x08; } cmd[3] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_powerstat(RIG *rig, powerstat_t status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cmd[3] = status == RIG_POWER_OFF ? 0xff : 0xfe; /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } hamlib-4.6.5/rigs/yaesu/ft100.h0000664000175000017500000000252415056640443011554 /* * hamlib - (C) Frank Singleton 2000-2003 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft100.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-100 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT100_H #define _FT100_H 1 #define FT100_WRITE_DELAY 0 #define FT100_POST_WRITE_DELAY 25 /* max is 200ms */ #define FT100_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT100_H */ hamlib-4.6.5/rigs/yaesu/ft891.h0000664000175000017500000001167415056640443011603 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft891.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT891_H #define _FT891_H 1 #define FT891_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT891_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_FMN) #define FT891_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT891_AM_RX_MODES (RIG_MODE_AM) #define FT891_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_FMN) #define FT891_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT891_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT891_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ RIG_MODE_FM|RIG_MODE_FMN) /* 100 W class */ #define FT891_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT891_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT891_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT891_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // borrowed from FT991 #define FT891_RFPOWER_METER_CAL \ { \ 7, \ { \ {0, 0.0f}, \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT891_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT891_ANTS (RIG_ANT_CURR) #define FT891_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT891_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT891_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT891_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT891_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT891_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT891_PACING_INTERVAL 5 // #define FT891_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-891 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT891_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT891_POST_WRITE_DELAY 50 /* Reuse newcat_get_cmd */ extern int newcat_get_cmd(RIG *rig); #endif /* _FT891_H */ hamlib-4.6.5/rigs/yaesu/ft747.c0000664000175000017500000006563715056640443011606 /* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft747.c - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-747GX using the "CAT" interface * box (FIF-232C) or similar * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO - FS * * 1. rationalise code, more helper functions [started] * 2. get_channel, set_func/get_func * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft747.h" /* * Native FT747 functions. This is what I have to work with :-) * */ enum ft747_native_cmd_e { FT_747_NATIVE_SPLIT_OFF = 0, FT_747_NATIVE_SPLIT_ON, FT_747_NATIVE_RECALL_MEM, FT_747_NATIVE_VFO_TO_MEM, FT_747_NATIVE_DLOCK_OFF, FT_747_NATIVE_DLOCK_ON, FT_747_NATIVE_VFO_A, FT_747_NATIVE_VFO_B, FT_747_NATIVE_M_TO_VFO, FT_747_NATIVE_UP_500K, FT_747_NATIVE_DOWN_500K, FT_747_NATIVE_CLARIFY_OFF, FT_747_NATIVE_CLARIFY_ON, FT_747_NATIVE_FREQ_SET, FT_747_NATIVE_MODE_SET_LSB, FT_747_NATIVE_MODE_SET_USB, FT_747_NATIVE_MODE_SET_CWW, FT_747_NATIVE_MODE_SET_CWN, FT_747_NATIVE_MODE_SET_AMW, FT_747_NATIVE_MODE_SET_AMN, FT_747_NATIVE_MODE_SET_FMW, FT_747_NATIVE_MODE_SET_FMN, FT_747_NATIVE_PACING, FT_747_NATIVE_PTT_OFF, FT_747_NATIVE_PTT_ON, FT_747_NATIVE_UPDATE, FT_747_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft747_native_cmd_e ft747_native_cmd_t; /* Internal MODES - when setting modes via cmd_mode_set() */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CWW 0x02 #define MODE_SET_CWN 0x03 #define MODE_SET_AMW 0x04 #define MODE_SET_AMN 0x05 #define MODE_SET_FMW 0x06 #define MODE_SET_FMN 0x07 /* * Mode Bitmap. Bits 5 and 6 unused * When READING modes */ #define MODE_FM 0x01 #define MODE_AM 0x02 #define MODE_CW 0x04 #define MODE_FMN 0x81 #define MODE_AMN 0x82 #define MODE_CWN 0x84 #define MODE_USB 0x08 #define MODE_LSB 0x10 #define MODE_NAR 0x80 /* All relevant bits */ #define MODE_MASK 0x9f /* * Status Flag Masks when reading */ #define SF_DLOCK 0x01 #define SF_SPLIT 0x02 #define SF_CLAR 0x04 #define SF_VFOAB 0x08 #define SF_VFOMR 0x10 #define SF_RXTX 0x20 #define SF_RESV 0x40 #define SF_PRI 0x80 /* * Local VFO CMD's, according to spec */ #define FT747_VFO_A 0x00 #define FT747_VFO_B 0x01 /* * Some useful offsets in the status update map (offset) * * Manual appears to be full of mistakes regarding offsets etc.. -- FS * */ #define FT747_SUMO_DISPLAYED_MEM 0x17 #define FT747_SUMO_DISPLAYED_MODE 0x18 #define FT747_SUMO_DISPLAYED_STATUS 0x00 #define FT747_SUMO_DISPLAYED_FREQ 0x01 #define FT747_SUMO_VFO_A_FREQ 0x09 #define FT747_SUMO_VFO_B_FREQ 0x11 /* * API local implementation */ static int ft747_init(RIG *rig); static int ft747_cleanup(RIG *rig); static int ft747_open(RIG *rig); static int ft747_close(RIG *rig); static int ft747_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft747_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft747_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft747_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft747_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft747_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft747_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft747_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft747_get_split(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft747_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft747_get_mem(RIG *rig, vfo_t vfo, int *ch); /* Private helper function prototypes */ static int ft747_get_update_data(RIG *rig); static int ft747_send_priv_cmd(RIG *rig, unsigned char ci); /* Native ft747 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ft747_ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory*/ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* vfo to memory*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* dial lock = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* dial lock = on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* memory to vfo*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* up 500 khz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* down 500 khz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarify off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* clarify on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* mode set CWW */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set CWN */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set AMW */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* mode set AMN */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* mode set FMW */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* mode set FMN */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* pacing set */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* request update from rig */ }; /* * Receiver caps */ #define FT747_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT747_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT747_AM_RX_MODES (RIG_MODE_AM) #define FT747_FM_RX_MODES (RIG_MODE_FM) /* * TX caps */ #define FT747_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT747_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ /* * no opcode for RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN * TODO: LOCK */ #define FT747_FUNC_ALL (RIG_FUNC_LOCK) #define FT747_VFOS (RIG_VFO_A|RIG_VFO_B) /* * FT747 channel caps. * Last 2 channels don't have split memory */ #define FT747_SPLIT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .funcs = RIG_FUNC_LOCK, \ } #define FT747_NOSPLIT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .funcs = RIG_FUNC_LOCK, \ } /* * Private data * */ struct ft747_priv_data { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT747_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ struct timeval status_tv; }; /* * ft747 rigs capabilities. * Also this struct is READONLY! */ struct rig_caps ft747_caps = { RIG_MODEL(RIG_MODEL_FT747), .model_name = "FT-747GX", .mfg_name = "Yaesu", .version = "20241108.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT747_WRITE_DELAY, .post_write_delay = FT747_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = FT747_FUNC_ALL, .has_set_func = FT747_FUNC_ALL, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), /* 9999 */ .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 17, RIG_MTYPE_MEM, FT747_SPLIT_MEM_CAP }, { 18, 19, RIG_MTYPE_MEM, FT747_NOSPLIT_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(100), .endf = 29999900, .modes = FT747_ALL_RX_MODES, .low_power = -1, .high_power = -1, .vfo = FT747_VFOS }, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1500), 1999900, FT747_OTHER_TX_MODES, .low_power = 5000, .high_power = 100000, .vfo = FT747_VFOS}, /* 100W class */ {.startf = kHz(1500), .endf = 1999900, FT747_AM_TX_MODES, .low_power = 2000, .high_power = 25000, .vfo = FT747_VFOS}, /* 25W class */ {.startf = kHz(3500), 3999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(3500), 3999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = kHz(7000), 7499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(7000), 7499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(10), 10499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(10), 10499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(14), 14499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(14), 14499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(18), 18499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(18), 18499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(21), 21499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(21), 21499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = kHz(24500), 24999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(24500), 24999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(28), 29999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(28), 29999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, RIG_FRNG_END, }, .tuning_steps = { {FT747_SSB_CW_RX_MODES, 25}, /* fast off */ {FT747_SSB_CW_RX_MODES, 2500}, /* fast on */ {FT747_AM_RX_MODES, kHz(1)}, /* fast off */ {FT747_AM_RX_MODES, kHz(10)}, /* fast on */ {FT747_FM_RX_MODES, kHz(5)}, /* fast off */ {FT747_FM_RX_MODES, 12500}, /* fast on */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(1.8)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* AM filter with narrow selection */ {RIG_MODE_FM, kHz(19)}, /* FM wide filter, with optional FM unit. */ {RIG_MODE_FM, kHz(8)}, /* FM with optional FM unit */ RIG_FLT_END, }, .priv = NULL, /* private data */ .rig_init = ft747_init, .rig_cleanup = ft747_cleanup, .rig_open = ft747_open, /* port opened */ .rig_close = ft747_close, /* port closed */ .set_freq = ft747_set_freq, /* set freq */ .get_freq = ft747_get_freq, /* get freq */ .set_mode = ft747_set_mode, /* set mode */ .get_mode = ft747_get_mode, /* get mode */ .set_vfo = ft747_set_vfo, /* set vfo */ .get_vfo = ft747_get_vfo, /* get vfo */ .set_split_vfo = ft747_set_split, /* set split */ .get_split_vfo = ft747_get_split, /* get split */ .set_ptt = ft747_set_ptt, /* set ptt */ .set_mem = ft747_set_mem, /* set mem */ .get_mem = ft747_get_mem, /* get mem */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ int ft747_init(RIG *rig) { STATE(rig)->priv = (struct ft747_priv_data *) calloc(1, sizeof(struct ft747_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* * ft747_cleanup routine * the serial port is closed by the frontend */ int ft747_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft747_open routine * */ int ft747_open(RIG *rig) { struct rig_state *rig_s; hamlib_port_t *rp = RIGPORT(rig); struct ft747_priv_data *p; int ret; rig_s = STATE(rig); p = (struct ft747_priv_data *)rig_s->priv; rig_debug(RIG_DEBUG_VERBOSE, "ft747:rig_open: write_delay = %i msec \n", rp->write_delay); rig_debug(RIG_DEBUG_VERBOSE, "ft747:rig_open: post_write_delay = %i msec \n", rp->post_write_delay); /* * Copy native cmd PACING to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = FT747_PACING_DEFAULT_VALUE; /* get pacing value, and store in private cmd */ rig_debug(RIG_DEBUG_VERBOSE, "ft747: read pacing = %i \n", FT747_PACING_DEFAULT_VALUE); /* send PACING cmd to rig, once for all */ ret = write_block(rp, p->p_cmd, YAESU_CMD_LENGTH); if (ret < 0) { return ret; } rig_force_cache_timeout(&p->status_tv); return RIG_OK; } /* * ft747_close routine * */ int ft747_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* * Example of wrapping backend function inside frontend API * */ int ft747_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft747_priv_data *p; unsigned char *cmd; /* points to sequence to send */ // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz \n"; p = (struct ft747_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "ft747: requested freq = %"PRIfreq" Hz vfo = %s \n", freq, rig_strvfo(vfo)); /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_FREQ_SET].nseq, YAESU_CMD_LENGTH); /* store bcd format in p_cmd (LSB), round to nearest 10 Hz even though the rig will internally then round to 25 Hz steps */ to_bcd(p->p_cmd, (freq + 5) / 10, 8); rig_debug(RIG_DEBUG_VERBOSE, fmt, __func__, (int64_t)from_bcd(p->p_cmd, 8) * 10); rig_force_cache_timeout(&p->status_tv); cmd = p->p_cmd; /* get native sequence */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } /* * Return Freq for a given VFO */ int ft747_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft747_priv_data *p; struct rig_cache *cachep = CACHE(rig); freq_t f; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s, freqMainA=%.0f, freqMainB=%.0f\n", __func__, rig_strvfo(vfo), cachep->freqMainA, cachep->freqMainB); if (vfo == RIG_VFO_CURR) { vfo = cachep->vfo; } if (cachep->ptt == RIG_PTT_ON) { *freq = RIG_VFO_B ? cachep->freqMainB : cachep->freqMainA; return RIG_OK; } p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } // the leading 2 bytes are zero so we just use 4 bytes for the freq switch (vfo) { case RIG_VFO_CURR: /* grab freq and convert */ f = from_bcd_be(&(p->update_data[FT747_SUMO_DISPLAYED_FREQ]), 8); break; case RIG_VFO_A: f = from_bcd_be(&(p->update_data[FT747_SUMO_VFO_A_FREQ]), 8); break; case RIG_VFO_B: f = from_bcd_be(&(p->update_data[FT747_SUMO_VFO_B_FREQ]), 8); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_VERBOSE, "ft747: freq = %"PRIfreq" Hz for VFO = %s\n", f, rig_strvfo(vfo)); (*freq) = f; /* return displayed frequency */ return RIG_OK; } /* * set mode : eg AM, CW etc for a given VFO * */ int ft747_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ pbwidth_t width_normal; width_normal = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { width = width_normal; } /* * translate mode from generic to ft747 specific */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s \n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_AMN; } else { cmd_index = FT_747_NATIVE_MODE_SET_AMW; } break; case RIG_MODE_CW: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_CWN; } else { cmd_index = FT_747_NATIVE_MODE_SET_CWW; } break; case RIG_MODE_USB: cmd_index = FT_747_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: cmd_index = FT_747_NATIVE_MODE_SET_LSB; break; case RIG_MODE_FM: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_FMN; } else { cmd_index = FT_747_NATIVE_MODE_SET_FMW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } rig_debug(RIG_DEBUG_VERBOSE, "ft747: cmd_index = %i \n", cmd_index); rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); /* * phew! now send cmd to rig */ return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft747_priv_data *p; unsigned char mymode; /* ft747 mode */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } mymode = p->update_data[FT747_SUMO_DISPLAYED_MODE]; mymode &= MODE_MASK; /* mask out bits 5 and 6 */ rig_debug(RIG_DEBUG_VERBOSE, "ft747: mymode = %x \n", mymode); /* * translate mode from ft747 to generic. */ switch (mymode & 0x1f) { case MODE_FM: (*mode) = RIG_MODE_FM; break; case MODE_AM: (*mode) = RIG_MODE_AM; break; case MODE_CW: (*mode) = RIG_MODE_CW; break; case MODE_USB: (*mode) = RIG_MODE_USB; break; case MODE_LSB: (*mode) = RIG_MODE_LSB; break; default: return -RIG_EPROTO; /* sorry, unknown mode */ break; } if (mymode & MODE_NAR) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int ft747_set_vfo(RIG *rig, vfo_t vfo) { struct ft747_priv_data *p; unsigned char cmd_index; /* index of sequence to send */ p = (struct ft747_priv_data *)STATE(rig)->priv; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: cmd_index = FT_747_NATIVE_VFO_A; break; case RIG_VFO_B: cmd_index = FT_747_NATIVE_VFO_B; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_force_cache_timeout(&p->status_tv); return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_vfo(RIG *rig, vfo_t *vfo) { struct ft747_priv_data *p; unsigned char status; /* ft747 status flag */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } status = p->update_data[FT747_SUMO_DISPLAYED_STATUS]; status &= SF_VFOAB; /* check VFO bit*/ rig_debug(RIG_DEBUG_VERBOSE, "ft747: vfo status = %x \n", status); /* * translate vfo status from ft747 to generic. */ if (status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: VFO = B\n", __func__); (*vfo) = RIG_VFO_B; return RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: VFO = A\n", __func__); (*vfo) = RIG_VFO_A; return RIG_OK; } } int ft747_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; /* index of sequence to send */ cmd_index = split == RIG_SPLIT_ON ? FT_747_NATIVE_SPLIT_ON : FT_747_NATIVE_SPLIT_OFF; rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_split(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft747_priv_data *p; unsigned char status; /* ft747 status flag */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } status = p->update_data[FT747_SUMO_DISPLAYED_STATUS]; if (((status & SF_VFOAB) && (status & SF_RXTX)) || (!(status & SF_VFOAB) && !(status & SF_RXTX))) { *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; } else { *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; } return RIG_OK; } int ft747_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ switch (ptt) { case RIG_PTT_OFF: cmd_index = FT_747_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT_747_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); /* * phew! now send cmd to rig */ return ft747_send_priv_cmd(rig, cmd_index); } int ft747_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft747_priv_data *p; p = (struct ft747_priv_data *)STATE(rig)->priv; if (ch < 0 || ch > 0x13) { return -RIG_EINVAL; } /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_RECALL_MEM].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = ch; rig_force_cache_timeout(&p->status_tv); return write_block(RIGPORT(rig), p->p_cmd, YAESU_CMD_LENGTH); } int ft747_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft747_priv_data *p; unsigned char mem_nb; int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } mem_nb = p->update_data[FT747_SUMO_DISPLAYED_MEM]; if (mem_nb > 0x13) { return -RIG_EPROTO; } *ch = mem_nb; return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using buffer indicated in *priv struct. * * need to use this when doing ft747_get_* stuff */ static int ft747_get_update_data(RIG *rig) { hamlib_port_t *rigport; struct ft747_priv_data *p; //unsigned char last_byte; p = (struct ft747_priv_data *)STATE(rig)->priv; rigport = RIGPORT(rig); if (CACHE(rig)->ptt == RIG_PTT_ON || !rig_check_cache_timeout(&p->status_tv, FT747_CACHE_TIMEOUT)) { return RIG_OK; } if (!STATE(rig)->transmit) /* rig doesn't respond in Tx mode */ { int ret; //int port_timeout; rig_flush(rigport); /* send UPDATE command to fetch data*/ ret = ft747_send_priv_cmd(rig, FT_747_NATIVE_UPDATE); if (ret < 0) { return ret; } ret = read_block(rigport, p->update_data, FT747_STATUS_UPDATE_DATA_LENGTH); if (ret < 0) { return ret; } #if 0 // skip this extra byte -- we will flush it before doing a read port_timeout = rigport->timeout; rigport->timeout = 20; /* ms */ /* read sometimes-missing last byte (345th), but don't fail */ read_block(rigport, &last_byte, 1); rigport->timeout = port_timeout; #endif } /* update cache date */ gettimeofday(&p->status_tv, NULL); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. */ static int ft747_send_priv_cmd(RIG *rig, unsigned char ci) { if (!ft747_ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_VERBOSE, "%s: attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return write_block(RIGPORT(rig), ft747_ncmd[ci].nseq, YAESU_CMD_LENGTH); } hamlib-4.6.5/rigs/yaesu/ft3000.c0000664000175000017500000003552615056640443011641 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft3000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-DX3000 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "misc.h" #include "newcat.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft5000.h" #include "tones.h" const struct newcat_priv_caps ftdx3000_priv_caps = { .roofing_filter_count = 11, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, } }; const struct confparams ftdx3000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz", "300 Hz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz", "AUTO - 300 Hz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx3000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; int ft3000_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char *cmd; int err; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (ant) { case 1: cmd = "AN01;"; // R3/1 ANT1/ANT3 break; case 2: cmd = "AN02;"; // RE/2 ANT2/ANT3 break; case 3: cmd = "AN03;"; // TRX ANT3 break; default: rig_debug(RIG_DEBUG_ERR, "%s: expected 1,2,3 got %u\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", cmd); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int ft3000_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; ENTERFUNC; option->i = 0; // default to no options // find out what ANT3 setting SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", "AN0;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (strlen(priv->ret_data) >= 7) { char c = priv->ret_data[3]; switch (c) { case '1': *ant_rx = RIG_ANT_3; *ant_tx = RIG_ANT_1; break; case '2': *ant_rx = RIG_ANT_3; *ant_tx = RIG_ANT_2; break; case '3': *ant_rx = *ant_tx = RIG_ANT_3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna=%c\n", __func__, c); RETURNFUNC(-RIG_EPROTO); } } *ant_curr = *ant_tx; // current points to tx antenna RETURNFUNC(RIG_OK); } /* * FTDX 3000 rig capabilities * Seems to be largely compatible with the FTDX 5000, * so this is just a copy of the FTDX 5000 caps. * It really needs to be reviewed for accuracy, but it works for WSJT-X. */ struct rig_caps ftdx3000_caps = { RIG_MODEL(RIG_MODEL_FTDX3000), .model_name = "FTDX-3000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".12", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, // write_delay 5ms or less was causing VS1;VS; to answer with VS0 instead of VS1 even though change did occur // see https://github.com/Hamlib/Hamlib/issues/906 .write_delay = 0, // delay of 1 broke rigctl -- all ? responses .post_write_delay = FTDX5000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX5000_FUNCS, .has_set_func = FTDX5000_FUNCS, .has_get_level = FTDX5000_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_MICGAIN #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_MICGAIN #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX5000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, /* one of the few diffs from the 5000 */ .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FTDX5000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx3000_ext_tokens, .extlevels = ftdx3000_ext_levels, .priv = &ftdx3000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = ft3000_set_ant, .get_ant = ft3000_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/yaesu/ft1000mp.h0000664000175000017500000000774115056640443012177 /* * ft1000mp.h - (C) Stephane Fillod 2002 (fillods@users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-1000MP using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT1000MP_H #define _FT1000MP_H 1 #define FT1000MP_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ #define FT1000MP_STATUS_UPDATE_LENGTH 16 /* 0x10 U = 02 return size */ #define FT1000MP_PACING_INTERVAL 5 #define FT1000MP_PACING_DEFAULT_VALUE 0 #define FT1000MP_WRITE_DELAY 5 /* Delay sequential fast writes */ #define FT1000MP_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT1000MP_DEFAULT_READ_TIMEOUT 28 * ( 3 + (FT1000MP_PACING_INTERVAL * FT1000MP_PACING_DEFAULT_VALUE)) /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte in 2.2917 msec * => 28 bytes in 64 msec * * delay for 1 byte = 2.2917 + (pace_interval * 5) * * pace_interval time to read 345 bytes * ------------ ---------------------- * * 0 64 msec * 1 321 msec * 2 642 msec * 255 16.4 sec * */ /* * Internal MODES - when setting modes via cmd_mode_set() * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW 0x02 #define MODE_SET_CWR 0x03 #define MODE_SET_AM 0x04 #define MODE_SET_AMS 0x05 #define MODE_SET_FM 0x06 #define MODE_SET_FMW 0x07 /* what width is that? */ #define MODE_SET_RTTYL 0x08 #define MODE_SET_RTTYU 0x09 #define MODE_SET_PKTL 0x0a #define MODE_SET_PKTF 0x0b /* * Mode Bitmap. * When READING modes * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 #define MODE_RTTY 0x05 #define MODE_PKT 0x06 /* relevant bits: 5,6,7 */ #define MODE_MASK 0x07 /* * Status Flag Masks when reading * */ #define SF_DLOCK 0x01 #define SF_SPLITA 0x01 #define SF_SPLITB 0x02 #define SF_CLAR 0x04 #define SF_VFOAB 0x10 /* Status byte 0, bit 4, VFO A == 0, VFO B == 1 */ #define SF_VFOMR 0x10 #define SF_RXTX 0x20 #define SF_RESV 0x40 #define SF_PRI 0x80 /* * Local VFO CMD's, according to spec * */ #define FT1000MP_VFO_A 0x00 #define FT1000MP_VFO_B 0x01 /* * Some useful offsets in the status update map (offset) * */ #define FT1000MP_SUMO_DISPLAYED_STATUS 0x00 #define FT1000MP_SUMO_DISPLAYED_FREQ 0x01 #define FT1000MP_SUMO_VFO_A_FREQ 0x01 #define FT1000MP_SUMO_VFO_B_FREQ 0x11 #define FT1000MP_SUMO_VFO_A_CLAR 0x05 #define FT1000MP_SUMO_VFO_B_CLAR 0x15 #define FT1000MP_SUMO_VFO_A_MODE 0x07 #define FT1000MP_SUMO_VFO_B_MODE 0x17 #define FT1000MP_SUMO_VFO_A_IF 0x08 #define FT1000MP_SUMO_VFO_B_IF 0x18 #define FT1000MP_SUMO_VFO_A_MEM 0x09 #define FT1000MP_SUMO_VFO_B_MEM 0x19 /* mask extra mode bit from IF Filter status byte in VFO status block */ #define IF_MODE_MASK 0x80 #endif /* _FT1000MP_H */ hamlib-4.6.5/rigs/yaesu/ft1200.h0000664000175000017500000001214615056640443011637 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft1200.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * ft1200.h - (C) David Fannin 2015 (kk6df at arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-1200 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX1200_H #define _FTDX1200_H 1 #define FTDX1200_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FTDX1200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN) #define FTDX1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX1200_AM_RX_MODES (RIG_MODE_AM) #define FTDX1200_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FTDX1200_FM_RX_MODES (FTDX1200_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FTDX1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX1200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM) /* 100 W class */ #define FTDX1200_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ /* TBC */ #define FTDX1200_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FTDX1200_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_TUNER) /* TBC */ #define FTDX1200_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FTDX1200_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FTDX1200_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FTDX1200_TX_ANTS (RIG_ANT_1|RIG_ANT_2) #define FTDX1200_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX1200_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX1200_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX1200_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX1200_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX1200_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT2000_PACING_INTERVAL 5 // #define FT2000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-2000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX1200_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX1200_POST_WRITE_DELAY 5 #endif /* _FTDX1200_H */ hamlib-4.6.5/rigs/yaesu/Makefile.am0000664000175000017500000000177115056640443012610 ## Process this file with automake to produce Makefile.in ## Yeasu radios that use the legacy CAT commands YAESUSRC = ft100.c ft100.h ft747.c ft747.h ft817.c ft817.h ft847.c ft847.h \ ft890.c ft890.h ft900.c ft900.h ft920.c ft920.h ft1000mp.c ft1000mp.h \ ft857.c ft857.h ft897.c ft897.h ft990.c ft990.h ft990v12.c ft990v12.h frg8800.c ft757gx.c \ ft757gx.h ft600.h ft600.c ft736.c frg100.c frg100.h frg9600.c ft1000d.c \ ft1000d.h vr5000.c ft767gx.c ft767gx.h ft840.c ft840.h ft980.c ft980.h \ vx1700.c vx1700.h ftdx10.h ft710.c pmr171.c ## Yaesu radios that use the new Kenwood style CAT commands NEWCATSRC = newcat.c newcat.h ft450.c ft450.h ft950.c ft950.h ft991.c ft991.h \ ft2000.c ft2000.h ft9000.c ft9000.h ft5000.c ft5000.h ft1200.c ft1200.h \ ft891.c ft891.h ftdx101.c ftdx101.h ftdx101mp.c ft3000.c ftdx10.c ft710.h noinst_LTLIBRARIES = libhamlib-yaesu.la libhamlib_yaesu_la_SOURCES = yaesu.c yaesu.h level_gran_yaesu.h $(YAESUSRC) $(NEWCATSRC) EXTRA_DIST = README.ft890 README.ft920 Android.mk hamlib-4.6.5/rigs/yaesu/ft991.c0000664000175000017500000010761715056640443011602 /* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft991.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * (C) Michael Black W9MDB 2015 -- taken from ft950.c * * The FT991 is very much like the FT950 except freq max increases for 440MHz * So most of this code is a duplicate of the FT950 * * This shared library provides an API for communicating * via serial interface to an FT-991 using the "CAT" interface * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "misc.h" #include "newcat.h" #include "yaesu.h" #include "ft991.h" /* Prototypes */ static int ft991_init(RIG *rig); static int ft991_set_vfo(RIG *rig, vfo_t vfo); static int ft991_get_vfo(RIG *rig, vfo_t *vfo); static int ft991_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft991_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft991_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft991_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static void debug_ft991info_data(const ft991info *rdata); static int ft991_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft991_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int ft991_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft991_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); static int ft991_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft991_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int ft991_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); static int ft991_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); const struct confparams ft991_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { TOK_MAXPOWER_HF, "MAXPOWER_HF", "Maxpower HF", "Maxpower HF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_6M, "MAXPOWER_6M", "Maxpower 6m", "Maxpower 6m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_VHF, "MAXPOWER_VHF", "Maxpower VHF", "Maxpower VHF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { TOK_MAXPOWER_UHF, "MAXPOWER_UHF", "Maxpower UHF", "Maxpower UHF", NULL, RIG_CONF_NUMERIC, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft991_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_UHF, TOK_MAXPOWER_VHF, TOK_BACKEND_NONE }; /* * FT-991 rig capabilities */ struct rig_caps ft991_caps = { RIG_MODEL(RIG_MODEL_FT991), .model_name = "FT-991", .mfg_name = "Yaesu", .version = NEWCAT_VER ".18", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT991_WRITE_DELAY, .post_write_delay = FT991_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT991_FUNCS, .has_set_func = FT991_FUNCS, .has_get_level = FT991_LEVELS, .has_set_level = RIG_LEVEL_SET(FT991_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDAIR,BAND70CM,BAND33CM"}} }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT991_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT991_RFPOWER_METER_CAL, .str_cal = FT991_STR_CAL, .id_meter_cal = FT991_ID_CAL, .vd_meter_cal = FT991_VD_CAL, .comp_meter_cal = FT991_COMP_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 118, 127, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_VOICE }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, // Rig only has 1 model .rx_range_list1 = { {kHz(30), MHz(56), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(118), MHz(164), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(420), MHz(470), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(54), FT991_OTHER_TX_MODES, W(5), W(100), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(1.8), MHz(54), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ {MHz(144), MHz(148), FT991_OTHER_TX_MODES, W(5), W(50), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(144), MHz(148), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ {MHz(430), MHz(450), FT991_OTHER_TX_MODES, W(5), W(50), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(430), MHz(450), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT991_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT991_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT991_AM_RX_MODES, Hz(100)}, /* Normal */ {FT991_AM_RX_MODES, kHz(1)}, /* Fast */ {FT991_FM_RX_MODES, Hz(100)}, /* Normal */ {FT991_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT991_RTTY_DATA_RX_MODES, Hz(500)}, /* Normal RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(300)}, /* Narrow RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(3000)}, /* Wide RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(2400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(2000)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1700)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1200)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(800)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(450)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(350)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(250)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(200)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(150)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(100)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(50)}, /* RTTY, DATA */ {FT991_CW_RX_MODES, Hz(2400)}, /* Normal CW */ {FT991_CW_RX_MODES, Hz(500)}, /* Narrow CW */ {FT991_CW_RX_MODES, Hz(3000)}, /* Wide CW */ {FT991_CW_RX_MODES, Hz(2000)}, /* CW */ {FT991_CW_RX_MODES, Hz(1700)}, /* CW */ {FT991_CW_RX_MODES, Hz(1400)}, /* CW */ {FT991_CW_RX_MODES, Hz(1200)}, /* CW */ {FT991_CW_RX_MODES, Hz(800)}, /* CW */ {FT991_CW_RX_MODES, Hz(450)}, /* CW */ {FT991_CW_RX_MODES, Hz(400)}, /* CW */ {FT991_CW_RX_MODES, Hz(350)}, /* CW */ {FT991_CW_RX_MODES, Hz(300)}, /* CW */ {FT991_CW_RX_MODES, Hz(250)}, /* CW */ {FT991_CW_RX_MODES, Hz(200)}, /* CW */ {FT991_CW_RX_MODES, Hz(150)}, /* CW */ {FT991_CW_RX_MODES, Hz(100)}, /* CW */ {FT991_CW_RX_MODES, Hz(50)}, /* CW */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1500)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3200)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(3000)}, /* SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2300)}, /* SSB */ {RIG_MODE_SSB, Hz(2200)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {FT991_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM, PKTFM, C4FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft991_ext_tokens, .extlevels = ft991_ext_levels, .priv = NULL, /* private data FIXME: */ .rig_init = ft991_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = ft991_set_vfo, .get_vfo = ft991_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_split_freq = ft991_set_split_freq, .get_split_freq = ft991_get_split_freq, .get_split_mode = ft991_get_split_mode, .set_split_mode = ft991_set_split_mode, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_parm = newcat_get_parm, .set_parm = newcat_set_parm, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = ft991_set_ctcss_tone, .get_ctcss_tone = ft991_get_ctcss_tone, .set_dcs_code = ft991_set_dcs_code, .get_dcs_code = ft991_get_dcs_code, .set_ctcss_sql = ft991_set_ctcss_sql, .get_ctcss_sql = ft991_get_ctcss_sql, .set_dcs_sql = ft991_set_dcs_sql, .get_dcs_sql = ft991_get_dcs_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .send_voice_mem = newcat_send_voice_mem, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int ft991_get_tx_split(RIG *rig, split_t *in_split) { vfo_t cur_tx_vfo; int rval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !in_split) { return (-RIG_EINVAL); } rval = newcat_get_tx_vfo(rig, &cur_tx_vfo); if (rval != RIG_OK) { return (rval); } if (cur_tx_vfo == RIG_VFO_B || cur_tx_vfo == RIG_VFO_MEM) { *in_split = RIG_SPLIT_ON; } else if (cur_tx_vfo == RIG_VFO_A) { *in_split = RIG_SPLIT_OFF; } else { return (-RIG_EINVAL); } return (rval); } int ft991_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int rval; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rval = ft991_get_tx_split(rig, &is_split); if (rval != RIG_OK) { return (rval); } if (CACHE(rig)->freqMainB == tx_freq) { rig_debug(RIG_DEBUG_TRACE, "%s: freq %.0f already set on VFOB\n", __func__, tx_freq); return RIG_OK; } if (is_split == RIG_SPLIT_OFF) { rval = newcat_set_tx_vfo(rig, RIG_VFO_B); if (rval != RIG_OK) { return (rval); } } rval = newcat_set_freq(rig, RIG_VFO_B, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s newcat_set_freq() rval = %d freq = %f\n", __func__, rval, tx_freq); return (rval); } int ft991_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int rval; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rval = ft991_get_tx_split(rig, &is_split); if (rval != RIG_OK) { return (rval); } if (is_split == RIG_SPLIT_OFF) { *tx_freq = 0.0; return (rval); } rval = newcat_get_freq(rig, RIG_VFO_B, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s newcat_get_freq() rval = %d freq = %f\n", __func__, rval, *tx_freq); return (rval); } /* * rig_get_split_mode* * * Get the '991 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 991 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft991_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct newcat_priv_data *priv; int err; ft991info *rdata; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !tx_mode || !tx_width) { return -RIG_EINVAL; } priv = (struct newcat_priv_data *)STATE(rig)->priv; rdata = (ft991info *)priv->ret_data; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "OI;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } debug_ft991info_data(rdata); *tx_mode = newcat_rmode(rdata->mode); rig_debug(RIG_DEBUG_VERBOSE, "%s opposite mode %s\n", __func__, rig_strrmode(*tx_mode)); *tx_width = RIG_PASSBAND_NORMAL; return RIG_OK; } static void debug_ft991info_data(const ft991info *rdata) { rig_debug(RIG_DEBUG_VERBOSE, "%s command %2.2s\n", __func__, rdata->command); rig_debug(RIG_DEBUG_VERBOSE, "%s memory_ch %3.3s\n", __func__, rdata->memory_ch); rig_debug(RIG_DEBUG_VERBOSE, "%s vfo_freq %9.9s\n", __func__, rdata->vfo_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s clarifier %5.5s\n", __func__, rdata->clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s rx_clarifier %c\n", __func__, rdata->rx_clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s tx_clarifier %c\n", __func__, rdata->tx_clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s mode %c\n", __func__, rdata->mode); rig_debug(RIG_DEBUG_VERBOSE, "%s vfo_memory %c\n", __func__, rdata->vfo_memory); rig_debug(RIG_DEBUG_VERBOSE, "%s tone_mode %c\n", __func__, rdata->tone_mode); rig_debug(RIG_DEBUG_VERBOSE, "%s fixed %2.2s\n", __func__, rdata->fixed); rig_debug(RIG_DEBUG_VERBOSE, "%s repeater_offset %c\n", __func__, rdata->repeater_offset); rig_debug(RIG_DEBUG_VERBOSE, "%s terminator %c\n", __func__, rdata->terminator); } /* * rig_set_split_mode * * Set the '991 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Pass band is not set here nor does it make sense as the * FT991 cannot receive on VFO B. The FT991 cannot set * VFO B mode directly so we'll just set A and swap A * into B but we must preserve the VFO A mode and VFO B * frequency. * */ static int ft991_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct newcat_priv_data *priv; struct rig_state *state; int err; char restore_commands[NEWCAT_DATA_LEN]; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (CACHE(rig)->modeMainB == tx_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: mode %s already set on VFOB\n", __func__, rig_strrmode(tx_mode)); return RIG_OK; } err = ft991_get_tx_split(rig, &is_split); if (err != RIG_OK) { return (err); } if (is_split == RIG_SPLIT_ON) { err = newcat_set_tx_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return (err); } } state = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct newcat_priv_data *)state->priv; /* append VFO A mode restore command first as we want to minimize any Rx glitches */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD0;"); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } SNPRINTF(restore_commands, sizeof(restore_commands), "AB;%.*s", (int)sizeof(restore_commands) - 4, priv->ret_data); /* append VFO B frequency restore command */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FB;"); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } size_t len = strlen(restore_commands); SNPRINTF(restore_commands + len, sizeof(restore_commands) - len, "%.*s", (int)(sizeof(restore_commands) - len - 1), priv->ret_data); /* Change mode on VFOA */ if (RIG_OK != (err = newcat_set_mode(rig, RIG_VFO_A, tx_mode, RIG_PASSBAND_NOCHANGE))) { return err; } /* Send the copy VFO A to VFO B and restore commands */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", restore_commands); return newcat_set_cmd(rig); } static int ft991_init(RIG *rig) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s\n", __func__, rig->caps->version); ret = newcat_init(rig); if (ret != RIG_OK) { return ret; } STATE(rig)->current_vfo = RIG_VFO_A; return RIG_OK; } static int ft991_find_current_vfo(RIG *rig, vfo_t *vfo, tone_t *enc_dec_mode, rmode_t *mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ft991info *info = (ft991info *)priv->ret_data; int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IF;"); /* Get info */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } debug_ft991info_data(info); if (enc_dec_mode != NULL) { *enc_dec_mode = info->tone_mode; } if (mode != NULL) { *mode = newcat_rmode(info->mode); } switch (info->vfo_memory) { case '1': // Memory case '2': // Memory Tune case '3': // Quick Memory case '4': // Quick Memory Tune *vfo = RIG_VFO_MEM; break; case '0': // VFO *vfo = RIG_VFO_A; break; default: rig_debug(RIG_DEBUG_BUG, "%s: unexpected vfo returned 0x%X\n", __func__, info->vfo_memory); return -RIG_EINTERNAL; } return RIG_OK; } static int ft991_get_enabled_ctcss_dcs_mode(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0;"); /* Get enabled mode */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } return priv->ret_data[3]; } static int ft991_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean tone_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) { if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: tone = %u, tone_match = %d, i = %d\n", __func__, tone, tone_match, i); if (tone_match == FALSE && tone != 0) { return -RIG_EINVAL; } if (tone == 0) /* turn off ctcss */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00%3.3d;CT02;", i); } return newcat_set_cmd(rig); } static int ft991_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int ret; int t; int ret_data_len; tone_t enc_dec_mode; rmode_t rmode; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called with vfo %s\n", __func__, rig_strvfo(vfo)); *tone = 0; ret = ft991_find_current_vfo(rig, &vfo, &enc_dec_mode, &rmode); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s current vfo is %s\n", __func__, rig_strvfo(vfo)); if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return RIG_OK; } if ((enc_dec_mode == '0') || // CTCSS and DCS Disabled (enc_dec_mode == '3') || // DCS Encode and Decode Enabled (enc_dec_mode == '4')) // DCS Encode only { return RIG_OK; // Any of the above not CTCSS return 0 } /* Get CTCSS TONE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ rig_debug(RIG_DEBUG_TRACE, "%s ctcss code %d\n", __func__, t); if (t < 0 || t > 49) { return -RIG_EINVAL; } *tone = rig->caps->ctcss_list[t]; return RIG_OK; } static int ft991_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; rmode_t rmode; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); err = ft991_find_current_vfo(rig, &vfo, NULL, &rmode); if (err != RIG_OK) { return err; } if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return -RIG_EINVAL; // Invalid mode for setting ctcss } if (tone == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { int i; ncboolean tone_match; for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) { if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } } if (tone_match == FALSE) { return -RIG_EINVAL; // Tone not on the list } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN0%3.3d;CT01;", i); } return newcat_set_cmd(rig); } static int ft991_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int ret; int t; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *tone = 0; ret = ft991_get_enabled_ctcss_dcs_mode(rig); if (ret < 0) { return ret; } if (ret != '1') // If not CTCSS Encode and Decode return tone of zero. { return RIG_OK; } /* Get CTCSS TONE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ rig_debug(RIG_DEBUG_TRACE, "%s ctcss code %d\n", __func__, t); if (t < 0 || t > 49) { return -RIG_EINVAL; } *tone = rig->caps->ctcss_list[t]; return RIG_OK; } static int ft991_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int t; tone_t enc_dec_mode; rmode_t rmode; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *code = 0; err = ft991_find_current_vfo(rig, &vfo, &enc_dec_mode, &rmode); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s current vfo is %s\n", __func__, rig_strvfo(vfo)); if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return RIG_OK; } if ((enc_dec_mode == '0') || // Encode off (enc_dec_mode == '1') || // CTCSS Encode and Decode (enc_dec_mode == '2')) // CTCSS Encode Only { return RIG_OK; // Any of the above not DCS return 0 } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01;"); /* Get DCS code */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* code index */ if (t < 0 || t > 103) { return -RIG_EINVAL; } *code = rig->caps->dcs_list[t]; rig_debug(RIG_DEBUG_TRACE, "%s dcs code %u\n", __func__, *code); return RIG_OK; } static int ft991_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean code_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, code_match = FALSE; rig->caps->dcs_list[i] != 0; i++) { if (code == rig->caps->dcs_list[i]) { code_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: code = %u, code_match = %d, i = %d\n", __func__, code, code_match, i); if (code_match == FALSE && code != 0) { return -RIG_EINVAL; } if (code == 0) /* turn off dcs */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01%3.3d;CT04;", i); } return newcat_set_cmd(rig); } static int ft991_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean code_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, code_match = FALSE; rig->caps->dcs_list[i] != 0; i++) { if (code == rig->caps->dcs_list[i]) { code_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: code = %u, code_match = %d, i = %d\n", __func__, code, code_match, i); if (code_match == FALSE && code != 0) { return -RIG_EINVAL; } if (code == 0) /* turn off dcs */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01%3.3d;CT03;", i); } return newcat_set_cmd(rig); } static int ft991_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int codeindex; int ret; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *code = 0; ret = ft991_get_enabled_ctcss_dcs_mode(rig); if (ret < 0) { return ret; } if (ret != '3') { return RIG_OK; // If not DCS Encode and Decode return zero. } /* Get DCS CODE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; codeindex = atoi(retlvl); /* code index */ rig_debug(RIG_DEBUG_TRACE, "%s dcs code %d\n", __func__, codeindex); if (codeindex < 0 || codeindex > 103) { return -RIG_EINVAL; } *code = rig->caps->dcs_list[codeindex]; return RIG_OK; } // VFO functions so rigctld can be used without --vfo argument static int ft991_set_vfo(RIG *rig, vfo_t vfo) { STATE(rig)->current_vfo = vfo; RETURNFUNC2(RIG_OK); } static int ft991_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = STATE(rig)->current_vfo; RETURNFUNC2(RIG_OK); } hamlib-4.6.5/rigs/wj/0000775000175000017500000000000015056640500010112 5hamlib-4.6.5/rigs/wj/wj8888.c0000664000175000017500000001021615056640443011164 /* * Hamlib Watkins-Johnson backend - WJ-8888 description * Copyright (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "wj.h" /* modes: what about ISB(Independent Sideband)? */ #define WJ8888_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_AMS) #define WJ8888_FUNC (RIG_FUNC_NONE) #define WJ8888_LEVEL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) #define WJ8888_VFO (RIG_VFO_A) /* FIXME: real measures */ #define WJ8888_STR_CAL { 2, \ { \ { 0x00, -60 }, /* -115.5dBm .. -99.5dBm */ \ { 0x7f, 60 } \ } } /* * WJ-8888 receiver capabilities. * * Needs async I/O board * * * TODO: BFO */ struct rig_caps wj8888_caps = { RIG_MODEL(RIG_MODEL_WJ8888), .model_name = "WJ-8888", .mfg_name = "Watkins-Johnson", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, /* jumper E26 */ .serial_rate_max = 9600, /* jumper E19 */ .serial_data_bits = 8, .serial_stop_bits = 1, /* jumper between E5 & E6 */ .serial_parity = RIG_PARITY_NONE, /* no jumper between E3 & E4 */ .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 5, /* typical 5ms, max 15ms */ .timeout = 2000, .retry = 3, .has_get_func = WJ8888_FUNC, .has_set_func = WJ8888_FUNC, .has_get_level = WJ8888_LEVEL, .has_set_level = RIG_LEVEL_SET(WJ8888_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 0x7f } }, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(8), /* IF at 455kHz */ .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = WJ8888_STR_CAL, .cfgparams = wj_cfg_params, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), WJ8888_MODES, -1, -1, WJ8888_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), WJ8888_MODES, -1, -1, WJ8888_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {WJ8888_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {WJ8888_MODES, kHz(2)}, {WJ8888_MODES, Hz(500)}, {WJ8888_MODES, kHz(4)}, {WJ8888_MODES, kHz(8)}, /* option (in spare, to be fixed) */ {WJ8888_MODES, Hz(200)}, {WJ8888_MODES, kHz(1)}, {WJ8888_MODES, kHz(3)}, {WJ8888_MODES, kHz(6)}, {WJ8888_MODES, kHz(12)}, {WJ8888_MODES, kHz(16)}, RIG_FLT_END, }, .rig_init = wj_init, .rig_cleanup = wj_cleanup, .set_conf = wj_set_conf, .get_conf = wj_get_conf, .set_freq = wj_set_freq, .get_freq = wj_get_freq, .set_mode = wj_set_mode, .get_mode = wj_get_mode, .set_level = wj_set_level, .get_level = wj_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/wj/wj.c0000664000175000017500000002250115056640443010624 /* * Hamlib Watkins-Johnson backend - main file * Copyright (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "wj.h" #define CMDSZ 10 const struct confparams wj_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 15, 1 } } }, { RIG_CONF_END, NULL, } }; /* * modes */ #define MD_AM 0 #define MD_FM 1 #define MD_CW 2 #define MD_VCW 3 /* BFO variable */ #define MD_ISB 4 #define MD_LSB 5 #define MD_USB 6 #define MD_AMNL 7 /* * wj_transaction * * I'm not sure how monitor protocol works, whether you have * to send the full frame, or just the modal byte. --SF * * TODO: decode the whole reply, and maybe do some caching */ static int wj_transaction(RIG *rig, int monitor) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf[CMDSZ] = { 0x8, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char rxbuf[CMDSZ]; unsigned char freqbuf[4]; unsigned wj_agc, wj_mode, wj_width, wj_bfo, wj_rfgain; int retval; if (monitor) { buf[1] |= 0x40; /* Monitor+AGC dump */ } else { buf[0] |= 0x40; /* Command */ } buf[0] |= priv->receiver_id & 0x0f; /* tuned frequency */ to_bcd_be(freqbuf, priv->freq / 10, 7); buf[1] |= freqbuf[0] & 0x3f; buf[2] |= freqbuf[1] >> 1; buf[3] |= ((freqbuf[1] & 0x1) << 6) | (freqbuf[2] >> 2); buf[4] |= ((freqbuf[2] & 0x2) << 5) | (freqbuf[3] >> 3); /* gain mode */ switch (priv->agc.i) { case RIG_AGC_SLOW: wj_agc = 0; break; /* slow, 2s */ case RIG_AGC_OFF: wj_agc = 1; break; /* "not used" */ case RIG_AGC_FAST: wj_agc = 2; break; /* normal, 0.1s */ case RIG_AGC_USER: wj_agc = 3; break; /* manual */ default: return -RIG_EINVAL; } buf[4] |= wj_agc & 0x1; buf[5] |= (wj_agc & 0x2) << 5; /* IF BW */ switch (priv->width) { case 200: case 1000: wj_width = 0; break; /* spare */ case 500: wj_width = 1; break; case 2000: wj_width = 2; break; case 4000: wj_width = 3; break; case 8000: wj_width = 4; break; case 3000: case 6000: case 12000: case 16000: wj_width = 5; break; /* spare */ default: return -RIG_EINVAL; } buf[5] |= (wj_width & 0x7) << 3; /* Detection mode */ switch (priv->mode) { case RIG_MODE_CW: wj_mode = (priv->ifshift.i != 0) ? MD_VCW : MD_CW; break; case RIG_MODE_USB: wj_mode = MD_USB; break; case RIG_MODE_LSB: wj_mode = MD_LSB; break; case RIG_MODE_FM: wj_mode = MD_FM; break; case RIG_MODE_AM: wj_mode = MD_AM; break; case RIG_MODE_AMS: wj_mode = MD_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(priv->mode)); return -RIG_EINVAL; } buf[5] |= wj_mode & 0x7; /* BFO frequency, not sure though */ wj_bfo = (priv->ifshift.i / 10) + 0x400; /* LSBit is 10Hz, +455kHz */ buf[6] |= (wj_bfo >> 5) & 0x3f; buf[7] |= (wj_bfo & 0x1f) << 2; /* RF gain */ wj_rfgain = (unsigned)(priv->rfgain.f * 0x7f); buf[7] |= (wj_rfgain >> 6) & 0x1; buf[8] |= (wj_rfgain & 0x3f) << 1; /* buf[9]: not used if command byte, but must be transmitted */ rig_flush(rp); retval = write_block(rp, buf, CMDSZ); if (retval != RIG_OK) { return retval; } if (monitor) { /* * Transceiver sends back ">" */ retval = read_block(rp, rxbuf, CMDSZ); if (retval < 0 || retval > CMDSZ) { return -RIG_ERJCTED; } /* * TODO: analyze back the reply, and fill in the priv struct */ priv->rawstr.i = rxbuf[9] & 0x7f; } return retval; } int wj_init(RIG *rig) { struct wj_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct wj_priv_data *)calloc(1, sizeof(struct wj_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = 0; priv->freq = kHz(500); priv->mode = RIG_MODE_AM; priv->width = kHz(8); priv->agc.i = RIG_AGC_SLOW; priv->rfgain.f = 1; priv->ifshift.i = 0; return RIG_OK; } /* */ int wj_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int wj_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int wj_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int wj_get_conf(RIG *rig, hamlib_token_t token, char *val) { return wj_get_conf2(rig, token, val, 128); } /* * wj_set_freq * Assumes rig!=NULL */ int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; priv->freq = freq; return wj_transaction(rig, 0); } /* * wj_get_freq * Assumes rig!=NULL */ int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } *freq = priv->freq; return RIG_OK; } /* * wj_set_mode * Assumes rig!=NULL */ int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; priv->mode = mode; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } priv->width = width; } return wj_transaction(rig, 0); } /* * wj_get_mode * Assumes rig!=NULL */ int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } *mode = priv->mode; *width = priv->width; return RIG_OK; } /* * wj_set_level * Assumes rig!=NULL */ int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_IF: priv->ifshift.i = val.i; break; case RIG_LEVEL_RF: priv->rfgain.f = val.f; break; case RIG_LEVEL_AGC: priv->agc.i = val.i; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return wj_transaction(rig, 0); } /* * wj_get_level * Assumes rig!=NULL */ int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval = RIG_OK; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = priv->rawstr.i; break; case RIG_LEVEL_IF: val->i = priv->ifshift.i; break; case RIG_LEVEL_RF: val->f = priv->rfgain.f; break; case RIG_LEVEL_AGC: val->i = priv->agc.i; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } /* * initrigs_wj is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(wj) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&wj8888_caps); return RIG_OK; } hamlib-4.6.5/rigs/wj/wj.h0000664000175000017500000000345715056640443010642 /* * Hamlib Watkins-Johnson backend - main header * Copyright (c) 2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _WJ_H #define _WJ_H 1 #include #include "token.h" #define BACKEND_VER "20040912" #define TOK_RIGID TOKEN_BACKEND(1) extern const struct confparams wj_cfg_params[]; struct wj_priv_data { unsigned receiver_id; freq_t freq; rmode_t mode; pbwidth_t width; value_t agc; value_t rfgain; value_t ifshift; value_t rawstr; }; int wj_set_conf(RIG *rig, hamlib_token_t token, const char *val); int wj_get_conf(RIG *rig, hamlib_token_t token, char *val); int wj_init(RIG *rig); int wj_cleanup(RIG *rig); int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern struct rig_caps wj8888_caps; #endif /* _WJ_H */ hamlib-4.6.5/rigs/wj/Android.mk0000664000175000017500000000037315056640443011754 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := wj8888.c wj.c LOCAL_MODULE := wj LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/wj/Makefile.in0000664000175000017500000005254515056640453012121 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/wj ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_wj_la_LIBADD = am__objects_1 = wj8888.lo wj.lo am_libhamlib_wj_la_OBJECTS = $(am__objects_1) libhamlib_wj_la_OBJECTS = $(am_libhamlib_wj_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/wj.Plo ./$(DEPDIR)/wj8888.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_wj_la_SOURCES) DIST_SOURCES = $(libhamlib_wj_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ WJSRC = wj8888.c wj.c wj.h noinst_LTLIBRARIES = libhamlib-wj.la libhamlib_wj_la_SOURCES = $(WJSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/wj/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/wj/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-wj.la: $(libhamlib_wj_la_OBJECTS) $(libhamlib_wj_la_DEPENDENCIES) $(EXTRA_libhamlib_wj_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_wj_la_OBJECTS) $(libhamlib_wj_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wj.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wj8888.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/wj.Plo -rm -f ./$(DEPDIR)/wj8888.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/wj.Plo -rm -f ./$(DEPDIR)/wj8888.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/wj/Makefile.am0000664000175000017500000000017515056640443012077 WJSRC = wj8888.c wj.c wj.h noinst_LTLIBRARIES = libhamlib-wj.la libhamlib_wj_la_SOURCES = $(WJSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/rft/0000775000175000017500000000000015056640477010302 5hamlib-4.6.5/rigs/rft/Android.mk0000664000175000017500000000037515056640443012131 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ekd500.c rft.c LOCAL_MODULE := rft LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/rft/Makefile.in0000664000175000017500000005257715056640453012301 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/rft ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_rft_la_LIBADD = am__objects_1 = ekd500.lo rft.lo am_libhamlib_rft_la_OBJECTS = $(am__objects_1) libhamlib_rft_la_OBJECTS = $(am_libhamlib_rft_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ekd500.Plo ./$(DEPDIR)/rft.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_rft_la_SOURCES) DIST_SOURCES = $(libhamlib_rft_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RFTSRC = ekd500.c rft.c rft.h noinst_LTLIBRARIES = libhamlib-rft.la libhamlib_rft_la_SOURCES = $(RFTSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/rft/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/rft/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-rft.la: $(libhamlib_rft_la_OBJECTS) $(libhamlib_rft_la_DEPENDENCIES) $(EXTRA_libhamlib_rft_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_rft_la_OBJECTS) $(libhamlib_rft_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ekd500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rft.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ekd500.Plo -rm -f ./$(DEPDIR)/rft.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ekd500.Plo -rm -f ./$(DEPDIR)/rft.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/rft/rft.h0000664000175000017500000000204315056640443011156 /* * Hamlib RFT backend - main header * Copyright (c) 2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RFT_H #define _RFT_H 1 #include #define BACKEND_VER "20031007" int rft_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern struct rig_caps ekd500_caps; #endif /* _RFT_H */ hamlib-4.6.5/rigs/rft/rft.c0000664000175000017500000000450215056640443011153 /* * Hamlib RFT backend - main file * Copyright (c) 2003 by Thomas B. Ruecker * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "rft.h" #define BUFSZ 64 #define CR "\x0d" #define EOM CR /* * rft_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL */ int rft_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * rft_set_freq * Assumes rig!=NULL */ int rft_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16], ackbuf[16]; int ack_len, retval; /* */ SNPRINTF(freqbuf, sizeof(freqbuf), "FRQ%f" EOM, (float)freq / 1000); retval = rft_transaction(rig, freqbuf, strlen(freqbuf), ackbuf, &ack_len); return retval; } /* * initrigs_rft is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(rft) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ekd500_caps); return RIG_OK; } hamlib-4.6.5/rigs/rft/ekd500.c0000664000175000017500000000650415056640443011354 /* * Hamlib RFT backend - EKD-500 description * Copyright (c) 2003-2009 by Thomas B. Ruecker * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rft.h" #define EKD500_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) #define EKD500_FUNC (RIG_FUNC_NONE) #define EKD500_LEVEL_ALL (RIG_LEVEL_NONE) #define EKD500_PARM_ALL (RIG_PARM_NONE) #define EKD500_VFO (RIG_VFO_A) #define EKD500_VFO_OPS (RIG_OP_NONE) /* * EKD-500 rig capabilities. * * Documentation: * http://www.premium-rx.org/ekd500.htm */ struct rig_caps ekd500_caps = { RIG_MODEL(RIG_MODEL_EKD500), .model_name = "EKD-500", .mfg_name = "RFT", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 2400, .serial_data_bits = 7, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = EKD500_FUNC, .has_set_func = EKD500_FUNC, .has_get_level = EKD500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EKD500_LEVEL_ALL), .has_get_parm = EKD500_PARM_ALL, .has_set_parm = RIG_PARM_SET(EKD500_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = EKD500_VFO_OPS, .chan_list = { RIG_CHAN_END, /* FIXME */ }, .rx_range_list1 = { {kHz(10), MHz(30), EKD500_MODES, -1, -1, EKD500_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), EKD500_MODES, -1, -1, EKD500_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {EKD500_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rft_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/rft/Makefile.am0000664000175000017500000000020315056640443012242 RFTSRC = ekd500.c rft.c rft.h noinst_LTLIBRARIES = libhamlib-rft.la libhamlib_rft_la_SOURCES = $(RFTSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/drake/0000775000175000017500000000000015056640476010574 5hamlib-4.6.5/rigs/drake/r8a.c0000664000175000017500000001243115056640443011345 /* * Hamlib Drake backend - R-8A description * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "drake.h" #define R8A_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_FM) #define R8A_FUNC (RIG_FUNC_MN|RIG_FUNC_LOCK|RIG_FUNC_NB) #define R8A_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define R8A_PARM_ALL (RIG_PARM_TIME) #define R8A_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_VFO|RIG_VFO_MEM) #define R8A_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL|RIG_OP_CPY) #define R8A_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define R8A_STR_CAL { 16, { \ { 0, -60 }, \ { 1, -48 }, \ { 11, -42 }, \ { 27, -36 }, \ { 39, -30 }, \ { 51, -24 }, \ { 64, -18 }, \ { 80, -12 }, \ { 97, -6 }, \ { 116, 0 }, \ { 138, 10 }, \ { 163, 20 }, \ { 195, 30 }, \ { 217, 40 }, \ { 228, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define DRAKE_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = R8A_FUNC, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ } /* * R-8A rig capabilities. * * specs: http://www.dxing.com/rx/r8.htm * */ struct rig_caps r8a_caps = { RIG_MODEL(RIG_MODEL_DKR8A), .model_name = "R-8A", .mfg_name = "Drake", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .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_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = R8A_FUNC, .has_set_func = R8A_FUNC, .has_get_level = R8A_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R8A_LEVEL_ALL), .has_get_parm = R8A_PARM_ALL, .has_set_parm = RIG_PARM_SET(R8A_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, /* TODO: actually has RIG_TRN_RIG */ .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = R8A_VFO_OPS, .chan_list = { { 0, 439, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(30), R8A_MODES, -1, -1, R8A_VFO, R8A_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), R8A_MODES, -1, -1, R8A_VFO, R8A_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {R8A_MODES, 10}, {R8A_MODES, 100}, {R8A_MODES, kHz(1)}, {R8A_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(1.8)}, RIG_FLT_END, }, .str_cal = R8A_STR_CAL, .priv = NULL, .rig_init = drake_init, .rig_cleanup = drake_cleanup, .set_freq = drake_set_freq, .get_freq = drake_get_freq, .set_vfo = drake_set_vfo, .get_vfo = drake_get_vfo, .set_mode = drake_set_mode, .get_mode = drake_get_mode, .set_func = drake_set_func, .get_func = drake_get_func, .set_level = drake_set_level, .get_level = drake_get_level, .set_ant = drake_set_ant, .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, .set_channel = drake_set_chan, .get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, .get_info = drake_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/drake/Android.mk0000664000175000017500000000040415056640443012415 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := r8a.c r8b.c drake.c LOCAL_MODULE := drake LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/drake/Makefile.in0000664000175000017500000005312615056640452012562 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/drake ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_drake_la_LIBADD = am__objects_1 = r8a.lo r8b.lo drake.lo am_libhamlib_drake_la_OBJECTS = $(am__objects_1) libhamlib_drake_la_OBJECTS = $(am_libhamlib_drake_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/drake.Plo ./$(DEPDIR)/r8a.Plo \ ./$(DEPDIR)/r8b.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_drake_la_SOURCES) DIST_SOURCES = $(libhamlib_drake_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DRAKESRC = r8a.c r8b.c drake.c drake.h noinst_LTLIBRARIES = libhamlib-drake.la libhamlib_drake_la_SOURCES = $(DRAKESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/drake/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/drake/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-drake.la: $(libhamlib_drake_la_OBJECTS) $(libhamlib_drake_la_DEPENDENCIES) $(EXTRA_libhamlib_drake_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_drake_la_OBJECTS) $(libhamlib_drake_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drake.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r8a.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r8b.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/drake.Plo -rm -f ./$(DEPDIR)/r8a.Plo -rm -f ./$(DEPDIR)/r8b.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/drake.Plo -rm -f ./$(DEPDIR)/r8a.Plo -rm -f ./$(DEPDIR)/r8b.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/drake/drake.h0000664000175000017500000000453015056640443011747 /* * Hamlib Drake backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DRAKE_H #define _DRAKE_H 1 #include #define BACKEND_VER "20200319" struct drake_priv_data { int curr_ch; }; int drake_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int drake_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int drake_set_vfo(RIG *rig, vfo_t vfo); int drake_get_vfo(RIG *rig, vfo_t *vfo); int drake_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int drake_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int drake_init(RIG *rig); int drake_cleanup(RIG *rig); int drake_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int drake_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int drake_set_mem(RIG *rig, vfo_t vfo, int ch); int drake_get_mem(RIG *rig, vfo_t vfo, int *ch); int drake_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan); int drake_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int drake_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int drake_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int drake_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int drake_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int drake_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int drake_set_powerstat (RIG * rig, powerstat_t status); int drake_get_powerstat (RIG * rig, powerstat_t *status); const char *drake_get_info(RIG *rig); extern struct rig_caps r8a_caps; extern struct rig_caps r8b_caps; #endif /* _DRAKE_H */ hamlib-4.6.5/rigs/drake/drake.c0000664000175000017500000007021115056640443011741 /* * Hamlib Drake backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "cal.h" #include "register.h" #include "drake.h" /* * Protocol information available at http://www.rldrake.com/swl/R8B.pdf */ #define BUFSZ 64 #define CR "\x0d" #define LF "\x0a" #define EOM CR #define MD_USB '1' #define MD_LSB '2' #define MD_RTTY '3' #define MD_CW '4' #define MD_FM '5' #define MD_AM '6' /* * drake_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int drake_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } int drake_init(RIG *rig) { struct drake_priv_data *priv; STATE(rig)->priv = calloc(1, sizeof(struct drake_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->curr_ch = 0; return RIG_OK; } int drake_cleanup(RIG *rig) { struct drake_priv_data *priv = STATE(rig)->priv; free(priv); return RIG_OK; } /* * drake_set_freq * Assumes rig!=NULL */ int drake_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char freqbuf[16], ackbuf[16]; int ack_len, retval; /* * 10Hz resolution * TODO: round nearest? */ SNPRINTF((char *) freqbuf, sizeof(freqbuf), "F%07u" EOM, (unsigned int)freq / 10); retval = drake_transaction(rig, (char *) freqbuf, strlen((char *)freqbuf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_freq * Assumes rig!=NULL, freq!=NULL */ int drake_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int freq_len, retval; char freqbuf[BUFSZ]; double f; char fmult; retval = drake_transaction(rig, "RF" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } /* RA command returns *fffff.ff*mHz */ if (freq_len != 15) { rig_debug(RIG_DEBUG_ERR, "drake_get_freq: wrong answer %s, " "len=%d\n", freqbuf, freq_len); return -RIG_ERJCTED; } fmult = freqbuf[10]; freqbuf[9] = '\0'; /* extract freq */ sscanf(freqbuf + 1, "%lf", &f); f *= 1000.0; if (fmult == 'M' || fmult == 'm') { f *= 1000.0; } *freq = (freq_t)f; return RIG_OK; } /* * drake_set_vfo * Assumes rig!=NULL */ int drake_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmdbuf[16], ackbuf[16]; int ack_len, retval; char vfo_function; switch (vfo) { case RIG_VFO_A : vfo_function = 'A'; break; case RIG_VFO_B : vfo_function = 'B'; break; case RIG_VFO_VFO: vfo_function = 'F'; break; case RIG_VFO_MEM: vfo_function = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "drake_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } if ((vfo_function == 'A') || (vfo_function == 'B')) { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "V%c" EOM, vfo_function); } if ((vfo_function == 'F') || (vfo_function == 'C')) { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "%c" EOM, vfo_function); } retval = drake_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_vfo * Assumes rig!=NULL */ int drake_get_vfo(RIG *rig, vfo_t *vfo) { int mdbuf_len, retval; char mdbuf[BUFSZ]; retval = drake_transaction(rig, "RA" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len < 35) { rig_debug(RIG_DEBUG_ERR, "drake_get_vfo: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } if (mdbuf[0] == '*') { *vfo = RIG_VFO_MEM; } else { char cvfo = (mdbuf[9] & 0x38); switch (cvfo) { case '0' : *vfo = RIG_VFO_B; break; case '8' : *vfo = RIG_VFO_A; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_vfo: unsupported vfo %c\n", cvfo); *vfo = RIG_VFO_VFO; return -RIG_EINVAL; } } return RIG_OK; } /* * drake_set_mode * Assumes rig!=NULL */ int drake_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char mdbuf[16], ackbuf[16]; unsigned char mode_sel; int ack_len, retval; switch (mode) { case RIG_MODE_CW: mode_sel = MD_CW; break; case RIG_MODE_ECSSUSB: case RIG_MODE_USB: mode_sel = MD_USB; break; case RIG_MODE_ECSSLSB: case RIG_MODE_LSB: mode_sel = MD_LSB; break; case RIG_MODE_FM: mode_sel = MD_FM; break; case RIG_MODE_AMS: case RIG_MODE_AM: mode_sel = MD_AM; break; case RIG_MODE_RTTY: mode_sel = MD_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "drake_set_mode: " "unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) mdbuf, sizeof(mdbuf), "M%c" EOM, mode_sel); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (width != RIG_PASSBAND_NOCHANGE) { if (mode != RIG_MODE_FM) { unsigned int width_sel; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= 500) { width_sel = '0'; } else if (width <= 1800) { width_sel = '1'; } else if (width <= 2300) { width_sel = '2'; } else if (width <= 4000) { width_sel = '4'; } else { width_sel = '6'; } SNPRINTF((char *) mdbuf, sizeof(mdbuf), "W%c" EOM, width_sel); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); } } if ((mode == RIG_MODE_AMS) || (mode == RIG_MODE_ECSSUSB) || (mode == RIG_MODE_ECSSLSB) || (mode == RIG_MODE_AM) || (mode == RIG_MODE_USB) || (mode == RIG_MODE_LSB)) { SNPRINTF((char *) mdbuf, sizeof(mdbuf), "S%c" EOM, ((mode == RIG_MODE_AMS) || (mode == RIG_MODE_ECSSUSB) || (mode == RIG_MODE_ECSSLSB)) ? 'O' : 'F'); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); } return retval; } /* * drake_get_mode * Assumes rig!=NULL */ int drake_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char cmode; char cwidth; char csynch; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_mode: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } cmode = mdbuf[3]; cwidth = mdbuf[4]; csynch = mdbuf[5]; switch (cwidth & 0x37) { case '0': *width = s_Hz(500); break; case '1': *width = s_Hz(1800); break; case '2': *width = s_Hz(2300); break; case '3': *width = s_Hz(4000); break; case '4': *width = s_Hz(6000); break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported width %c\n", cwidth); *width = RIG_PASSBAND_NORMAL; return -RIG_EINVAL; } if ((cwidth >= '0') && (cwidth <= '4')) { switch (cmode & 0x33) { case '0': *mode = RIG_MODE_LSB; break; case '1': *mode = RIG_MODE_RTTY; break; case '2': *mode = RIG_MODE_FM; *width = s_Hz(12000); break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported mode %c\n", cmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } } else { switch (cmode & 0x33) { case '0': *mode = RIG_MODE_USB; break; case '1': *mode = RIG_MODE_CW; break; case '2': *mode = RIG_MODE_AM; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported mode %c\n", cmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } } if ((csynch & 0x34) == '4') { if (*mode == RIG_MODE_AM) { *mode = RIG_MODE_AMS; } else if (*mode == RIG_MODE_USB) { *mode = RIG_MODE_ECSSUSB; } else if (*mode == RIG_MODE_LSB) { *mode = RIG_MODE_ECSSLSB; } } return RIG_OK; } /* * drake_set_ant * Assumes rig!=NULL */ int drake_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { unsigned char buf[16], ackbuf[16]; int ack_len, retval; SNPRINTF((char *) buf, sizeof(buf), "A%c" EOM, ant == RIG_ANT_1 ? '1' : (ant == RIG_ANT_2 ? '2' : 'C')); retval = drake_transaction(rig, (char *) buf, strlen((char *)buf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_ant * Assumes rig!=NULL */ int drake_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char cant; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_ant: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } cant = mdbuf[3]; switch (cant & 0x3c) { case '0': *ant_curr = RIG_ANT_1; break; case '4': *ant_curr = RIG_ANT_3; break; case '8': *ant_curr = RIG_ANT_2; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_ant: unsupported antenna %c\n", cant); return -RIG_EINVAL; } return RIG_OK; } /* * drake_set_mem * Assumes rig!=NULL */ int drake_set_mem(RIG *rig, vfo_t vfo, int ch) { int ack_len, retval; char buf[16], ackbuf[16]; struct drake_priv_data *priv = STATE(rig)->priv; priv->curr_ch = ch; SNPRINTF(buf, sizeof(buf), "C%03d" EOM, ch); ack_len = 0; // fix compile-time warning "possibly uninitialized" retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); if (ack_len != 2) { rig_debug(RIG_DEBUG_ERR, "drake_set_mem: could not set channel %03d.\n", ch); retval = -RIG_ERJCTED; } return retval; } /* * drake_get_mem * Assumes rig!=NULL */ int drake_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct drake_priv_data *priv = STATE(rig)->priv; int mdbuf_len, retval; char mdbuf[BUFSZ]; int chan; retval = drake_transaction(rig, "RC" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 6) { rig_debug(RIG_DEBUG_ERR, "drake_get_mem: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } mdbuf[4] = '\0'; /* extract channel no */ sscanf(mdbuf + 1, "%03d", &chan); *ch = chan; priv->curr_ch = chan; return RIG_OK; } /* * drake_set_chan * Assumes rig!=NULL */ int drake_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan) { const struct drake_priv_data *priv = STATE(rig)->priv; vfo_t old_vfo; int old_chan; char mdbuf[16], ackbuf[16]; int ack_len, retval; value_t dummy; dummy.i = 0; drake_get_vfo(rig, &old_vfo); old_chan = 0; /* set to vfo if needed */ if (old_vfo == RIG_VFO_MEM) { old_chan = priv->curr_ch; retval = drake_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { return retval; } } /* set all memory features */ drake_set_ant(rig, RIG_VFO_CURR, chan->ant, dummy); drake_set_freq(rig, RIG_VFO_CURR, chan->freq); drake_set_mode(rig, RIG_VFO_CURR, chan->mode, chan->width); drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_NB, (chan->funcs & RIG_FUNC_NB) == RIG_FUNC_NB); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_AGC, chan->levels[rig_setting2idx(RIG_LEVEL_AGC)]); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)]); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, chan->levels[rig_setting2idx(RIG_LEVEL_ATT)]); drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_MN, (chan->funcs & RIG_FUNC_MN) == RIG_FUNC_MN); SNPRINTF(mdbuf, sizeof(mdbuf), "PR" EOM "%03d" EOM, chan->channel_num); retval = drake_transaction(rig, mdbuf, strlen(mdbuf), ackbuf, &ack_len); if (old_vfo == RIG_VFO_MEM) { drake_set_mem(rig, RIG_VFO_CURR, old_chan); } return retval; } /* * drake_get_chan * Assumes rig!=NULL */ int drake_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct drake_priv_data *priv = STATE(rig)->priv; vfo_t old_vfo; int old_chan; char mdbuf[BUFSZ], freqstr[BUFSZ]; int mdbuf_len, retval; chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); drake_get_vfo(rig, &old_vfo); old_chan = 0; if (old_vfo == RIG_VFO_MEM) { old_chan = priv->curr_ch; } //go to new channel retval = drake_set_mem(rig, RIG_VFO_CURR, chan->channel_num); if (retval != RIG_OK) { return RIG_OK; } //now decipher it retval = drake_transaction(rig, "RA" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len < 35) { rig_debug(RIG_DEBUG_ERR, "drake_get_channel: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } if ((mdbuf[5] >= '4') && (mdbuf[5] <= '?')) { chan->funcs |= RIG_FUNC_NB; } switch (mdbuf[5] & 0x33) { case '0': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; case '2': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; case '3': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; } if ((mdbuf[6] & 0x3c) == '8') { chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 10; } if ((mdbuf[6] & 0x3c) == '4') { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 10; } if ((mdbuf[6] & 0x32) == '2') { chan->funcs |= RIG_FUNC_MN; } switch (mdbuf[7] & 0x3c) { case '0': chan->ant = RIG_ANT_1; break; case '4': chan->ant = RIG_ANT_3; break; case '8': chan->ant = RIG_ANT_2; break; default : chan->ant = RIG_ANT_NONE; } switch (mdbuf[8] & 0x37) { case '0': chan->width = s_Hz(500); break; case '1': chan->width = s_Hz(1800); break; case '2': chan->width = s_Hz(2300); break; case '3': chan->width = s_Hz(4000); break; case '4': chan->width = s_Hz(6000); break; default : chan->width = RIG_PASSBAND_NORMAL; } if ((mdbuf[8] >= '0') && (mdbuf[8] <= '4')) { switch (mdbuf[7] & 0x33) { case '0': chan->mode = RIG_MODE_LSB; break; case '1': chan->mode = RIG_MODE_RTTY; break; case '2': chan->mode = RIG_MODE_FM; chan->width = s_Hz(12000); break; default : chan->mode = RIG_MODE_NONE; } } else { switch (mdbuf[7] & 0x33) { case '0': chan->mode = RIG_MODE_USB; break; case '1': chan->mode = RIG_MODE_CW; break; case '2': chan->mode = RIG_MODE_AM; break; default : chan->mode = RIG_MODE_NONE; } } if ((mdbuf[9] & 0x34) == '4') { if (chan->mode == RIG_MODE_AM) { chan->mode = RIG_MODE_AMS; } else if (chan->mode == RIG_MODE_USB) { chan->mode = RIG_MODE_ECSSUSB; } else if (chan->mode == RIG_MODE_LSB) { chan->mode = RIG_MODE_ECSSLSB; } } strncpy(freqstr, mdbuf + 11, 9); freqstr[9] = 0x00; if ((mdbuf[21] == 'k') || (mdbuf[21] == 'K')) { chan->freq = strtod(freqstr, NULL) * 1000.0; } if ((mdbuf[21] == 'm') || (mdbuf[21] == 'M')) { chan->freq = strtod(freqstr, NULL) * 1000000.0; } strncpy(chan->channel_desc, mdbuf + 25, 7); chan->channel_desc[7] = '\0'; // in case strncpy did not terminate the string //now put the radio back the way it was //we apparently can't do a read-only channel read if (old_vfo != RIG_VFO_MEM) { retval = drake_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { return retval; } } else { retval = drake_set_mem(rig, RIG_VFO_CURR, old_chan); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * drake_vfo_op * Assumes rig!=NULL */ int drake_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct drake_priv_data *priv = STATE(rig)->priv; char buf[16], ackbuf[16]; int len, ack_len, retval; switch (op) { case RIG_OP_UP: SNPRINTF(buf, sizeof(buf), "U"); break; case RIG_OP_DOWN: SNPRINTF(buf, sizeof(buf), "D"); break; case RIG_OP_CPY: SNPRINTF(buf, sizeof(buf), "A E B" EOM); break; case RIG_OP_TO_VFO: /* len = SNPRINTF(buf,"C%03d" EOM, priv->curr_ch); */ SNPRINTF(buf, sizeof(buf), "F" EOM); break; case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), "EC%03d" EOM, priv->curr_ch); break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "PR" EOM "%03d" EOM, priv->curr_ch); break; default: return -RIG_EINVAL; } len = strlen(buf); retval = drake_transaction(rig, buf, len, buf[len - 1] == 0x0d ? ackbuf : NULL, &ack_len); return retval; } /* * drake_set_func * Assumes rig!=NULL */ int drake_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[16], ackbuf[16]; int ack_len, retval; switch (func) { case RIG_FUNC_MN: SNPRINTF(buf, sizeof(buf), "N%c" EOM, status ? 'O' : 'F'); break; case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "L%c" EOM, status ? 'O' : 'F'); break; case RIG_FUNC_NB: /* TODO: NB narrow */ SNPRINTF(buf, sizeof(buf), "B%c" EOM, status ? 'W' : 'F'); break; default: return -RIG_EINVAL; } retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * drake_get_func * Assumes rig!=NULL */ int drake_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char mc; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_func: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } switch (func) { case RIG_FUNC_MN: mc = mdbuf[2]; *status = ((mc & 0x32) == '2'); break; case RIG_FUNC_NB: /* TODO: NB narrow */ mc = mdbuf[1]; *status = ((mc >= '4') && (mc <= '?')); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get func %s\n", rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * drake_set_level * Assumes rig!=NULL */ int drake_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[16], ackbuf[16]; int ack_len, retval; switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(buf, sizeof(buf), "G%c" EOM, val.i ? '+' : '0'); break; case RIG_LEVEL_ATT: SNPRINTF(buf, sizeof(buf), "G%c" EOM, val.i ? '-' : '0'); break; case RIG_LEVEL_AGC: SNPRINTF(buf, sizeof(buf), "A%c" EOM, val.i == RIG_AGC_OFF ? 'O' : (val.i == RIG_AGC_FAST ? 'F' : 'S')); break; default: return -RIG_EINVAL; } retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * drake_get_level * Assumes rig!=NULL */ int drake_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int lvl_len, retval, ss; char lvlbuf[BUFSZ]; char mc; if ((level != RIG_LEVEL_RAWSTR) && (level != RIG_LEVEL_STRENGTH)) { retval = drake_transaction(rig, "RM" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer %s, " "len=%d\n", lvlbuf, lvl_len); return -RIG_ERJCTED; } } switch (level) { case RIG_LEVEL_RAWSTR: retval = drake_transaction(rig, "RSS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; val->i = strtol(lvlbuf + 1, (char **)NULL, 16); break; case RIG_LEVEL_STRENGTH: retval = drake_transaction(rig, "RSS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; ss = strtol(lvlbuf + 1, (char **)NULL, 16); val->i = (int)rig_raw2val(ss, &rig->caps->str_cal); break; case RIG_LEVEL_PREAMP: mc = lvlbuf[2]; if ((mc & 0x3c) == '8') { val->i = 10; } else { val->i = 0; } break; case RIG_LEVEL_ATT: mc = lvlbuf[2]; if ((mc & 0x3c) == '4') { val->i = 10; } else { val->i = 0; } break; case RIG_LEVEL_AGC: mc = lvlbuf[1]; switch (mc & 0x33) { case '0': val->i = RIG_AGC_OFF; break; case '2': val->i = RIG_AGC_FAST; break; case '3': val->i = RIG_AGC_SLOW; break; default : val->i = RIG_AGC_FAST; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int drake_set_powerstat(RIG *rig, powerstat_t status) { char buf[16], ackbuf[16]; int ack_len, retval; SNPRINTF(buf, sizeof(buf), "P%c" EOM, status == RIG_POWER_OFF ? 'F' : 'O'); retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } int drake_get_powerstat(RIG *rig, powerstat_t *status) { int mdlen, retval; char mdbuf[BUFSZ]; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdlen); if (retval != RIG_OK) { return retval; } *status = (mdlen == 8); return RIG_OK; } /* * drake_set_freq * Assumes rig!=NULL */ const char *drake_get_info(RIG *rig) { static char idbuf[BUFSZ]; int retval, id_len; retval = drake_transaction(rig, "ID" EOM, 3, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } idbuf[id_len] = '\0'; return idbuf; } /* * initrigs_drake is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(drake) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&r8a_caps); rig_register(&r8b_caps); return RIG_OK; } /* * probe_drake(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(drake) { static char idbuf[BUFSZ]; int retval, id_len; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->parm.serial.rate = r8b_caps.serial_rate_max; port->write_delay = port->post_write_delay = 0; port->timeout = 50; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "ID" EOM, 3); id_len = read_string(port, (unsigned char *) idbuf, BUFSZ, LF, 1, 0, 1); close(port->fd); if (retval != RIG_OK || id_len <= 0 || id_len >= BUFSZ) { return RIG_MODEL_NONE; } idbuf[id_len] = '\0'; if (!strcmp(idbuf, "R8B")) { if (cfunc) { (*cfunc)(port, RIG_MODEL_DKR8B, data); } return RIG_MODEL_DKR8B; } if (!strcmp(idbuf, "R8A")) /* TBC */ { if (cfunc) { (*cfunc)(port, RIG_MODEL_DKR8A, data); } return RIG_MODEL_DKR8A; } /* * not found... */ if (memcmp(idbuf, "ID" EOM, 3)) /* catch loopback serial */ rig_debug(RIG_DEBUG_VERBOSE, "probe_drake: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf); return RIG_MODEL_NONE; } hamlib-4.6.5/rigs/drake/r8b.c0000664000175000017500000001242315056640443011347 /* * Hamlib Drake backend - R-8B description * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "drake.h" #define R8B_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_ECSS|RIG_MODE_FM) #define R8B_FUNC (RIG_FUNC_MN|RIG_FUNC_LOCK|RIG_FUNC_NB) #define R8B_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define R8B_PARM_ALL (RIG_PARM_TIME) #define R8B_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_VFO|RIG_VFO_MEM) #define R8B_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL|RIG_OP_CPY) #define R8B_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define R8B_STR_CAL { 16, { \ { 0, -60 }, \ { 1, -48 }, \ { 11, -42 }, \ { 27, -36 }, \ { 39, -30 }, \ { 51, -24 }, \ { 64, -18 }, \ { 80, -12 }, \ { 97, -6 }, \ { 116, 0 }, \ { 138, 10 }, \ { 163, 20 }, \ { 195, 30 }, \ { 217, 40 }, \ { 228, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define DRAKE_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = 1, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ } /* * R-8B rig capabilities. * * manual: http://www.rldrake.com/swl/R8B.pdf * */ struct rig_caps r8b_caps = { RIG_MODEL(RIG_MODEL_DKR8B), .model_name = "R-8B", .mfg_name = "Drake", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .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_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = R8B_FUNC, .has_set_func = R8B_FUNC, .has_get_level = R8B_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R8B_LEVEL_ALL), .has_get_parm = R8B_PARM_ALL, .has_set_parm = RIG_PARM_SET(R8B_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, /* TODO: actually has RIG_TRN_RIG */ .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = R8B_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(10), MHz(30), R8B_MODES, -1, -1, R8B_VFO, R8B_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), R8B_MODES, -1, -1, R8B_VFO, R8B_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {R8B_MODES, 10}, {R8B_MODES, 100}, {R8B_MODES, kHz(1)}, {R8B_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(1.8)}, RIG_FLT_END, }, .str_cal = R8B_STR_CAL, .priv = NULL, .rig_init = drake_init, .rig_cleanup = drake_cleanup, .set_freq = drake_set_freq, .get_freq = drake_get_freq, .set_vfo = drake_set_vfo, .get_vfo = drake_get_vfo, .set_mode = drake_set_mode, .get_mode = drake_get_mode, .set_func = drake_set_func, .get_func = drake_get_func, .set_level = drake_set_level, .get_level = drake_get_level, .set_ant = drake_set_ant, .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, .set_channel = drake_set_chan, .get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, .get_info = drake_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/drake/Makefile.am0000664000175000017500000000022215056640443012536 DRAKESRC = r8a.c r8b.c drake.c drake.h noinst_LTLIBRARIES = libhamlib-drake.la libhamlib_drake_la_SOURCES = $(DRAKESRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/dummy/0000775000175000017500000000000015056640476010641 5hamlib-4.6.5/rigs/dummy/dummy_common.h0000664000175000017500000000211415056640443013425 /* * Hamlib Dummy backend - shared routines * Copyright (c) 2020 by Mikael Nousiainen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DUMMY_COMMON_H #define _DUMMY_COMMON_H 1 #include "hamlib/rig.h" struct ext_list *alloc_init_ext(const struct confparams *cfp); struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token); #endif /* _DUMMY_H */ hamlib-4.6.5/rigs/dummy/aclog.c0000664000175000017500000006256415056640443012021 /* * Hamlib ACLog backend - main file * Copyright (c) 2023 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define TRUE 1 #define FALSE 0 #define MAXCMDLEN 8192 #define MAXXMLLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:1100" #define ACLOG_VFOS (RIG_VFO_A) #define ACLOG_MODES (RIG_MODE_AM | RIG_MODE_PKTAM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_SSB | RIG_MODE_LSB | RIG_MODE_USB |\ RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_FMN | RIG_MODE_PKTFM |\ RIG_MODE_C4FM) #define streq(s1,s2) (strcmp(s1,s2)==0) struct aclog_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from aclog */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; //Structure for mapping aclog dynamic modes to hamlib modes //aclog displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_aclog; }; //ACLog will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, "|USB|"}, {RIG_MODE_USB, "|SSB|"}, {RIG_MODE_LSB, "|LSB|"}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, "|AM|"}, {RIG_MODE_FM, "|FM|"}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, "|CW|"}, {RIG_MODE_CWR, "|CWR|"}, {RIG_MODE_RTTY, "|RTTY|"}, {RIG_MODE_RTTYR, "|RTTYR|"}, {RIG_MODE_C4FM, "|C4FM|"}, {0, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * read_transaction * Assumes rig!=NULL, xml!=NULL, xml_len>=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = "\r\n"; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected aclog responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, tmp_buf); // if our first response we should see the HTTP header if (strlen(xml) == 0 && strstr(tmp_buf, "") == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Expected '', got '%s'\n", __func__, tmp_buf); continue; // we'll try again } if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int aclog_transaction(RIG *rig, char *cmd, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; strcpy(xml, "UNKNOWN"); set_transaction_active(rig); if (value) { value[0] = 0; } do { int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } if (value) { read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK } // we get an unknown response if function does not exist if (strstr(xml, "UNKNOWN")) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ENAVAIL); } if (value) { strncpy(value, xml, value_len); } } while (((value && strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * aclog_init * Assumes rig!=NULL */ static int aclog_init(RIG *rig) { struct aclog_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct aclog_priv_data *)calloc(1, sizeof( struct aclog_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct aclog_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); RETURNFUNC(RIG_OK); } /* * modeMapGet * Assumes mode!=NULL * Return the string for ACLog for the given hamlib mode */ static const char *modeMapGet(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_aclog == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_aclog='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_aclog); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_aclog) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_aclog); return (modeMap[i].mode_aclog); } } rig_debug(RIG_DEBUG_ERR, "%s: ACLog does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given ACLog string */ static rmode_t modeMapGetHamlib(const char *modeACLog) { int i; char modeCheck[64]; SNPRINTF(modeCheck, sizeof(modeCheck), "|%s|", modeACLog); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeCheck, modeMap[i].mode_aclog); if (modeMap[i].mode_aclog && strcmp(modeMap[i].mode_aclog, modeCheck) == 0) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeACLog); return (RIG_MODE_NONE); } /* * aclog_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL * * string='23SSBPH1,296.171100 ' */ static int aclog_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int i, j = 0; char f_string[32]; char value[MAXARGLEN]; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = "\r\n"; int retval; retval = aclog_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: READBMF failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } char *p = strstr(value, ""); *freq = 0; if (p) { // Move the pointer to the first digit. p += strlen(""); // Parse "1,296.171100" ignoring the comma. for (i = 0; p[i] != '<'; i++) { if (isdigit(p[i])) { f_string[j++] = p[i]; } else if (ispunct(p[i]) && p[i] == '.') { f_string[j++] = p[i]; } } f_string[j] = '\0'; rig_debug(RIG_DEBUG_TRACE, "%s: f_string=%s\n", __func__, f_string); *freq = strtold(f_string, NULL); rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } *freq *= 1e6; // convert from MHz to Hz if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else // future support in ACLOG maybe? { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * aclog_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int aclog_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char value[MAXCMDLEN]; char *cmdp; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } cmdp = "\r\n"; /* default to old way */ retval = aclog_transaction(rig, cmdp, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } char *p = strstr(value, ""); char modetmp[32]; modetmp[0] = 0; if (p) { *mode = RIG_MODE_NONE; int n = sscanf(p, "%31[^<]", modetmp); if (n == 1) { *mode = modeMapGetHamlib(modetmp); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse from '%s'\n", __func__, value); *mode = RIG_MODE_USB; // just default to USB if we fail parsing } } rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } *width = 2400; // just default to 2400 for now RETURNFUNC(RIG_OK); } /* * aclog_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_open(RIG *rig) { int retval; char value[MAXARGLEN]; char *p; //;struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); retval = aclog_transaction(rig, "\r\n", value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: PROGRAM failed: %s", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_TRACE, "%s: returned value=%s\n", __func__, value); char version_pgm[64]; sscanf(value, "N3FJP's Amateur Contact Log%63[^<]", version_pgm); rig_debug(RIG_DEBUG_VERBOSE, "%s: ACLog version=%s\n", __func__, version_pgm); double version_api = 0; p = strstr(value, ""); if (p) { sscanf(strstr(value, ""), "%lf", &version_api); } rig_debug(RIG_DEBUG_VERBOSE, "%s ACLog API version %.1lf\n", __func__, version_api); retval = aclog_transaction(rig, "\r\n", value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: RIGENABLED failed,,,not fatal: %s\n", __func__, rigerror(retval)); } p = strstr(value, ""); char transceiver[64]; strcpy(transceiver, "Unknown"); if (p) { sscanf(p, "%63[^<]", transceiver); } rig_debug(RIG_DEBUG_VERBOSE, "Transceiver=%s\n", transceiver); freq_t freq; retval = aclog_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: aclog_get_freq not working!!\n", __func__); RETURNFUNC(-RIG_EPROTO); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); RETURNFUNC(retval); } /* * aclog_close * Assumes rig!=NULL */ static int aclog_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * aclog_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_cleanup(RIG *rig) { struct aclog_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct aclog_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_aclog was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_aclog) { free(modeMap[i].mode_aclog); modeMap[i].mode_aclog = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * aclog_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd[MAXARGLEN]; char value[1024]; //struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } #if 0 if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } #endif SNPRINTF(cmd, sizeof(cmd), "%lfTRUE\r\n", freq / 1e6); retval = aclog_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * aclog_set_mode * Assumes rig!=NULL */ static int aclog_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char cmd[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); // Set the mode if (strstr(modeMapGet(mode), "ERROR") == NULL) { ttmode = strdup(modeMapGet(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGet failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd, sizeof(cmd), "%s\r\n", pttmode); free(ttmode); retval = aclog_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * aclog_get_vfo * assumes rig!=NULL, vfo != NULL */ static int aclog_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = RIG_VFO_A; RETURNFUNC(RIG_OK); } /* * aclog_get_info * assumes rig!=NULL */ static const char *aclog_get_info(RIG *rig) { const struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE( rig)->priv; return (priv->info); } static int aclog_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int aclog_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } /* * aclog_set_ptt * Assumes rig!=NULL */ static int aclog_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd[MAXCMDLEN]; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } snprintf(cmd, sizeof(cmd), ptt == RIG_PTT_ON ? "\r\n" : "\r\n"); retval = aclog_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } struct rig_caps aclog_caps = { RIG_MODEL(RIG_MODEL_ACLOG), .model_name = "ACLog", .mfg_name = "N3FJP", .version = "20230120.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 2, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = ACLOG_MODES, .low_power = -1, .high_power = -1, ACLOG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = ACLOG_MODES, .low_power = -1, .high_power = -1, ACLOG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {ACLOG_MODES, 1}, {ACLOG_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = aclog_init, .rig_open = aclog_open, .rig_close = aclog_close, .rig_cleanup = aclog_cleanup, .set_freq = aclog_set_freq, .get_freq = aclog_get_freq, .get_vfo = aclog_get_vfo, .set_mode = aclog_set_mode, .get_mode = aclog_get_mode, .get_info = aclog_get_info, .set_ptt = aclog_set_ptt, //.get_ptt = aclog_get_ptt, .power2mW = aclog_power2mW, .mW2power = aclog_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/dummy/tci1x.c0000664000175000017500000016404515056640443011761 /* * Hamlib TCI 1.X backend - main file * Copyright (c) 2021 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include "dummy_common.h" #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 8192 #define MAXBUFLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:50001" #define FALSE 0 #ifdef TRUE #undef TRUE #endif #define TRUE (!FALSE) #define TCI_VFOS (RIG_VFO_A|RIG_VFO_B) #define TCI1X_MODES (RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM | RIG_MODE_AM) #define TCI1X_LEVELS (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_MICGAIN | RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER_METER | RIG_LEVEL_RFPOWER_METER_WATTS | RIG_LEVEL_RFPOWER) #define TCI1X_PARM (TOK_TCI1X_VERIFY_FREQ|TOK_TCI1X_VERIFY_PTT) #define streq(s1,s2) (strcmp(s1,s2)==0) static int tci1x_init(RIG *rig); static int tci1x_open(RIG *rig); static int tci1x_close(RIG *rig); static int tci1x_cleanup(RIG *rig); static int tci1x_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tci1x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tci1x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tci1x_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tci1x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tci1x_get_vfo(RIG *rig, vfo_t *vfo); static int tci1x_set_vfo(RIG *rig, vfo_t vfo); static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tci1x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int tci1x_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int tci1x_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int tci1x_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tci1x_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tci1x_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int tci1x_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); #ifdef XXNOTIMPLEMENTED static int tci1x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tci1x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tci1x_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int tci1x_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); #endif static const char *tci1x_get_info(RIG *rig); static int tci1x_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int tci1x_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); struct tci1x_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from tci1x */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_verify_cmds; // has the verify cmd in FLRig 1.3.54.1 or higher float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; /* level's and parm's tokens */ #define TOK_TCI1X_VERIFY_FREQ TOKEN_BACKEND(1) #define TOK_TCI1X_VERIFY_PTT TOKEN_BACKEND(2) static const struct confparams tci1x_ext_parms[] = { { TOK_TCI1X_VERIFY_FREQ, "VERIFY_FREQ", "Verify set_freq", "If true will verify set_freq otherwise is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { TOK_TCI1X_VERIFY_PTT, "VERIFY_PTT", "Verify set_ptt", "If true will verify set_ptt otherwise set_ptt is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; struct rig_caps tci1x_caps = { RIG_MODEL(RIG_MODEL_TCI1X), .model_name = "TCI1.X", .mfg_name = "Expert Elec", .version = "20211125.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 1, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TCI1X_LEVELS, .has_set_level = RIG_LEVEL_SET(TCI1X_LEVELS), .has_get_parm = TCI1X_PARM, .has_set_parm = RIG_PARM_SET(TCI1X_PARM), .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TCI1X_MODES, .low_power = -1, .high_power = -1, TCI_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TCI1X_MODES, .low_power = -1, .high_power = -1, TCI_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {TCI1X_MODES, 1}, {TCI1X_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .extparms = tci1x_ext_parms, .rig_init = tci1x_init, .rig_open = tci1x_open, .rig_close = tci1x_close, .rig_cleanup = tci1x_cleanup, .set_freq = tci1x_set_freq, .get_freq = tci1x_get_freq, .set_mode = tci1x_set_mode, .get_mode = tci1x_get_mode, .set_vfo = tci1x_set_vfo, .get_vfo = tci1x_get_vfo, .get_info = tci1x_get_info, .set_ptt = tci1x_set_ptt, .get_ptt = tci1x_get_ptt, .set_split_mode = tci1x_set_split_mode, .set_split_freq = tci1x_set_split_freq, .get_split_freq = tci1x_get_split_freq, .set_split_vfo = tci1x_set_split_vfo, .get_split_vfo = tci1x_get_split_vfo, .set_split_freq_mode = tci1x_set_split_freq_mode, .get_split_freq_mode = tci1x_get_split_freq_mode, #ifdef XXNOTIMPLEMENTED .set_level = tci1x_set_level, .get_level = tci1x_get_level, .set_ext_parm = tci1x_set_ext_parm, .get_ext_parm = tci1x_get_ext_parm, #endif .power2mW = tci1x_power2mW, .mW2power = tci1x_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //Structure for mapping tci1x dynamic modes to hamlib modes //tci1x displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_tci1x; }; //FLRig will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, NULL}, {RIG_MODE_LSB, NULL}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, NULL}, {RIG_MODE_FM, NULL}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, NULL}, {RIG_MODE_CWR, NULL}, {RIG_MODE_RTTY, NULL}, {RIG_MODE_RTTYR, NULL}, {RIG_MODE_C4FM, NULL}, {0, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * * read_transaction * Assumes rig!=NULL, buf!=NULL, buf_len big enough to hold response */ static int read_transaction(RIG *rig, unsigned char *buf, int buf_len) { int retry; char *delims = ";"; ENTERFUNC; retry = 0; do { if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), buf, buf_len, delims, strlen(delims), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, buf); if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } } while (retry-- > 0 && strlen((char *) buf) == 0); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } RETURNFUNC(RIG_OK); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, const unsigned char *buf, int buf_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (buf_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, buf, buf_len); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int tci1x_transaction(RIG *rig, char *cmd, char *cmd_arg, char *value, int value_len) { int retry = 0; unsigned char frame[1024]; ENTERFUNC; memset(frame, 0, sizeof(frame)); if (value) { value[0] = 0; } frame[0] = 0x81; frame[1] = strlen(cmd); frame[2] = 0x00; frame[3] = 0x00; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x00; frame[7] = 0x00; frame[8] = 0x00; frame[9] = 0x00; frame[10] = 0x00; frame[11] = 0x00; strcat((char *) &frame[12], cmd); do { int retval; if (retry < 2) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, frame, strlen(cmd) + 12); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } read_transaction(rig, (unsigned char *) value, value_len); rig_debug(RIG_DEBUG_VERBOSE, "%s: value=%s\n", __func__, value); } while ((value && (strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * tci1x_init * Assumes rig!=NULL */ static int tci1x_init(RIG *rig) { struct tci1x_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct tci1x_priv_data *)calloc(1, sizeof( struct tci1x_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tci1x_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); priv->ext_parms = alloc_init_ext(tci1x_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } RETURNFUNC(RIG_OK); } /* * modeMapGetTCI * Assumes mode!=NULL * Return the string for TCI for the given hamlib mode */ static const char *modeMapGetTCI(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_tci1x == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_tci1x='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_tci1x); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_tci1x) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_tci1x); return (modeMap[i].mode_tci1x); } } rig_debug(RIG_DEBUG_ERR, "%s: FlRig does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given TCI string */ static rmode_t modeMapGetHamlib(const char *modeTCI) { int i; char modeTCICheck[MAXBUFLEN + 2]; SNPRINTF(modeTCICheck, sizeof(modeTCICheck), "|%s|", modeTCI); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeTCICheck, modeMap[i].mode_tci1x); if (modeMap[i].mode_tci1x && strcmp(modeMap[i].mode_tci1x, modeTCICheck) == 0) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeTCI); return (RIG_MODE_NONE); } /* * modeMapAdd * Assumes modes!=NULL */ static void modeMapAdd(rmode_t *modes, rmode_t mode_hamlib, char *mode_tci1x) { int i; int len1; rig_debug(RIG_DEBUG_TRACE, "%s:mode_tci1x=%s\n", __func__, mode_tci1x); // if we already have it just return // We get ERROR if the mode is not known so non-ERROR is OK if (modeMapGetHamlib(mode_tci1x) != RIG_MODE_NONE) { return; } len1 = strlen(mode_tci1x) + 3; /* bytes needed for allocating */ for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_hamlib == mode_hamlib) { int len2; *modes |= modeMap[i].mode_hamlib; /* we will pipe delimit all the entries for easier matching */ /* all entries will have pipe symbol on both sides */ if (modeMap[i].mode_tci1x == NULL) { modeMap[i].mode_tci1x = calloc(1, len1); if (modeMap[i].mode_tci1x == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error allocating memory for modeMap\n", __func__); return; } } len2 = strlen(modeMap[i].mode_tci1x); /* current len w/o null */ modeMap[i].mode_tci1x = realloc(modeMap[i].mode_tci1x, strlen(modeMap[i].mode_tci1x) + len1); if (strlen(modeMap[i].mode_tci1x) == 0) { modeMap[i].mode_tci1x[0] = '|'; } strncat(modeMap[i].mode_tci1x, mode_tci1x, len1 + len2); strncat(modeMap[i].mode_tci1x, "|", len1 + len2); rig_debug(RIG_DEBUG_TRACE, "%s: Adding mode=%s, index=%d, result=%s\n", __func__, mode_tci1x, i, modeMap[i].mode_tci1x); return; } } } /* * tci1x_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_open(RIG *rig) { int retval; int trx_count = 0; char value[MAXBUFLEN]; char arg[MAXBUFLEN]; rmode_t modes; char *p; char *pr; //struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; arg[0] = '?'; arg[1] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: version %s\n", __func__, rig->caps->version); char *websocket = "GET / HTTP/1.1\r\nHost: localhost:50001\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: TnwnvtFT6akIBYQC7nh3vA==\r\nSec-WebSocket-Version: 13\r\n\r\n"; write_transaction(rig, (unsigned char *) websocket, strlen(websocket)); do { retval = read_transaction(rig, (unsigned char *) value, sizeof(value)); rig_debug(RIG_DEBUG_VERBOSE, "%s: value=%s\n", __func__, value); } while (retval == RIG_OK && strlen(value) > 0); retval = tci1x_transaction(rig, "device;", NULL, value, sizeof(value)); dump_hex((unsigned char *)value, strlen(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: DEVICE failed: %s\n", __func__, rigerror(retval)); // we fall through and assume old version } sscanf(&value[2], "device:%8191s", value); rig_debug(RIG_DEBUG_VERBOSE, "%s: TCI Device is %s\n", __func__, arg); // Receive only retval = tci1x_transaction(rig, "receive_only;", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: RECEIVE_ONLY failed: %s\n", __func__, rigerror(retval)); } sscanf(&value[2], "receive_only:%8191s", value); rig_debug(RIG_DEBUG_VERBOSE, "%s: readonly is %8191s\n", __func__, arg); // TRX count retval = tci1x_transaction(rig, "trx_count;", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: TRX_COUNT failed..not fatal: %s\n", __func__, rigerror(retval)); } sscanf(&value[2], "trx_count:%d", &trx_count); rig_debug(RIG_DEBUG_VERBOSE, "Trx count=%d\n", trx_count); freq_t freq; retval = tci1x_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_get_freq not working!!\n", __func__); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); //tci1x_get_split_vfo(rig, vfo, &priv->split, &vfo_tx); RETURNFUNC2(RIG_OK); /* find out available widths and modes */ retval = tci1x_transaction(rig, "modulations_list;", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(&value[2], "modulations_list:%8191s", arg); rig_debug(RIG_DEBUG_VERBOSE, "%s: modes=%s\n", __func__, arg); modes = 0; pr = value; /* The following modes in TCI are not implemented yet A1A AM-2 AM6.0 AM-D1 -- doesn't appear to be read/set AM-D2 -- doesn't appear to be read/set AM-D3 -- doesn't appear to be read/set AMW -- don't have mode in rig.h CW2.4 -- could be CW CW500 -- could be CWN but CWN not in rig.h CW-N -- could be CWN but CWN not in rig.h CWN -- dcould be CWN but CWN not in rig.h CW-NR -- don't have mode in rig.h DATA2-LSB DV DV-R F1B FM-D1 -- doesn't appear to be read/set FM-D2 -- doesn't appear to be read/set FM-D3 -- doesn't appear to be read/set H3E M11 USB-D -- doesn't appear to be read/set USB-D1 -- doesn't appear to be read/set USB-D2 -- doesn't appear to be read/set USB-D3 -- doesn't appear to be read/set USER-L -- doesn't appear to be read/set USER-U -- doesn't appear to be read/set */ for (p = strtok_r(value, ",", &pr); p != NULL; p = strtok_r(NULL, ",", &pr)) { if (streq(p, "AM-D")) { modeMapAdd(&modes, RIG_MODE_PKTAM, p); } else if (streq(p, "AM")) { modeMapAdd(&modes, RIG_MODE_AM, p); } else if (streq(p, "AM-N")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "AMN")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "CW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-L")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-LSB")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-R")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-U")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-USB")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CWL")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CWU")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "D-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "D-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "DATA-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-R")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIG")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGI")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGL")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DIGU")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DSB")) { modeMapAdd(&modes, RIG_MODE_DSB, p); } else if (streq(p, "FM")) { modeMapAdd(&modes, RIG_MODE_FM, p); } else if (streq(p, "FM-D")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "FMN")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FM-N")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FMW")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "FSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "FSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "LCW")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "LSB")) { modeMapAdd(&modes, RIG_MODE_LSB, p); } else if (streq(p, "LSB-D")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D1")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D2")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D3")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "NFM")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "PKT")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "PKT-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "PKT-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "PKT-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "PKT(L)")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "PKT(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "PSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "PSK-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "PSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "PSK-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "SAH")) { modeMapAdd(&modes, RIG_MODE_SAH, p); } else if (streq(p, "SAL")) { modeMapAdd(&modes, RIG_MODE_SAL, p); } else if (streq(p, "SAM")) { modeMapAdd(&modes, RIG_MODE_SAM, p); } else if (streq(p, "USB")) { modeMapAdd(&modes, RIG_MODE_USB, p); } else if (streq(p, "USB-D")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D1")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D2")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D3")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USER-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USER-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "W-FM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "WFM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "UCW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "C4FM")) { modeMapAdd(&modes, RIG_MODE_C4FM, p); } else if (streq(p, "SPEC")) { modeMapAdd(&modes, RIG_MODE_SPEC, p); } else if (streq(p, "DRM")) // we don't support DRM yet (or maybe ever) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no mapping for mode %s\n", __func__, p); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode (new?) for this rig='%s'\n", __func__, p); } } STATE(rig)->mode_list = modes; retval = rig_strrmodes(modes, value, sizeof(value)); if (retval != RIG_OK) // we might get TRUNC but we can still print the debug { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: hamlib modes=%s\n", __func__, value); RETURNFUNC2(retval); } /* * tci1x_close * Assumes rig!=NULL */ static int tci1x_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * tci1x_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_cleanup(RIG *rig) { struct tci1x_priv_data *priv; ENTERFUNC; priv = (struct tci1x_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * tci1x_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int tci1x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = vfo == RIG_VFO_A ? "vfo:0:0;" : "vfo:0:1:"; int retval; int n; retval = tci1x_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } n = sscanf(&value[2], "vfo:%*d,%*d,%lf", freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: got '%s', scanned %d items\n", __func__, value, n); if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * tci1x_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.0f", freq); value_t val; rig_get_ext_parm(rig, TOK_TCI1X_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_verify_vfoA/B=%d\n", __func__, val.i); if (vfo == RIG_VFO_A) { cmd = "rig.set_vfoA"; if (val.i) { cmd = "rig.set_verify_vfoA"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqA = freq; } else { cmd = "rig.set_vfoB"; if (val.i) { cmd = "rig.set_verify_vfoB"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqB = freq; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * tci1x_set_ptt * Assumes rig!=NULL */ static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_arg[MAXARGLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", ptt); value_t val; char *cmd = "rig.set_ptt"; rig_get_ext_parm(rig, TOK_TCI1X_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: fast_set_ptt=%d\n", __func__, val.i); if (val.i) { cmd = "rig.set_ptt_fast"; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } /* * tci1x_get_ptt * Assumes rig!=NUL, ptt!=NULL */ static int tci1x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char value[MAXCMDLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); int retval; retval = tci1x_transaction(rig, "rig.get_ptt", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } *ptt = atoi(value); rig_debug(RIG_DEBUG_TRACE, "%s: '%s'\n", __func__, value); priv->ptt = *ptt; RETURNFUNC(RIG_OK); } /* * tci1x_set_split_mode * Assumes rig!=NULL */ static int tci1x_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (vfo) { case RIG_VFO_CURR: vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: vfo = RIG_VFO_B; break; } // If no change don't do it...modes are kept up to date by client calls // to get_mode and set_mode so should be current here rig_debug(RIG_DEBUG_TRACE, "%s: vfoa privmode=%s\n", __func__, rig_strrmode(priv->curr_modeA)); rig_debug(RIG_DEBUG_TRACE, "%s: vfob privmode=%s\n", __func__, rig_strrmode(priv->curr_modeB)); // save some VFO swapping .. may replace with VFO specific calls that won't cause VFO change if (vfo == RIG_VFO_A && mode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_B && mode == priv->curr_modeB) { RETURNFUNC(RIG_OK); } retval = tci1x_set_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: set mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(retval); } /* * tci1x_set_mode * Assumes rig!=NULL */ static int tci1x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; int needBW; int vfoSwitched; char cmd_arg[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB vfoSwitched = 0; rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); // If we don't have the get_bwA call we have to switch VFOs ourself if (!priv->has_get_bwA && vfo == RIG_VFO_B && STATE(rig)->current_vfo != RIG_VFO_B) { vfoSwitched = 1; rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOB = %d\n", __func__, vfoSwitched); } if (vfoSwitched) // swap to B and we'll swap back later { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOB = %d\n", __func__, vfoSwitched); retval = tci1x_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } // Set the mode if (modeMapGetTCI(mode)) { ttmode = strdup(modeMapGetTCI(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGetFlRig failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } // if (strncmp(ttmode,"ERROR",5)==0) RETURNFUNC(-RIG_EINTERN); pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", pttmode); free(ttmode); if (!priv->has_get_modeA) { retval = tci1x_transaction(rig, "rig.set_mode", cmd_arg, NULL, 0); } else { char *cmd = "rig.set_modeA"; if (vfo == RIG_VFO_B) { cmd = "rig.set_modeB"; } else { // we make VFO_B mode unknown so it expires the cache priv->curr_modeB = RIG_MODE_NONE; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // Determine if we need to update the bandwidth needBW = 0; if (vfo == RIG_VFO_A) { needBW = priv->curr_widthA != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOA, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else if (vfo == RIG_VFO_B) { needBW = priv->curr_widthB != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOB, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else { rig_debug(RIG_DEBUG_TRACE, "%s: needBW unknown vfo=%s\n", __func__, rig_strvfo(vfo)); } // Need to update the bandwidth if (width > 0 && needBW) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%ld", width); retval = tci1x_transaction(rig, "rig.set_bandwidth", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } // Return to VFOA if needed rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOA? = %d\n", __func__, vfoSwitched); if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOA\n", __func__); retval = tci1x_set_vfo(rig, RIG_VFO_A); if (retval < 0) { RETURNFUNC(retval); } } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * tci1x_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int tci1x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int vfoSwitched; char value[MAXCMDLEN]; char *cmdp; vfo_t curr_vfo; rmode_t my_mode; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } curr_vfo = STATE(rig)->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->ptt) { if (vfo == RIG_VFO_A) { *mode = priv->curr_modeA; } else { *mode = priv->curr_modeB; } rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate vfoSwitched = 0; if (priv->has_get_modeA == 0 && vfo == RIG_VFO_B && curr_vfo != RIG_VFO_B) { vfoSwitched = 1; } if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s switch to VFOB=%d\n", __func__, priv->has_get_modeA); retval = tci1x_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } cmdp = "rig.get_mode"; /* default to old way */ if (priv->has_get_modeA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in tci1x */ /* vfo B may not be getting polled though in TCI */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_modeA"; if (vfo == RIG_VFO_B) { cmdp = "rig.get_modeB"; } } retval = tci1x_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } my_mode = modeMapGetHamlib(value); *mode = my_mode; rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } /* Get the bandwidth */ cmdp = "rig.get_bw"; /* default to old way */ if (priv->has_get_bwA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in tci1x */ /* vfo B may not be getting polled though in TCI */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_bwA"; if (vfo == RIG_VFO_B) { cmdp = "rig.get_bwB"; } } retval = tci1x_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s width='%s'\n", __func__, rig_strrmode(*mode), value); // we get 2 entries pipe separated for bandwidth, lower and upper if (strlen(value) > 0) { char *p = value; /* we might get two values and then we want the 2nd one */ if (strchr(value, '|') != NULL) { p = strchr(value, '|') + 1; } *width = atoi(p); } if (vfo == RIG_VFO_A) { priv->curr_widthA = *width; } else { priv->curr_widthB = *width; } // Return to VFOA if needed if (vfoSwitched) { retval = tci1x_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * tci1x_set_vfo * assumes rig!=NULL */ static int tci1x_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd_arg[MAXBUFLEN]; struct rig_state *rs = STATE(rig); const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", vfo == RIG_VFO_A ? "A" : "B"); retval = tci1x_transaction(rig, "rig.set_AB", cmd_arg, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig.set_AB failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } STATE(rig)->current_vfo = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB /* for some rigs TCI turns off split when VFOA is selected */ /* so if we are in split and asked for A we have to turn split back on */ if (priv->split && vfo == RIG_VFO_A) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", priv->split); retval = tci1x_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * tci1x_get_vfo * assumes rig!=NULL, vfo != NULL */ static int tci1x_get_vfo(RIG *rig, vfo_t *vfo) { char value[MAXCMDLEN]; ENTERFUNC; int retval; retval = tci1x_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo value=%s\n", __func__, value); switch (value[0]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; default: *vfo = RIG_VFO_CURR; RETURNFUNC(-RIG_EINVAL); } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } STATE(rig)->current_vfo = *vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(RIG_OK); } /* * tci1x_set_split_freq * assumes rig!=NULL */ static int tci1x_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd_arg[MAXBUFLEN]; freq_t qtx_freq; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } // we always split on VFOB so if no change just return retval = tci1x_get_freq(rig, RIG_VFO_B, &qtx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tx_freq == qtx_freq) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.6f", tx_freq); retval = tci1x_transaction(rig, "rig.set_vfoB", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->curr_freqB = tx_freq; RETURNFUNC(RIG_OK); } /* * tci1x_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = tci1x_get_freq(rig, RIG_VFO_B, tx_freq); priv->curr_freqB = *tx_freq; RETURNFUNC(retval); } /* * tci1x_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; vfo_t qtx_vfo; split_t qsplit; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; char cmd_arg[MAXBUFLEN]; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); retval = tci1x_get_split_vfo(rig, RIG_VFO_A, &qsplit, &qtx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } if (split == qsplit) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", split); retval = tci1x_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->split = split; RETURNFUNC(RIG_OK); } /* * tci1x_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char value[MAXCMDLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; int retval; retval = tci1x_transaction(rig, "rig.get_split", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } *tx_vfo = RIG_VFO_B; *split = atoi(value); priv->split = *split; rig_debug(RIG_DEBUG_TRACE, "%s tx_vfo=%s, split=%d\n", __func__, rig_strvfo(*tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * tci1x_set_split_freq_mode * assumes rig!=NULL */ static int tci1x_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; rmode_t qmode; pbwidth_t qwidth; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; // we always do split on VFOB retval = tci1x_set_freq(rig, RIG_VFO_B, freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s tci1x_set_freq failed\n", __func__); RETURNFUNC(retval); } // Make VFOB mode match VFOA mode, keep VFOB width retval = tci1x_get_mode(rig, RIG_VFO_B, &qmode, &qwidth); if (retval != RIG_OK) { RETURNFUNC(retval); } if (qmode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } retval = tci1x_set_mode(rig, RIG_VFO_B, priv->curr_modeA, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s tci1x_set_mode failed\n", __func__); RETURNFUNC(retval); } retval = tci1x_set_vfo(rig, RIG_VFO_A); RETURNFUNC(retval); } /* * tci1x_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int tci1x_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { RETURNFUNC(-RIG_ENTARGET); } retval = tci1x_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = tci1x_get_mode(rig, vfo, mode, width); } RETURNFUNC(retval); } #ifdef XXNOTIMPLEMENTED static int tci1x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; char *param_type = "i4"; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s level=%d, val=%f\n", __func__, rig_strvfo(vfo), (int)level, val.f); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_RF: cmd = "rig.set_rfgain"; val.f *= 100; break; case RIG_LEVEL_AF: cmd = "rig.set_volume"; val.f *= 100; break; case RIG_LEVEL_MICGAIN: cmd = "rig.set_micgain"; val.f *= 100; break; case RIG_LEVEL_RFPOWER: cmd = "rig.set_power"; val.f *= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: invalid level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "<%s>%d", param_type, (int)val.f, param_type); retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * tci1x_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ static int tci1x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char value[MAXARGLEN]; char *cmd; int retval; const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: cmd = "rig.get_volume"; break; case RIG_LEVEL_RF: cmd = "rig.get_rfgain"; break; case RIG_LEVEL_MICGAIN: cmd = "rig.get_micgain"; break; case RIG_LEVEL_STRENGTH: cmd = "rig.get_smeter"; break; case RIG_LEVEL_RFPOWER: cmd = "rig.get_power"; break; case RIG_LEVEL_RFPOWER_METER_WATTS: case RIG_LEVEL_RFPOWER_METER: cmd = "rig.get_pwrmeter"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } retval = tci1x_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // most levels are 0-100 -- may have to allow for different ranges switch (level) { case RIG_LEVEL_STRENGTH: val->i = atoi(value) - 54; //if (val->i > 0) val->i /= 10; rig_debug(RIG_DEBUG_TRACE, "%s: val.i='%s'(%d)\n", __func__, value, val->i); break; case RIG_LEVEL_RFPOWER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER_WATTS: val->f = atof(value) * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; default: val->f = atof(value) / 100; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%f)\n", __func__, value, val->f); } RETURNFUNC(RIG_OK); } #endif /* * tci1x_get_info * assumes rig!=NULL */ static const char *tci1x_get_info(RIG *rig) { const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; return (priv->info); } static int tci1x_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int tci1x_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } #ifdef XXNOTIMPLEMENTED static int tci1x_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_TCI1X_VERIFY_FREQ: case TOK_TCI1X_VERIFY_PTT: if (val.i && !priv->has_verify_cmds) { rig_debug(RIG_DEBUG_ERR, "%s: FLRig version 1.3.54.18 or higher needed to support fast functions\n", __func__); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int tci1x_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_TCI1X_VERIFY_FREQ: case TOK_TCI1X_VERIFY_PTT: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int tci1x_set_ext_parm(RIG *rig, setting_t parm, value_t val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int tci1x_get_ext_parm(RIG *rig, setting_t parm, value_t *val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } #endif hamlib-4.6.5/rigs/dummy/dummy.c0000664000175000017500000021335215056640443012060 /* * Hamlib Dummy backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * #include /* UNIX standard function definitions */ // cppcheck-suppress * #include #include "hamlib/rig.h" #include "dummy_common.h" #include "serial.h" #include "parallel.h" #include "cm108.h" #include "gpio.h" #include "misc.h" #include "tones.h" #include "idx_builtin.h" #include "register.h" #include "dummy.h" #define NB_CHAN 22 /* see caps->chan_list */ #define CMDSLEEP 20*1000 /* ms for each command */ struct dummy_priv_data { /* current vfo already in rig_state ? */ vfo_t curr_vfo; vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */ split_t split; vfo_t tx_vfo; ptt_t ptt; powerstat_t powerstat; int bank; value_t parms[RIG_SETTING_MAX]; int ant_option[4]; /* simulate 4 antennas */ int trn; /* transceive */ channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ // we're trying to emulate all sorts of vfo possibilities so this looks redundant channel_t vfo_maina; channel_t vfo_mainb; channel_t vfo_suba; channel_t vfo_subb; channel_t vfo_c; channel_t mem[NB_CHAN]; struct ext_list *ext_funcs; struct ext_list *ext_parms; char *magic_conf; int static_data; //freq_t freq_vfoa; //freq_t freq_vfob; }; /* levels pertain to each VFO */ static const struct confparams dummy_ext_levels[] = { { TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { TOK_EL_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_funcs[] = { { TOK_EL_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; /* parms pertain to the whole rig */ static const struct confparams dummy_ext_parms[] = { { TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* cfgparams are configuration item generally used by the backend's open() method */ static const struct confparams dummy_cfg_params[] = { { TOK_CFG_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", "DX", RIG_CONF_STRING, { } }, { TOK_CFG_STATIC_DATA, "static_data", "Static data", "Output only static data, no randomization of meter values", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /********************************************************************/ static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan) { chan->channel_num = 0; chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN_A: chan->freq = MHz(145); break; case RIG_VFO_B: case RIG_VFO_MAIN_B: chan->freq = MHz(146); break; case RIG_VFO_SUB_A: chan->freq = MHz(147); break; case RIG_VFO_SUB_B: chan->freq = MHz(148); break; case RIG_VFO_C: chan->freq = MHz(149); break; default: rig_debug(RIG_DEBUG_ERR, "%s(%d) unknown vfo=%s\n", __FILE__, __LINE__, rig_strvfo(vfo)); } chan->mode = RIG_MODE_FM; chan->width = rig_passband_normal(rig, RIG_MODE_FM); chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = vfo; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->ctcss_tone = 0; chan->dcs_code = 0; chan->ctcss_sql = 0; chan->dcs_sql = 0; chan->rit = 0; chan->xit = 0; chan->tuning_step = 0; chan->ant = 0; chan->funcs = (setting_t)0; memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t)); } static void copy_chan(channel_t *dest, const channel_t *src) { struct ext_list *saved_ext_levels; int i; /* TODO: ext_levels[] of different sizes */ for (i = 0; !RIG_IS_EXT_END(src->ext_levels[i]) && !RIG_IS_EXT_END(dest->ext_levels[i]); i++) { dest->ext_levels[i] = src->ext_levels[i]; } saved_ext_levels = dest->ext_levels; memcpy(dest, src, sizeof(channel_t)); dest->ext_levels = saved_ext_levels; } static int dummy_init(RIG *rig) { struct dummy_priv_data *priv; int i; ENTERFUNC; priv = (struct dummy_priv_data *)calloc(1, sizeof(struct dummy_priv_data)); if (!priv) { RETURNFUNC(-RIG_ENOMEM); } STATE(rig)->priv = (void *)priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); RIGPORT(rig)->type.rig = RIG_PORT_NONE; priv->split = RIG_SPLIT_OFF; priv->ptt = RIG_PTT_OFF; priv->powerstat = RIG_POWER_ON; STATE(rig)->powerstat = priv->powerstat; priv->bank = 0; memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); memset(priv->mem, 0, sizeof(priv->mem)); for (i = 0; i < NB_CHAN; i++) { priv->mem[i].channel_num = i; priv->mem[i].vfo = RIG_VFO_MEM; priv->mem[i].ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->mem[i].ext_levels) { RETURNFUNC(-RIG_ENOMEM); } } priv->vfo_maina.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_maina.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_mainb.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_mainb.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_suba.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_suba.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_subb.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_subb.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_c.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_c.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->ext_funcs = alloc_init_ext(dummy_ext_funcs); if (!priv->ext_funcs) { RETURNFUNC(-RIG_ENOMEM); } priv->ext_parms = alloc_init_ext(dummy_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } init_chan(rig, RIG_VFO_MAIN_A, &priv->vfo_maina); init_chan(rig, RIG_VFO_MAIN_B, &priv->vfo_mainb); init_chan(rig, RIG_VFO_SUB_A, &priv->vfo_suba); init_chan(rig, RIG_VFO_SUB_B, &priv->vfo_subb); init_chan(rig, RIG_VFO_C, &priv->vfo_c); priv->curr = &priv->vfo_maina; if (rig->caps->rig_model == RIG_MODEL_DUMMY_NOVFO) { priv->curr_vfo = priv->last_vfo = RIG_VFO_CURR; } else { priv->curr_vfo = priv->last_vfo = RIG_VFO_A; } priv->magic_conf = strdup("DX"); RETURNFUNC(RIG_OK); } static int dummy_cleanup(RIG *rig) { struct rig_state *rs = STATE(rig); struct dummy_priv_data *priv = (struct dummy_priv_data *)rs->priv; int i; ENTERFUNC; for (i = 0; i < NB_CHAN; i++) { free(priv->mem[i].ext_levels); } free(priv->vfo_maina.ext_levels); free(priv->vfo_mainb.ext_levels); free(priv->vfo_suba.ext_levels); free(priv->vfo_subb.ext_levels); free(priv->vfo_c.ext_levels); free(priv->ext_funcs); free(priv->ext_parms); free(priv->magic_conf); if (rs->priv) { free(rs->priv); } rs->priv = NULL; RETURNFUNC(RIG_OK); } static int dummy_open(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_DUMMY_NOVFO) { // then we emulate a rig without set_vfo or get_vfo rig_debug(RIG_DEBUG_VERBOSE, "%s: Emulating rig without get_vfo or set_vfo\n", __func__); rig->caps->set_vfo = NULL; rig->caps->get_vfo = NULL; } usleep(CMDSLEEP); RETURNFUNC(RIG_OK); } static int dummy_close(RIG *rig) { ENTERFUNC; usleep(CMDSLEEP); RETURNFUNC(RIG_OK); } static int dummy_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dummy_priv_data *priv; ENTERFUNC; priv = (struct dummy_priv_data *)STATE(rig)->priv; switch (token) { case TOK_CFG_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; case TOK_CFG_STATIC_DATA: priv->static_data = atoi(val) ? 1 : 0; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_get_conf(RIG *rig, hamlib_token_t token, char *val) { struct dummy_priv_data *priv; ENTERFUNC; priv = (struct dummy_priv_data *)STATE(rig)->priv; switch (token) { case TOK_CFG_MAGICCONF: strcpy(val, priv->magic_conf); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dummy_priv_data *priv; char fstr[20]; ENTERFUNC; if (rig == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: rig is NULL!!!\n", __func__); RETURNFUNC(-RIG_EINVAL); } priv = (struct dummy_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX) { vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } // if needed for testing enable this to emulate a rig with 100hz resolution #if 0 // we emulate a rig with 100Hz set freq interval limits -- truncation freq = freq - fmod(freq, 100); #endif usleep(CMDSLEEP); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.freq = freq; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.freq = freq; break; case RIG_VFO_SUB_A: priv->vfo_suba.freq = freq; break; case RIG_VFO_SUB_B: priv->vfo_subb.freq = freq; break; case RIG_VFO_C: priv->vfo_c.freq = freq; break; } if (!priv->split) { priv->curr->tx_freq = freq; } rig_debug(RIG_DEBUG_TRACE, "%s: curr->freq=%.0f, curr->tx_freq=%.0f\n", __func__, priv->curr->freq, priv->curr->tx_freq); RETURNFUNC(RIG_OK); } static int dummy_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct dummy_priv_data *priv = (struct dummy_priv_data *)rs->priv; ENTERFUNC; if (vfo == RIG_VFO_CURR && rig->caps->rig_model != RIG_MODEL_DUMMY_NOVFO) { vfo = priv->curr_vfo; } if ((vfo == RIG_VFO_SUB && rs->uplink == 1) || (vfo == RIG_VFO_MAIN && rs->uplink == 2)) { rig_debug(RIG_DEBUG_TRACE, "%s: uplink=%d, ignoring get_freq\n", __func__, rs->uplink); RETURNFUNC(RIG_OK); } usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: *freq = priv->vfo_maina.freq; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: *freq = priv->vfo_mainb.freq; break; case RIG_VFO_SUB_A: *freq = priv->vfo_suba.freq; break; case RIG_VFO_SUB_B: *freq = priv->vfo_subb.freq; break; case RIG_VFO_C: *freq = priv->vfo_c.freq; break; default: RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); RETURNFUNC(RIG_OK); } static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; struct rig_cache *cachep = CACHE(rig); char buf[16]; ENTERFUNC; usleep(CMDSLEEP); sprintf_freq(buf, sizeof(buf), width); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s %s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), buf); vfo = vfo_fixup(rig, vfo, cachep->split); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } if (width == RIG_PASSBAND_NOCHANGE) { switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: width = priv->vfo_maina.width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: width = priv->vfo_mainb.width; break; case RIG_VFO_SUB_A: width = priv->vfo_suba.width; break; case RIG_VFO_SUB_B: width = priv->vfo_subb.width; break; case RIG_VFO_C: width = priv->vfo_c.width; break; } } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.mode = mode; priv->vfo_maina.width = width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.mode = mode; priv->vfo_mainb.width = width; break; case RIG_VFO_SUB_A: priv->vfo_suba.mode = mode; priv->vfo_suba.width = width; break; case RIG_VFO_SUB_B: priv->vfo_subb.mode = mode; priv->vfo_subb.width = width; break; case RIG_VFO_C: priv->vfo_c.mode = mode; priv->vfo_c.width = width; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } vfo = vfo_fixup(rig, vfo, cachep->split); if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(RIG_OK); } if (width == RIG_PASSBAND_NORMAL) { width = curr->width = rig_passband_normal(rig, mode); } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.width = width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.width = width; break; case RIG_VFO_SUB_A: priv->vfo_suba.width = width; break; case RIG_VFO_SUB_B: priv->vfo_subb.width = width; break; case RIG_VFO_C: priv->vfo_c.width = width; break; } RETURNFUNC(RIG_OK); } static int dummy_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: *mode = priv->vfo_maina.mode; *width = priv->vfo_maina.width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: *mode = priv->vfo_mainb.mode; *width = priv->vfo_mainb.width; break; case RIG_VFO_SUB_A: *mode = priv->vfo_suba.mode; *width = priv->vfo_suba.width; break; case RIG_VFO_SUB_B: *mode = priv->vfo_subb.mode; *width = priv->vfo_subb.width; break; case RIG_VFO_C: *mode = priv->vfo_c.mode; *width = priv->vfo_c.width; break; } RETURNFUNC(RIG_OK); } static int dummy_set_vfo(RIG *rig, vfo_t vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } switch (vfo) { case RIG_VFO_VFO: /* FIXME */ case RIG_VFO_RX: case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->curr = &priv->vfo_maina; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->curr = &priv->vfo_mainb; break; case RIG_VFO_SUB_A: priv->curr = &priv->vfo_suba; break; case RIG_VFO_SUB_B: priv->curr = &priv->vfo_subb; break; case RIG_VFO_C: priv->curr = &priv->vfo_c; break; case RIG_VFO_MEM: if (curr->channel_num >= 0 && curr->channel_num < NB_CHAN) { priv->curr = &priv->mem[curr->channel_num]; break; } case RIG_VFO_TX: if (priv->tx_vfo == RIG_VFO_A) { priv->curr = &priv->vfo_maina; } else if (priv->tx_vfo == RIG_VFO_B) { priv->curr = &priv->vfo_mainb; } else if (priv->tx_vfo == RIG_VFO_MEM) { priv->curr = &priv->mem[curr->channel_num]; } else { priv->curr = &priv->vfo_maina; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s unknown vfo: %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } priv->last_vfo = priv->curr_vfo; priv->curr_vfo = vfo; STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } static int dummy_get_vfo(RIG *rig, vfo_t *vfo) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; usleep(CMDSLEEP); *vfo = priv->curr_vfo; RETURNFUNC(RIG_OK); } static int dummy_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->ptt = ptt; RETURNFUNC(RIG_OK); } static int dummy_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; hamlib_port_t *pttp = PTTPORT(rig); int rc; int status = 0; ENTERFUNC; usleep(CMDSLEEP); // sneak a look at the hardware PTT and OR that in with our result // as if it had keyed us switch (pttp->type.ptt) { case RIG_PTT_SERIAL_DTR: if (pttp->fd >= 0) { if (RIG_OK != (rc = ser_get_dtr(pttp, &status))) { RETURNFUNC(rc); } *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } else { *ptt = RIG_PTT_OFF; } break; case RIG_PTT_SERIAL_RTS: if (pttp->fd >= 0) { if (RIG_OK != (rc = ser_get_rts(pttp, &status))) { RETURNFUNC(rc); } *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } else { *ptt = RIG_PTT_OFF; } break; case RIG_PTT_PARALLEL: if (pttp->fd >= 0) { if (RIG_OK != (rc = par_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; case RIG_PTT_CM108: if (pttp->fd >= 0) { if (RIG_OK != (rc = cm108_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; case RIG_PTT_GPIO: case RIG_PTT_GPION: if (pttp->fd >= 0) { if (RIG_OK != (rc = gpio_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; default: *ptt = priv->ptt; break; } RETURNFUNC(RIG_OK); } static int dummy_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { static int twiddle = 0; ENTERFUNC; usleep(CMDSLEEP); *dcd = (twiddle++ & 1) ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } static int dummy_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->rptr_shift = rptr_shift; RETURNFUNC(RIG_OK); } static int dummy_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *rptr_shift = curr->rptr_shift; RETURNFUNC(RIG_OK); } static int dummy_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->rptr_offs = rptr_offs; RETURNFUNC(RIG_OK); } static int dummy_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *rptr_offs = curr->rptr_offs; RETURNFUNC(RIG_OK); } static int dummy_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->ctcss_tone = tone; RETURNFUNC(RIG_OK); } static int dummy_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *tone = curr->ctcss_tone; RETURNFUNC(RIG_OK); } static int dummy_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->dcs_code = code; RETURNFUNC(RIG_OK); } static int dummy_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *code = curr->dcs_code; RETURNFUNC(RIG_OK); } static int dummy_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->ctcss_sql = tone; RETURNFUNC(RIG_OK); } static int dummy_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *tone = curr->ctcss_sql; RETURNFUNC(RIG_OK); } static int dummy_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->dcs_sql = code; RETURNFUNC(RIG_OK); } static int dummy_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *code = curr->dcs_sql; RETURNFUNC(RIG_OK); } static int dummy_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), tx_freq); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but set_split_freq() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_set_freq(rig, priv->tx_vfo, tx_freq); priv->curr->tx_freq = tx_freq; rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, tx_freq); RETURNFUNC(retval); } static int dummy_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but get_split_freq() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_get_freq(rig, priv->tx_vfo, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, *tx_freq); RETURNFUNC(retval); } static int dummy_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n", __func__, rig_strvfo(vfo), rig_strrmode(tx_mode), tx_width); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but set_split_mode() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_set_mode(rig, priv->tx_vfo, tx_mode, tx_width); curr->tx_mode = tx_mode; if (RIG_PASSBAND_NOCHANGE == tx_width) { RETURNFUNC(retval); } curr->tx_width = tx_width; RETURNFUNC(retval); } static int dummy_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but get_split_mode() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_get_mode(rig, priv->tx_vfo, tx_mode, tx_width); rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n", __func__, rig_strvfo(vfo), rig_strrmode(*tx_mode), *tx_width); RETURNFUNC(retval); } static int dummy_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n", __func__, split, rig_strvfo(vfo), rig_strvfo(tx_vfo)); if (tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->curr_vfo; } if (tx_vfo == RIG_VFO_CURR || tx_vfo == RIG_VFO_TX) { tx_vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } priv->split = split; priv->tx_vfo = tx_vfo; RETURNFUNC(RIG_OK); } static int dummy_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; *split = priv->split; *tx_vfo = priv->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n", __func__, *split, rig_strvfo(vfo), rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } static int dummy_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->rit = rit; RETURNFUNC(RIG_OK); } static int dummy_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *rit = curr->rit; RETURNFUNC(RIG_OK); } static int dummy_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->xit = xit; RETURNFUNC(RIG_OK); } static int dummy_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *xit = curr->xit; RETURNFUNC(RIG_OK); } static int dummy_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->tuning_step = ts; RETURNFUNC(RIG_OK); } static int dummy_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *ts = curr->tuning_step; RETURNFUNC(RIG_OK); } static int dummy_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rig_strfunc(func), status); if (status) { curr->funcs |= func; } else { curr->funcs &= ~func; } RETURNFUNC(RIG_OK); } static int dummy_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *status = (curr->funcs & func) ? 1 : 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strfunc(func)); RETURNFUNC(RIG_OK); } static int dummy_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int idx; char lstr[32]; ENTERFUNC; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } curr->levels[idx] = val; if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strlevel(level), lstr); RETURNFUNC(RIG_OK); } static int dummy_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int idx; static float rfpower = 0; ENTERFUNC; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: if (priv->static_data) { curr->levels[idx].i = -12; } else { uint64_t level1, level2; /* make S-Meter jiggle */ int qrm = -56; if (curr->freq < MHz(7)) { qrm = -20; } else if (curr->freq < MHz(21)) { qrm = -30; } else if (curr->freq < MHz(50)) { qrm = -50; } level1 = LVL_ATT; level2 = LVL_PREAMP; curr->levels[idx].i = qrm + (time(NULL) % 32) + (rand() % 4) - curr->levels[level1].i + curr->levels[level2].i; } break; case RIG_LEVEL_RFPOWER_METER: if (priv->static_data) { curr->levels[idx].f = 0.5f; } else { curr->levels[idx].f = (float)(time(NULL) % 32) / 64.0f + (float)( rand() % 4) / 8.0f; rfpower = curr->levels[idx].f; } break; case RIG_LEVEL_RFPOWER_METER_WATTS: if (priv->static_data) { curr->levels[idx].f = 50.0f; } else { #if 0 curr->levels[idx].f = (float)(time(NULL) % 32) / 64.0f + (float)( rand() % 4) / 8.0f; #endif curr->levels[idx].f = 100.0f * rfpower; } break; case RIG_LEVEL_COMP_METER: if (priv->static_data) { curr->levels[idx].f = 3.5f; } else { curr->levels[idx].f = 0.5f + (float)(time(NULL) % 32) / 16.0f + (float)( rand() % 200) / 20.0f; } break; case RIG_LEVEL_VD_METER: if (priv->static_data) { curr->levels[idx].f = 13.82f; } else { curr->levels[idx].f = 13.82f + (float)(time(NULL) % 10) / 50.0f - (float)( rand() % 10) / 40.0f; } break; case RIG_LEVEL_ID_METER: if (priv->static_data) { curr->levels[idx].f = 0.85f; } else { curr->levels[idx].f = 2.0f + (float)(time(NULL) % 320) / 16.0f - (float)( rand() % 40) / 20.0f; } break; } memcpy(val, &curr->levels[idx], sizeof(value_t)); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strlevel(level)); RETURNFUNC(RIG_OK); } static int dummy_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; char lstr[64]; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: case TOK_EL_MAGICCOMBO: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } elp = find_ext(curr->ext_levels, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ elp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int dummy_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: case TOK_EL_MAGICCOMBO: break; default: RETURNFUNC(-RIG_EINVAL); } elp = find_ext(curr->ext_levels, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICEXTFUNC: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_CHECKBUTTON: break; case RIG_CONF_BUTTON: break; default: RETURNFUNC(-RIG_EINTERNAL); } elp = find_ext(priv->ext_funcs, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ elp->val.i = status; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, cfp->name, status); RETURNFUNC(RIG_OK); } static int dummy_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICEXTFUNC: break; default: RETURNFUNC(-RIG_EINVAL); } elp = find_ext(priv->ext_funcs, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *status = elp->val.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_powerstat(RIG *rig, powerstat_t status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->powerstat = status; RETURNFUNC(RIG_OK); } static int dummy_get_powerstat(RIG *rig, powerstat_t *status) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; *status = priv->powerstat; RETURNFUNC(RIG_OK); } static int dummy_set_parm(RIG *rig, setting_t parm, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } if (RIG_PARM_IS_STRING(parm)) { strcpy(pstr, val.cs); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int dummy_get_parm(RIG *rig, setting_t parm, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } static int dummy_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EP_MAGICPARM: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int dummy_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EP_MAGICPARM: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; switch (ant) { case RIG_ANT_CURR: break; case RIG_ANT_1: case RIG_ANT_2: case RIG_ANT_3: case RIG_ANT_4: curr->ant = ant; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna requested=0x%02x\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } priv->ant_option[rig_setting2idx(curr->ant)] = option.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called ant=0x%02x, option=%d, curr->ant=0x%02x\n", __func__, ant, option.i, curr->ant); RETURNFUNC(RIG_OK); } static int dummy_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x\n", __func__, ant); switch (ant) { case RIG_ANT_CURR: *ant_curr = curr->ant; break; case RIG_ANT_1: case RIG_ANT_2: case RIG_ANT_3: case RIG_ANT_4: *ant_curr = ant; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna requested=0x%02x\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: ant_curr=0x%02x, idx=%d\n", __func__, *ant_curr, rig_setting2idx(*ant_curr)); option->i = priv->ant_option[rig_setting2idx(*ant_curr)]; RETURNFUNC(RIG_OK); } static int dummy_set_bank(RIG *rig, vfo_t vfo, int bank) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->bank = bank; RETURNFUNC(RIG_OK); } static int dummy_set_mem(RIG *rig, vfo_t vfo, int ch) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (ch < 0 || ch >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } if (priv->curr_vfo == RIG_VFO_MEM) { priv->curr = &priv->mem[ch]; } else { priv->curr->channel_num = ch; } RETURNFUNC(RIG_OK); } static int dummy_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *ch = curr->channel_num; RETURNFUNC(RIG_OK); } static int dummy_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rig_strscan(scan), ch); /* TODO: change freq, etc. */ RETURNFUNC(RIG_OK); } static void chan_vfo(channel_t *chan, vfo_t vfo) { chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); } static int dummy_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int ret; freq_t freq; shortfreq_t ts; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfop(op)); switch (op) { case RIG_OP_FROM_VFO: /* VFO->MEM */ if (priv->curr_vfo == RIG_VFO_MEM) { int ch = curr->channel_num; copy_chan(curr, priv->last_vfo == RIG_VFO_A ? &priv->vfo_maina : &priv->vfo_mainb); curr->channel_num = ch; curr->channel_desc[0] = '\0'; curr->vfo = RIG_VFO_MEM; } else { channel_t *mem_chan = &priv->mem[curr->channel_num]; copy_chan(mem_chan, curr); mem_chan->channel_num = curr->channel_num; mem_chan->channel_desc[0] = '\0'; mem_chan->vfo = RIG_VFO_MEM; } break; case RIG_OP_TO_VFO: /* MEM->VFO */ if (priv->curr_vfo == RIG_VFO_MEM) { channel_t *vfo_chan = (priv->last_vfo == RIG_VFO_A) ? &priv->vfo_maina : &priv->vfo_mainb; copy_chan(vfo_chan, curr); chan_vfo(vfo_chan, priv->last_vfo); } else { copy_chan(&priv->mem[curr->channel_num], curr); chan_vfo(curr, priv->curr_vfo); } break; case RIG_OP_CPY: /* VFO A = VFO B or VFO B = VFO A */ if (priv->curr_vfo == RIG_VFO_A) { copy_chan(&priv->vfo_mainb, &priv->vfo_maina); chan_vfo(&priv->vfo_mainb, RIG_VFO_B); break; } else if (priv->curr_vfo == RIG_VFO_B) { copy_chan(&priv->vfo_maina, &priv->vfo_mainb); chan_vfo(&priv->vfo_maina, RIG_VFO_A); break; } rig_debug(RIG_DEBUG_VERBOSE, "%s beep!\n", __func__); break; case RIG_OP_XCHG: /* Exchange VFO A/B */ { channel_t chan; chan.ext_levels = alloc_init_ext(dummy_ext_levels); if (!chan.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } copy_chan(&chan, &priv->vfo_mainb); copy_chan(&priv->vfo_mainb, &priv->vfo_maina); copy_chan(&priv->vfo_maina, &chan); chan_vfo(&priv->vfo_maina, RIG_VFO_A); chan_vfo(&priv->vfo_mainb, RIG_VFO_B); free(chan.ext_levels); break; } case RIG_OP_MCL: /* Memory clear */ if (priv->curr_vfo == RIG_VFO_MEM) { struct ext_list *saved_ext_levels = curr->ext_levels; int saved_ch = curr->channel_num; int i; for (i = 0; !RIG_IS_EXT_END(curr->ext_levels[i]); i++) { curr->ext_levels[i].val.i = 0; } memset(curr, 0, sizeof(channel_t)); curr->ext_levels = saved_ext_levels; curr->channel_num = saved_ch; curr->vfo = RIG_VFO_MEM; } else { struct ext_list *saved_ext_levels = curr->ext_levels; channel_t *mem_chan = &priv->mem[curr->channel_num]; int i; for (i = 0; !RIG_IS_EXT_END(mem_chan->ext_levels[i]); i++) { mem_chan->ext_levels[i].val.i = 0; } memset(mem_chan, 0, sizeof(channel_t)); mem_chan->ext_levels = saved_ext_levels; mem_chan->channel_num = curr->channel_num; mem_chan->vfo = RIG_VFO_MEM; } break; case RIG_OP_TOGGLE: if (priv->curr_vfo == RIG_VFO_A) { RETURNFUNC(dummy_set_vfo(rig, RIG_VFO_B)); } else if (priv->curr_vfo == RIG_VFO_B) { RETURNFUNC(dummy_set_vfo(rig, RIG_VFO_A)); } else { RETURNFUNC(-RIG_EVFO); } case RIG_OP_RIGHT: case RIG_OP_LEFT: case RIG_OP_TUNE: /* NOP */ break; case RIG_OP_BAND_UP: case RIG_OP_BAND_DOWN: RETURNFUNC(-RIG_ENIMPL); case RIG_OP_UP: ret = dummy_get_freq(rig, vfo, &freq); if (!ret) { break; } ret = dummy_get_ts(rig, vfo, &ts); if (!ret) { break; } dummy_set_freq(rig, vfo, freq + ts); /* up */ break; case RIG_OP_DOWN: ret = dummy_get_freq(rig, vfo, &freq); if (!ret) { break; } ret = dummy_get_ts(rig, vfo, &ts); if (!ret) { break; } dummy_set_freq(rig, vfo, freq - ts); /* down */ break; default: break; } RETURNFUNC(RIG_OK); } static int dummy_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (!chan->ext_levels) { RETURNFUNC(-RIG_EINVAL); } if (chan->channel_num < 0 || chan->channel_num >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } /* TODO: * - check ext_levels is the right length */ switch (chan->vfo) { case RIG_VFO_MEM: copy_chan(&priv->mem[chan->channel_num], chan); break; case RIG_VFO_A: copy_chan(&priv->vfo_maina, chan); break; case RIG_VFO_B: copy_chan(&priv->vfo_mainb, chan); break; case RIG_VFO_CURR: copy_chan(priv->curr, chan); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (chan->channel_num < 0 || chan->channel_num >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } if (!chan->ext_levels) { chan->ext_levels = alloc_init_ext(dummy_ext_levels); if (!chan->ext_levels) { RETURNFUNC(-RIG_ENOMEM); } } /* TODO: * - check ext_levels is the right length */ switch (chan->vfo) { case RIG_VFO_MEM: copy_chan(chan, &priv->mem[chan->channel_num]); break; case RIG_VFO_A: copy_chan(chan, &priv->vfo_maina); break; case RIG_VFO_B: copy_chan(chan, &priv->vfo_mainb); break; case RIG_VFO_CURR: copy_chan(chan, priv->curr); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_set_trn(RIG *rig, int trn) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; priv->trn = trn; RETURNFUNC2(RIG_OK); } static int dummy_get_trn(RIG *rig, int *trn) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; *trn = priv->trn; RETURNFUNC2(RIG_OK); } static const char *dummy_get_info(RIG *rig) { return "Nothing much (dummy)"; } static int dummy_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, digits); RETURNFUNC(RIG_OK); } static int dummy_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { ENTERFUNC; strcpy(digits, "0123456789ABCDEF"); *length = 16; RETURNFUNC(RIG_OK); } static int dummy_send_morse(RIG *rig, vfo_t vfo, const char *msg) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_stop_morse(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); /* Pretend this is a 100W radio */ *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int dummy_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); /* Pretend this is a 100W radio */ if (mwpower > 100000) { RETURNFUNC(-RIG_EINVAL); } *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } static int m_year, m_month, m_day, m_hour, m_min, m_sec, m_utc_offset; static double m_msec; int dummy_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int retval = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: %04d-%02d-%02dT%02d:%02d:%02d.%.03f%s%02u\n", __func__, year, month, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", (unsigned)(abs(utc_offset))); m_year = year; m_month = month; m_day = day; if (hour >= 0) { m_hour = hour; m_min = min; m_sec = sec; m_msec = msec; m_utc_offset = utc_offset; } return retval; } int dummy_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval = RIG_OK; *year = m_year; *month = m_month; *day = m_day; *hour = m_hour; *min = m_min; *sec = m_sec; *msec = m_msec; *utc_offset = m_utc_offset; rig_debug(RIG_DEBUG_VERBOSE, "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf%s%02u\n'", __func__, *year, *month, *day, *hour, *min, *sec, *msec, *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); return retval; } /* * Dummy rig capabilities. */ /* * The following macros set bitmasks for the various funcs, levels, parms, * etc. This dummy backend claims support for almost all of them. */ #define DUMMY_FUNC ((setting_t)-1ULL) /* All possible functions */ #define DUMMY_LEVEL (((setting_t)-1ULL)&~(1ULL<<27)) /* All levels except SQLSTAT */ #define DUMMY_PARM ((setting_t)-1ULL) /* All possible parms */ #define DUMMY_VFO_OP 0x7ffffffUL /* All possible VFO OPs */ #define DUMMY_SCAN 0x7ffffffUL /* All possible scan OPs */ #define DUMMY_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_C|RIG_VFO_MEM|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define DUMMY_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | \ RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_WFM | \ RIG_MODE_CWR | RIG_MODE_RTTYR) #define DUMMY_MEM_CAP { \ .bank_num = 1, \ .vfo = 1, \ .ant = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ .rptr_shift = 1, \ .rptr_offs = 1, \ .tuning_step = 1, \ .rit = 1, \ .xit = 1, \ .funcs = DUMMY_FUNC, \ .levels = RIG_LEVEL_SET(DUMMY_LEVEL), \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .dcs_code = 1, \ .dcs_sql = 1, \ .scan_group = 1, \ .flags = 1, \ .channel_desc = 1, \ .ext_levels = 1, \ } struct rig_caps dummy_caps = { RIG_MODEL(RIG_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20240709.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = RIG_TARGETABLE_PTT | RIG_TARGETABLE_RITXIT | RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NONE, .has_get_func = DUMMY_FUNC, .has_set_func = DUMMY_FUNC, .has_get_level = DUMMY_LEVEL, .has_set_level = RIG_LEVEL_SET(DUMMY_LEVEL), .has_get_parm = DUMMY_PARM, .has_set_parm = RIG_PARM_SET(DUMMY_PARM), .level_gran = { [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0f / 255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05f }, .max = { .f = 1 }, .step = { .f = 1.0f / 511.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0f }, .max = { .f = 1 }, .step = { .f = 1.0f / 255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0f }, .max = { .f = 100 }, .step = { .f = 1.0f / 255.0f } }, [LVL_CWPITCH] = { .step = { .i = 10 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .chan_list = { { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, { 19, 19, RIG_MTYPE_CALL }, { 20, NB_CHAN - 1, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .scan_ops = DUMMY_SCAN, .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .preamp = { 10, RIG_DBLST_END, }, .agc_level_count = 7, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SUPERFAST, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO, RIG_AGC_USER }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = W(5), .high_power = W(100), DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#2" }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DUMMY_MODES, 1}, {DUMMY_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_RTTY, Hz(300)}, {RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY, Hz(50)}, {RIG_MODE_RTTY, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .max_rit = 9990, .max_xit = 9990, .max_ifshift = 10000, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .spectrum_attenuator = { 10, 20, 30, RIG_DBLST_END, }, .priv = NULL, /* priv */ .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .rig_init = dummy_init, .rig_cleanup = dummy_cleanup, .rig_open = dummy_open, .rig_close = dummy_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_freq = dummy_set_freq, .get_freq = dummy_get_freq, .set_mode = dummy_set_mode, .get_mode = dummy_get_mode, .set_vfo = dummy_set_vfo, .get_vfo = dummy_get_vfo, .set_powerstat = dummy_set_powerstat, .get_powerstat = dummy_get_powerstat, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_get_info, .set_ptt = dummy_set_ptt, .get_ptt = dummy_get_ptt, .get_dcd = dummy_get_dcd, .set_rptr_shift = dummy_set_rptr_shift, .get_rptr_shift = dummy_get_rptr_shift, .set_rptr_offs = dummy_set_rptr_offs, .get_rptr_offs = dummy_get_rptr_offs, .set_ctcss_tone = dummy_set_ctcss_tone, .get_ctcss_tone = dummy_get_ctcss_tone, .set_dcs_code = dummy_set_dcs_code, .get_dcs_code = dummy_get_dcs_code, .set_ctcss_sql = dummy_set_ctcss_sql, .get_ctcss_sql = dummy_get_ctcss_sql, .set_dcs_sql = dummy_set_dcs_sql, .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = dummy_set_split_freq, .get_split_freq = dummy_get_split_freq, .set_split_mode = dummy_set_split_mode, .get_split_mode = dummy_get_split_mode, .set_split_vfo = dummy_set_split_vfo, .get_split_vfo = dummy_get_split_vfo, .set_rit = dummy_set_rit, .get_rit = dummy_get_rit, .set_xit = dummy_set_xit, .get_xit = dummy_get_xit, .set_ts = dummy_set_ts, .get_ts = dummy_get_ts, .set_ant = dummy_set_ant, .get_ant = dummy_get_ant, .set_bank = dummy_set_bank, .set_mem = dummy_set_mem, .get_mem = dummy_get_mem, .vfo_op = dummy_vfo_op, .scan = dummy_scan, .send_dtmf = dummy_send_dtmf, .recv_dtmf = dummy_recv_dtmf, .send_morse = dummy_send_morse, .stop_morse = dummy_stop_morse, .send_voice_mem = dummy_send_voice_mem, .set_channel = dummy_set_channel, .get_channel = dummy_get_channel, .set_trn = dummy_set_trn, .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, .set_clock = dummy_set_clock, .get_clock = dummy_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps dummy_no_vfo_caps = { RIG_MODEL(RIG_MODEL_DUMMY_NOVFO), .model_name = "Dummy No VFO", .mfg_name = "Hamlib", .version = "20240409.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = RIG_TARGETABLE_PTT | RIG_TARGETABLE_RITXIT | RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NONE, .has_get_func = DUMMY_FUNC, .has_set_func = DUMMY_FUNC, .has_get_level = DUMMY_LEVEL, .has_set_level = RIG_LEVEL_SET(DUMMY_LEVEL), .has_get_parm = DUMMY_PARM, .has_set_parm = RIG_PARM_SET(DUMMY_PARM), .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .chan_list = { { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, { 19, 19, RIG_MTYPE_CALL }, { 20, NB_CHAN - 1, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .scan_ops = DUMMY_SCAN, .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .preamp = { 10, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = W(5), .high_power = W(100), DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#2" }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DUMMY_MODES, 1}, {DUMMY_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_RTTY, Hz(300)}, {RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY, Hz(50)}, {RIG_MODE_RTTY, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .max_rit = 9990, .max_xit = 9990, .max_ifshift = 10000, .priv = NULL, /* priv */ .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .rig_init = dummy_init, .rig_cleanup = dummy_cleanup, .rig_open = dummy_open, .rig_close = dummy_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_freq = dummy_set_freq, .get_freq = dummy_get_freq, .set_mode = dummy_set_mode, .get_mode = dummy_get_mode, .set_vfo = dummy_set_vfo, .get_vfo = dummy_get_vfo, .set_powerstat = dummy_set_powerstat, .get_powerstat = dummy_get_powerstat, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_get_info, .set_ptt = dummy_set_ptt, .get_ptt = dummy_get_ptt, .get_dcd = dummy_get_dcd, .set_rptr_shift = dummy_set_rptr_shift, .get_rptr_shift = dummy_get_rptr_shift, .set_rptr_offs = dummy_set_rptr_offs, .get_rptr_offs = dummy_get_rptr_offs, .set_ctcss_tone = dummy_set_ctcss_tone, .get_ctcss_tone = dummy_get_ctcss_tone, .set_dcs_code = dummy_set_dcs_code, .get_dcs_code = dummy_get_dcs_code, .set_ctcss_sql = dummy_set_ctcss_sql, .get_ctcss_sql = dummy_get_ctcss_sql, .set_dcs_sql = dummy_set_dcs_sql, .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = dummy_set_split_freq, .get_split_freq = dummy_get_split_freq, .set_split_mode = dummy_set_split_mode, .get_split_mode = dummy_get_split_mode, .set_split_vfo = dummy_set_split_vfo, .get_split_vfo = dummy_get_split_vfo, .set_rit = dummy_set_rit, .get_rit = dummy_get_rit, .set_xit = dummy_set_xit, .get_xit = dummy_get_xit, .set_ts = dummy_set_ts, .get_ts = dummy_get_ts, .set_ant = dummy_set_ant, .get_ant = dummy_get_ant, .set_bank = dummy_set_bank, .set_mem = dummy_set_mem, .get_mem = dummy_get_mem, .vfo_op = dummy_vfo_op, .scan = dummy_scan, .send_dtmf = dummy_send_dtmf, .recv_dtmf = dummy_recv_dtmf, .send_morse = dummy_send_morse, .send_voice_mem = dummy_send_voice_mem, .set_channel = dummy_set_channel, .get_channel = dummy_get_channel, .set_trn = dummy_set_trn, .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, .set_clock = dummy_set_clock, .get_clock = dummy_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; DECLARE_INITRIG_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dummy_caps); rig_register(&netrigctl_caps); rig_register(&flrig_caps); rig_register(&trxmanager_caps); rig_register(&dummy_no_vfo_caps); rig_register(&aclog_caps); rig_register(&sdrsharp_caps); rig_register(&quisk_caps); // rig_register(&tci1x_caps); return RIG_OK; } hamlib-4.6.5/rigs/dummy/netampctl.c0000664000175000017500000001126615056640443012714 /* * Hamlib Netampctl backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/amplifier.h" #include "iofunc.h" #define CMD_MAX 32 #define BUF_MAX 64 /* * Helper function with protocol return code parsing */ static int netampctl_transaction(AMP *amp, char *cmd, int len, char *buf) { int ret; hamlib_port_t *ampp = AMPPORT(amp); ret = write_block(ampp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret < 0) { return ret; } if (!memcmp(buf, NETAMPCTL_RET, strlen(NETAMPCTL_RET))) { return atoi(buf + strlen(NETAMPCTL_RET)); } return ret; } static int netampctl_open(AMP *amp) { int ret; //struct amp_state *rs = AMPSTATE(amp); hamlib_port_t *ampp = AMPPORT(amp); int pamp_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } pamp_ver = atoi(buf); #define AMPCTLD_PAMP_VER 0 if (pamp_ver < AMPCTLD_PAMP_VER) { return -RIG_EPROTO; } ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } do { ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, string=%s\n", __func__, buf); } } while (ret > 0); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int netampctl_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(AMPPORT(amp), (unsigned char *) "q\n", 2); return RIG_OK; } static int netampctl_set_freq(AMP *amp, freq_t freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } static int netampctl_get_freq(AMP *amp, freq_t *freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *freq = 12345; return -RIG_ENIMPL; } #if 0 static int netampctl_reset(AMP *amp, amp_reset_t reset) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "R %d\n", reset); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static const char *netampctl_get_info(AMP *amp) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } /* * NET ampctl capabilities. */ const struct amp_caps netampctl_caps = { AMP_MODEL(AMP_MODEL_NETAMPCTL), .model_name = "NET ampctl", .mfg_name = "Hamlib", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .timeout = 2000, .retry = 3, .priv = NULL, /* priv */ /* .amp_init = netampctl_init, */ /* .amp_cleanup = netampctl_cleanup, */ .amp_open = netampctl_open, .amp_close = netampctl_close, .get_freq = netampctl_get_freq, .set_freq = netampctl_set_freq, .get_info = netampctl_get_info }; hamlib-4.6.5/rigs/dummy/rot_pstrotator.h0000664000175000017500000000361615056640443014037 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_PSTROTATOR_H #define _ROT_PSTROTATOR_H 1 #include "rotator.h" #include "token.h" /* backend conf */ #define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rot_caps pstrotator_caps; extern struct rot_caps netrotctl_caps; #if defined(HAVE_PTHREAD) typedef struct pstrotator_handler_args_sw { ROT *rot; int port; // port for reading PstRotator messages -- always +1 from base port } pstrotator_handler_args; typedef struct pstrotator_handler_priv_data_s { pthread_t thread_id; pstrotator_handler_args args; int pstrotator_handler_thread_run; int sockfd2; } pstrotator_handler_priv_data; #endif #endif /* _ROT_PSTROTATOR_H */ hamlib-4.6.5/rigs/dummy/trxmanager.c0000664000175000017500000007375415056640443013107 /* i Hamlib TRXManager backend - main file * Copyright (c) 2018 by Michael Black W9MDB * Derived from flrig.c * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include "trxmanager.h" #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 64 #define DEFAULTPATH "127.0.0.1:1003" #define TRXMANAGER_VFOS (RIG_VFO_A|RIG_VFO_B) #define TRXMANAGER_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) #define streq(s1,s2) (strcmp(s1,s2)==0) #define FLRIG_MODE_LSB '1' #define FLRIG_MODE_USB '2' #define FLRIG_MODE_CW '3' #define FLRIG_MODE_FM '4' #define FLRIG_MODE_AM '5' #define FLRIG_MODE_RTTY '6' #define FLRIG_MODE_CWR '7' #define FLRIG_MODE_RTTYR '9' #define FLRIG_MODE_PKTLSB 'C' #define FLRIG_MODE_PKTUSB 'D' #define FLRIG_MODE_PKTFM 'E' #define FLRIG_MODE_PKTAM 'F' // Hamlib doesn't support D2/D3 modes in hamlib yet // So we define them here but they aren't implemented #define FLRIG_MODE_PKTLSB2 'G' #define FLRIG_MODE_PKTUSB2 'H' #define FLRIG_MODE_PKTFM2 'I' #define FLRIG_MODE_PKTAM2 'J' #define FLRIG_MODE_PKTLSB3 'K' #define FLRIG_MODE_PKTUSB3 'L' #define FLRIG_MODE_PKTFM3 'M' #define FLRIG_MODE_PKTAM3 'N' static int trxmanager_init(RIG *rig); static int trxmanager_open(RIG *rig); static int trxmanager_close(RIG *rig); static int trxmanager_cleanup(RIG *rig); static int trxmanager_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int trxmanager_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int trxmanager_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int trxmanager_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int trxmanager_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int trxmanager_get_vfo(RIG *rig, vfo_t *vfo); static int trxmanager_set_vfo(RIG *rig, vfo_t vfo); static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int trxmanager_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int trxmanager_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int trxmanager_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int trxmanager_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int trxmanager_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int trxmanager_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int trxmanager_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static const char *trxmanager_get_info(RIG *rig); struct trxmanager_priv_data { vfo_t vfo_curr; char info[100]; split_t split; }; struct rig_caps trxmanager_caps = { RIG_MODEL(RIG_MODEL_TRXMANAGER_RIG), .model_name = "TRXManager 5.7.630+", .mfg_name = "TRXManager", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 10000, // long timeout to allow for antenna tuning and such .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TRXMANAGER_MODES, .low_power = -1, .high_power = -1, TRXMANAGER_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TRXMANAGER_MODES, .low_power = -1, .high_power = -1, TRXMANAGER_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {TRXMANAGER_MODES, 1}, {TRXMANAGER_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = trxmanager_init, .rig_open = trxmanager_open, .rig_close = trxmanager_close, .rig_cleanup = trxmanager_cleanup, .set_freq = trxmanager_set_freq, .get_freq = trxmanager_get_freq, .set_mode = trxmanager_set_mode, .get_mode = trxmanager_get_mode, .set_vfo = trxmanager_set_vfo, .get_vfo = trxmanager_get_vfo, .get_info = trxmanager_get_info, .set_ptt = trxmanager_set_ptt, .get_ptt = trxmanager_get_ptt, .set_split_mode = trxmanager_set_split_mode, .set_split_freq = trxmanager_set_split_freq, .get_split_freq = trxmanager_get_split_freq, .set_split_vfo = trxmanager_set_split_vfo, .get_split_vfo = trxmanager_get_split_vfo, .set_split_freq_mode = trxmanager_set_split_freq_mode, .get_split_freq_mode = trxmanager_get_split_freq_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return FALSE; } return TRUE; } #if 0 // looks like we don't need this but it's here just in case /* * vfo_curr * Assumes rig!=NULL */ static int vfo_curr(RIG *rig, vfo_t vfo) { int retval = 0; vfo_t vfocurr; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; // get the current VFO from trxmanager in case user changed it if ((retval = trxmanager_get_vfo(rig, &vfocurr)) != RIG_OK) { return retval; } priv->vfo_curr = vfocurr; retval = (vfo == vfocurr); return retval; } #endif /* * read_transaction * Assumes rig!=NULL, response!=NULL, response_len>=MAXCMDLEN */ static int read_transaction(RIG *rig, char *response, int response_len) { const char *delims = "\n"; int len; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); len = read_string(RIGPORT(rig), (unsigned char *) response, response_len, delims, strlen(delims), 0, 1); if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_init * Assumes rig!=NULL */ static int trxmanager_init(RIG *rig) { struct trxmanager_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, BACKEND_VER); STATE(rig)->priv = (struct trxmanager_priv_data *)calloc(1, sizeof(struct trxmanager_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct trxmanager_priv_data)); /* * set arbitrary initial status */ priv->vfo_curr = RIG_VFO_A; priv->split = 0; if (!rig->caps) { return -RIG_EINVAL; } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); return RIG_OK; } /* * trxmanager_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_open(RIG *rig) { int retval; char *cmd; char *saveptr; char response[MAXCMDLEN] = ""; hamlib_port_t *rp = RIGPORT(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, BACKEND_VER); rp->timeout = 10000; // long timeout for antenna switching/tuning retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) == 0) { rig_debug(RIG_DEBUG_ERR, "%s response len==0\n", __func__); return -RIG_EPROTO; } // Should have rig info now strtok_r(response, ";\r\n", &saveptr); strncpy(priv->info, &response[2], sizeof(priv->info)); rig_debug(RIG_DEBUG_VERBOSE, "%s connected to %s\n", __func__, priv->info); // Turn off active messages cmd = "AI0;"; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strncmp("AI0;", response, 4) != 0) { rig_debug(RIG_DEBUG_ERR, "%s AI invalid response=%s\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s AI response=%s\n", __func__, response); cmd = "FN;"; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s FN; write failed\n", __func__); } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s FN response=%s\n", __func__, response); priv->vfo_curr = RIG_VFO_A; return retval; } /* * trxmanager_close * Assumes rig!=NULL */ static int trxmanager_close(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return RIG_OK; } /* * trxmanager_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * trxmanager_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int trxmanager_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; int n; char vfoab; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } priv->vfo_curr = vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } vfoab = vfo == RIG_VFO_A ? 'R' : 'T'; SNPRINTF(cmd, sizeof(cmd), "X%c;", vfoab); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } *freq = 0; n = sscanf(&response[2], "%lg", freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: can't parse freq from %s", __func__, response); } if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\n", __func__); return -RIG_EPROTO; } return retval; } /* * trxmanager_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char vfoab; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; const struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } vfoab = vfo == RIG_VFO_A ? 'A' : 'B'; SNPRINTF(cmd, sizeof(cmd), "F%c%011lu;", vfoab, (unsigned long)freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } /* * trxmanager_set_ptt * Assumes rig!=NULL */ static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "%s;", ptt == 1 ? "TX" : "RX"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 5 || strstr(response, cmd) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_get_ptt * Assumes rig!=NULL ptt!=NULL */ static int trxmanager_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char cptt; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "IF;"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 40) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: IF response len=%d\n", __func__, (int)strlen(response)); cptt = response[28]; *ptt = cptt == '0' ? 0 : 1; return RIG_OK; } /* * trxmanager_set_split_mode * Assumes rig!=NULL */ static int trxmanager_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = trxmanager_set_mode(rig, RIG_VFO_B, mode, width); return retval; } /* * trxmanager_set_mode * Assumes rig!=NULL */ static int trxmanager_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char ttmode; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } ttmode = FLRIG_MODE_USB; switch (mode) { case RIG_MODE_LSB: ttmode = RIG_MODE_LSB; break; case RIG_MODE_USB: ttmode = RIG_MODE_USB; break; case RIG_MODE_CW: ttmode = FLRIG_MODE_CW; break; case RIG_MODE_FM: ttmode = FLRIG_MODE_FM; break; case RIG_MODE_AM: ttmode = FLRIG_MODE_AM; break; case RIG_MODE_RTTY: ttmode = FLRIG_MODE_RTTY; break; case RIG_MODE_CWR: ttmode = FLRIG_MODE_CWR; break; case RIG_MODE_RTTYR: ttmode = FLRIG_MODE_RTTYR; break; case RIG_MODE_PKTLSB: ttmode = FLRIG_MODE_PKTLSB; break; case RIG_MODE_PKTUSB: ttmode = FLRIG_MODE_PKTUSB; break; case RIG_MODE_PKTFM: ttmode = FLRIG_MODE_PKTFM; break; case RIG_MODE_PKTAM: ttmode = FLRIG_MODE_PKTAM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "MD%c;", ttmode); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } // Get the response retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s: response=%s\n", __func__, response); // Can't set BW on TRXManger as of 20180427 -- can only read it return RIG_OK; } /* * trxmanager_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int trxmanager_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int n; long iwidth = 0; char tmode; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; hamlib_port_t *rp = RIGPORT(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } priv->vfo_curr = vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "MD;"); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } n = sscanf(response, "MD%c;", &tmode); if (n != 1 || strlen(response) != 6) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } switch (tmode) { case FLRIG_MODE_LSB: *mode = RIG_MODE_LSB; break; case FLRIG_MODE_USB: *mode = RIG_MODE_USB; break; case FLRIG_MODE_CW: *mode = RIG_MODE_CW; break; case FLRIG_MODE_FM: *mode = RIG_MODE_FM; break; case FLRIG_MODE_AM: *mode = RIG_MODE_AM; break; case FLRIG_MODE_RTTY: *mode = RIG_MODE_RTTY; break; case FLRIG_MODE_CWR: *mode = RIG_MODE_CWR; break; case FLRIG_MODE_RTTYR: *mode = RIG_MODE_RTTYR; break; case FLRIG_MODE_PKTLSB: *mode = RIG_MODE_PKTLSB; break; case FLRIG_MODE_PKTUSB: *mode = RIG_MODE_PKTUSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode='%c'\n", __func__, tmode); return -RIG_ENIMPL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); // now get the bandwidth SNPRINTF(cmd, sizeof(cmd), "BW;"); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strncmp(response, "BW", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } n = sscanf(response, "BW%ld;", &iwidth); if (n != 1) { char *saveptr; rig_debug(RIG_DEBUG_ERR, "%s bandwidth scan failed '%s'\n", __func__, strtok_r(response, "\r\n", &saveptr)); return -RIG_EPROTO; } *width = iwidth; printf("Bandwidth=%ld\n", *width); return RIG_OK; } static int trxmanager_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct rig_state *rs = STATE(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_VERBOSE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } SNPRINTF(cmd, sizeof(cmd), "FN%d;", vfo == RIG_VFO_A ? 0 : 1); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } priv->vfo_curr = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } static int trxmanager_get_vfo(RIG *rig, vfo_t *vfo) { // TRXManager does not swap vfos // So we maintain our own internal state during set_vfo // This keeps the hamlib interface consistent with other rigs struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; char vfoab; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); vfoab = priv->vfo_curr; switch (vfoab) { case RIG_VFO_A: *vfo = RIG_VFO_A; break; case RIG_VFO_B: *vfo = RIG_VFO_B; break; default: priv->vfo_curr = *vfo; *vfo = RIG_VFO_CURR; return -RIG_EINVAL; } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } priv->vfo_curr = *vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } /* * trxmanager_set_split_freq */ static int trxmanager_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "XT%011lu;", (unsigned long) tx_freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } /* * trxmanager_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = trxmanager_get_freq(rig, RIG_VFO_B, tx_freq); return retval; } /* * trxmanager_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; split_t tsplit; vfo_t ttx_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); #if 0 /* for flrig we have to be on VFOA when we set split for VFOB Tx */ /* we can keep the rig on VFOA since we can set freq by VFO now */ if (!vfo_curr(rig, RIG_VFO_A)) { trxmanager_set_vfo(rig, RIG_VFO_A); } #endif retval = trxmanager_get_split_vfo(rig, vfo, &tsplit, &ttx_vfo); if (retval < 0) { return retval; } if (tsplit == split) { return RIG_OK; } // don't need to change it SNPRINTF(cmd, sizeof(cmd), "SP%c;", split ? '1' : '0'); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 6 || strstr(response, cmd) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; int tsplit = 0; int n; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); SNPRINTF(cmd, sizeof(cmd), "SP;"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } *tx_vfo = RIG_VFO_B; n = sscanf(response, "SP%d", &tsplit); if (n == 0 || n == EOF) { rig_debug(RIG_DEBUG_ERR, "%s error getting split from '%s'\n", __func__, response); } *split = tsplit; priv->split = *split; return RIG_OK; } /* * trxmanager_set_split_freq_mode * assumes rig!=NULL */ static int trxmanager_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX && vfo != RIG_VFO_B) { return -RIG_ENTARGET; } // assume split is on B // SNPRINTF(cmd, sizeof(cmd), "XT%011lu;", (unsigned long)freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 16 || strstr(response, cmd) == NULL) { FILE *fp; rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); fp = fopen("debug.txt", "w+"); fprintf(fp, "XT response=%s\n", response); fclose(fp); return -RIG_EPROTO; } priv->split = 1; // XT command also puts rig in split return retval; } /* * trxmanager_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int trxmanager_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { return -RIG_ENTARGET; } retval = trxmanager_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = trxmanager_get_mode(rig, vfo, mode, width); } return retval; } static const char *trxmanager_get_info(RIG *rig) { const struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return priv->info; } hamlib-4.6.5/rigs/dummy/trxmanager.h0000664000175000017500000000221215056640443013071 /* * Hamlib TRXManager backend - main header * Copyright (c) 2017 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Derived from flrig.h * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TRXMANAGER_H #define _TRXMANAGER_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20210613" #define EOM "\r" #define TRUE 1 #define FALSE 0 extern struct rig_caps trxmanager_caps; #endif /* _TRXMANAGER_H */ hamlib-4.6.5/rigs/dummy/Android.mk0000664000175000017500000000051315056640443012463 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dummy.c rot_dummy.c netrigctl.c netrotctl.c flrig.c trxmanager.c dummy_common.c sdrsharp.c LOCAL_MODULE := dummy LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/dummy/Makefile.in0000664000175000017500000006000515056640452012621 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/dummy ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_dummy_la_LIBADD = am__objects_1 = dummy_common.lo dummy.lo rot_dummy.lo \ rot_pstrotator.lo netrigctl.lo netrotctl.lo flrig.lo \ trxmanager.lo amp_dummy.lo netampctl.lo tci1x.lo aclog.lo \ sdrsharp.lo quisk.lo am_libhamlib_dummy_la_OBJECTS = $(am__objects_1) libhamlib_dummy_la_OBJECTS = $(am_libhamlib_dummy_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/aclog.Plo ./$(DEPDIR)/amp_dummy.Plo \ ./$(DEPDIR)/dummy.Plo ./$(DEPDIR)/dummy_common.Plo \ ./$(DEPDIR)/flrig.Plo ./$(DEPDIR)/netampctl.Plo \ ./$(DEPDIR)/netrigctl.Plo ./$(DEPDIR)/netrotctl.Plo \ ./$(DEPDIR)/quisk.Plo ./$(DEPDIR)/rot_dummy.Plo \ ./$(DEPDIR)/rot_pstrotator.Plo ./$(DEPDIR)/sdrsharp.Plo \ ./$(DEPDIR)/tci1x.Plo ./$(DEPDIR)/trxmanager.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_dummy_la_SOURCES) DIST_SOURCES = $(libhamlib_dummy_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DUMMYSRC = dummy_common.c dummy_common.h dummy.c dummy.h rot_dummy.c rot_dummy.h rot_pstrotator.c rot_pstrotator.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h amp_dummy.c amp_dummy.h netampctl.c tci1x.c aclog.c sdrsharp.c quisk.c noinst_LTLIBRARIES = libhamlib-dummy.la libhamlib_dummy_la_SOURCES = $(DUMMYSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/dummy/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/dummy/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-dummy.la: $(libhamlib_dummy_la_OBJECTS) $(libhamlib_dummy_la_DEPENDENCIES) $(EXTRA_libhamlib_dummy_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_dummy_la_OBJECTS) $(libhamlib_dummy_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aclog.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amp_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flrig.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netampctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrigctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrotctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quisk.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_pstrotator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdrsharp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tci1x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trxmanager.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/aclog.Plo -rm -f ./$(DEPDIR)/amp_dummy.Plo -rm -f ./$(DEPDIR)/dummy.Plo -rm -f ./$(DEPDIR)/dummy_common.Plo -rm -f ./$(DEPDIR)/flrig.Plo -rm -f ./$(DEPDIR)/netampctl.Plo -rm -f ./$(DEPDIR)/netrigctl.Plo -rm -f ./$(DEPDIR)/netrotctl.Plo -rm -f ./$(DEPDIR)/quisk.Plo -rm -f ./$(DEPDIR)/rot_dummy.Plo -rm -f ./$(DEPDIR)/rot_pstrotator.Plo -rm -f ./$(DEPDIR)/sdrsharp.Plo -rm -f ./$(DEPDIR)/tci1x.Plo -rm -f ./$(DEPDIR)/trxmanager.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/aclog.Plo -rm -f ./$(DEPDIR)/amp_dummy.Plo -rm -f ./$(DEPDIR)/dummy.Plo -rm -f ./$(DEPDIR)/dummy_common.Plo -rm -f ./$(DEPDIR)/flrig.Plo -rm -f ./$(DEPDIR)/netampctl.Plo -rm -f ./$(DEPDIR)/netrigctl.Plo -rm -f ./$(DEPDIR)/netrotctl.Plo -rm -f ./$(DEPDIR)/quisk.Plo -rm -f ./$(DEPDIR)/rot_dummy.Plo -rm -f ./$(DEPDIR)/rot_pstrotator.Plo -rm -f ./$(DEPDIR)/sdrsharp.Plo -rm -f ./$(DEPDIR)/tci1x.Plo -rm -f ./$(DEPDIR)/trxmanager.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/dummy/netrotctl.c0000664000175000017500000002225215056640443012740 /* * Hamlib Netrotctl backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "iofunc.h" #define CMD_MAX 32 #define BUF_MAX 64 /* * Helper function with protocol return code parsing */ static int netrotctl_transaction(ROT *rot, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rotp = ROTPORT(rot); /* flush anything in the read buffer before command is sent */ rig_flush(rotp); ret = write_block(rotp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret < 0) { return ret; } if (!memcmp(buf, NETROTCTL_RET, strlen(NETROTCTL_RET))) { return atoi(buf + strlen(NETROTCTL_RET)); } return ret; } static int netrotctl_open(ROT *rot) { int ret; struct rot_state *rs = ROTSTATE(rot); hamlib_port_t *rotp = ROTPORT(rot); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } prot_ver = atoi(buf); #define ROTCTLD_PROT_VER 1 ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (prot_ver == 0) { return (RIG_OK); } // Prot 1 is tag=value format and should cover any needed additions do { char setting[32], value[1024]; ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } // ignore the rot_model if (strncmp(buf, "done", 4) == 0) { return (RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "min_az") == 0) { rs->min_az = rot->caps->min_az = atof(value); } else if (strcmp(setting, "max_az") == 0) { rs->max_az = rot->caps->max_az = atof(value); } else if (strcmp(setting, "min_el") == 0) { rs->min_el = rot->caps->min_el = atof(value); } else if (strcmp(setting, "max_el") == 0) { rs->max_el = rot->caps->max_el = atof(value); } else if (strcmp(setting, "south_zero") == 0) { rs->south_zero = atoi(value); } else if (strcmp(setting, "rot_type") == 0) { if (strcmp(value, "AzEl") == 0) { rot->caps->rot_type = ROT_TYPE_AZEL; } else if (strcmp(value, "Az") == 0) { rot->caps->rot_type = ROT_TYPE_AZIMUTH; } else if (strcmp(value, "El") == 0) { rot->caps->rot_type = ROT_TYPE_ELEVATION; } } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } } while (1); return RIG_OK; } static int netrotctl_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(ROTPORT(rot), (unsigned char *) "q\n", 2); return RIG_OK; } static int netrotctl_set_position(ROT *rot, azimuth_t az, elevation_t el) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %f %f\n", __func__, az, el); SNPRINTF(cmd, sizeof(cmd), "P %f %f\n", az, el); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *az = atof(buf); ret = read_string(ROTPORT(rot), (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *el = atof(buf); return RIG_OK; } static int netrotctl_stop(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "S\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_park(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "K\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_reset(ROT *rot, rot_reset_t reset) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "R %d\n", reset); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_move(ROT *rot, int direction, int speed) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "M %d %d\n", direction, speed); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static const char *netrotctl_get_info(ROT *rot) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } /* * NET rotctl capabilities. */ struct rot_caps netrotctl_caps = { ROT_MODEL(ROT_MODEL_NETROTCTL), .model_name = "NET rotctl", .mfg_name = "Hamlib", .version = "20221110.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .timeout = 2000, .retry = 3, .min_az = -180., .max_az = 180., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ /* .rot_init = netrotctl_init, */ /* .rot_cleanup = netrotctl_cleanup, */ .rot_open = netrotctl_open, .rot_close = netrotctl_close, .set_position = netrotctl_set_position, .get_position = netrotctl_get_position, .park = netrotctl_park, .stop = netrotctl_stop, .reset = netrotctl_reset, .move = netrotctl_move, .get_info = netrotctl_get_info, }; /* * S.A.T. rotator mimics net rotor but only minimal capabilities. * Fails to work with net rotor since it fails dump_state. */ static int satrotcrl_rot_init(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } struct rot_caps satrotctl_caps = { ROT_MODEL(ROT_MODEL_SATROTCTL), .model_name = "S.A.T. Satellite ctl", .mfg_name = "csntechnologies.net", .version = "20240609.0", .copyright = "LGPL", .status = RIG_STATUS_UNTESTED, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_NETWORK, .timeout = 400, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .rot_init = satrotcrl_rot_init, .set_position = netrotctl_set_position, .get_position = netrotctl_get_position, }; hamlib-4.6.5/rigs/dummy/dummy.h0000664000175000017500000000335315056640443012063 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DUMMY_H #define _DUMMY_H 1 #include "hamlib/rig.h" #include "token.h" /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rig_caps dummy_caps; extern struct rig_caps dummy_no_vfo_caps; extern struct rig_caps netrigctl_caps; extern struct rig_caps flrig_caps; extern struct rig_caps trxmanager_caps; extern struct rig_caps tci1x_caps; extern struct rig_caps aclog_caps; extern struct rig_caps sdrsharp_caps; extern struct rig_caps quisk_caps; int netrigctl_get_vfo_mode(RIG *); #endif /* _DUMMY_H */ hamlib-4.6.5/rigs/dummy/rot_pstrotator.c0000664000175000017500000003425615056640443014036 /* i Hamlib PSTRotator backend * Copyright (c) 2024 Michael Black W9MDB * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include #include "hamlib/rotator.h" #include "dummy_common.h" #include "rig.h" #include "register.h" #include "idx_builtin.h" #include "misc.h" #include "iofunc.h" #include "rot_pstrotator.h" #include "rotlist.h" #include "network.h" #define PSTROTATOR_ROT_FUNC 0 #define PSTROTATOR_ROT_LEVEL ROT_LEVEL_SPEED #define PSTROTATOR_ROT_PARM 0 #define PSTROTATOR_ROT_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN ) struct pstrotator_rot_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; rot_status_t status; int sockfd2; // the reply port for PSTRotator which is port+1 pthread_t threadid; int receiving; // true if we are receiving az/el data }; static int write_transaction(ROT *rot, char *cmd) { int try = rot->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = ROTPORT(rot); // This shouldn't ever happen...but just in case // We need to avoid an empty write as rotctld replies with blank line if (strlen(cmd) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); return (retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { char cmd2[64]; if (strchr(cmd, '\r') == NULL) { sprintf(cmd2, "%s\r", cmd); } retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return (-RIG_EIO); } } return RIG_OK; } static void set_timeout(int fd, int sec, int usec) { struct timeval timeout; timeout.tv_sec = sec; timeout.tv_usec = usec; //rig_debug(RIG_DEBUG_VERBOSE, "%s: sec=%d, usec=%d, timeout = %.6lf\n", __func__, // sec, usec, sec + usec / 1e6); if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: setsockopt failed: %s\n", __func__, strerror(errno)); } } void readPacket(int sockfd, char *buf, int buf_len, int expected) { struct sockaddr_in serverAddr; socklen_t addrLen = sizeof(serverAddr); buf[0] = 0; if (expected) { set_timeout(sockfd, 1, 0); } else { set_timeout(sockfd, 0, 0); } ssize_t n = recvfrom(sockfd, buf, buf_len, 0, (struct sockaddr *)&serverAddr, &addrLen); if (n < 0) { #ifdef _WIN32 int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK || err == WSAETIMEDOUT) { #if 0 if (expected) rig_debug(RIG_DEBUG_ERR, "%s: recvfrom timed out. Is PSTRotator Setup/UDP Control enabled?\n", __func__); #endif } else { rig_debug(RIG_DEBUG_ERR, "%s: recvfrom error %d: %s\n", __func__, err, strerror(errno)); } #else if (errno == EWOULDBLOCK || errno == EAGAIN) { if (expected) rig_debug(RIG_DEBUG_ERR, "%s: recvfrom timed out. Is PSTRotator Setup/UDP Control checked?\n", __func__); } else { rig_debug(RIG_DEBUG_ERR, "%s: recvfrom error: %s\n", __func__, strerror(errno)); } #endif n = 0; } buf[n] = '\0'; // Null-terminate the received data strtok(buf, "\r\n"); // get rid of CRs and such //if (n > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: buf=%s\n", __func__, buf); } } #if defined(HAVE_PTHREAD) #if 0 typedef struct pstrotator_handler_args_sw { int port; // port for reading PstRotator messages -- always +1 from base port } pstrotator_handler_args; typedef struct pstrotator_handler_priv_data_s { pthread_t thread_id; pstrotator_handler_args args; } pstrotator_handler_priv_data; #endif static void *pstrotator_handler_start(void *arg) { ROT *rot = (ROT *)arg; struct rot_state *rs = STATE(rot); struct pstrotator_rot_priv_data *priv = rs->priv; pstrotator_handler_priv_data *pstrotator_handler_priv; rs->pstrotator_handler_priv_data = calloc(1, sizeof(pstrotator_handler_priv_data)); if (rs->pstrotator_handler_priv_data == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: priv is NULL?\n", __func__); return NULL; } pstrotator_handler_priv = (pstrotator_handler_priv_data *) rs->pstrotator_handler_priv_data; pstrotator_handler_priv->args.rot = rot; pstrotator_handler_priv->pstrotator_handler_thread_run = 1; priv->receiving = 0; while (pstrotator_handler_priv->pstrotator_handler_thread_run) { int az = 0, el = 0; char buf[256]; readPacket(priv->sockfd2, buf, sizeof(buf), 1); if (strlen(buf) == 0) { hl_usleep(20 * 1000); continue; } //dump_hex((unsigned char *)buf, strlen(buf)); int n = sscanf(buf, "AZ:%g", &priv->az); n += sscanf(buf, "EL:%g", &priv->el); if (n > 0) { priv->receiving = 1; } if (priv->az != az && priv->el != el) { priv->status = ROT_STATUS_MOVING; } else if (priv->az < az) { priv->status = ROT_STATUS_MOVING_LEFT; } else if (priv->az > az) { priv->status = ROT_STATUS_MOVING_RIGHT; } else if (priv->el < el) { priv->status = ROT_STATUS_MOVING_DOWN; } else if (priv->el > el) { priv->status = ROT_STATUS_MOVING_UP; } else { priv->status = ROT_STATUS_NONE; } //if (n > 0) rig_debug(RIG_DEBUG_CACHE, "%s: az=%.1f, el=%.1f\n", __func__, priv->az, priv->el); } return NULL; } #endif static int pstrotator_rot_init(ROT *rot) { struct pstrotator_rot_priv_data *priv; struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rs->priv = (struct pstrotator_rot_priv_data *) calloc(1, sizeof(struct pstrotator_rot_priv_data)); if (!rs->priv) { return -RIG_ENOMEM; } priv = rs->priv; ROTPORT(rot)->type.rig = RIG_PORT_UDP_NETWORK; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; strcpy(ROTPORT(rot)->pathname, "192.168.56.1:12000"); return RIG_OK; } static int pstrotator_rot_cleanup(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(rs->priv); rs->priv = NULL; return RIG_OK; } static int pstrotator_rot_open(ROT *rot) { struct pstrotator_rot_priv_data *priv; int port = 0; int n1, n2, n3, n4; int sockfd; int retval; struct sockaddr_in clientAddr; struct rot_state *rs = ROTSTATE(rot); pthread_attr_t attr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct pstrotator_rot_priv_data *)rs->priv; //priv->port2 = rs->rotport; //priv->port2.type.rig = RIG_PORT_UDP_NETWORK; rig_debug(RIG_DEBUG_VERBOSE, "%s: pathname=%s\n", __func__, ROTPORT(rot)->pathname); sscanf(ROTPORT(rot)->pathname, "%d.%d.%d.%d:%d", &n1, &n2, &n3, &n4, &port); //sprintf(priv->port2.pathname, "%d.%d.%d.%d:%d", n1, n2, n3, n4, port+1); //rig_debug(RIG_DEBUG_VERBOSE, "%s: port2 pathname=%s\n", __func__, priv->port2.pathname); //network_open(&priv->port2, port+1); if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: socket failed: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } // Bind socket to client address memset(&clientAddr, 0, sizeof(clientAddr)); clientAddr.sin_family = AF_INET; clientAddr.sin_addr.s_addr = INADDR_ANY; clientAddr.sin_port = htons(12001); if (bind(sockfd, (const struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: bind failed: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } priv->sockfd2 = sockfd; set_timeout(priv->sockfd2, 1, 0); pthread_attr_init(&attr); retval = pthread_create(&priv->threadid, &attr, pstrotator_handler_start, rot); if (retval != 0) { rig_debug(RIG_DEBUG_ERR, "%s; pthread_create error: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } return RIG_OK; } static int pstrotator_rot_close(ROT *rot) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; pstrotator_handler_priv_data *pstrotator_handler_priv; pstrotator_handler_priv = (pstrotator_handler_priv_data *) ROTSTATE(rot)->pstrotator_handler_priv_data; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); pstrotator_handler_priv->pstrotator_handler_thread_run = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: waiting for thread to stop\n", __func__); pthread_join(priv->threadid, NULL); rig_debug(RIG_DEBUG_VERBOSE, "%s: thread stopped\n", __func__); priv->threadid = 0; return RIG_OK; } #if 0 static int pstrotator_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; default: return -RIG_EINVAL; } return RIG_OK; } #endif #if 0 static int pstrotator_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: SNPRINTF(val, val_len, "%s", priv->magic_conf); break; default: return -RIG_EINVAL; } return RIG_OK; } #endif #if 0 static int pstrotator_get_conf(ROT *rot, hamlib_token_t token, char *val) { return pstrotator_get_conf2(rot, token, val, 128); } #endif static int pstrotator_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); char cmd[64]; sprintf(cmd, "%f.2", az); write_transaction(rot, cmd); sprintf(cmd, "%f.2", el); write_transaction(rot, cmd); priv->az = az; priv->el = el; return RIG_OK; } /* * Get position of rotor, simulating slow rotation */ static int pstrotator_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); write_transaction(rot, "AZ?"); write_transaction(rot, "EL?"); hl_usleep(10 * 1000); *az = priv->az; *el = priv->el; return RIG_OK; } static int pstrotator_rot_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); write_transaction(rot, "1"); return RIG_OK; } static const char *pstrotator_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "PSTRotator"; } static int pstrotator_rot_get_status(ROT *rot, rot_status_t *status) { const struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; *status = priv->status; return RIG_OK; } /* * Dummy rotator capabilities. */ struct rot_caps pstrotator_caps = { ROT_MODEL(ROT_MODEL_PSTROTATOR), .model_name = "PstRotator", .mfg_name = "YO3DMU", .version = "20240613.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 1000, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .has_get_func = PSTROTATOR_ROT_FUNC, .has_set_func = PSTROTATOR_ROT_FUNC, .has_get_level = PSTROTATOR_ROT_LEVEL, .has_set_level = ROT_LEVEL_SET(PSTROTATOR_ROT_LEVEL), .has_get_parm = PSTROTATOR_ROT_PARM, .has_set_parm = ROT_PARM_SET(PSTROTATOR_ROT_PARM), //.level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .has_status = PSTROTATOR_ROT_STATUS, .rot_init = pstrotator_rot_init, .rot_cleanup = pstrotator_rot_cleanup, .rot_open = pstrotator_rot_open, .rot_close = pstrotator_rot_close, .set_position = pstrotator_rot_set_position, .get_position = pstrotator_rot_get_position, .park = pstrotator_rot_park, .get_info = pstrotator_rot_get_info, .get_status = pstrotator_rot_get_status, }; hamlib-4.6.5/rigs/dummy/netrigctl.c0000664000175000017500000021314215056640443012715 /* * Hamlib Netrigctl backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "iofunc.h" #include "misc.h" #include "num_stdio.h" #include "dummy.h" #define CMD_MAX 64 #define BUF_MAX 1024 #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EPROTO; else do {} while(0) struct netrigctl_priv_data { vfo_t vfo_curr; int rigctld_vfo_mode; vfo_t rx_vfo; vfo_t tx_vfo; }; int netrigctl_get_vfo_mode(RIG *rig) { struct netrigctl_priv_data *priv; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; return priv->rigctld_vfo_mode; } /* * Helper function with protocol return code parsing */ static int netrigctl_transaction(RIG *rig, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called len=%d\n", __func__, len); /* flush anything in the read buffer before command is sent */ rig_flush(rp); ret = write_block(rp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret < 0) { return ret; } if (strncmp(buf, NETRIGCTL_RET, strlen(NETRIGCTL_RET)) == 0) { return atoi(buf + strlen(NETRIGCTL_RET)); } return ret; } /* this will fill vfostr with the vfo value if the vfo mode is enabled * otherwise string will be null terminated * this allows us to use the string in snprintf in either mode */ static int netrigctl_vfostr(RIG *rig, char *vfostr, int len, vfo_t vfo) { struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); if (len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: len must be >=5, len=%d\n", __func__, len); return -RIG_EPROTO; } vfostr[0] = 0; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo==RIG_VFO_CURR, curr=%s\n", __func__, rig_strvfo(priv->vfo_curr)); vfo = priv->vfo_curr; if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } } else if (vfo == RIG_VFO_RX) { vfo = priv->rx_vfo; } else if (vfo == RIG_VFO_TX) { vfo = priv->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt=%d\n", __func__, STATE(rig)->vfo_opt); if (STATE(rig)->vfo_opt || priv->rigctld_vfo_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt vfo=%u\n", __func__, vfo); char *myvfo; switch (vfo) { case RIG_VFO_B: myvfo = "VFOB"; break; case RIG_VFO_C: myvfo = "VFOC"; break; case RIG_VFO_MAIN: myvfo = "Main"; break; case RIG_VFO_MAIN_A: myvfo = "MainA"; break; case RIG_VFO_MAIN_B: myvfo = "MainB"; break; case RIG_VFO_SUB: myvfo = "Sub"; break; case RIG_VFO_SUB_A: myvfo = "SubA"; break; case RIG_VFO_SUB_B: myvfo = "SubB"; break; case RIG_VFO_MEM: myvfo = "MEM"; break; default: myvfo = "VFOA"; } SNPRINTF(vfostr, len, " %s", myvfo); } return RIG_OK; } static int netrigctl_init(RIG *rig) { // cppcheck says leak here but it's freed in cleanup struct netrigctl_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct netrigctl_priv_data *)calloc(1, sizeof( struct netrigctl_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct netrigctl_priv_data)); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); /* * set arbitrary initial status * VFO will be updated in open call */ priv->vfo_curr = RIG_VFO_A; priv->rigctld_vfo_mode = 0; return RIG_OK; } static int netrigctl_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int parse_array_int(const char *s, const char *delim, int *array, int array_len) { char *p; char *dup = strdup(s); char *rest = dup; int n = 0; while ((p = strtok_r(rest, delim, &rest))) { if (n == array_len) // too many items { return n; } array[n] = atoi(p); //printf("%d\n", array[n]); ++n; } free(dup); return n; } int parse_array_double(const char *s, const char *delim, double *array, int array_len) { char *p; char *dup = strdup(s); char *rest = dup; int n = 0; while ((p = strtok_r(rest, delim, &rest))) { if (n == array_len) // too many items { return n; } array[n] = atof(p); //printf("%f\n", array[n]); ++n; } free(dup); return n; } static int netrigctl_open(RIG *rig) { int ret, i; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; ENTERFUNC; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; priv->rx_vfo = RIG_VFO_A; priv->tx_vfo = RIG_VFO_B; SNPRINTF(cmd, sizeof(cmd), "\\chk_vfo\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (sscanf(buf, "%d", &priv->rigctld_vfo_mode) == 1) { STATE(rig)->vfo_opt = priv->rigctld_vfo_mode; rig_debug(RIG_DEBUG_TRACE, "%s: chkvfo=%d\n", __func__, priv->rigctld_vfo_mode); } else if (ret == 2) { if (buf[0]) { sscanf(buf, "%d", &priv->rigctld_vfo_mode); } } else if (ret < 0) { rig_debug(RIG_DEBUG_WARN, "%s: chk_vfo error: %s\n", __func__, rigerror(ret)); } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown value returned from netrigctl_transaction=%d\n", __func__, ret); } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_mode=%d\n", __func__, priv->rigctld_vfo_mode); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } prot_ver = atoi(buf); #define RIGCTLD_PROT_VER 0 if (prot_ver < RIGCTLD_PROT_VER) { RETURNFUNC(-RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->deprecated_itu_region = atoi(buf); for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &(rs->rx_range_list[i].startf), &(rs->rx_range_list[i].endf), &(rs->rx_range_list[i].modes), &(rs->rx_range_list[i].low_power), &(rs->rx_range_list[i].high_power), &(rs->rx_range_list[i].vfo), &(rs->rx_range_list[i].ant) ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->rx_range_list[i])) { break; } } for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->tx_range_list[i].startf, &rs->tx_range_list[i].endf, &rs->tx_range_list[i].modes, &rs->tx_range_list[i].low_power, &rs->tx_range_list[i].high_power, &rs->tx_range_list[i].vfo, &rs->tx_range_list[i].ant ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->tx_range_list[i])) { break; } switch (i) { } rig->caps->tx_range_list1->startf = rs->tx_range_list[i].startf; rig->caps->tx_range_list1->endf = rs->tx_range_list[i].endf; rig->caps->tx_range_list1->modes = rs->tx_range_list[i].modes; rig->caps->tx_range_list1->low_power = rs->tx_range_list[i].low_power; rig->caps->tx_range_list1->high_power = rs->tx_range_list[i].high_power; rig->caps->tx_range_list1->vfo = rs->tx_range_list[i].vfo; rig->caps->tx_range_list1->ant = rs->tx_range_list[i].ant; } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->tuning_steps[i].modes, &rs->tuning_steps[i].ts); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS_END(rs->tuning_steps[i])) { break; } } for (i = 0; i < HAMLIB_FLTLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->filters[i].modes, &rs->filters[i].width); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FLT_END(rs->filters[i])) { break; } } #if 0 /* TODO */ chan_t chan_list[HAMLIB_CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_rit = rs->max_rit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_xit = rs->max_xit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_ifshift = rs->max_ifshift = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->announces = atoi(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->preamp[0], &rs->preamp[1], &rs->preamp[2], &rs->preamp[3], &rs->preamp[4], &rs->preamp[5], &rs->preamp[6]); rig->caps->preamp[0] = rs->preamp[0]; rig->caps->preamp[1] = rs->preamp[1]; rig->caps->preamp[2] = rs->preamp[2]; rig->caps->preamp[3] = rs->preamp[3]; rig->caps->preamp[4] = rs->preamp[4]; rig->caps->preamp[5] = rs->preamp[5]; rig->caps->preamp[6] = rs->preamp[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->preamp[ret] = rs->preamp[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->attenuator[0], &rs->attenuator[1], &rs->attenuator[2], &rs->attenuator[3], &rs->attenuator[4], &rs->attenuator[5], &rs->attenuator[6]); rig->caps->attenuator[0] = rs->attenuator[0]; rig->caps->attenuator[1] = rs->attenuator[1]; rig->caps->attenuator[2] = rs->attenuator[2]; rig->caps->attenuator[3] = rs->attenuator[3]; rig->caps->attenuator[4] = rs->attenuator[4]; rig->caps->attenuator[5] = rs->attenuator[5]; rig->caps->attenuator[6] = rs->attenuator[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->attenuator[ret] = rs->attenuator[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_func = rs->has_get_func = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_func = rs->has_set_func = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_level = rs->has_get_level = strtoll(buf, NULL, 0); #if 0 // don't think we need this anymore if (rs->has_get_level & RIG_LEVEL_RAWSTR) { /* include STRENGTH because the remote rig may be able to provide a front end emulation, if it can't then an -RIG_EINVAL will be returned */ rs->has_get_level |= RIG_LEVEL_STRENGTH; rig->caps->has_get_level |= RIG_LEVEL_STRENGTH; } #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_level = rs->has_set_level = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->has_get_parm = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_parm = rs->has_set_parm = strtoll(buf, NULL, 0); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { rs->mode_list |= rs->rx_range_list[i].modes; rs->vfo_list |= rs->rx_range_list[i].vfo; } for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { rs->mode_list |= rs->tx_range_list[i].modes; rs->vfo_list |= rs->tx_range_list[i].vfo; } if (rs->vfo_list == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_list empty, defaulting to A/B\n", __func__); rs->vfo_list = RIG_VFO_A | RIG_VFO_B; } if (prot_ver == 0) { RETURNFUNC(RIG_OK); } // otherwise we continue reading protocol 1 fields do { char setting[32], value[1024]; hamlib_port_t *pttp = PTTPORT(rig); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); strtok(buf, "\r\n"); // chop the EOL rig_debug(RIG_DEBUG_VERBOSE, "## %s\n", buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } if (strncmp(buf, "done", 4) == 0) { RETURNFUNC(RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "vfo_ops") == 0) { rig->caps->vfo_ops = STATE(rig)->vfo_ops = strtoll(value, NULL, 0); rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, rig->caps->vfo_ops); } else if (strcmp(setting, "ptt_type") == 0) { ptt_type_t temp = (ptt_type_t)strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type='%s'(%d)\n", __func__, value, temp); if (RIG_PTT_RIG_MICDATA == pttp->type.ptt || temp == RIG_PTT_RIG_MICDATA) { /* * remote PTT must always be RIG_PTT_RIG_MICDATA * if there is any PTT capability and we have not * locally overridden it */ pttp->type.ptt = RIG_PTT_RIG_MICDATA; rig->caps->ptt_type = STATE(rig)->ptt_type = RIG_PTT_RIG_MICDATA; rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, pttp->type.ptt); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type= %d\n", __func__, temp); pttp->type.ptt = temp; rig->caps->ptt_type = STATE(rig)->ptt_type = temp; } } else if (strcmp(setting, "targetable_vfo") == 0) { rig->caps->targetable_vfo = STATE(rig)->targetable_vfo = strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: targetable_vfo=0x%2x\n", __func__, rig->caps->targetable_vfo); } else if (strcmp(setting, "has_set_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_vfo = NULL; } } else if (strcmp(setting, "has_get_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_vfo = NULL; } } else if (strcmp(setting, "has_set_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_freq = NULL; } } else if (strcmp(setting, "has_get_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_freq = NULL; } } else if (strcmp(setting, "has_set_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_conf = NULL; } } else if (strcmp(setting, "has_get_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_conf = NULL; } } else if (strcmp(setting, "has_get_ant") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_ant = NULL; } } else if (strcmp(setting, "has_set_ant") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_ant = NULL; } } #if 0 // for the future else if (strcmp(setting, "has_set_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_trn = NULL; } } else if (strcmp(setting, "has_get_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_trn = NULL; } } #endif else if (strcmp(setting, "has_power2mW") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->power2mW = NULL; } } else if (strcmp(setting, "has_mW2power") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->mW2power = NULL; } } else if (strcmp(setting, "timeout") == 0) { // use the rig's timeout value plus 500ms for potential network delays rig->caps->timeout = strtol(value, NULL, 0) + 500; rig_debug(RIG_DEBUG_TRACE, "%s: timeout value = '%s', final timeout=%d\n", __func__, value, rig->caps->timeout); } else if (strcmp(setting, "rig_model") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%s\n", __func__, value); } else if (strcmp(setting, "rigctld_version") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rigctld_version=%s\n", __func__, value); } else if (strcmp(setting, "ctcss_list") == 0) { int n; double ctcss[CTCSS_LIST_SIZE]; rig->caps->ctcss_list = calloc(CTCSS_LIST_SIZE, sizeof(tone_t)); n = parse_array_double(value, " \n\r", ctcss, CTCSS_LIST_SIZE); for (i = 0; i < CTCSS_LIST_SIZE && ctcss[i] != 0; ++i) { rig->caps->ctcss_list[i] = ctcss[i] * 10; } if (n < CTCSS_LIST_SIZE) { rig->caps->ctcss_list[n] = 0; } } else if (strcmp(setting, "dcs_list") == 0) { int n; int dcs[DCS_LIST_SIZE + 1]; rig->caps->dcs_list = calloc(DCS_LIST_SIZE, sizeof(tone_t)); n = parse_array_int(value, " \n\r", dcs, DCS_LIST_SIZE); for (i = 0; i < DCS_LIST_SIZE && dcs[i] != 0; i++) { rig->caps->dcs_list[i] = dcs[i]; } if (n < DCS_LIST_SIZE) { rig->caps->dcs_list[n] = 0; } } else if (strcmp(setting, "agc_levels") == 0) { char *p = strtok(value, " "); rig->caps->agc_levels[0] = RIG_AGC_NONE; // default value gets overwritten rig->caps->agc_level_count = 0; while (p) { int agc_code; char agc_string[32]; int n = sscanf(p, "%d=%31s\n", &agc_code, agc_string); if (n == 2) { rig->caps->agc_levels[i++] = agc_code; rig->caps->agc_level_count++; rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has agc code=%d, level=%s\n", __func__, agc_code, agc_string); } else { rig_debug(RIG_DEBUG_ERR, "%s did not parse code=agc from '%s'\n", __func__, p); } rig_debug(RIG_DEBUG_VERBOSE, "%d=%s\n", agc_code, agc_string); p = strtok(NULL, " "); } } else if (strcmp(setting, "level_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); rig->caps->level_gran[i].min.f = rs->level_gran[i].min.f = min; rig->caps->level_gran[i].max.f = rs->level_gran[i].max.f = max; rig->caps->level_gran[i].step.f = rs->level_gran[i].step.f = step; } else { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); rig->caps->level_gran[i].min.i = rs->level_gran[i].min.i = min; rig->caps->level_gran[i].max.i = rs->level_gran[i].max.i = max; rig->caps->level_gran[i].step.i = rs->level_gran[i].step.i = step; } p = strtok(NULL, ";"); } } else if (strcmp(setting, "parm_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int idx, level; sscanf(p, "%d", &idx); level = rig_idx2setting(idx); rig->caps->parm_gran[i].step.s = 0; if (RIG_PARM_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); rig->caps->parm_gran[i].min.f = rs->parm_gran[i].min.f = min; rig->caps->parm_gran[i].max.f = rs->parm_gran[i].max.f = max; rig->caps->parm_gran[i].step.f = rs->parm_gran[i].step.f = step; } else if (RIG_PARM_IS_STRING(level)) { rig->caps->parm_gran[i].step.s = strdup(value); } else // must be INT { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); rig->caps->parm_gran[i].min.i = rs->parm_gran[i].min.i = min; rig->caps->parm_gran[i].max.i = rs->parm_gran[i].max.i = max; rig->caps->parm_gran[i].step.i = rs->parm_gran[i].step.i = step; } p = strtok(NULL, ";"); } } else if (strcmp(setting, "hamlib_version") == 0) { //printf("rigctld: %s\n", value); } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid dumpcaps line, expected 'setting=value', got '%s'\n", __func__, buf); } } while (1); if (rs->auto_power_on) { rig_set_powerstat(rig, 1); } RETURNFUNC(RIG_OK); } static int netrigctl_close(RIG *rig) { const struct rig_state *rs = STATE(rig); int ret; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rs->auto_power_off && rs->comm_state) { rig_set_powerstat(rig, 0); } ret = netrigctl_transaction(rig, "q\n", 2, buf); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: close error %s\n", __func__, rigerror(ret)); return ret; } rig_debug(RIG_DEBUG_ERR, "%s: done\n", __func__); usleep(10 * 1000); return RIG_OK; } static int netrigctl_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #if 1 // implement set_freq VFO later if it can be detected ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "F%s %"FREQFMT"\n", vfostr, freq); #else SNPRINTF(cmd, sizeof(cmd), "F %"FREQFMT"\n", freq); #endif ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s\n", __func__, strtok(cmd, "\r\n")); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; #if 0 // disable until we figure out if we can do this without breaking backwards compatibility char vfotmp[16]; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "f%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s, reply=%s\n", __func__, strtok(cmd, "\r\n"), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, freq)); #if 0 // implement set_freq VFO later if it can be detected ret = read_string(RIGPORT(rig), buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *vfotmp = rig_parse_vfo(buf); #endif return RIG_OK; } static int netrigctl_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "M%s %s %li\n", vfostr, rig_strrmode(mode), width); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "m%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *width = atoi(buf); return RIG_OK; } static int netrigctl_set_vfo(RIG *rig, vfo_t vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "V %s\n", rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd='%s'\n", __func__, cmd); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } priv->vfo_curr = vfo; // remember our vfo STATE(rig)->current_vfo = vfo; return ret; } static int netrigctl_get_vfo(RIG *rig, vfo_t *vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "v\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret == -RIG_ENAVAIL || ret == -RIG_ENIMPL) { // for rigs without get_vfo we'll use our saved vfo *vfo = priv->vfo_curr; return RIG_OK; } if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *vfo = rig_parse_vfo(buf); priv->vfo_curr = *vfo; return RIG_OK; } static int netrigctl_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; hamlib_port_t *pttp = PTTPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, ptt=%d, ptt_type=%d\n", __func__, rig_strvfo(vfo), ptt, pttp->type.ptt); if (pttp->type.ptt == RIG_PTT_NONE) { return RIG_OK; } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "T%s %d\n", vfostr, ptt); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s", __func__, cmd); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "t%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ptt = atoi(buf); return RIG_OK; } static int netrigctl_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcd%s\n", vfostr); /* FIXME */ ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *dcd = atoi(buf); return RIG_OK; } static int netrigctl_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "R%s %s\n", vfostr, rig_strptrshift(rptr_shift)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "r%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *rptr_shift = rig_parse_rptr_shift(buf); return RIG_OK; } static int netrigctl_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "O%s %ld\n", vfostr, rptr_offs); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "o%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rptr_offs = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "C%s %u\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "c%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "D%s %u\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "d%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_ctcss_sql%s %u\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_ctcss_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_dcs_sql%s %u\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcs_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "I%s %"FREQFMT"\n", vfostr, tx_freq); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "i%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq)); return RIG_OK; } static int netrigctl_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "X%s %s %li\n", vfostr, rig_strrmode(tx_mode), tx_width); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "x%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tx_width = atoi(buf); return RIG_OK; } static int netrigctl_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, vfotx=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "S%s %d %s\n", vfostr, split, rig_strvfo(tx_vfo)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "s%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *split = atoi(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_vfo = rig_parse_vfo(buf); return RIG_OK; } static int netrigctl_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "J%s %ld\n", vfostr, rit); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "j%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rit = atoi(buf); return RIG_OK; } static int netrigctl_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Z%s %ld\n", vfostr, xit); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "z%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *xit = atoi(buf); return RIG_OK; } static int netrigctl_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "N%s %ld\n", vfostr, ts); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "n%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ts = atoi(buf); return RIG_OK; } static int netrigctl_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "U%s %s %i\n", vfostr, rig_strfunc(func), status); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (strlen(rig_strfunc(func)) == 0) { return -RIG_ENAVAIL; } SNPRINTF(cmd, sizeof(cmd), "u%s %s\n", vfostr, rig_strfunc(func)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int netrigctl_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char lstr[32]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "L%s %s %s\n", vfostr, rig_strlevel(level), lstr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "l%s %s\n", vfostr, rig_strlevel(level)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = atof(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_powerstat(RIG *rig, powerstat_t status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\set_powerstat %d\n", status); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_powerstat(RIG *rig, powerstat_t *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\get_powerstat\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { int offset = 0; // see if there is a RPRT answer to make SDR++ happy if (strstr(buf, "RPRT")) { offset = 4; } *status = atoi(&buf[offset]); } else { // was causing problems with sdr++ since it does not have PS command // a return of 1 should indicate there is no powerstat command available // so we fake the ON status // also a problem with Flex 6xxx and Log4OM not working due to lack of PS command if (ret != -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_ON\n", __func__, ret); *status = RIG_POWER_ON; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_OFF\n", __func__, ret); *status = RIG_POWER_OFF; } } return RIG_OK; // always return RIG_OK } static int netrigctl_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char pstr[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } SNPRINTF(cmd, sizeof(cmd), "P %s %s\n", rig_strparm(parm), pstr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_parm(RIG *rig, setting_t parm, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p %s\n", rig_strparm(parm)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_PARM_IS_FLOAT(parm)) { val->f = atoi(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; int i_ant = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d\n", __func__, ant, option.i); switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: more than 4 antennas? ant=0x%02x\n", __func__, ant); } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Y%s %d %d\n", vfostr, i_ant, option.i); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (ant == RIG_ANT_CURR) { SNPRINTF(cmd, sizeof(cmd), "y%s\n", vfostr); } else { SNPRINTF(cmd, sizeof(cmd), "y%s %u\n", vfostr, ant); } ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: buf='%s'\n", __func__, buf); ret = sscanf(buf, "%u\n", ant_curr); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 ant integer in '%s', got %d\n", __func__, buf, ret); } if (ant != RIG_ANT_CURR) { ret = sscanf(buf, "%d\n", &option->i); } if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d\n", &(option->i)); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } return RIG_OK; } static int netrigctl_set_bank(RIG *rig, vfo_t vfo, int bank) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "B %d\n", bank); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "E%s %d\n", vfostr, ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "e %s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ch = atoi(buf); return RIG_OK; } static int netrigctl_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "g %s %d\n", rig_strscan(scan), ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "G%s %s\n", vfostr, rig_strvfop(op)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { return -RIG_ENIMPL; } static int netrigctl_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { return -RIG_ENIMPL; } static const char *netrigctl_get_info(RIG *rig) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } static int netrigctl_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { int ret, len; char *cmdp; const char cmd[] = "\\send_dtmf "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + digits + \n + \0) len = strlen(cmd) + strlen(digits) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, digits); ret = netrigctl_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\recv_dtmf\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > *length) { ret = *length; } strncpy(digits, buf, ret); *length = ret; digits [ret] = '\0'; return RIG_OK; } static int netrigctl_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\send_voice_mem %d\n", ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int ret, len; char *cmdp; const char cmd[] = "\\send_morse "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + msg + \n + \0) len = strlen(cmd) + strlen(msg) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, msg); ret = netrigctl_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_stop_morse(RIG *rig, vfo_t vfo) { int ret; char cmd[] = "\\stop_morse\n"; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_vfo_opt(RIG *rig, int status) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_vfo_opt %d\n", status); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } STATE(rig)->vfo_opt = status; return RIG_OK; } #if 0 // for the futurem -- would have to poll to get the pushed data static int netrigctl_set_trn(RIG *rig, int trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_trn %s\n", trn ? "ON" : "OFF"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int netrigctl_get_trn(RIG *rig, int *trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_trn\n"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } if (strstr(buf, "OFF")) { *trn = RIG_TRN_OFF; } else if (strstr(buf, "RIG")) { *trn = RIG_TRN_RIG; } else if (strstr(buf, "POLL")) { *trn = RIG_TRN_POLL; } else { rig_debug(RIG_DEBUG_ERR, "%s: Expected OFF, RIG, or POLL, got '%s'\n", __func__, buf); ret = -RIG_EINVAL; } RETURNFUNC(ret); } #endif static int netrigctl_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\mW2power %u %.0f %s\n", mwpower, freq, rig_strrmode(mode)); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *power = atof(buf); RETURNFUNC(RIG_OK); } static int netrigctl_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char cmdbuf[64]; char buf[BUF_MAX]; int ret; ENTERFUNC; // we shouldn't need any precision than microwatts SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\power2mW %.3f %.0f %s\n", power, freq, rig_strrmode(mode)); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *mwpower = atof(buf); RETURNFUNC(RIG_OK); } int netrigctl_password(RIG *rig, const char *key1) { char cmdbuf[256]; char buf[BUF_MAX]; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s\n", __func__, key1); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1); retval = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (retval != RIG_OK) { retval = -RIG_EPROTO; } RETURNFUNC(retval); } int netrigctl_set_lock_mode(RIG *rig, int lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_lock_mode %d\n", lock); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } return (RIG_OK); } int netrigctl_get_lock_mode(RIG *rig, int *lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_lock_mode\n"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret == 0) { return -RIG_EPROTO; } sscanf(buf, "%d", lock); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); return (RIG_OK); } int netrigctl_send_raw(RIG *rig, char *s) { int ret; char buf[BUF_MAX]; ret = netrigctl_transaction(rig, s, strlen(s), buf); return ret; } /* * Netrigctl rig capabilities. */ struct rig_caps netrigctl_caps = { RIG_MODEL(RIG_MODEL_NETRIGCTL), .model_name = "NET rigctl", .mfg_name = "Hamlib", .version = "20250211.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NETWORK, .timeout = 10000, /* enough for the worst rig we have */ .retry = 5, /* following fields updated in rig_state at opening time */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { }, .transceive = RIG_TRN_OFF, .attenuator = { }, .preamp = { }, .rx_range_list2 = { RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { }, .filters = { RIG_FLT_END, }, .max_rit = 0, .max_xit = 0, .max_ifshift = 0, .priv = NULL, .rig_init = netrigctl_init, .rig_cleanup = netrigctl_cleanup, .rig_open = netrigctl_open, .rig_close = netrigctl_close, .set_freq = netrigctl_set_freq, .get_freq = netrigctl_get_freq, .set_mode = netrigctl_set_mode, .get_mode = netrigctl_get_mode, .set_vfo = netrigctl_set_vfo, .get_vfo = netrigctl_get_vfo, .set_powerstat = netrigctl_set_powerstat, .get_powerstat = netrigctl_get_powerstat, .set_level = netrigctl_set_level, .get_level = netrigctl_get_level, .set_func = netrigctl_set_func, .get_func = netrigctl_get_func, .set_parm = netrigctl_set_parm, .get_parm = netrigctl_get_parm, .get_info = netrigctl_get_info, .set_ptt = netrigctl_set_ptt, .get_ptt = netrigctl_get_ptt, .get_dcd = netrigctl_get_dcd, .set_rptr_shift = netrigctl_set_rptr_shift, .get_rptr_shift = netrigctl_get_rptr_shift, .set_rptr_offs = netrigctl_set_rptr_offs, .get_rptr_offs = netrigctl_get_rptr_offs, .set_ctcss_tone = netrigctl_set_ctcss_tone, .get_ctcss_tone = netrigctl_get_ctcss_tone, .set_dcs_code = netrigctl_set_dcs_code, .get_dcs_code = netrigctl_get_dcs_code, .set_ctcss_sql = netrigctl_set_ctcss_sql, .get_ctcss_sql = netrigctl_get_ctcss_sql, .set_dcs_sql = netrigctl_set_dcs_sql, .get_dcs_sql = netrigctl_get_dcs_sql, .set_split_freq = netrigctl_set_split_freq, .get_split_freq = netrigctl_get_split_freq, .set_split_mode = netrigctl_set_split_mode, .get_split_mode = netrigctl_get_split_mode, .set_split_vfo = netrigctl_set_split_vfo, .get_split_vfo = netrigctl_get_split_vfo, .set_rit = netrigctl_set_rit, .get_rit = netrigctl_get_rit, .set_xit = netrigctl_set_xit, .get_xit = netrigctl_get_xit, .set_ts = netrigctl_set_ts, .get_ts = netrigctl_get_ts, .set_ant = netrigctl_set_ant, .get_ant = netrigctl_get_ant, .set_bank = netrigctl_set_bank, .set_mem = netrigctl_set_mem, .get_mem = netrigctl_get_mem, .vfo_op = netrigctl_vfo_op, .scan = netrigctl_scan, .send_dtmf = netrigctl_send_dtmf, .recv_dtmf = netrigctl_recv_dtmf, .send_morse = netrigctl_send_morse, .send_voice_mem = netrigctl_send_voice_mem, .stop_morse = netrigctl_stop_morse, .set_channel = netrigctl_set_channel, .get_channel = netrigctl_get_channel, .set_vfo_opt = netrigctl_set_vfo_opt, //.set_trn = netrigctl_set_trn, //.get_trn = netrigctl_get_trn, .power2mW = netrigctl_power2mW, .mW2power = netrigctl_mW2power, .password = netrigctl_password, .set_lock_mode = netrigctl_set_lock_mode, .get_lock_mode = netrigctl_get_lock_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/dummy/rot_dummy.h0000664000175000017500000000307015056640443012743 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_DUMMY_H #define _ROT_DUMMY_H 1 #include "rotator.h" #include "token.h" /* backend conf */ #define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rot_caps dummy_rot_caps; extern struct rot_caps netrotctl_caps; extern struct rot_caps pstrotator; extern struct rot_caps satrotctl_caps; #endif /* _ROT_DUMMY_H */ hamlib-4.6.5/rigs/dummy/sdrsharp.c0000664000175000017500000003214415056640443012551 /* * Hamlib rigctld backend - works with SDR#'s gpredict plugin for example * Copyright (c) 2023 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define TRUE 1 #define FALSE 0 #define MAXCMDLEN 128 #define MAXXMLLEN 128 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:4532" #define SDRSHARP_VFOS (RIG_VFO_A) #define SDRSHARP_MODES (RIG_MODE_NONE) struct sdrsharp_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * read_transaction * Assumes rig!=NULL, xml!=NULL, xml_len>=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = "\n"; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected sdrsharp responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { // rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int sdrsharp_transaction(RIG *rig, char *cmd, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; set_transaction_active(rig); if (value) { value[0] = 0; } do { int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } if (value) { read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK strncpy(value, xml, value_len); } } while (((value && strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * sdrsharp_init * Assumes rig!=NULL */ static int sdrsharp_init(RIG *rig) { struct sdrsharp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct sdrsharp_priv_data *)calloc(1, sizeof( struct sdrsharp_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct sdrsharp_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); RETURNFUNC(RIG_OK); } /* * sdrsharp_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int sdrsharp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct sdrsharp_priv_data *priv = (struct sdrsharp_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = "f\n"; int retval; retval = sdrsharp_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: READBMF failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } *freq = 0; sscanf(value, "%lf", freq); if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else // future support in SDRSHARP maybe? { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * sdrsharp_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_open(RIG *rig) { int retval; char value[MAXARGLEN]; ENTERFUNC; value[0] = '?'; value[1] = 0; freq_t freq; retval = sdrsharp_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: sdrsharp_get_freq not working!!\n", __func__); RETURNFUNC(-RIG_EPROTO); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); RETURNFUNC(retval); } /* * sdrsharp_close * Assumes rig!=NULL */ static int sdrsharp_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * sdrsharp_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_cleanup(RIG *rig) { struct sdrsharp_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct sdrsharp_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_sdrsharp was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_sdrsharp) { free(modeMap[i].mode_sdrsharp); modeMap[i].mode_sdrsharp = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * sdrsharp_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd[MAXARGLEN]; char value[1024]; //struct sdrsharp_priv_data *priv = (struct sdrsharp_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } #if 0 if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } #endif SNPRINTF(cmd, sizeof(cmd), "F %.0lf\n", freq); retval = sdrsharp_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(value, "RPRT %d", &retval); RETURNFUNC2(retval); } /* * sdrsharp_get_vfo * assumes rig!=NULL, vfo != NULL */ static int sdrsharp_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = RIG_VFO_A; RETURNFUNC(RIG_OK); } struct rig_caps sdrsharp_caps = { RIG_MODEL(RIG_MODEL_SDRSHARP), .model_name = "SDR#/gpredict", .mfg_name = "Airspy", .version = "20230127.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 2, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = SDRSHARP_MODES, .low_power = -1, .high_power = -1, SDRSHARP_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = SDRSHARP_MODES, .low_power = -1, .high_power = -1, SDRSHARP_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {SDRSHARP_MODES, 1}, {SDRSHARP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = sdrsharp_init, .rig_open = sdrsharp_open, .rig_close = sdrsharp_close, .rig_cleanup = sdrsharp_cleanup, .get_vfo = sdrsharp_get_vfo, .set_freq = sdrsharp_set_freq, .get_freq = sdrsharp_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/dummy/flrig.h0000664000175000017500000000201215056640443012022 /* * Hamlib FLRig backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLRIG_H #define _FLRIG_H 1 #include "hamlib/rig.h" #define EOM "\r" #define TRUE 1 #define FALSE 0 extern struct rig_caps flrig_caps; #endif /* _FLRIG_H */ hamlib-4.6.5/rigs/dummy/dummy_common.c0000664000175000017500000000351515056640443013426 /* * Hamlib Dummy backend - shared routines * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann * Copyright (c) 2020 by Mikael Nousiainen * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include #include "hamlib/rig.h" struct ext_list *alloc_init_ext(const struct confparams *cfp) { struct ext_list *elp; int i, nb_ext; if (cfp == NULL) { return NULL; } for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++) ; elp = calloc((nb_ext + 1), sizeof(struct ext_list)); if (!elp) { return NULL; } for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++) { elp[i].token = cfp[i].token; /* value reset already by calloc */ } /* last token in array is set to 0 by calloc */ return elp; } struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token) { int i; if (elp == NULL) { return NULL; } for (i = 0; elp[i].token != 0; i++) { if (elp[i].token == token) { return &elp[i]; } } return NULL; } hamlib-4.6.5/rigs/dummy/flrig.c0000664000175000017500000022763615056640443012042 /* * Hamlib FLRig backend - main file * Copyright (c) 2017 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include #include "dummy_common.h" #include "flrig.h" #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 8192 #define MAXXMLLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:12345" #define FLRIG_VFOS (RIG_VFO_A|RIG_VFO_B) #define FLRIG_MODES (RIG_MODE_AM | RIG_MODE_PKTAM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_SSB | RIG_MODE_LSB | RIG_MODE_USB |\ RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_FMN | RIG_MODE_PKTFM |\ RIG_MODE_C4FM | RIG_MODE_DSTAR) #define FLRIG_LEVELS (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_MICGAIN | RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER_METER | RIG_LEVEL_RFPOWER_METER_WATTS | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR) #define FLRIG_PARM (TOK_FLRIG_VERIFY_FREQ|TOK_FLRIG_VERIFY_PTT) #define streq(s1,s2) (strcmp(s1,s2)==0) static int flrig_init(RIG *rig); static int flrig_open(RIG *rig); static int flrig_close(RIG *rig); static int flrig_cleanup(RIG *rig); static int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int flrig_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int flrig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int flrig_get_vfo(RIG *rig, vfo_t *vfo); static int flrig_set_vfo(RIG *rig, vfo_t vfo); static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int flrig_set_func(RIG *rig, vfo_t vfo, setting_t setting, int status); static int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int flrig_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int flrig_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int flrig_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int flrig_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int flrig_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int flrig_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); static const char *flrig_get_info(RIG *rig); static int flrig_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int flrig_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); struct flrig_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from flrig */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ int has_verify_cmds; // has the verify cmd in FLRig 1.3.54.1 or higher float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; int get_SWR; int has_get_modeB; /* True if this function is available */ int has_get_bwB; /* True if this function is available */ int has_set_bwB; /* True if this function is available */ }; /* level's and parm's tokens */ #define TOK_FLRIG_VERIFY_FREQ TOKEN_BACKEND(1) #define TOK_FLRIG_VERIFY_PTT TOKEN_BACKEND(2) static const struct confparams flrig_ext_parms[] = { { TOK_FLRIG_VERIFY_FREQ, "VERIFY_FREQ", "Verify set_freq", "If true will verify set_freq otherwise is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { TOK_FLRIG_VERIFY_PTT, "VERIFY_PTT", "Verify set_ptt", "If true will verify set_ptt otherwise set_ptt is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; struct rig_caps flrig_caps = { RIG_MODEL(RIG_MODEL_FLRIG), .model_name = "", .mfg_name = "FLRig", .version = "20250107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 5000, .retry = 2, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_TUNER, .set_func = flrig_set_func, .has_get_level = FLRIG_LEVELS, .has_set_level = RIG_LEVEL_SET(FLRIG_LEVELS), .has_get_parm = FLRIG_PARM, .has_set_parm = RIG_PARM_SET(FLRIG_PARM), .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = FLRIG_MODES, .low_power = -1, .high_power = -1, FLRIG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = FLRIG_MODES, .low_power = -1, .high_power = -1, FLRIG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {FLRIG_MODES, 1}, {FLRIG_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .extparms = flrig_ext_parms, .rig_init = flrig_init, .rig_open = flrig_open, .rig_close = flrig_close, .rig_cleanup = flrig_cleanup, .set_freq = flrig_set_freq, .get_freq = flrig_get_freq, .set_mode = flrig_set_mode, .get_mode = flrig_get_mode, .set_vfo = flrig_set_vfo, .get_vfo = flrig_get_vfo, .get_info = flrig_get_info, .set_ptt = flrig_set_ptt, .get_ptt = flrig_get_ptt, .set_split_mode = flrig_set_split_mode, .set_split_freq = flrig_set_split_freq, .get_split_freq = flrig_get_split_freq, .set_split_vfo = flrig_set_split_vfo, .get_split_vfo = flrig_get_split_vfo, .set_split_freq_mode = flrig_set_split_freq_mode, .get_split_freq_mode = flrig_get_split_freq_mode, .set_level = flrig_set_level, .get_level = flrig_get_level, .set_ext_parm = flrig_set_ext_parm, .get_ext_parm = flrig_get_ext_parm, .power2mW = flrig_power2mW, .mW2power = flrig_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //Structure for mapping flrig dynamic modes to hamlib modes //flrig displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_flrig; }; //FLRig will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, NULL}, {RIG_MODE_LSB, NULL}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, NULL}, {RIG_MODE_PKTAM, NULL}, {RIG_MODE_FM, NULL}, {RIG_MODE_PKTFM, NULL}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, NULL}, {RIG_MODE_CWR, NULL}, {RIG_MODE_RTTY, NULL}, {RIG_MODE_RTTYR, NULL}, {RIG_MODE_C4FM, NULL}, {RIG_MODE_DSTAR, NULL}, {RIG_MODE_USBD1, NULL}, {RIG_MODE_USBD2, NULL}, {RIG_MODE_USBD3, NULL}, {RIG_MODE_LSBD1, NULL}, {RIG_MODE_LSBD2, NULL}, {RIG_MODE_LSBD3, NULL}, {0, NULL} }; // Fallback mappings between modes struct s_fmodeMap { rmode_t mode_flrig; char *old_mode_hamlib; char *new_mode_hamlib; }; // Some radios (icom) provide PKT data on LSB/USB-D1 by default. Add these modes. static struct s_fmodeMap fmodeMap[] = { { RIG_MODE_PKTLSB, "PKTLSB", "LSB-D1" }, { RIG_MODE_PKTUSB, "PKTUSB", "USB-D1" }, {0, NULL, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /*Rather than use some huge XML library we only need a few things * So we'll hand craft them * xml_build takes a value and returns an xml string for FLRig */ // cppcheck-suppress constParameterPointer static char *xml_build(RIG *rig, char *cmd, char *value, char *xmlbuf, int xmlbuflen) { char xml[4096]; // we shouldn't need more the 4096 bytes for this char tmp[32]; char *header; // We want at least a 4K buf to play with if (xmlbuflen < 4096) { rig_debug(RIG_DEBUG_ERR, "%s: xmllen < 4096\n", __func__); return NULL; } header = "POST /RPC2 HTTP/1.1\r\n" "User-Agent: XMLRPC++ 0.8\r\n" "Host: 127.0.0.1:12345\r\n" "Content-type: text/xml\r\n"; SNPRINTF(xmlbuf, xmlbuflen, "%s", header); SNPRINTF(xml, sizeof(xml), "\r\n\r\n", RIGPORT(rig)->client_port); strncat(xml, "", sizeof(xml) - 1); strncat(xml, cmd, sizeof(xml) - strlen(xml) - 1); strncat(xml, "\r\n", sizeof(xml) - strlen(xml) - 1); if (value && strlen(value) > 0) { strncat(xml, value, sizeof(xml) - 1); } strncat(xml, "\r\n", sizeof(xml) - 1); strncat(xmlbuf, "Content-length: ", xmlbuflen - 1); SNPRINTF(tmp, sizeof(tmp), "%d\r\n\r\n", (int)strlen(xml)); strncat(xmlbuf, tmp, xmlbuflen - 1); strncat(xmlbuf, xml, xmlbuflen - 1); return xmlbuf; } /*This is a very crude xml parse specific to what we need from FLRig * This works for strings, doubles, I4-type values, and arrays * Arrays are returned pipe delimited */ static char *xml_parse2(char *xml, char *value, int valueLen) { char *delims = "<>\r\n"; char *xmltmp = strdup(xml); //rig_debug(RIG_DEBUG_TRACE, "%s: xml='%s'\n", __func__,xml); char *pr = xml; char *p = strtok_r(xmltmp, delims, &pr); value[0] = 0; while (p) { if (streq(p, "value")) { p = strtok_r(NULL, delims, &pr); if (streq(p, "array")) { continue; } if (streq(p, "/value")) { continue; } // empty value if (streq(p, "i4") || streq(p, "double") || streq(p, "int") || streq(p, "string")) { p = strtok_r(NULL, delims, &pr); } else if (streq(p, "array")) { strtok_r(NULL, delims, &pr); p = strtok_r(NULL, delims, &pr); } if (strlen(value) + strlen(p) + 1 < valueLen) { if (value[0] != 0) { strcat(value, "|"); } strcat(value, p); } else // we'll just stop adding stuff { rig_debug(RIG_DEBUG_ERR, "%s: max value length exceeded\n", __func__); } } else { p = strtok_r(NULL, delims, &pr); } } rig_debug(RIG_DEBUG_TRACE, "%s: value returned='%s'\n", __func__, value); if (rig_need_debug(RIG_DEBUG_WARN) && value != NULL && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: xml='%s'\n", __func__, xml); } free(xmltmp); return value; } /* * xml_parse * Assumes xml!=NULL, value!=NULL, value_len big enough * returns the string value contained in the xml string */ static char *xml_parse(char *xml, char *value, int value_len) { char *next; char *pxml; /* first off we should have an OK on the 1st line */ if (strstr(xml, " 200 OK") == NULL) { return (NULL); } rig_debug(RIG_DEBUG_TRACE, "%s XML:\n%s\n", __func__, xml); // find the xml skipping the other stuff above it pxml = strstr(xml, "=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = ""; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected flrig responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } rig_debug(RIG_DEBUG_TRACE, "%s: before read_string\n", __func__); int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); // "", 17,0,1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, tmp_buf); // if our first response we should see the HTTP header if (strlen(xml) == 0 && strstr(tmp_buf, "HTTP/1.1 200 OK") == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Expected 'HTTP/1.1 200 OK', got '%s'\n", __func__, tmp_buf); continue; // we'll try again } if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); // Slow down just a bit -- not sure this is needed anymore but not a big deal here // hl_usleep(2 * 1000); // try without this retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int flrig_transaction(RIG *rig, char *cmd, char *cmd_arg, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; set_transaction_active(rig); if (value) { value[0] = 0; } do { char *pxml; int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } pxml = xml_build(rig, cmd, cmd_arg, xml, sizeof(xml)); retval = write_transaction(rig, pxml, strlen(pxml)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK // we get an unknown response if function does not exist if (strstr(xml, "unknown")) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ENAVAIL); } if (strstr(xml, "get_bw") && strstr(xml, "NONE")) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ENAVAIL); } if (value) { xml_parse(xml, value, value_len); } } while (((value && strlen(value) == 0) || (strlen(xml) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * flrig_init * Assumes rig!=NULL */ static int flrig_init(RIG *rig) { struct flrig_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct flrig_priv_data *)calloc(1, sizeof( struct flrig_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct flrig_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; priv->get_SWR = 1; // we'll try getSWR once to see if it works if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); priv->ext_parms = alloc_init_ext(flrig_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } RETURNFUNC(RIG_OK); } /* * modeMapGetFLRig * Assumes mode!=NULL * Return the string for FLRig for the given hamlib mode */ static const char *modeMapGetFLRig(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_flrig == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_flrig='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_flrig); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_flrig) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_flrig); return (modeMap[i].mode_flrig); } } rig_debug(RIG_DEBUG_ERR, "%s: FlRig does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given FLRig string */ static rmode_t modeMapGetHamlib(const char *modeFLRig) { int i; char modeFLRigCheck[64]; SNPRINTF(modeFLRigCheck, sizeof(modeFLRigCheck), "|%s|", modeFLRig); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeFLRigCheck, modeMap[i].mode_flrig); if (modeMap[i].mode_flrig && strstr(modeMap[i].mode_flrig, modeFLRigCheck)) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeFLRig); return (RIG_MODE_NONE); } /* * modeMapAdd * Assumes modes!=NULL */ static void modeMapAdd(rmode_t *modes, rmode_t mode_hamlib, char *mode_flrig, int force) { int i; int len1; rig_debug(RIG_DEBUG_TRACE, "%s:mode_flrig=%s\n", __func__, mode_flrig); // if we already have it just return // unless forced where we want to add additional hamlib->flrig mapping // for flrig mode that already exists in map // // We get ERROR if the mode is not known so non-ERROR is OK if (!force && modeMapGetHamlib(mode_flrig) != RIG_MODE_NONE) { return; } len1 = strlen(mode_flrig) + 3; /* bytes needed for allocating */ for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_hamlib == mode_hamlib) { int len2; *modes |= modeMap[i].mode_hamlib; /* we will pipe delimit all the entries for easier matching */ /* all entries will have pipe symbol on both sides */ if (modeMap[i].mode_flrig == NULL) { modeMap[i].mode_flrig = calloc(1, len1); if (modeMap[i].mode_flrig == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error allocating memory for modeMap\n", __func__); return; } } len2 = strlen(modeMap[i].mode_flrig); /* current len w/o null */ modeMap[i].mode_flrig = realloc(modeMap[i].mode_flrig, strlen(modeMap[i].mode_flrig) + len1); if (strlen(modeMap[i].mode_flrig) == 0) { modeMap[i].mode_flrig[0] = '|'; } strncat(modeMap[i].mode_flrig, mode_flrig, len1 + len2); strncat(modeMap[i].mode_flrig, "|", len1 + len2); rig_debug(RIG_DEBUG_TRACE, "%s: Adding mode=%s, index=%d, result=%s\n", __func__, mode_flrig, i, modeMap[i].mode_flrig); return; } } } /* * flrig_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_open(RIG *rig) { int retval; char value[MAXXMLLEN]; //char arg[MAXXMLLEN]; rmode_t modes; char *p; char *pr; split_t split; vfo_t tx_vfo; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); retval = flrig_transaction(rig, "main.get_version", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_version failed: %s\nAssuming version < 1.3.54", __func__, rigerror(retval)); // we fall through and assume old version } int v1 = 0, v2 = 0, v3 = 0, v4 = 0; sscanf(value, "%d.%d.%d.%d", &v1, &v2, &v3, &v4); char version[32]; sprintf(version, "%03d%03d%03d%03d", v1, v2, v3, v4); int iversion = 0; sscanf(version, "%d", &iversion); rig_debug(RIG_DEBUG_VERBOSE, "%s: version='%s'=%d\n", __func__, version, iversion); priv->has_verify_cmds = 0; if (iversion >= 1003054000) // 1.3.54 or greater { priv->has_verify_cmds = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_vfoA/ptt is available\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s FlRig version %s\n", __func__, value); retval = flrig_transaction(rig, "rig.get_xcvr", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_xcvr failed,,,not fatal: %s\n", __func__, rigerror(retval)); } strncpy(priv->info, value, sizeof(priv->info)); rig_debug(RIG_DEBUG_VERBOSE, "Transceiver=%s\n", value); char model_name[256]; snprintf(model_name,sizeof(model_name), "%.248s(%s)", value, "FLRig"); rig->caps->model_name = strdup(model_name); STATE(rig)->model_name = strdup(model_name); /* see if get_pwrmeter_scale is available */ retval = flrig_transaction(rig, "rig.get_pwrmeter_scale", NULL, value, sizeof(value)); priv->powermeter_scale = 1; // default if (retval == RIG_OK) { priv->powermeter_scale = atof(value); } /* see if get_modeA is available */ retval = flrig_transaction(rig, "rig.get_modeA", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_get_modeA = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeA is not available=%s\n", __func__, value); } else { priv->has_get_modeA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeA is available\n", __func__); } /* see if get_modeB is available */ retval = flrig_transaction(rig, "rig.get_modeB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_get_modeB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeB is not available=%s\n", __func__, value); } else { priv->has_get_modeB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeB is available\n", __func__); } freq_t freq; retval = flrig_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_get_freq not working!!\n", __func__); RETURNFUNC(-RIG_EPROTO); } /* see if get_bwA is available */ retval = flrig_transaction(rig, "rig.get_bwA", NULL, value, sizeof(value)); int dummy; if (retval == RIG_ENAVAIL || value[0] == 0 || sscanf(value, "%d", &dummy) <= 0) // must not have it { priv->has_get_bwA = 0; priv->has_get_bwB = 0; // if we don't have A then surely we don't have B either priv->has_set_bwA = 0; // and we don't have set functions either priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwA/B is not available=%s\n", __func__, value); } else { priv->has_get_bwA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwA is available=%s\n", __func__, value); } /* see if set_bwA is available */ retval = flrig_transaction(rig, "rig.set_bwA", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_set_bwA = 0; priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwA is not available=%s\n", __func__, value); } else { priv->has_set_bwA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwA is available=%s\n", __func__, value); } if (priv->has_get_bwA) { // see if get_bwB is available FLRig can return empty value too retval = flrig_transaction(rig, "rig.get_bwB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL || strlen(value) == 0) // must not have it { priv->has_get_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwB is not available=%s\n", __func__, value); } else { priv->has_get_bwB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwB is available=%s\n", __func__, value); } /* see if set_bwB is available */ retval = flrig_transaction(rig, "rig.set_bwB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwB is not available=%s\n", __func__, value); } else { priv->has_set_bwB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwB is available=%s\n", __func__, value); } } retval = flrig_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (streq(value, "A")) { rs->current_vfo = RIG_VFO_A; } else { rs->current_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(rs->current_vfo), value); //vfo_t vfo=RIG_VFO_A; //vfo_t vfo_tx=RIG_VFO_B; // split is always VFOB //flrig_get_split_vfo(rig, vfo, &priv->split, &vfo_tx); /* find out available widths and modes */ retval = flrig_transaction(rig, "rig.get_modes", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: modes=%s\n", __func__, value); modes = 0; pr = value; /* The following modes in FLRig are not implemented yet A1A AM-2 AM6.0 AM-D1 -- doesn't appear to be read/set AM-D2 -- doesn't appear to be read/set AM-D3 -- doesn't appear to be read/set AMW -- don't have mode in rig.h CW2.4 -- could be CW CW500 -- could be CWN but CWN not in rig.h CW-N -- could be CWN but CWN not in rig.h CWN -- dcould be CWN but CWN not in rig.h CW-NR -- don't have mode in rig.h DATA2-LSB DV DV-R F1B FM-D1 -- doesn't appear to be read/set FM-D2 -- doesn't appear to be read/set FM-D3 -- doesn't appear to be read/set H3E M11 USB-D -- doesn't appear to be read/set USER-L -- doesn't appear to be read/set USER-U -- doesn't appear to be read/set */ for (p = strtok_r(value, "|", &pr); p != NULL; p = strtok_r(NULL, "|", &pr)) { if (streq(p, "AM-D")) { modeMapAdd(&modes, RIG_MODE_PKTAM, p, 0); } else if (streq(p, "AM")) { modeMapAdd(&modes, RIG_MODE_AM, p, 0); } else if (streq(p, "AM-N")) { modeMapAdd(&modes, RIG_MODE_AMN, p, 0); } else if (streq(p, "AMN")) { modeMapAdd(&modes, RIG_MODE_AMN, p, 0); } else if (streq(p, "CW")) { modeMapAdd(&modes, RIG_MODE_CW, p, 0); } else if (streq(p, "CW-L")) { modeMapAdd(&modes, RIG_MODE_CWR, p, 0); } else if (streq(p, "CW-LSB")) { modeMapAdd(&modes, RIG_MODE_CWR, p, 0); } else if (streq(p, "CW-R")) { modeMapAdd(&modes, RIG_MODE_CWR, p, 0); } else if (streq(p, "CW-U")) { modeMapAdd(&modes, RIG_MODE_CW, p, 0); } else if (streq(p, "CW-USB")) { modeMapAdd(&modes, RIG_MODE_CW, p, 0); } else if (streq(p, "CWL")) { modeMapAdd(&modes, RIG_MODE_CWR, p, 0); } else if (streq(p, "CWU")) { modeMapAdd(&modes, RIG_MODE_CW, p, 0); } else if (streq(p, "D-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "D-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DATA")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DATA-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p, 0); } else if (streq(p, "DATA-FMN")) { modeMapAdd(&modes, RIG_MODE_PKTFMN, p, 0); } else if (streq(p, "DATA-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "DATA-R")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "DATA-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "DATA-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DATA-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DIG")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DIGI")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DIGL")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "DIGI-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "DIGU")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DIGI-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "DSB")) { modeMapAdd(&modes, RIG_MODE_DSB, p, 0); } else if (streq(p, "FM")) { modeMapAdd(&modes, RIG_MODE_FM, p, 0); } else if (streq(p, "FM-D")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p, 0); } else if (streq(p, "FMN")) { modeMapAdd(&modes, RIG_MODE_FMN, p, 0); } else if (streq(p, "FM-N")) { modeMapAdd(&modes, RIG_MODE_FMN, p, 0); } else if (streq(p, "FMW")) { modeMapAdd(&modes, RIG_MODE_WFM, p, 0); } else if (streq(p, "FSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "FSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "LCW")) { modeMapAdd(&modes, RIG_MODE_CWR, p, 0); } else if (streq(p, "LSB")) { modeMapAdd(&modes, RIG_MODE_LSB, p, 0); } else if (streq(p, "LSB-D")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "LSB-D1")) { modeMapAdd(&modes, RIG_MODE_LSBD1, p, 0); } else if (streq(p, "LSB-D2")) { modeMapAdd(&modes, RIG_MODE_LSBD2, p, 0); } else if (streq(p, "LSB-D3")) { modeMapAdd(&modes, RIG_MODE_LSBD3, p, 0); } else if (streq(p, "NFM")) { modeMapAdd(&modes, RIG_MODE_FMN, p, 0); } else if (streq(p, "PKT")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "PKT-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p, 0); } else if (streq(p, "PKT-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "PKT-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "PKT(L)")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "PKT(U)")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "PSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "PSK-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "PSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "PSK-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "RTTY")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "RTTY-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "RTTY-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "RTTY-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "RTTY(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p, 0); } else if (streq(p, "RTTY(R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p, 0); } else if (streq(p, "SAH")) { modeMapAdd(&modes, RIG_MODE_SAH, p, 0); } else if (streq(p, "SAL")) { modeMapAdd(&modes, RIG_MODE_SAL, p, 0); } else if (streq(p, "SAM")) { modeMapAdd(&modes, RIG_MODE_SAM, p, 0); } else if (streq(p, "USB")) { modeMapAdd(&modes, RIG_MODE_USB, p, 0); } else if (streq(p, "USB-D")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "USB-D1")) { modeMapAdd(&modes, RIG_MODE_USBD1, p, 0); } else if (streq(p, "USB-D2")) { modeMapAdd(&modes, RIG_MODE_USBD2, p, 0); } else if (streq(p, "USB-D3")) { modeMapAdd(&modes, RIG_MODE_USBD3, p, 0); } else if (streq(p, "USER-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p, 0); } else if (streq(p, "USER-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p, 0); } else if (streq(p, "W-FM")) { modeMapAdd(&modes, RIG_MODE_WFM, p, 0); } else if (streq(p, "WFM")) { modeMapAdd(&modes, RIG_MODE_WFM, p, 0); } else if (streq(p, "UCW")) { modeMapAdd(&modes, RIG_MODE_CW, p, 0); } else if (streq(p, "C4FM")) { modeMapAdd(&modes, RIG_MODE_C4FM, p, 0); } else if (streq(p, "SPEC")) { modeMapAdd(&modes, RIG_MODE_SPEC, p, 0); } else if (streq(p, "DV")) { modeMapAdd(&modes, RIG_MODE_DSTAR, p, 0); } else if (streq(p, "DRM")) // we don't support DRM yet (or maybe ever) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no mapping for mode %s\n", __func__, p); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode (new?) for this rig='%s'\n", __func__, p); } } // fallback between modes for (struct s_fmodeMap *mode = fmodeMap; mode->old_mode_hamlib != NULL; mode++) { if (modeMapGetHamlib(mode->old_mode_hamlib) == RIG_MODE_NONE && modeMapGetHamlib(mode->new_mode_hamlib) != RIG_MODE_NONE) { modeMapAdd(&modes, mode->mode_flrig, mode->new_mode_hamlib, 1); } } rs->mode_list = modes; retval = rig_strrmodes(modes, value, sizeof(value)); if (retval != RIG_OK) // we might get TRUNC but we can still print the debug { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: hamlib modes=%s\n", __func__, value); rig_get_split_vfo(rig, RIG_VFO_A, &split, &tx_vfo); #if 0 retval = flrig_transaction(rig, "rig.get_agc_labels", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_ERR, "%s: agc_labels=%s\n", __func__, value); #endif RETURNFUNC(retval); } /* * flrig_close * Assumes rig!=NULL */ static int flrig_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * flrig_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_cleanup(RIG *rig) { struct flrig_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct flrig_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_flrig was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_flrig) { free(modeMap[i].mode_flrig); modeMap[i].mode_flrig = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * flrig_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = vfo == RIG_VFO_A ? "rig.get_vfoA" : "rig.get_vfoB"; int retval; retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } *freq = atof(value); #if 0 // zero is actually valid for PowerSDR if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else #endif { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * flrig_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.0f", freq); value_t val; rig_get_ext_parm(rig, TOK_FLRIG_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_verify_vfoA/B=%d\n", __func__, val.i); if (vfo == RIG_VFO_A) { cmd = "rig.set_vfoA"; if (val.i) { cmd = "rig.set_verify_vfoA"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqA = freq; } else { cmd = "rig.set_vfoB"; if (val.i) { cmd = "rig.set_verify_vfoB"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqB = freq; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); hl_usleep(100 * 1000); // FLRig needs a moment to update the active VFO if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * flrig_set_ptt * Assumes rig!=NULL */ static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_arg[MAXARGLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", ptt); value_t val; char *cmd = "rig.set_ptt"; rig_get_ext_parm(rig, TOK_FLRIG_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: fast_set_ptt=%d\n", __func__, val.i); if (val.i) { cmd = "rig.set_ptt_fast"; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } /* * flrig_get_ptt * Assumes rig!=NUL, ptt!=NULL */ static int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char value[MAXCMDLEN]; char xml[MAXXMLLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; xml[0] = 0; value[0] = 0; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); int retval; retval = flrig_transaction(rig, "rig.get_ptt", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (strlen(value) > 0) { xml_parse(xml, value, sizeof(value)); *ptt = atoi(value); rig_debug(RIG_DEBUG_TRACE, "%s: '%s'\n", __func__, value); priv->ptt = *ptt; } RETURNFUNC(RIG_OK); } /* * flrig_set_split_mode * Assumes rig!=NULL */ static int flrig_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (vfo) { case RIG_VFO_CURR: vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: vfo = RIG_VFO_B; break; } // If no change don't do it...modes are kept up to date by client calls // to get_mode and set_mode so should be current here rig_debug(RIG_DEBUG_TRACE, "%s: vfoa privmode=%s\n", __func__, rig_strrmode(priv->curr_modeA)); rig_debug(RIG_DEBUG_TRACE, "%s: vfob privmode=%s\n", __func__, rig_strrmode(priv->curr_modeB)); // save some VFO swapping .. may replace with VFO specific calls that won't cause VFO change if (vfo == RIG_VFO_A && mode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_B && mode == priv->curr_modeB) { RETURNFUNC(RIG_OK); } retval = flrig_set_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: set mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(retval); } /* * flrig_set_mode * Assumes rig!=NULL */ static int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; int needBW; int vfoSwitched; char cmd_arg[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB vfoSwitched = 0; rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(rs->current_vfo)); // If we don't have the get_bwA call we have to switch VFOs ourself if (!priv->has_get_bwA && vfo == RIG_VFO_B && rs->current_vfo != RIG_VFO_B) { vfoSwitched = 1; rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOB = %d\n", __func__, vfoSwitched); } if (vfoSwitched) // swap to B and we'll swap back later { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOB = %d\n", __func__, vfoSwitched); retval = flrig_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } // Set the mode if (modeMapGetFLRig(mode)) { ttmode = strdup(modeMapGetFLRig(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGetFlRig failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } // if (strncmp(ttmode,"ERROR",5)==0) RETURNFUNC(-RIG_EINTERN); pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", pttmode); free(ttmode); if (!priv->has_get_modeA) { retval = flrig_transaction(rig, "rig.set_mode", cmd_arg, NULL, 0); } else { char *cmd = "rig.set_modeA"; if (vfo == RIG_VFO_B) { cmd = "rig.set_modeB"; } else { // we make VFO_B mode unknown so it expires the cache priv->curr_modeB = RIG_MODE_NONE; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // Determine if we need to update the bandwidth needBW = 0; if (vfo == RIG_VFO_A) { needBW = priv->curr_widthA != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOA, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else if (vfo == RIG_VFO_B) { needBW = priv->curr_widthB != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOB, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else { rig_debug(RIG_DEBUG_TRACE, "%s: needBW unknown vfo=%s\n", __func__, rig_strvfo(vfo)); } // Need to update the bandwidth if (width > 0 && needBW) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%ld", width); if (priv->has_set_bwA && vfo == RIG_VFO_A) { retval = flrig_transaction(rig, "rig.set_bwA", cmd_arg, NULL, 0); } else if (priv->has_set_bwB && vfo == RIG_VFO_B) { retval = flrig_transaction(rig, "rig.set_bwB", cmd_arg, NULL, 0); } else { retval = flrig_transaction(rig, "rig.set_bandwidth", cmd_arg, NULL, 0); } if (retval < 0) { RETURNFUNC(retval); } } // Return to VFOA if needed rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOA? = %d\n", __func__, vfoSwitched); if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOA\n", __func__); retval = flrig_set_vfo(rig, RIG_VFO_A); if (retval < 0) { RETURNFUNC(retval); } } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * flrig_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int flrig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int vfoSwitched; char value[MAXCMDLEN]; char *cmdp; vfo_t curr_vfo; rmode_t my_mode; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *width = 0; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } curr_vfo = rs->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->ptt) { if (vfo == RIG_VFO_A) { *mode = priv->curr_modeA; } else { *mode = priv->curr_modeB; } rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate vfoSwitched = 0; if (priv->has_get_modeA == 0 && vfo == RIG_VFO_B && curr_vfo != RIG_VFO_B) { vfoSwitched = 1; } if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s switch to VFOB=%d\n", __func__, priv->has_get_modeA); retval = flrig_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } cmdp = "rig.get_mode"; /* default to old way */ if (priv->has_get_modeA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in flrig */ /* vfo B may not be getting polled though in FLRig */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_modeA"; if (priv->has_get_modeB && vfo == RIG_VFO_B) { cmdp = "rig.get_modeB"; } } retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } my_mode = modeMapGetHamlib(value); *mode = my_mode; rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } /* Get the bandwidth */ cmdp = "rig.get_bw"; /* default to old way */ if (priv->has_get_bwA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in flrig */ /* vfo B may not be getting polled though in FLRig */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_bwA"; retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (strlen(value) == 0) // sometimes we get a null reply here -- OK...deal with it { rig_debug(RIG_DEBUG_WARN, "%s: empty value, returning cached bandwidth\n", __func__); *width = CACHE(rig)->widthMainA; RETURNFUNC(RIG_OK); } if (retval == RIG_OK && strstr(value, "NONE")) { priv->has_get_bwA = priv->has_get_bwB = 0; *width = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: does not have rig.get_bwA/B\n", __func__); RETURNFUNC(RIG_OK); } if (retval != RIG_OK || strstr(value, "NONE")) { RETURNFUNC(retval); } if (priv->has_get_bwB && vfo == RIG_VFO_B) { cmdp = "rig.get_bwB"; retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (strlen(value) == 0) { rig_debug(RIG_DEBUG_WARN, "%s: empty value, returning cached bandwidth\n", __func__); *width = CACHE(rig)->widthMainA; RETURNFUNC(RIG_OK); } if (retval == RIG_OK && strlen(value) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: does not have rig.get_bwB\n", __func__); priv->has_get_bwB = 0; *width = 0; } if (retval != RIG_OK) { RETURNFUNC(retval); } } } rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s width='%s'\n", __func__, rig_strrmode(*mode), value); // we get 2 entries pipe separated for bandwidth, lower and upper if (strlen(value) > 0) { char *p = value; /* we might get two values and then we want the 2nd one */ if (strchr(value, '|') != NULL) { p = strchr(value, '|') + 1; } *width = atoi(p); if (strstr(p, "k")) { *width = *width * 1000; } rig_debug(RIG_DEBUG_TRACE, "%s: p=%s, *width=%d\n", __func__, p, (int)(*width)); if (strcmp(p, "FIXED") == 0) { switch (*mode) { case RIG_MODE_PKTAM: case RIG_MODE_AM: case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = 10000; break; } } } if (vfo == RIG_VFO_A) { priv->curr_widthA = *width; } else { priv->curr_widthB = *width; } // Return to VFOA if needed if (vfoSwitched) { retval = flrig_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * flrig_set_vfo * assumes rig!=NULL */ static int flrig_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd_arg[MAXXMLLEN]; struct rig_state *rs = STATE(rig); const struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", vfo == RIG_VFO_A ? "A" : "B"); retval = flrig_transaction(rig, "rig.set_AB", cmd_arg, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig.set_AB failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } rs->current_vfo = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB /* for some rigs FLRig turns off split when VFOA is selected */ /* so if we are in split and asked for A we have to turn split back on */ if (priv->split && vfo == RIG_VFO_A) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", priv->split); retval = flrig_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * flrig_get_vfo * assumes rig!=NULL, vfo != NULL */ static int flrig_get_vfo(RIG *rig, vfo_t *vfo) { char value[MAXCMDLEN]; ENTERFUNC; int retval; retval = flrig_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo value=%s\n", __func__, value); switch (value[0]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; default: *vfo = RIG_VFO_CURR; RETURNFUNC(-RIG_EINVAL); } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } STATE(rig)->current_vfo = *vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(RIG_OK); } /* * flrig_set_split_freq * assumes rig!=NULL */ static int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd_arg[MAXXMLLEN]; freq_t qtx_freq; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } // we always split on VFOB so if no change just return retval = flrig_get_freq(rig, RIG_VFO_B, &qtx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tx_freq == qtx_freq) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.6f", tx_freq); retval = flrig_transaction(rig, "rig.set_vfoB", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->curr_freqB = tx_freq; RETURNFUNC(RIG_OK); } /* * flrig_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = flrig_get_freq(rig, RIG_VFO_B, tx_freq); priv->curr_freqB = *tx_freq; RETURNFUNC(retval); } /* * flrig_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; vfo_t qtx_vfo; split_t qsplit; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; char cmd_arg[MAXXMLLEN]; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); retval = flrig_get_split_vfo(rig, RIG_VFO_A, &qsplit, &qtx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } if (split == qsplit) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", split); retval = flrig_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->split = split; RETURNFUNC(RIG_OK); } /* * flrig_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char value[MAXCMDLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; int retval; retval = flrig_transaction(rig, "rig.get_split", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } *split = atoi(value); priv->split = *split; *tx_vfo = *split ? RIG_VFO_B : RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s tx_vfo=%s, split=%d\n", __func__, rig_strvfo(*tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * flrig_set_split_freq_mode * assumes rig!=NULL */ static int flrig_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; rmode_t qmode; pbwidth_t qwidth; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; // we always do split on VFOB retval = flrig_set_freq(rig, RIG_VFO_B, freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s flrig_set_freq failed\n", __func__); RETURNFUNC(retval); } // Make VFOB mode match VFOA mode, keep VFOB width retval = flrig_get_mode(rig, RIG_VFO_B, &qmode, &qwidth); if (retval != RIG_OK) { RETURNFUNC(retval); } if (qmode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } retval = flrig_set_mode(rig, RIG_VFO_B, priv->curr_modeA, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s flrig_set_mode failed\n", __func__); RETURNFUNC(retval); } retval = flrig_set_vfo(rig, RIG_VFO_A); RETURNFUNC(retval); } /* * flrig_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int flrig_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { RETURNFUNC(-RIG_ENTARGET); } retval = flrig_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = flrig_get_mode(rig, vfo, mode, width); } RETURNFUNC(retval); } static int flrig_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; char *param_type = "i4"; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s level=%d, val=%f\n", __func__, rig_strvfo(vfo), (int)level, val.f); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_RF: cmd = "rig.set_rfgain"; val.f *= 100; break; case RIG_LEVEL_AF: cmd = "rig.set_volume"; val.f *= 100; break; case RIG_LEVEL_MICGAIN: cmd = "rig.set_micgain"; val.f *= 100; break; case RIG_LEVEL_RFPOWER: cmd = "rig.set_power"; val.f *= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: invalid level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "<%s>%d", param_type, (int)val.f, param_type); retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } typedef struct { float mtr; float swr; } swrpair; static swrpair swrtbl[] = { {0.0, 1.0}, {10.5, 1.5}, {23.0, 2.0}, {35.0, 2.5}, {48.0, 3.0}, {100.0, 10.0 } // assuming 10.0 is infinity for FLRig }; // Function to interpolate SWR from MTR float interpolateSWR(float mtr) { int i; for (i = 0; i < sizeof(swrtbl) / sizeof(swrpair) - 1; i++) { if (mtr == swrtbl[i].mtr) { // Exact match return swrtbl[i].swr; } if (mtr < swrtbl[i + 1].mtr) { // Perform linear interpolation float slope = (swrtbl[i + 1].swr - swrtbl[i].swr) / (swrtbl[i + 1].mtr - swrtbl[i].mtr); float swr = round((swrtbl[i].swr + slope * (mtr - swrtbl[i].mtr)) * 10) / 10.0; rig_debug(RIG_DEBUG_VERBOSE, "%s: swr=%f\n", __func__, swr); return swr; } } // If mtr is not within the range of values in the table, you could choose to return an error or extrapolate return 10; // Example er } /* * flrig_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ static int flrig_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char value[MAXARGLEN]; char *cmd; int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: cmd = "rig.get_volume"; break; case RIG_LEVEL_RF: cmd = "rig.get_rfgain"; break; case RIG_LEVEL_MICGAIN: cmd = "rig.get_micgain"; break; case RIG_LEVEL_STRENGTH: cmd = "rig.get_DBM"; break; case RIG_LEVEL_SWR: cmd = "rig.get_swrmeter"; // we'll try get_SWR at least once to see if it works if (priv->get_SWR) { cmd = "rig.get_SWR"; } break; case RIG_LEVEL_RFPOWER: cmd = "rig.get_power"; break; case RIG_LEVEL_RFPOWER_METER_WATTS: case RIG_LEVEL_RFPOWER_METER: cmd = "rig.get_pwrmeter"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL && strcmp(cmd, "rig.get_SWR") == 0) { priv->get_SWR = 0; cmd = "rig.get_swrmeter"; // revert to old flrig method retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // most levels are 0-100 -- may have to allow for different ranges switch (level) { case RIG_LEVEL_SWR: { if (priv->get_SWR) { val->f = atof(value); } else { val->f = interpolateSWR(atoi(value)); } break; } case RIG_LEVEL_STRENGTH: val->i = atoi(value) + 73; rig_debug(RIG_DEBUG_TRACE, "%s: val.i='%s'(%d)\n", __func__, value, val->i); break; case RIG_LEVEL_RFPOWER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER_WATTS: val->f = atof(value) * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; default: val->f = atof(value) / 100; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%f)\n", __func__, value, val->f); } RETURNFUNC(RIG_OK); } /* * flrig_get_info * assumes rig!=NULL */ static const char *flrig_get_info(RIG *rig) { const struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE( rig)->priv; return (priv->info); } static int flrig_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int flrig_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } static int flrig_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FLRIG_VERIFY_FREQ: case TOK_FLRIG_VERIFY_PTT: if (val.i && !priv->has_verify_cmds) { rig_debug(RIG_DEBUG_ERR, "%s: FLRig version 1.3.54.18 or higher needed to support fast functions\n", __func__); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int flrig_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FLRIG_VERIFY_FREQ: case TOK_FLRIG_VERIFY_PTT: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } HAMLIB_EXPORT(int) flrig_cat_string2(RIG *rig, const char *arg, char *value, int value_size) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, arg); SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", arg); retval = flrig_transaction(rig, "rig.cat_string", cmd_arg, value, value_size); rig_debug(RIG_DEBUG_VERBOSE, "%s: returned '%s'\n", __func__, value); return retval; } HAMLIB_EXPORT(int) flrig_cat_string(RIG *rig, const char *arg) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, arg); SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", arg); retval = flrig_transaction(rig, "rig.cat_string", cmd_arg, NULL, 0); return retval; } int flrig_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: level=%s, status=%d\n", __func__, rig_strfunc(func), status); switch (func) { case RIG_FUNC_TUNER: SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", status); retval = flrig_transaction(rig, "rig.tune", cmd_arg, NULL, 0); break; default: retval = -RIG_ENIMPL; } return retval; } #if 0 static int flrig_set_ext_parm(RIG *rig, setting_t parm, value_t val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int flrig_get_ext_parm(RIG *rig, setting_t parm, value_t *val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } #endif hamlib-4.6.5/rigs/dummy/quisk.c0000664000175000017500000020431115056640443012054 /* * Hamlib Quisk backend - main file * Copyright (c) 2023 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "iofunc.h" #include "misc.h" #include "num_stdio.h" #include "dummy.h" #define CMD_MAX 64 #define BUF_MAX 1024 #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EPROTO; else do {} while(0) struct quisk_priv_data { vfo_t vfo_curr; int rigctld_vfo_mode; vfo_t rx_vfo; vfo_t tx_vfo; }; #if 0 int quisk_get_vfo_mode(RIG *rig) { struct quisk_priv_data *priv; priv = (struct quisk_priv_data *)STATE(rig)->priv; return priv->rigctld_vfo_mode; } #endif /* * Helper function with protocol return code parsing */ static int quisk_transaction(RIG *rig, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called len=%d\n", __func__, len); /* flush anything in the read buffer before command is sent */ rig_flush(rp); ret = write_block(rp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret < 0) { return ret; } if (strncmp(buf, NETRIGCTL_RET, strlen(NETRIGCTL_RET)) == 0) { return atoi(buf + strlen(NETRIGCTL_RET)); } return ret; } /* this will fill vfostr with the vfo value if the vfo mode is enabled * otherwise string will be null terminated * this allows us to use the string in snprintf in either mode */ static int quisk_vfostr(RIG *rig, char *vfostr, int len, vfo_t vfo) { struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); if (len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: len must be >=5, len=%d\n", __func__, len); return -RIG_EPROTO; } vfostr[0] = 0; priv = (struct quisk_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo==RIG_VFO_CURR, curr=%s\n", __func__, rig_strvfo(priv->vfo_curr)); vfo = priv->vfo_curr; if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } } else if (vfo == RIG_VFO_RX) { vfo = priv->rx_vfo; } else if (vfo == RIG_VFO_TX) { vfo = priv->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt=%d\n", __func__, STATE(rig)->vfo_opt); if (STATE(rig)->vfo_opt || priv->rigctld_vfo_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt vfo=%u\n", __func__, vfo); char *myvfo; switch (vfo) { case RIG_VFO_B: myvfo = "VFOB"; break; case RIG_VFO_C: myvfo = "VFOC"; break; case RIG_VFO_MAIN: myvfo = "Main"; break; case RIG_VFO_MAIN_A: myvfo = "MainA"; break; case RIG_VFO_MAIN_B: myvfo = "MainB"; break; case RIG_VFO_SUB: myvfo = "Sub"; break; case RIG_VFO_SUB_A: myvfo = "SubA"; break; case RIG_VFO_SUB_B: myvfo = "SubB"; break; case RIG_VFO_MEM: myvfo = "MEM"; break; default: myvfo = "VFOA"; } SNPRINTF(vfostr, len, " %s", myvfo); } return RIG_OK; } static int quisk_init(RIG *rig) { // cppcheck says leak here but it's freed in cleanup struct quisk_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct quisk_priv_data *)calloc(1, sizeof( struct quisk_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct quisk_priv_data)); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); /* * set arbitrary initial status * VFO will be updated in open call */ priv->vfo_curr = RIG_VFO_A; priv->rigctld_vfo_mode = 0; return RIG_OK; } static int quisk_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } // these are in netrigctl.c extern int parse_array_int(const char *s, const char *delim, int *array, int array_len); extern int parse_array_double(const char *s, const char *delim, double *array, int array_len); static int quisk_open(RIG *rig) { int ret, i; struct rig_state *rs = STATE(rig); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct quisk_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; priv = (struct quisk_priv_data *)rs->priv; priv->rx_vfo = RIG_VFO_A; priv->tx_vfo = RIG_VFO_A; SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } prot_ver = atoi(buf); #define RIGCTLD_PROT_VER 0 if (prot_ver < RIGCTLD_PROT_VER) { RETURNFUNC(-RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->deprecated_itu_region = atoi(buf); for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &(rs->rx_range_list[i].startf), &(rs->rx_range_list[i].endf), &(rs->rx_range_list[i].modes), &(rs->rx_range_list[i].low_power), &(rs->rx_range_list[i].high_power), &(rs->rx_range_list[i].vfo), &(rs->rx_range_list[i].ant) ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->rx_range_list[i])) { break; } } for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->tx_range_list[i].startf, &rs->tx_range_list[i].endf, &rs->tx_range_list[i].modes, &rs->tx_range_list[i].low_power, &rs->tx_range_list[i].high_power, &rs->tx_range_list[i].vfo, &rs->tx_range_list[i].ant ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->tx_range_list[i])) { break; } switch (i) { } rig->caps->tx_range_list1->startf = rs->tx_range_list[i].startf; rig->caps->tx_range_list1->endf = rs->tx_range_list[i].endf; rig->caps->tx_range_list1->modes = rs->tx_range_list[i].modes; rig->caps->tx_range_list1->low_power = rs->tx_range_list[i].low_power; rig->caps->tx_range_list1->high_power = rs->tx_range_list[i].high_power; rig->caps->tx_range_list1->vfo = rs->tx_range_list[i].vfo; rig->caps->tx_range_list1->ant = rs->tx_range_list[i].ant; } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->tuning_steps[i].modes, &rs->tuning_steps[i].ts); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS_END(rs->tuning_steps[i])) { break; } } for (i = 0; i < HAMLIB_FLTLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->filters[i].modes, &rs->filters[i].width); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FLT_END(rs->filters[i])) { break; } } #if 0 /* TODO */ chan_t chan_list[HAMLIB_CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_rit = rs->max_rit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_xit = rs->max_xit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_ifshift = rs->max_ifshift = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->announces = atoi(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->preamp[0], &rs->preamp[1], &rs->preamp[2], &rs->preamp[3], &rs->preamp[4], &rs->preamp[5], &rs->preamp[6]); rig->caps->preamp[0] = rs->preamp[0]; rig->caps->preamp[1] = rs->preamp[1]; rig->caps->preamp[2] = rs->preamp[2]; rig->caps->preamp[3] = rs->preamp[3]; rig->caps->preamp[4] = rs->preamp[4]; rig->caps->preamp[5] = rs->preamp[5]; rig->caps->preamp[6] = rs->preamp[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->preamp[ret] = rs->preamp[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->attenuator[0], &rs->attenuator[1], &rs->attenuator[2], &rs->attenuator[3], &rs->attenuator[4], &rs->attenuator[5], &rs->attenuator[6]); rig->caps->attenuator[0] = rs->attenuator[0]; rig->caps->attenuator[1] = rs->attenuator[1]; rig->caps->attenuator[2] = rs->attenuator[2]; rig->caps->attenuator[3] = rs->attenuator[3]; rig->caps->attenuator[4] = rs->attenuator[4]; rig->caps->attenuator[5] = rs->attenuator[5]; rig->caps->attenuator[6] = rs->attenuator[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->attenuator[ret] = rs->attenuator[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_func = rs->has_get_func = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_func = rs->has_set_func = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_level = rs->has_get_level = strtoll(buf, NULL, 0); #if 0 // don't think we need this anymore if (rs->has_get_level & RIG_LEVEL_RAWSTR) { /* include STRENGTH because the remote rig may be able to provide a front end emulation, if it can't then an -RIG_EINVAL will be returned */ rs->has_get_level |= RIG_LEVEL_STRENGTH; rig->caps->has_get_level |= RIG_LEVEL_STRENGTH; } #endif HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_level = rs->has_set_level = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->has_get_parm = strtoll(buf, NULL, 0); #if 0 HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } HAMLIB_TRACE; rig->caps->has_set_parm = rs->has_set_parm = strtoll(buf, NULL, 0); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { rs->mode_list |= rs->rx_range_list[i].modes; rs->vfo_list |= rs->rx_range_list[i].vfo; } HAMLIB_TRACE; for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { rs->mode_list |= rs->tx_range_list[i].modes; rs->vfo_list |= rs->tx_range_list[i].vfo; } HAMLIB_TRACE; if (rs->vfo_list == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_list empty, defaulting to A/B\n", __func__); rs->vfo_list = RIG_VFO_A | RIG_VFO_B; } HAMLIB_TRACE; #endif if (prot_ver == 0) { RETURNFUNC(RIG_OK); } HAMLIB_TRACE; // otherwise we continue reading protocol 1 fields do { char setting[32], value[1024]; hamlib_port_t *pttp = PTTPORT(rig); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); strtok(buf, "\r\n"); // chop the EOL if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } if (strncmp(buf, "done", 4) == 0) { RETURNFUNC(RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "vfo_ops") == 0) { rig->caps->vfo_ops = strtoll(value, NULL, 0); rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, rig->caps->vfo_ops); } else if (strcmp(setting, "ptt_type") == 0) { ptt_type_t temp = (ptt_type_t)strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type='%s'(%d)\n", __func__, value, temp); if (RIG_PTT_RIG_MICDATA == pttp->type.ptt || temp == RIG_PTT_RIG_MICDATA) { /* * remote PTT must always be RIG_PTT_RIG_MICDATA * if there is any PTT capability and we have not * locally overridden it */ pttp->type.ptt = RIG_PTT_RIG_MICDATA; rig->caps->ptt_type = RIG_PTT_RIG_MICDATA; rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, pttp->type.ptt); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type= %d\n", __func__, temp); pttp->type.ptt = temp; rig->caps->ptt_type = temp; } } else if (strcmp(setting, "targetable_vfo") == 0) { rig->caps->targetable_vfo = strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: targetable_vfo=0x%2x\n", __func__, rig->caps->targetable_vfo); } else if (strcmp(setting, "has_set_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_vfo = NULL; } } else if (strcmp(setting, "has_get_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_vfo = NULL; } } else if (strcmp(setting, "has_set_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_freq = NULL; } } else if (strcmp(setting, "has_get_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_freq = NULL; } } else if (strcmp(setting, "has_set_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_conf = NULL; } } else if (strcmp(setting, "has_get_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_conf = NULL; } } #if 0 // for the future else if (strcmp(setting, "has_set_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_trn = NULL; } } else if (strcmp(setting, "has_get_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_trn = NULL; } } #endif else if (strcmp(setting, "has_power2mW") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->power2mW = NULL; } } else if (strcmp(setting, "has_mW2power") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->mW2power = NULL; } } else if (strcmp(setting, "timeout") == 0) { // use the rig's timeout value plus 500ms for potential network delays rig->caps->timeout = strtol(value, NULL, 0) + 500; rig_debug(RIG_DEBUG_TRACE, "%s: timeout value = '%s', final timeout=%d\n", __func__, value, rig->caps->timeout); } else if (strcmp(setting, "rig_model") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%s\n", __func__, value); } else if (strcmp(setting, "rigctld_version") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rigctld_version=%s\n", __func__, value); } else if (strcmp(setting, "ctcss_list") == 0) { int n; double ctcss[CTCSS_LIST_SIZE]; rig->caps->ctcss_list = calloc(CTCSS_LIST_SIZE, sizeof(tone_t)); n = parse_array_double(value, " \n\r", ctcss, CTCSS_LIST_SIZE); for (i = 0; i < CTCSS_LIST_SIZE && ctcss[i] != 0; ++i) { rig->caps->ctcss_list[i] = ctcss[i] * 10; } if (n < CTCSS_LIST_SIZE) { rig->caps->ctcss_list[n] = 0; } } else if (strcmp(setting, "dcs_list") == 0) { int n; int dcs[DCS_LIST_SIZE + 1]; rig->caps->dcs_list = calloc(DCS_LIST_SIZE, sizeof(tone_t)); n = parse_array_int(value, " \n\r", dcs, DCS_LIST_SIZE); for (i = 0; i < DCS_LIST_SIZE && dcs[i] != 0; i++) { rig->caps->dcs_list[i] = dcs[i]; } if (n < DCS_LIST_SIZE) { rig->caps->dcs_list[n] = 0; } } else if (strcmp(setting, "agc_levels") == 0) { char *p = strtok(value, " "); rig->caps->agc_levels[0] = RIG_AGC_NONE; // default value gets overwritten rig->caps->agc_level_count = 0; while (p) { int agc_code; char agc_string[32]; int n = sscanf(p, "%d=%31s\n", &agc_code, agc_string); if (n == 2) { rig->caps->agc_levels[i++] = agc_code; rig->caps->agc_level_count++; rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has agc code=%d, level=%s\n", __func__, agc_code, agc_string); } else { rig_debug(RIG_DEBUG_ERR, "%s did not parse code=agc from '%s'\n", __func__, p); } rig_debug(RIG_DEBUG_VERBOSE, "%d=%s\n", agc_code, agc_string); p = strtok(NULL, " "); } } else if (strcmp(setting, "level_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); rig->caps->level_gran[i].min.f = rs->level_gran[i].min.f = min; rig->caps->level_gran[i].max.f = rs->level_gran[i].max.f = max; rig->caps->level_gran[i].step.f = rs->level_gran[i].step.f = step; } else { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); rig->caps->level_gran[i].min.i = rs->level_gran[i].min.i = min; rig->caps->level_gran[i].max.i = rs->level_gran[i].max.i = max; rig->caps->level_gran[i].step.i = rs->level_gran[i].step.i = step; } p = strtok(NULL, ";"); } } else if (strcmp(setting, "parm_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &step); rig->caps->parm_gran[i].min.f = rs->parm_gran[i].min.f = min; rig->caps->parm_gran[i].max.f = rs->parm_gran[i].max.f = max; rig->caps->parm_gran[i].step.f = rs->parm_gran[i].step.f = step; } else { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &step); rig->caps->parm_gran[i].min.i = rs->parm_gran[i].min.i = min; rig->caps->parm_gran[i].max.i = rs->parm_gran[i].max.i = max; rig->caps->parm_gran[i].step.i = rs->parm_gran[i].step.i = step; } p = strtok(NULL, ";"); } } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid dumpcaps line, expected 'setting=value', got '%s'\n", __func__, buf); } } while (1); if (rs->auto_power_on) { rig_set_powerstat(rig, 1); } RETURNFUNC(RIG_OK); } static int quisk_close(RIG *rig) { const struct rig_state *rs = STATE(rig); int ret; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rs->auto_power_off && rs->comm_state) { rig_set_powerstat(rig, 0); } ret = quisk_transaction(rig, "q\n", 2, buf); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: close error %s\n", __func__, rigerror(ret)); return ret; } rig_debug(RIG_DEBUG_ERR, "%s: done\n", __func__); usleep(10 * 1000); return RIG_OK; } static int quisk_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #if 1 // implement set_freq VFO later if it can be detected ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "F%s %"FREQFMT"\n", vfostr, freq); #else SNPRINTF(cmd, sizeof(cmd), "F %"FREQFMT"\n", freq); #endif ret = quisk_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s\n", __func__, strtok(cmd, "\r\n")); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; #if 0 // disable until we figure out if we can do this without breaking backwards compatibility char vfotmp[16]; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "f%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s, reply=%s\n", __func__, strtok(cmd, "\r\n"), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, freq)); #if 0 // implement set_freq VFO later if it can be detected ret = read_string(RIGPORT(rig), buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *vfotmp = rig_parse_vfo(buf); #endif return RIG_OK; } static int quisk_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "M%s %s %li\n", vfostr, rig_strrmode(mode), width); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "m%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *width = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_vfo(RIG *rig, vfo_t vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct quisk_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "V%s %s\n", vfostr, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd='%s'\n", __func__, cmd); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } priv->vfo_curr = vfo; // remember our vfo STATE(rig)->current_vfo = vfo; return ret; } static int quisk_get_vfo(RIG *rig, vfo_t *vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct quisk_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "v\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret == -RIG_ENAVAIL || ret == -RIG_ENIMPL) { // for rigs without get_vfo we'll use our saved vfo *vfo = priv->vfo_curr; return RIG_OK; } if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *vfo = rig_parse_vfo(buf); priv->vfo_curr = *vfo; return RIG_OK; } #endif static int quisk_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, ptt=%d, ptt_type=%d\n", __func__, rig_strvfo(vfo), ptt, PTTPORT(rig)->type.ptt); if (PTTPORT(rig)->type.ptt == RIG_PTT_NONE) { return RIG_OK; } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "T%s %d\n", vfostr, ptt); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s", __func__, cmd); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "t%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ptt = atoi(buf); return RIG_OK; } static int quisk_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcd%s\n", vfostr); /* FIXME */ ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *dcd = atoi(buf); return RIG_OK; } static int quisk_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "R%s %s\n", vfostr, rig_strptrshift(rptr_shift)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "r%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *rptr_shift = rig_parse_rptr_shift(buf); return RIG_OK; } static int quisk_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "O%s %ld\n", vfostr, rptr_offs); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "o%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rptr_offs = atoi(buf); return RIG_OK; } static int quisk_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "C%s %u\n", vfostr, tone); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "c%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int quisk_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "D%s %u\n", vfostr, code); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "d%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int quisk_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_ctcss_sql%s %u\n", vfostr, tone); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_ctcss_sql%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int quisk_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_dcs_sql%s %u\n", vfostr, code); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcs_sql%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "I%s %"FREQFMT"\n", vfostr, tx_freq); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "i%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq)); return RIG_OK; } static int quisk_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "X%s %s %li\n", vfostr, rig_strrmode(tx_mode), tx_width); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "x%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tx_width = atoi(buf); return RIG_OK; } static int quisk_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, vfotx=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "S%s %d %s\n", vfostr, split, rig_strvfo(tx_vfo)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "s%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *split = atoi(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_vfo = rig_parse_vfo(buf); return RIG_OK; } #endif static int quisk_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "J%s %ld\n", vfostr, rit); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "j%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rit = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Z%s %ld\n", vfostr, xit); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "z%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *xit = atoi(buf); return RIG_OK; } #endif #if 0 static int quisk_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "N%s %ld\n", vfostr, ts); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "n%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ts = atoi(buf); return RIG_OK; } #endif static int quisk_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "U%s %s %i\n", vfostr, rig_strfunc(func), status); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (strlen(rig_strfunc(func)) == 0) { return -RIG_ENAVAIL; } SNPRINTF(cmd, sizeof(cmd), "u%s %s\n", vfostr, rig_strfunc(func)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int quisk_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char lstr[32]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "L%s %s %s\n", vfostr, rig_strlevel(level), lstr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "l%s %s\n", vfostr, rig_strlevel(level)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = atof(buf); } else { val->i = atoi(buf); } return RIG_OK; } #if 0 static int quisk_set_powerstat(RIG *rig, powerstat_t status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\set_powerstat %d\n", status); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_powerstat(RIG *rig, powerstat_t *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\get_powerstat\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { int offset = 0; // see if there is a RPRT answer to make SDR++ happy if (strstr(buf, "RPRT")) { offset = 4; } *status = atoi(&buf[offset]); } else { // was causing problems with sdr++ since it does not have PS command // a return of 1 should indicate there is no powerstat command available // so we fake the ON status // also a problem with Flex 6xxx and Log4OM not working due to lack of PS command if (ret != RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_ON\n", __func__, ret); *status = RIG_POWER_ON; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_OFF\n", __func__, ret); *status = RIG_POWER_OFF; } } return RIG_OK; // always return RIG_OK } #endif static int quisk_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char pstr[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } SNPRINTF(cmd, sizeof(cmd), "P %s %s\n", rig_strparm(parm), pstr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_parm(RIG *rig, setting_t parm, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p %s\n", rig_strparm(parm)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_PARM_IS_FLOAT(parm)) { val->f = atoi(buf); } else { val->i = atoi(buf); } return RIG_OK; } #if 0 static int quisk_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; int i_ant = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d\n", __func__, ant, option.i); switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: more than 4 antennas? ant=0x%02x\n", __func__, ant); } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Y%s %d %d\n", vfostr, i_ant, option.i); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (ant == RIG_ANT_CURR) { SNPRINTF(cmd, sizeof(cmd), "y%s\n", vfostr); } else { SNPRINTF(cmd, sizeof(cmd), "y%s %u\n", vfostr, ant); } ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: buf='%s'\n", __func__, buf); ret = sscanf(buf, "%u\n", ant_curr); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 ant integer in '%s', got %d\n", __func__, buf, ret); } if (ant != RIG_ANT_CURR) { ret = sscanf(buf, "%d\n", &option->i); } if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d\n", &(option->i)); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } return RIG_OK; } static int quisk_set_bank(RIG *rig, vfo_t vfo, int bank) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "B %d\n", bank); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_set_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "E%s %d\n", vfostr, ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "e %s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ch = atoi(buf); return RIG_OK; } static int quisk_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "g %s %d\n", rig_strscan(scan), ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "G%s %s\n", vfostr, rig_strvfop(op)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static const char *quisk_get_info(RIG *rig) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } #if 0 static int quisk_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { int ret, len; char *cmdp, cmd[] = "\\send_dtmf "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + digits + \n + \0) len = strlen(cmd) + strlen(digits) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, digits); ret = quisk_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\recv_dtmf\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > *length) { ret = *length; } strncpy(digits, buf, ret); *length = ret; digits [ret] = '\0'; return RIG_OK; } #endif #if 0 static int quisk_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\send_voice_mem %d\n", ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int ret, len; char *cmdp, cmd[] = "\\send_morse "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + msg + \n + \0) len = strlen(cmd) + strlen(msg) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, msg); ret = quisk_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_stop_morse(RIG *rig, vfo_t vfo) { int ret; char cmd[] = "\\stop_morse\n"; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static int quisk_set_vfo_opt(RIG *rig, int status) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_vfo_opt %d\n", status); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } STATE(rig)->vfo_opt = status; return RIG_OK; } #if 0 // for the futurem -- would have to poll to get the pushed data static int quisk_set_trn(RIG *rig, int trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_trn %s\n", trn ? "ON" : "OFF"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int quisk_get_trn(RIG *rig, int *trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_trn\n"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } if (strstr(buf, "OFF")) { *trn = RIG_TRN_OFF; } else if (strstr(buf, "RIG")) { *trn = RIG_TRN_RIG; } else if (strstr(buf, "POLL")) { *trn = RIG_TRN_POLL; } else { rig_debug(RIG_DEBUG_ERR, "%s: Expected OFF, RIG, or POLL, got '%s'\n", __func__, buf); ret = -RIG_EINVAL; } RETURNFUNC(ret); } #endif static int quisk_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\mW2power %u %.0f %s\n", mwpower, freq, rig_strrmode(mode)); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *power = atof(buf); RETURNFUNC(RIG_OK); } static int quisk_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char cmdbuf[64]; char buf[BUF_MAX]; int ret; ENTERFUNC; // we shouldn't need any precision than microwatts SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\power2mW %.3f %.0f %s\n", power, freq, rig_strrmode(mode)); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *mwpower = atof(buf); RETURNFUNC(RIG_OK); } int quisk_password(RIG *rig, const char *key1) { char cmdbuf[256]; char buf[BUF_MAX]; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s\n", __func__, key1); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1); retval = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (retval != RIG_OK) { retval = -RIG_EPROTO; } RETURNFUNC(retval); } #if 0 int quisk_set_lock_mode(RIG *rig, int lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_lock_mode %d\n", lock); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } return (RIG_OK); } #endif #if 0 int quisk_get_lock_mode(RIG *rig, int *lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_lock_mode\n"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret == 0) { return -RIG_EPROTO; } sscanf(buf, "%d", lock); return (RIG_OK); } #endif #if 0 int quisk_send_raw(RIG *rig, char *s) { int ret; char buf[BUF_MAX]; ret = quisk_transaction(rig, s, strlen(s), buf); return ret; } #endif /* * Netrigctl rig capabilities. */ struct rig_caps quisk_caps = { RIG_MODEL(RIG_MODEL_QUISK), .model_name = "Quisk", .mfg_name = "N2ADR James Ahlstrom", .version = "20230709.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NETWORK, .timeout = 10000, /* enough for the worst rig we have */ .retry = 5, /* following fields updated in rig_state at opening time */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { }, .transceive = RIG_TRN_OFF, .attenuator = { }, .preamp = { }, .rx_range_list2 = { RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { }, .filters = { RIG_FLT_END, }, .max_rit = 0, .max_xit = 0, .max_ifshift = 0, .priv = NULL, .rig_init = quisk_init, .rig_cleanup = quisk_cleanup, .rig_open = quisk_open, .rig_close = quisk_close, .set_freq = quisk_set_freq, .get_freq = quisk_get_freq, .set_mode = quisk_set_mode, .get_mode = quisk_get_mode, // .set_vfo = quisk_set_vfo, // .get_vfo = quisk_get_vfo, // .set_powerstat = quisk_set_powerstat, // .get_powerstat = quisk_get_powerstat, .set_level = quisk_set_level, .get_level = quisk_get_level, .set_func = quisk_set_func, .get_func = quisk_get_func, .set_parm = quisk_set_parm, .get_parm = quisk_get_parm, .get_info = quisk_get_info, .set_ptt = quisk_set_ptt, .get_ptt = quisk_get_ptt, .get_dcd = quisk_get_dcd, .set_rptr_shift = quisk_set_rptr_shift, .get_rptr_shift = quisk_get_rptr_shift, .set_rptr_offs = quisk_set_rptr_offs, .get_rptr_offs = quisk_get_rptr_offs, .set_ctcss_tone = quisk_set_ctcss_tone, .get_ctcss_tone = quisk_get_ctcss_tone, .set_dcs_code = quisk_set_dcs_code, .get_dcs_code = quisk_get_dcs_code, .set_ctcss_sql = quisk_set_ctcss_sql, .get_ctcss_sql = quisk_get_ctcss_sql, .set_dcs_sql = quisk_set_dcs_sql, .get_dcs_sql = quisk_get_dcs_sql, // .set_split_freq = quisk_set_split_freq, // .get_split_freq = quisk_get_split_freq, // .set_split_mode = quisk_set_split_mode, // .get_split_mode = quisk_get_split_mode, // .set_split_vfo = quisk_set_split_vfo, // .get_split_vfo = quisk_get_split_vfo, .set_rit = quisk_set_rit, .get_rit = quisk_get_rit, // .set_xit = quisk_set_xit, // .get_xit = quisk_get_xit, // .set_ts = quisk_set_ts, // .get_ts = quisk_get_ts, // .set_ant = quisk_set_ant, // .get_ant = quisk_get_ant, // .set_bank = quisk_set_bank, // .set_mem = quisk_set_mem, // .get_mem = quisk_get_mem, // .vfo_op = quisk_vfo_op, // .scan = quisk_scan, // .send_dtmf = quisk_send_dtmf, // .recv_dtmf = quisk_recv_dtmf, // .send_morse = quisk_send_morse, // .send_voice_mem = quisk_send_voice_mem, // .stop_morse = quisk_stop_morse, // .set_channel = quisk_set_channel, // .get_channel = quisk_get_channel, .set_vfo_opt = quisk_set_vfo_opt, //.set_trn = quisk_set_trn, //.get_trn = quisk_get_trn, .power2mW = quisk_power2mW, .mW2power = quisk_mW2power, .password = quisk_password, // .set_lock_mode = quisk_set_lock_mode, // .get_lock_mode = quisk_get_lock_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/dummy/amp_dummy.c0000664000175000017500000002167015056640443012715 /* * Hamlib Dummy backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/amplifier.h" #include "serial.h" #include "register.h" #include "amp_dummy.h" #if 0 static const struct confparams dummy_amp_ext_levels[] = { { AMP_LEVEL_SWR, "SWR", "SWR", "SWR", NULL, RIG_CONF_NUMERIC, { .n = { 1, 99, .1 } } } }; #endif #define AMP_LEVELS (AMP_LEVEL_SWR|AMP_LEVEL_PF|AMP_LEVEL_NH|AMP_LEVEL_PWR_INPUT|AMP_LEVEL_PWR_FWD|AMP_LEVEL_PWR_REFLECTED|AMP_LEVEL_PWR_PEAK|AMP_LEVEL_FAULT) struct dummy_amp_priv_data { freq_t freq; powerstat_t powerstat; }; static int dummy_amp_init(AMP *amp) { struct dummy_amp_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); AMPSTATE(amp)->priv = (struct dummy_amp_priv_data *) calloc(1, sizeof(struct dummy_amp_priv_data)); if (!AMPSTATE(amp)->priv) { return -RIG_ENOMEM; } priv = AMPSTATE(amp)->priv; AMPPORT(amp)->type.rig = RIG_PORT_NONE; priv->freq = 0; return RIG_OK; } static int dummy_amp_cleanup(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (AMPSTATE(amp)->priv) { free(AMPSTATE(amp)->priv); } AMPSTATE(amp)->priv = NULL; return RIG_OK; } static int dummy_amp_open(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_amp_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_amp_reset(AMP *amp, amp_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (reset) { case AMP_RESET_MEM: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset memory\n", __func__); break; case AMP_RESET_FAULT: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset fault\n", __func__); break; case AMP_RESET_AMP: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset amplifier\n", __func__); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset unknown=%d\n", __func__, reset); return -RIG_EINVAL; } return RIG_OK; } /* ^ON1 turns amp on ^ON0 turns amp off ^OP0 amp in standby ^OP1 amp in operate ^PWF which gets forward power from amp. Reply would be ^PWFnnnn format ^PWK which gets peak forward power. Response is ^PWKnnnn ^PWR peak reflected power. Response is ^PWRnnnn ^SW gets SWR. Response is ^SWnnn. Example return of ^SW025 would be 2.5:1 Also a way to display faults (there are commands) */ static int dummy_amp_get_freq(AMP *amp, freq_t *freq) { const struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *freq = priv->freq; return RIG_OK; } static int dummy_amp_set_freq(AMP *amp, freq_t freq) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv->freq = freq; return RIG_OK; } static const char *dummy_amp_get_info(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "Dummy amplifier"; } static int dummy_amp_get_level(AMP *amp, setting_t level, value_t *val) { static int flag = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); flag = !flag; // values toggle between two expected min/~max values for dev purposes switch (level) { case AMP_LEVEL_SWR: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_SWR\n", __func__); val->f = flag == 0 ? 1.0 : 99.0; return RIG_OK; case AMP_LEVEL_PF: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PF\n", __func__); val->f = flag == 0 ? 0 : 2701.2; return RIG_OK; case AMP_LEVEL_NH: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_NH\n", __func__); val->i = flag == 0 ? 0 : 8370; return RIG_OK; case AMP_LEVEL_PWR_INPUT: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRINPUT\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_FWD: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRFWD\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_REFLECTED: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRREFLECTED\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_PEAK: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRPEAK\n", __func__); val->i = flag == 0 ? 0 : 1500 ; return RIG_OK; case AMP_LEVEL_FAULT: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_FAULT\n", __func__); val->s = flag == 0 ? "No Fault" : "SWR too high"; // SWR too high for KPA1500 return RIG_OK; default: rig_debug(RIG_DEBUG_VERBOSE, "%s Unknown AMP_LEVEL=%s\n", __func__, rig_strlevel(level)); } rig_debug(RIG_DEBUG_VERBOSE, "%s flag=%d\n", __func__, flag); return -RIG_EINVAL; } static int dummy_amp_set_powerstat(AMP *amp, powerstat_t status) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; switch (status) { case RIG_POWER_OFF: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OFF\n", __func__); break; case RIG_POWER_ON: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_ON\n", __func__); break; case RIG_POWER_STANDBY: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_STANDBY\n", __func__); break; case RIG_POWER_OPERATE: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OPERATE\n", __func__); break; case RIG_POWER_UNKNOWN: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_UNKNOWN\n", __func__); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s called invalid power status=%d\n", __func__, status); return -RIG_EINVAL; break; } priv->powerstat = status; return RIG_OK; } static int dummy_amp_get_powerstat(AMP *amp, powerstat_t *status) { const struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; *status = priv->powerstat; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } #if 0 // not implemented yet static int dummy_amp_get_ext_level(AMP *amp, hamlib_token_t token, value_t *val) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = amp_ext_lookup_tok(amp, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case AMP_LEVEL_SWR: break; default: return -RIG_EINVAL; } elp = find_ext(curr->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } #endif /* * Dummy amplifier capabilities. */ const struct amp_caps dummy_amp_caps = { AMP_MODEL(AMP_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NONE, .has_get_level = AMP_LEVELS, .has_set_level = RIG_LEVEL_SET(AMP_LEVELS), .priv = NULL, /* priv */ .amp_init = dummy_amp_init, .amp_cleanup = dummy_amp_cleanup, .amp_open = dummy_amp_open, .amp_close = dummy_amp_close, .get_freq = dummy_amp_get_freq, .set_freq = dummy_amp_set_freq, .get_info = dummy_amp_get_info, .get_level = dummy_amp_get_level, .set_powerstat = dummy_amp_set_powerstat, .get_powerstat = dummy_amp_get_powerstat, .reset = dummy_amp_reset, }; DECLARE_INITAMP_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); amp_register(&dummy_amp_caps); amp_register(&netampctl_caps); return RIG_OK; } hamlib-4.6.5/rigs/dummy/amp_dummy.h0000664000175000017500000000203415056640443012713 /* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_DUMMY_H #define _AMP_DUMMY_H 1 #include "amplifier.h" extern const struct amp_caps dummy_amp_caps; extern const struct amp_caps netampctl_caps; #endif /* _AMP_DUMMY_H */ hamlib-4.6.5/rigs/dummy/rot_dummy.c0000664000175000017500000005543315056640443012750 /* * Hamlib Dummy backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include "hamlib/rotator.h" #include "dummy_common.h" #include "rig.h" #include "register.h" #include "idx_builtin.h" #include "rot_dummy.h" #include "rot_pstrotator.h" #include "rotlist.h" #define DUMMY_ROT_FUNC 0 #define DUMMY_ROT_LEVEL ROT_LEVEL_SPEED #define DUMMY_ROT_PARM 0 #define DUMMY_ROT_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) static int simulating = 0; // do we need rotator emulation for debug? struct dummy_rot_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; rot_status_t status; setting_t funcs; value_t levels[RIG_SETTING_MAX]; value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_funcs; struct ext_list *ext_levels; struct ext_list *ext_parms; char *magic_conf; }; static const struct confparams dummy_ext_levels[] = { { TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_funcs[] = { { TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_parms[] = { { TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* cfgparams are configuration item generally used by the backend's open() method */ static const struct confparams dummy_cfg_params[] = { { TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", "ROTATOR", RIG_CONF_STRING, { } }, { RIG_CONF_END, NULL, } }; static int dummy_rot_init(ROT *rot) { struct dummy_rot_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ROTSTATE(rot)->priv = (struct dummy_rot_priv_data *) calloc(1, sizeof(struct dummy_rot_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; priv->ext_funcs = alloc_init_ext(dummy_ext_funcs); if (!priv->ext_funcs) { return -RIG_ENOMEM; } priv->ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->ext_levels) { return -RIG_ENOMEM; } priv->ext_parms = alloc_init_ext(dummy_ext_parms); if (!priv->ext_parms) { return -RIG_ENOMEM; } ROTPORT(rot)->type.rig = RIG_PORT_NONE; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; priv->magic_conf = strdup("ROTATOR"); return RIG_OK; } static int dummy_rot_cleanup(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(priv->ext_funcs); free(priv->ext_levels); free(priv->ext_parms); free(priv->magic_conf); free(ROTSTATE(rot)->priv); ROTSTATE(rot)->priv = NULL; return RIG_OK; } static int dummy_rot_open(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rot->caps->rot_model == ROT_MODEL_DUMMY) { simulating = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: dummy rotator so simulating speed\n", __func__); } return RIG_OK; } static int dummy_rot_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct dummy_rot_priv_data *priv; priv = (struct dummy_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; default: return -RIG_EINVAL; } return RIG_OK; } static int dummy_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { struct dummy_rot_priv_data *priv; priv = (struct dummy_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: SNPRINTF(val, val_len, "%s", priv->magic_conf); break; default: return -RIG_EINVAL; } return RIG_OK; } static int dummy_get_conf(ROT *rot, hamlib_token_t token, char *val) { return dummy_get_conf2(rot, token, val, 128); } static int dummy_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); if (simulating) { priv->target_az = az; priv->target_el = el; gettimeofday(&priv->tv, NULL); } else { priv->az = priv->target_az = az; priv->el = priv->target_az = el; } return RIG_OK; } static void dummy_rot_simulate_rotation(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; struct timeval tv; unsigned elapsed; /* ms */ gettimeofday(&tv, NULL); elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 + (tv.tv_usec - priv->tv.tv_usec) / 1000; /* * Simulate rotation speed of 360 deg per minute */ #define DEG_PER_MS (360./60/1000) if (fabs(priv->target_az - priv->az) / DEG_PER_MS <= elapsed) { /* target reached */ priv->az = priv->target_az; priv->status &= ~(ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT); } else { if (priv->az < priv->target_az) { priv->az += (azimuth_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_RIGHT; } else { priv->az -= (azimuth_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT; } } if (fabs(priv->target_el - priv->el) / DEG_PER_MS <= elapsed) { /* target reached */ priv->el = priv->target_el; priv->status &= ~(ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN); } else { if (priv->el < priv->target_el) { priv->el += (elevation_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP; } else { priv->el -= (elevation_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_DOWN; } } if (priv->status & (ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_EL)) { priv->status |= ROT_STATUS_MOVING; } else { priv->status &= ~(ROT_STATUS_MOVING); } priv->tv = tv; } /* * Get position of rotor, simulating slow rotation */ static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (simulating && priv->az == priv->target_az && priv->el == priv->target_el) { *az = priv->az; *el = priv->el; return RIG_OK; } if (simulating) { dummy_rot_simulate_rotation(rot); } *az = priv->az; *el = priv->el; return RIG_OK; } static int dummy_rot_stop(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; azimuth_t az; elevation_t el; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); dummy_rot_get_position(rot, &az, &el); priv->target_az = priv->az = az; priv->target_el = priv->el = el; return RIG_OK; } static int dummy_rot_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume home is 0,0 */ dummy_rot_set_position(rot, 0, 0); return RIG_OK; } static int dummy_rot_reset(ROT *rot, rot_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_rot_move(ROT *rot, int direction, int speed) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_UP: return dummy_rot_set_position(rot, priv->target_az, 90); case ROT_MOVE_DOWN: return dummy_rot_set_position(rot, priv->target_az, 0); case ROT_MOVE_CCW: return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_CW: return dummy_rot_set_position(rot, 180, priv->target_el); case ROT_MOVE_UP_LEFT: dummy_rot_set_position(rot, priv->target_az, 90); return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_UP_RIGHT: dummy_rot_set_position(rot, priv->target_az, 90); return dummy_rot_set_position(rot, 180, priv->target_el); case ROT_MOVE_DOWN_LEFT: dummy_rot_set_position(rot, priv->target_az, 0); return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_DOWN_RIGHT: dummy_rot_set_position(rot, priv->target_az, 0); return dummy_rot_set_position(rot, 180, priv->target_el); default: return -RIG_EINVAL; } return RIG_OK; } static const char *dummy_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "Dummy rotator"; } static int dummy_set_func(ROT *rot, setting_t func, int status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rot_strfunc(func), status); if (status) { priv->funcs |= func; } else { priv->funcs &= ~func; } return RIG_OK; } static int dummy_get_func(ROT *rot, setting_t func, int *status) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; *status = (priv->funcs & func) ? 1 : 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strfunc(func)); return RIG_OK; } static int dummy_set_level(ROT *rot, setting_t level, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; char lstr[32]; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } priv->levels[idx] = val; if (ROT_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rot_strlevel(level), lstr); return RIG_OK; } static int dummy_get_level(ROT *rot, setting_t level, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } *val = priv->levels[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); return RIG_OK; } static int dummy_set_ext_level(ROT *rot, hamlib_token_t token, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICLEVEL: case TOK_EL_ROT_MAGICFUNC: case TOK_EL_ROT_MAGICOP: case TOK_EL_ROT_MAGICCOMBO: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: return -RIG_EINTERNAL; } elp = find_ext(priv->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* store value */ elp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); return RIG_OK; } static int dummy_get_ext_level(ROT *rot, hamlib_token_t token, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICLEVEL: case TOK_EL_ROT_MAGICFUNC: case TOK_EL_ROT_MAGICOP: case TOK_EL_ROT_MAGICCOMBO: break; default: return -RIG_EINVAL; } elp = find_ext(priv->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_set_ext_func(ROT *rot, hamlib_token_t token, int status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICEXTFUNC: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_CHECKBUTTON: break; case RIG_CONF_BUTTON: break; default: return -RIG_EINTERNAL; } elp = find_ext(priv->ext_funcs, token); if (!elp) { return -RIG_EINTERNAL; } /* store value */ elp->val.i = status; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, cfp->name, status); return RIG_OK; } static int dummy_get_ext_func(ROT *rot, hamlib_token_t token, int *status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICEXTFUNC: break; default: return -RIG_EINVAL; } elp = find_ext(priv->ext_funcs, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *status = elp->val.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_set_parm(ROT *rot, setting_t parm, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; char pstr[32]; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } if (ROT_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; return RIG_OK; } static int dummy_get_parm(ROT *rot, setting_t parm, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); return RIG_OK; } static int dummy_set_ext_parm(ROT *rot, hamlib_token_t token, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EP_ROT_MAGICPARM: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: return -RIG_EINTERNAL; } epp = find_ext(priv->ext_parms, token); if (!epp) { return -RIG_EINTERNAL; } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); return RIG_OK; } static int dummy_get_ext_parm(ROT *rot, hamlib_token_t token, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *epp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EP_ROT_MAGICPARM: break; default: return -RIG_EINVAL; } epp = find_ext(priv->ext_parms, token); if (!epp) { return -RIG_EINTERNAL; } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_rot_get_status(ROT *rot, rot_status_t *status) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; if (simulating) { dummy_rot_simulate_rotation(rot); } *status = priv->status; return RIG_OK; } /* * Dummy rotator capabilities. */ struct rot_caps dummy_rot_caps = { ROT_MODEL(ROT_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20220531.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_NONE, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .has_get_func = DUMMY_ROT_FUNC, .has_set_func = DUMMY_ROT_FUNC, .has_get_level = DUMMY_ROT_LEVEL, .has_set_level = ROT_LEVEL_SET(DUMMY_ROT_LEVEL), .has_get_parm = DUMMY_ROT_PARM, .has_set_parm = ROT_PARM_SET(DUMMY_ROT_PARM), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .has_status = DUMMY_ROT_STATUS, .rot_init = dummy_rot_init, .rot_cleanup = dummy_rot_cleanup, .rot_open = dummy_rot_open, .rot_close = dummy_rot_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_position = dummy_rot_set_position, .get_position = dummy_rot_get_position, .park = dummy_rot_park, .stop = dummy_rot_stop, .reset = dummy_rot_reset, .move = dummy_rot_move, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_rot_get_info, .get_status = dummy_rot_get_status, }; DECLARE_INITROT_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&dummy_rot_caps); rot_register(&netrotctl_caps); rot_register(&pstrotator_caps); rot_register(&satrotctl_caps); return RIG_OK; } hamlib-4.6.5/rigs/dummy/Makefile.am0000664000175000017500000000054715056640443012615 DUMMYSRC = dummy_common.c dummy_common.h dummy.c dummy.h rot_dummy.c rot_dummy.h rot_pstrotator.c rot_pstrotator.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h amp_dummy.c amp_dummy.h netampctl.c tci1x.c aclog.c sdrsharp.c quisk.c noinst_LTLIBRARIES = libhamlib-dummy.la libhamlib_dummy_la_SOURCES = $(DUMMYSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/skanti/0000775000175000017500000000000015056640477011000 5hamlib-4.6.5/rigs/skanti/trp8255.c0000664000175000017500000003012515056640443012207 /* * Hamlib Skanti backend - TRP8255 description * Copyright (c) 2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "idx_builtin.h" #include "iofunc.h" #define TRP8255_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8255_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8255_AM_TX_MODES RIG_MODE_AM #define TRP8255_FUNC (RIG_FUNC_MUTE) #define TRP8255_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AGC|\ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_SQL) #define TRP8255_PARM_ALL (RIG_PARM_TIME|RIG_PARM_BACKLIGHT) #define TRP8255_VFO_OPS (RIG_OP_TUNE|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY) #define TRP8255_VFO (RIG_VFO_A) #define TRP8255_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ } /* * Private data */ struct cu_priv_data { split_t split; /* current emulated split state */ int ch; /* current memorized memory channel */ }; static int cu_transaction(RIG *rig, const char *cmd, int cmd_len); static int cu_open(RIG *rig); static int cu_close(RIG *rig); static int cu_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int cu_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int cu_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int cu_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int cu_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int cu_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int cu_set_parm(RIG *rig, setting_t parm, value_t val); static int cu_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int cu_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int cu_set_mem(RIG *rig, vfo_t vfo, int ch); static int cu_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TRP 8255 rig capabilities. * The protocol is different than TRP8000, * because the TRP8255 has the "CU" (Control Unit). * */ struct rig_caps trp8255_caps = { RIG_MODEL(RIG_MODEL_TRP8255), .model_name = "TRP 8255 S R", .mfg_name = "Skanti", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 2400, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = TRP8255_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_SET(TRP8255_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(TRP8255_PARM_ALL), .vfo_ops = TRP8255_VFO_OPS, .preamp = { 10, RIG_DBLST_END }, /* TBC */ .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 76, RIG_MTYPE_MEM, TRP8255_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRP8255_ALL_MODES, -1, -1, TRP8255_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(2), MHz(30), TRP8255_AM_TX_MODES, W(4), W(40), TRP8255_VFO}, {MHz(2), MHz(30), TRP8255_OTHER_TX_MODES, W(10), W(100), TRP8255_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TRP8255_ALL_MODES, 10}, {TRP8255_ALL_MODES, 100}, {TRP8255_ALL_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* rough guesses */ {TRP8255_ALL_MODES, kHz(2.7)}, /* intermit */ {TRP8255_ALL_MODES, kHz(2.1)}, /* narrow */ {TRP8255_ALL_MODES, kHz(6)}, /* wide */ {TRP8255_ALL_MODES, Hz(500)}, /* very narrow */ RIG_FLT_END, }, .rig_open = cu_open, .rig_close = cu_close, .set_freq = cu_set_freq, .set_mode = cu_set_mode, .set_split_freq = cu_set_split_freq, .set_split_vfo = cu_set_split_vfo, .set_ptt = cu_set_ptt, .set_mem = cu_set_mem, .vfo_op = cu_vfo_op, .set_level = cu_set_level, .set_func = cu_set_func, .set_parm = cu_set_parm, .set_ts = cu_set_ts, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define ACK 0x06 #define NACK 0x15 #define CR "\x0d" /* TODO: retry */ static int cu_transaction(RIG *rig, const char *cmd, int cmd_len) { int i; char retchar; hamlib_port_t *rp = RIGPORT(rig); for (i = 0; i < cmd_len; i++) { int ret = write_block(rp, (unsigned char *) &cmd[i], 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &retchar, 1); switch (retchar) { case ACK: continue; case NACK: return -RIG_ERJCTED; default: return -RIG_EPROTO; } } return RIG_OK; } static int cu_open(RIG *rig) { const char cmd[] = { 0x01, 0x02 }; /* SOH, STX */ struct cu_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct cu_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = (struct cu_priv_data *)STATE(rig)->priv; memset(priv, 0, sizeof(struct cu_priv_data)); priv->split = RIG_SPLIT_OFF; priv->ch = 0; return cu_transaction(rig, cmd, 2); } static int cu_close(RIG *rig) { const char cmd[] = { 0x16 }; /* DLE */ struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; free(priv); return cu_transaction(rig, cmd, 1); } int cu_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; char cmdbuf[16]; int ret; if (freq >= MHz(100)) { return -RIG_EINVAL; } /* RX freq */ SNPRINTF(cmdbuf, sizeof(cmdbuf), ":%06u"CR, (unsigned)(freq / Hz(100))); ret = cu_transaction(rig, cmdbuf, strlen(cmdbuf)); if (ret != RIG_OK) { return ret; } if (priv->split != RIG_SPLIT_ON) { return cu_vfo_op(rig, vfo, RIG_OP_CPY); } return RIG_OK; } static int cu_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } int cu_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmdbuf[16]; if (freq >= MHz(100)) { return -RIG_EINVAL; } /* TX freq */ SNPRINTF(cmdbuf, sizeof(cmdbuf), ";%06u"CR, (unsigned)(freq / Hz(100))); return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char *cmd; int ret; switch (mode) { case RIG_MODE_USB: cmd = "X"; break; case RIG_MODE_LSB: cmd = "Y"; break; case RIG_MODE_AM: cmd = "Z"; break; case RIG_MODE_RTTY: cmd = "["; break; /* case RIG_MODE_R3E: cmd = "\\"; break; */ case RIG_MODE_CW: cmd = "]"; break; /* case RIG_MODE_MCW: cmd = '^'; break; */ default: return -RIG_EINVAL; } ret = cu_transaction(rig, cmd, 1); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width < rig_passband_normal(rig, mode)) { cmd = "D"; } else if (width > rig_passband_normal(rig, mode)) { cmd = "B"; } else { cmd = "C"; } return cu_transaction(rig, cmd, 1); } int cu_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[16]; cmdbuf[1] = 0; switch (level) { case RIG_LEVEL_PREAMP: cmdbuf[0] = val.i ? 'm' : 'n'; break; case RIG_LEVEL_ATT: cmdbuf[0] = val.i ? 'o' : 'p'; break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_AUTO: cmdbuf[0] = 'J'; break; case RIG_AGC_FAST: cmdbuf[0] = 'K'; break; case RIG_AGC_SLOW: cmdbuf[0] = 'L'; break; case RIG_AGC_OFF: cmdbuf[0] = 'M'; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_SQL: cmdbuf[0] = val.i ? 'o' : 'p'; break; case RIG_LEVEL_RFPOWER: if (val.f < 0.4) { cmdbuf[0] = 'S'; /* low */ } else if (val.f < 0.6) { cmdbuf[0] = 'U'; /* medium */ } else { cmdbuf[0] = 'W'; /* high */ } break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "y%02u"CR, (unsigned)(99 - val.f * 99)); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[16]; int cmd_len; cmd_len = 1; switch (func) { case RIG_FUNC_MUTE: cmdbuf[0] = status ? 'l' : 'k'; break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, cmd_len); } int cu_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char cmdbuf[16]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "w%c"CR, ts >= s_kHz(1) ? '2' : ts >= s_Hz(100) ? '1' : '0'); return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[16]; switch (parm) { case RIG_PARM_TIME: /* zap seconds */ val.i /= 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "f%02d%02d"CR, val.i / 60, val.i % 60); break; case RIG_PARM_BACKLIGHT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "z%1u"CR, (unsigned)(val.f * 5)); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char *cmd; cmd = ptt == RIG_PTT_ON ? "u" : "v"; return cu_transaction(rig, cmd, 1); } static int cu_set_mem(RIG *rig, vfo_t vfo, int ch) { struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; /* memorize channel for RIG_OP_TO_VFO & RIG_OP_FROM_VFO */ priv->ch = ch; return RIG_OK; } int cu_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; char cmdbuf[16]; switch (op) { case RIG_OP_TUNE: cmdbuf[0] = 'R'; cmdbuf[1] = 0; break; case RIG_OP_CPY: cmdbuf[0] = ':'; cmdbuf[1] = ';'; cmdbuf[2] = 0x0d; cmdbuf[3] = 0; break; case RIG_OP_TO_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "<%02u"CR, (unsigned)priv->ch); break; case RIG_OP_FROM_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "d%02u"CR, (unsigned)priv->ch); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } hamlib-4.6.5/rigs/skanti/Android.mk0000664000175000017500000000041615056640443012623 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := trp8000.c trp8255.c skanti.c LOCAL_MODULE := skanti LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/skanti/Makefile.in0000664000175000017500000005324015056640453012763 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/skanti ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_skanti_la_LIBADD = am__objects_1 = trp8000.lo trp8255.lo skanti.lo am_libhamlib_skanti_la_OBJECTS = $(am__objects_1) libhamlib_skanti_la_OBJECTS = $(am_libhamlib_skanti_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/skanti.Plo ./$(DEPDIR)/trp8000.Plo \ ./$(DEPDIR)/trp8255.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_skanti_la_SOURCES) DIST_SOURCES = $(libhamlib_skanti_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SKANTISRC = trp8000.c trp8255.c skanti.c skanti.h noinst_LTLIBRARIES = libhamlib-skanti.la libhamlib_skanti_la_SOURCES = $(SKANTISRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/skanti/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/skanti/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-skanti.la: $(libhamlib_skanti_la_OBJECTS) $(libhamlib_skanti_la_DEPENDENCIES) $(EXTRA_libhamlib_skanti_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_skanti_la_OBJECTS) $(libhamlib_skanti_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skanti.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trp8000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trp8255.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/skanti.Plo -rm -f ./$(DEPDIR)/trp8000.Plo -rm -f ./$(DEPDIR)/trp8255.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/skanti.Plo -rm -f ./$(DEPDIR)/trp8000.Plo -rm -f ./$(DEPDIR)/trp8255.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/skanti/trp8000.c0000664000175000017500000000764015056640443012201 /* * Hamlib Skanti backend - TRP8000 description * Copyright (c) 2004-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "skanti.h" /* modes: what about MCW, R3E ? */ #define TRP8000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8000_AM_TX_MODES RIG_MODE_AM #define TRP8000_FUNC (RIG_FUNC_NONE) #define TRP8000_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define TRP8000_PARM_ALL (RIG_PARM_NONE) #define TRP8000_VFO (RIG_VFO_A) /* TBC */ /* * trp8000 rig capabilities. * * * TODO: TUNING, BFO, SENSITIVITY(RF gain?) */ struct rig_caps trp8000_caps = { RIG_MODEL(RIG_MODEL_TRP8000), .model_name = "TRP8000", .mfg_name = "Skanti", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 300, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = TRP8000_FUNC, .has_set_func = TRP8000_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_SET(TRP8000_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(TRP8000_PARM_ALL), .vfo_ops = RIG_OP_TUNE, .preamp = { 10, RIG_DBLST_END }, /* TBC */ .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRP8000_ALL_MODES, -1, -1, TRP8000_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(2), MHz(30), TRP8000_AM_TX_MODES, W(4), W(40), TRP8000_VFO}, {MHz(2), MHz(30), TRP8000_OTHER_TX_MODES, W(10), W(100), TRP8000_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TRP8000_ALL_MODES, 10}, {TRP8000_ALL_MODES, 100}, {TRP8000_ALL_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* rough guesses */ {TRP8000_ALL_MODES, kHz(2.7)}, /* intermit */ {TRP8000_ALL_MODES, kHz(2.1)}, /* narrow */ {TRP8000_ALL_MODES, kHz(6)}, /* wide */ {TRP8000_ALL_MODES, Hz(500)}, /* very narrow */ RIG_FLT_END, }, .set_freq = skanti_set_freq, .set_mode = skanti_set_mode, .set_split_freq = skanti_set_split_freq, .set_ptt = skanti_set_ptt, .vfo_op = skanti_vfo_op, .set_level = skanti_set_level, .reset = skanti_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/skanti/skanti.c0000664000175000017500000001627615056640443012362 /* * Hamlib Skanti backend - main file * Copyright (c) 2004-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include #include "skanti.h" /* Line Feed */ #define EOM "\x0d" #define LF "\x0a" #define PROMPT ">" #define BUFSZ 32 /* * modes */ #define MD_LSB "L" #define MD_USB "J" #define MD_CW "A1" #define MD_MCW "A2" #define MD_AM "H" #define MD_RTTY "F" #define MD_R3E "R" /* * skanti_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int skanti_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, check for OK returned */ if (!data || !data_len) { /* * Transceiver sends back ">" */ char retbuf[BUFSZ + 1]; retval = read_string(rp, (unsigned char *) retbuf, BUFSZ, PROMPT, strlen(PROMPT), 0, 1); if (retval < 0) { return retval; } retbuf[retval] = '\0'; if (strstr(retbuf, PROMPT)) { return RIG_OK; } else { return -RIG_ERJCTED; } } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, strlen(LF), 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; /* strip CR/LF from string */ *data_len -= 2; data[*data_len] = 0; return RIG_OK; } /* * skanti_reset * Assumes rig!=NULL */ int skanti_reset(RIG *rig, reset_t reset) { int retval; /* * master reset * * returned data: *x1A345SF * whatever this means? unit serial #? */ retval = skanti_transaction(rig, "0" EOM, strlen("0" EOM), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * skanti_set_freq * Assumes rig!=NULL */ int skanti_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "Z%06ld" EOM, (long)(freq / 100)); return skanti_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * skanti_set_mode * Assumes rig!=NULL */ int skanti_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *sk_mode, *sk_filter; pbwidth_t passband_normal; switch (mode) { /* TODO: MCW, R3E */ case RIG_MODE_CW: sk_mode = MD_CW EOM; break; case RIG_MODE_USB: sk_mode = MD_USB EOM; break; case RIG_MODE_LSB: sk_mode = MD_LSB EOM; break; case RIG_MODE_RTTY: sk_mode = MD_RTTY EOM; break; case RIG_MODE_AM: sk_mode = MD_AM EOM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } retval = skanti_transaction(rig, sk_mode, strlen(sk_mode), NULL, NULL); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } /* * TODO: please sk8000 owners, check this, I'm not sure * which passband is default! */ passband_normal = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL || width == passband_normal) { sk_filter = "I" EOM; } else if (width < passband_normal) { sk_filter = width < 1000 ? "V" EOM : "N" EOM; } else { sk_filter = "W" EOM; } retval = skanti_transaction(rig, sk_filter, strlen(sk_filter), NULL, NULL); return retval; } /* * skanti_set_split_freq * Assumes rig!=NULL */ int skanti_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { char freqbuf[BUFSZ]; /* 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "T%06ld" EOM, (long)(tx_freq / 100)); return skanti_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * skanti_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int skanti_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[BUFSZ], *agc; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "R%c" EOM, val.i ? 'F' : 'O'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%c" EOM, val.i ? 'T' : 'O'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%cO" EOM, val.f < 0.33 ? 'L' : (val.f < 0.66 ? 'M' : 'F')); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_SLOW: agc = "AS"EOM; break; case RIG_AGC_FAST: agc = "AA"EOM; break; case RIG_AGC_OFF: agc = "AF"EOM; break; default: return -RIG_EINVAL; } return skanti_transaction(rig, agc, strlen(agc), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * skanti_set_ptt * Assumes rig!=NULL, ptt!=NULL */ int skanti_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "X%c" EOM, ptt == RIG_PTT_ON ? 'N' : 'F'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } int skanti_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { if (op != RIG_OP_TUNE) { return -RIG_EINVAL; } return skanti_transaction(rig, "XT"EOM, strlen("XT"EOM), NULL, NULL); } /* * initrigs_skanti is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(skanti) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&trp8000_caps); rig_register(&trp8255_caps); return RIG_OK; } hamlib-4.6.5/rigs/skanti/skanti.h0000664000175000017500000000270315056640443012355 /* * Hamlib Skanti backend - main header * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _SKANTI_H #define _SKANTI_H 1 #include #define BACKEND_VER "20191208" int skanti_reset(RIG *rig, reset_t reset); int skanti_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int skanti_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int skanti_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int skanti_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int skanti_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int skanti_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); extern struct rig_caps trp8000_caps; extern struct rig_caps trp8255_caps; #endif /* _SKANTI_H */ hamlib-4.6.5/rigs/skanti/Makefile.am0000664000175000017500000000024015056640443012741 SKANTISRC = trp8000.c trp8255.c skanti.c skanti.h noinst_LTLIBRARIES = libhamlib-skanti.la libhamlib_skanti_la_SOURCES = $(SKANTISRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/aor/0000775000175000017500000000000015056640476010267 5hamlib-4.6.5/rigs/aor/aor.h0000664000175000017500000000561015056640443011135 /* * Hamlib AOR backend - main header * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AOR_H #define _AOR_H 1 #include #define BACKEND_VER "20220630" int format8k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); int parse8k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); struct aor_priv_caps { int (*format_mode)(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); int (*parse_aor_mode)(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); char bank_base1; char bank_base2; }; int aor_close(RIG *rig); int aor_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int aor_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int aor_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int aor_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int aor_set_vfo(RIG *rig, vfo_t vfo); int aor_get_vfo(RIG *rig, vfo_t *vfo); int aor_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int aor_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int aor_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int aor_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); int aor_set_powerstat(RIG *rig, powerstat_t status); int aor_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int aor_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char *aor_get_info(RIG *rig); int aor_set_mem(RIG *rig, vfo_t vfo, int ch); int aor_get_mem(RIG *rig, vfo_t vfo, int *ch); int aor_set_bank(RIG *rig, vfo_t vfo, int bank); int aor_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int aor_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int aor_get_chan_all_cb (RIG * rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t); extern struct rig_caps ar2700_caps; extern struct rig_caps ar8200_caps; extern struct rig_caps ar8000_caps; extern struct rig_caps ar8600_caps; extern struct rig_caps ar5000_caps; extern struct rig_caps ar3000a_caps; extern struct rig_caps ar7030_caps; extern struct rig_caps ar3030_caps; extern struct rig_caps ar5000a_caps; extern struct rig_caps ar7030p_caps; extern struct rig_caps sr2200_caps; #endif /* _AOR_H */ hamlib-4.6.5/rigs/aor/aor.c0000664000175000017500000010245015056640443011130 /* * Hamlib AOR backend - main file * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "idx_builtin.h" #include "aor.h" /* * acknowledge is CR * Is \r portable enough? */ #define CR '\r' #define EOM "\r" #define BUFSZ 256 /* * modes in use by the "MD" command of AR8000 and AR8200 */ #define AR8K_WFM '0' #define AR8K_NFM '1' #define AR8K_AM '2' #define AR8K_USB '3' #define AR8K_LSB '4' #define AR8K_CW '5' #define AR8K_SFM '6' #define AR8K_WAM '7' #define AR8K_NAM '8' /* * aor_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int aor_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char ackbuf[BUFSZ]; int ack_len; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { data = ackbuf; } if (!data_len) { data_len = &ack_len; } /* * Do wait for a reply */ retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } /* chop LF head when present */ if (retval >= 1 && data[0] == '\x0a') { retval--; memmove(data, data + 1, retval); } *data_len = retval; if (*data_len < BUFSZ) { data[*data_len] = '\0'; } else { data[BUFSZ - 1] = '\0'; } if (retval >= 1 && data[0] == '?') { /* command failed? resync with radio */ write_block(rp, (unsigned char *) EOM, 1); return -RIG_EPROTO; } return RIG_OK; } /* * aor_close * Assumes rig!=NULL */ int aor_close(RIG *rig) { /* * terminate remote operation via the RS-232 * Note: use write_block() instead of aor_transaction * since no reply is to be expected. */ return write_block(RIGPORT(rig), (unsigned char *) "EX" EOM, 3); } static int format_freq(char *buf, int buf_len, freq_t freq) { int lowhz; int64_t f = (int64_t)freq; /* * actually, frequency must be like nnnnnnnnm0, * where m must be 0 or 5 (for 50Hz). */ lowhz = f % 100; f /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } f = f * 100 + lowhz; SNPRINTF(buf, buf_len, "RF%010"PRIll, f); return strlen(buf); } /* * aor_set_freq * Assumes rig!=NULL */ int aor_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int freq_len; freq_len = format_freq(freqbuf, sizeof(freqbuf), freq); strcpy(freqbuf + freq_len, EOM); freq_len += strlen(EOM); return aor_transaction(rig, freqbuf, freq_len, NULL, NULL); } /* * aor_get_freq * Assumes rig!=NULL, freq!=NULL */ int aor_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; retval = aor_transaction(rig, "RX" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strstr(freqbuf, "RF"); if (!rfp && rig->caps->rig_model == RIG_MODEL_AR8000) { rfp = strstr(freqbuf, "VA"); } if (!rfp && rig->caps->rig_model == RIG_MODEL_AR8000) { rfp = strstr(freqbuf, "VB"); } if (!rfp) { rig_debug(RIG_DEBUG_WARN, "NO RF in returned string in aor_get_freq: '%s'\n", freqbuf); return -RIG_EPROTO; } sscanf(rfp + 2, "%"SCNfreq, freq); return RIG_OK; } /* * aor_set_vfo * Assumes rig!=NULL */ int aor_set_vfo(RIG *rig, vfo_t vfo) { char *vfocmd; switch (vfo) { case RIG_VFO_VFO: if (rig->caps->rig_model == RIG_MODEL_AR8000) { vfocmd = "RF" EOM; } else { vfocmd = "VF" EOM; } break; case RIG_VFO_A: vfocmd = "VA" EOM; break; case RIG_VFO_B: vfocmd = "VB" EOM; break; case RIG_VFO_C: vfocmd = "VC" EOM; break; case RIG_VFO_N(3): vfocmd = "VD" EOM; break; case RIG_VFO_N(4): vfocmd = "VE" EOM; break; case RIG_VFO_MEM: vfocmd = "MR" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_set_vfo: unsupported vfo %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } return aor_transaction(rig, vfocmd, strlen(vfocmd), NULL, NULL); } /* * aor_get_vfo * Assumes rig!=NULL, freq!=NULL */ int aor_get_vfo(RIG *rig, vfo_t *vfo) { int vfo_len, retval; char vfobuf[BUFSZ]; retval = aor_transaction(rig, "RX" EOM, 3, vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { switch (vfobuf[0]) { case 'S': case 'D': *vfo = RIG_VFO_VFO; break; case 'V': *vfo = RIG_VFO_N(vfobuf[4] - 'A'); break; case 'M': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %s\n", vfobuf); return -RIG_EINVAL; } } else { switch (vfobuf[1]) { case 'S': case 'V': case 'F': *vfo = RIG_VFO_VFO; break; case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; case 'C': *vfo = RIG_VFO_C; break; case 'D': *vfo = RIG_VFO_N(3); break; case 'E': *vfo = RIG_VFO_N(4); break; case 'R': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %c\n", vfobuf[1]); return -RIG_EINVAL; } } return RIG_OK; } int format8k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: if (rig->caps->rig_model == RIG_MODEL_AR8000) { aormode = AR8K_AM; } else { switch (width) { case RIG_PASSBAND_NORMAL: case s_kHz(9): aormode = AR8K_AM; break; case s_kHz(12): aormode = AR8K_WAM; break; case s_kHz(3): aormode = AR8K_NAM; break; case RIG_PASSBAND_NOCHANGE: aormode = AR8K_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported passband %s %d\n", __func__, rig_strrmode(mode), (int)width); return -RIG_EINVAL; } } break; case RIG_MODE_CW: aormode = AR8K_CW; break; case RIG_MODE_USB: aormode = AR8K_USB; break; case RIG_MODE_LSB: aormode = AR8K_LSB; break; case RIG_MODE_WFM: aormode = AR8K_WFM; break; case RIG_MODE_FM: if (rig->caps->rig_model == RIG_MODEL_AR8000) { aormode = AR8K_NFM; } else { switch (width) { case RIG_PASSBAND_NORMAL: case s_kHz(12): aormode = AR8K_NFM; break; case s_kHz(9): aormode = AR8K_SFM; break; case RIG_PASSBAND_NOCHANGE: aormode = AR8K_NFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported passband %s %d\n", __func__, rig_strrmode(mode), (int)width); return -RIG_EINVAL; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } /* * aor_set_mode * Assumes rig!=NULL */ int aor_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char mdbuf[9]; char mdbuf2[16] = ""; int mdbuf2_len, retval; if (priv->format_mode(rig, mdbuf, sizeof(mdbuf), mode, width) <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: format_mode=%s failed?\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } strcat(mdbuf, EOM); switch (rig->caps->rig_model) { case RIG_MODEL_AR5000: case RIG_MODEL_AR5000A: SNPRINTF(mdbuf2, sizeof(mdbuf2), "%.3s", mdbuf); /* Extract first 'MD' part */ mdbuf2_len = strlen(mdbuf2); strcpy(mdbuf2 + mdbuf2_len, EOM); /* Add delimiter */ mdbuf2_len = strlen(mdbuf2); retval = aor_transaction(rig, mdbuf2, mdbuf2_len, NULL, NULL); if (retval != RIG_OK) { return retval; } strncpy(mdbuf2, mdbuf + 4, 3); /* Extract first 'BW' part */ mdbuf2[3] = '\0'; // in case strnpy produces and un-terminated string mdbuf2_len = strlen(mdbuf2); retval = aor_transaction(rig, mdbuf2, mdbuf2_len, NULL, NULL); if (retval != RIG_OK) { return retval; } break; default: retval = aor_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); } return retval; } /* * parse8k_aor_mode * don't care about aorwidth, * because there's no such BW command */ int parse8k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { *width = RIG_PASSBAND_NORMAL; switch (aormode) { case AR8K_AM: *mode = RIG_MODE_AM; break; case AR8K_NAM: *mode = RIG_MODE_AM; *width = rig_passband_narrow(rig, *mode); break; case AR8K_WAM: *mode = RIG_MODE_AM; *width = rig_passband_wide(rig, *mode); break; case AR8K_CW: *mode = RIG_MODE_CW; break; case AR8K_USB: *mode = RIG_MODE_USB; break; case AR8K_LSB: *mode = RIG_MODE_LSB; break; case AR8K_WFM: *mode = RIG_MODE_WFM; break; case AR8K_NFM: *mode = RIG_MODE_FM; break; case AR8K_SFM: *mode = RIG_MODE_FM; *width = rig_passband_narrow(rig, *mode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EINVAL; } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * aor_get_mode * Assumes rig!=NULL, mode!=NULL */ int aor_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char ackbuf[BUFSZ]; char ackbuf2[BUFSZ]; char *mdp, *mdp2; int ack_len, ack2_len, retval; retval = aor_transaction(rig, "MD" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } /* * search MD, because on the AR5000, AU is also returned * by MD request */ mdp = strstr(ackbuf, "MD"); if (!mdp) { rig_debug(RIG_DEBUG_ERR, "%s: no MD in returned string: '%s'\n", __func__, ackbuf); return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR5000 || rig->caps->rig_model == RIG_MODEL_AR5000A) { retval = aor_transaction(rig, "BW" EOM, 3, ackbuf2, &ack2_len); if (retval != RIG_OK) { return retval; } mdp2 = strstr(ackbuf2, "BW"); } else { mdp2 = mdp; } retval = priv->parse_aor_mode(rig, mdp[2], mdp2[2], mode, width); return retval; } /* * aor_set_ts * Assumes rig!=NULL */ int aor_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char tsbuf[BUFSZ]; /* * actually, tuning step must be like nnnnm0, * where m must be 0 or 5 (for 50Hz). */ SNPRINTF(tsbuf, sizeof(tsbuf), "ST%06ld" EOM, ts); return aor_transaction(rig, tsbuf, strlen(tsbuf), NULL, NULL); } /* * aor_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs; char lvlbuf[BUFSZ]; int agc; rs = STATE(rig); switch (level) { case RIG_LEVEL_ATT: { unsigned att = 0; unsigned i; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && !RIG_IS_DBLST_END(rs->attenuator[i]); i++) { if (rs->attenuator[i] == val.i) { att = i + 1; break; } } /* should be caught by the front end */ if ((val.i != 0) && (i >= HAMLIB_MAXDBLSTSIZ || RIG_IS_DBLST_END(rs->attenuator[i]))) { return -RIG_EINVAL; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT%u" EOM, att); break; } case RIG_LEVEL_AGC: /* AR5000 & AR5000A */ switch (val.i) { case RIG_AGC_FAST: agc = '0'; break; case RIG_AGC_MEDIUM: agc = '1'; break; case RIG_AGC_SLOW: agc = '2'; break; case RIG_AGC_OFF: default: agc = 'F'; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC%c" EOM, agc); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported aor_set_level %d\n", (int)level); return -RIG_EINVAL; } return aor_transaction(rig, lvlbuf, strlen(lvlbuf), NULL, NULL); } /* * aor_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int aor_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs = STATE(rig); char lvlbuf[BUFSZ], ackbuf[BUFSZ]; int ack_len, retval; switch (level) { case RIG_LEVEL_RAWSTR: SNPRINTF(lvlbuf, sizeof(lvlbuf), "LM" EOM); break; case RIG_LEVEL_ATT: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT" EOM); break; case RIG_LEVEL_AGC: /* AR5000 & AR5000A */ SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported %s %d\n", __func__, (int)level); return -RIG_EINVAL; } retval = aor_transaction(rig, lvlbuf, strlen(lvlbuf), ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RAWSTR: if (ack_len < 4 || ackbuf[0] != 'L' || ackbuf[1] != 'M') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { sscanf(ackbuf + 2, "%x", &val->u); val->i &= ~0x80; /* mask squelch status */ } else if (rig->caps->rig_model == RIG_MODEL_AR8200 || rig->caps->rig_model == RIG_MODEL_AR8600) { sscanf(ackbuf + 3, "%d", &val->i); } else { sscanf(ackbuf + 3, "%x", &val->u); } break; case RIG_LEVEL_ATT: { unsigned att; if (ack_len < 4 || ackbuf[0] != 'A' || ackbuf[1] != 'T') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { att = ackbuf[2] - '0'; } else { att = ackbuf[3] - '0'; } if (att == 0) { val->i = 0; break; } if (att > HAMLIB_MAXDBLSTSIZ || rs->attenuator[att - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "Unsupported att %s %u\n", __func__, att); return -RIG_EPROTO; } val->i = rs->attenuator[att - 1]; break; } case RIG_LEVEL_AGC: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'C') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR5000 || rig->caps->rig_model == RIG_MODEL_AR5000A) { /* AR5000A requires switching to be made on 3rd returned character. SM6PPS */ switch (ackbuf[2]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case 'F': default: val->i = RIG_AGC_OFF; } } else { /* Left the switching on 4th position in case models other than AR5000(A) use this. SM6PPS */ switch (ackbuf[3]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case 'F': default: val->i = RIG_AGC_OFF; } } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported %s %d\n", __func__, (int)level); return -RIG_EINVAL; } return RIG_OK; } /* * aor_get_dcd * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int aor_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char ackbuf[BUFSZ]; int ack_len, retval; retval = aor_transaction(rig, "LM" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len < 2 || ackbuf[0] != 'L' || ackbuf[1] != 'M') { return -RIG_EPROTO; } *dcd = ackbuf[2] == '%' ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * aor_set_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_set_powerstat(RIG *rig, powerstat_t status) { if (status == RIG_POWER_ON) { return aor_transaction(rig, "X" EOM, 2, NULL, NULL); } /* turn off power */ return aor_transaction(rig, "QP" EOM, 3, NULL, NULL); } /* * aor_vfo_op * Assumes rig!=NULL */ int aor_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char *aorcmd; switch (op) { case RIG_OP_UP: aorcmd = "\x1e" EOM; break; case RIG_OP_DOWN: aorcmd = "\x1f" EOM; break; case RIG_OP_RIGHT: aorcmd = "\x1c" EOM; break; case RIG_OP_LEFT: aorcmd = "\x1d" EOM; break; case RIG_OP_MCL: aorcmd = "MQ" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_vfo_op: unsupported op %d\n", op); return -RIG_EINVAL; } return aor_transaction(rig, aorcmd, strlen(aorcmd), NULL, NULL); } /* * aor_scan, scan operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char *aorcmd; switch (scan) { case RIG_SCAN_STOP: /* Not sure how to stop the scanning. * Maye by going by to MEM/VFO mode? * Any clue? */ if (vfo == RIG_VFO_CURR) { vfo = RIG_VFO_MEM; /* supported by all the AOR rigs */ } return rig_set_vfo(rig, vfo); case RIG_SCAN_MEM: aorcmd = "MS" EOM; break; case RIG_SCAN_SLCT: aorcmd = "SM" EOM; break; case RIG_SCAN_PROG: aorcmd = "VS" EOM; break; /* edges are VFO A & VFO B */ case RIG_SCAN_VFO: aorcmd = "VV1" EOM; break; /* VFO scan mode, VV0 for 2-VFO mode */ default: rig_debug(RIG_DEBUG_ERR, "aor_scan: unsupported scan %d\n", scan); return -RIG_EINVAL; } return aor_transaction(rig, aorcmd, strlen(aorcmd), NULL, NULL); } /* * aor_set_mem * Assumes rig!=NULL */ int aor_set_mem(RIG *rig, vfo_t vfo, int ch) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char membuf[BUFSZ]; int mem_num; char bank_base; /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ mem_num = ch % 100; if (mem_num >= 50 && priv->bank_base1 != priv->bank_base2) { bank_base = priv->bank_base2; mem_num -= 50; } else { bank_base = priv->bank_base1; } SNPRINTF(membuf, sizeof(membuf), "MR%c%02d" EOM, bank_base + ch / 100, mem_num); return aor_transaction(rig, membuf, strlen(membuf), NULL, NULL); } /* * aor_get_mem * Assumes rig!=NULL, freq!=NULL */ int aor_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; int mem_len, retval; char membuf[BUFSZ]; retval = aor_transaction(rig, "MR" EOM, 3, membuf, &mem_len); if (retval != RIG_OK) { return retval; } if (membuf[0] == '?' || membuf[2] == '?') { return -RIG_ENAVAIL; } sscanf(membuf + 3, "%d", ch); /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ if (membuf[2] >= priv->bank_base2) { *ch += 100 * (membuf[2] - priv->bank_base2) + 50; } else { *ch += 100 * (membuf[2] - priv->bank_base1); } return RIG_OK; } /* * aor_set_bank * Assumes rig!=NULL */ int aor_set_bank(RIG *rig, vfo_t vfo, int bank) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char membuf[BUFSZ]; SNPRINTF(membuf, sizeof(membuf), "MR%c" EOM, (bank % 10) + (bank < 10 ? priv->bank_base1 : priv->bank_base2)); return aor_transaction(rig, membuf, strlen(membuf), NULL, NULL); } int aor_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char aorcmd[BUFSZ]; int cmd_len; SNPRINTF(aorcmd, sizeof(aorcmd), "MX%c%02d ", chan->bank_num, chan->channel_num % 100); cmd_len = strlen(aorcmd); cmd_len += format_freq(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, chan->freq); /* * FIXME: automode */ cmd_len += snprintf(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, " AU%d ST%06d ", 0, (int)chan->tuning_step); cmd_len += priv->format_mode(rig, aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, chan->mode, chan->width); cmd_len += snprintf(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, " AT%d TM%12s%s", chan->levels[LVL_ATT].i ? 1 : 0, chan->channel_desc, EOM); return aor_transaction(rig, aorcmd, cmd_len, NULL, NULL); } static int parse_chan_line(RIG *rig, channel_t *chan, char *basep, const channel_cap_t *mem_caps) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char *tagp; int ts; /* * search for attribute tags in the line. * Using strstr enable support for various models * which may or may not have tag support. */ tagp = strstr(basep, "---"); if (tagp) { vfo_t vfo_save = chan->vfo; int ch_save = chan->channel_num; rig_debug(RIG_DEBUG_WARN, "%s: skipping, channel is empty: '%s'\n", __func__, basep); memset(chan, 0, sizeof(channel_t)); chan->vfo = vfo_save; chan->channel_num = ch_save; return -RIG_ENAVAIL; } /* bank_num */ if (mem_caps->bank_num) { tagp = strstr(basep, "MX"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MX in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->bank_num = tagp[2] - (tagp[2] >= priv->bank_base2 ? priv->bank_base2 + 10 : priv->bank_base1); } /* pass */ if (mem_caps->flags) { tagp = strstr(basep, "MP"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MP in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->flags = tagp[2] == '0' ? 0 : RIG_CHFLAG_SKIP; } /* frequency */ if (mem_caps->freq) { tagp = strstr(basep, "RF"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no RF in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } sscanf(tagp + 2, "%"SCNfreq, &chan->freq); } /* channel desc */ if (mem_caps->tuning_step) { tagp = strstr(basep, "ST"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no ST in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } ts = chan->tuning_step; sscanf(tagp + 2, "%d", &ts); } /* mode and width */ if (mem_caps->mode && mem_caps->width) { int retval; char *tag2p; tagp = strstr(basep, "MD"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MD in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } /* "BW" only on AR5000 */ tag2p = strstr(basep, "BW"); if (!tag2p) { tag2p = tagp; } retval = priv->parse_aor_mode(rig, tagp[2], tag2p[2], &chan->mode, &chan->width); if (retval != RIG_OK) { return retval; } } /* auto-mode */ if (mem_caps->funcs & RIG_FUNC_ABM) { tagp = strstr(basep, "AU"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no AU in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->funcs = tagp[2] == '0' ? 0 : RIG_FUNC_ABM; } /* attenuator */ if (mem_caps->levels & LVL_ATT) { tagp = strstr(basep, "AT"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no AT in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->levels[LVL_ATT].i = tagp[2] == '0' ? 0 : rig->caps->attenuator[tagp[2] - '0' - 1]; } /* channel desc */ if (mem_caps->channel_desc) { int i; tagp = strstr(basep, "TM"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no TM in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } strncpy(chan->channel_desc, tagp + 2, 12); chan->channel_desc[12] = '\0'; /* chop off trailing spaces */ for (i = 11; i > 0 && chan->channel_desc[i] == ' '; i--) { chan->channel_desc[i] = '\0'; } } return RIG_OK; } int aor_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char aorcmd[BUFSZ]; int chan_len; char chanbuf[BUFSZ]; int retval; channel_cap_t *mem_caps = NULL; chan_t *chan_list; int channel_num = chan->channel_num; chan_list = rig->caps->chan_list; if (chan->vfo == RIG_VFO_CURR) { /* * curr VFO mem_caps same as memory caps */ mem_caps = &chan_list[0].mem_caps; } else { int mem_num; char bank_base; /* * find mem_caps in caps, we'll need it later */ int i; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (channel_num >= chan_list[i].startc && channel_num <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } if (!mem_caps) { return -RIG_EINVAL; } /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ mem_num = channel_num % 100; if (mem_num >= 50 && priv->bank_base1 != priv->bank_base2) { bank_base = priv->bank_base2; mem_num -= 50; } else { bank_base = priv->bank_base1; } SNPRINTF(aorcmd, sizeof(aorcmd), "MR%c%02d" EOM, bank_base + channel_num / 100, mem_num); retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); /* is the channel empty? */ if (retval == -RIG_EPROTO && chanbuf[0] == '?') { chan->freq = RIG_FREQ_NONE; return -RIG_ENAVAIL; } if (retval != RIG_OK) { return retval; } } SNPRINTF(aorcmd, sizeof(aorcmd), "RX" EOM); retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } retval = parse_chan_line(rig, chan, chanbuf, mem_caps); if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return retval; } #define LINES_PER_MA 10 int aor_get_chan_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; int i, j, retval; chan_t *chan_list = STATE(rig)->chan_list; channel_t *chan; int chan_count; char aorcmd[BUFSZ]; int chan_len; char chanbuf[BUFSZ]; int chan_next = chan_list[0].startc; chan_count = chan_list[0].endc - chan_list[0].startc + 1; /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; retval = chan_cb(rig, vfo, &chan, chan_next, chan_list, arg); if (retval != RIG_OK) { return retval; } if (chan == NULL) { return -RIG_ENOMEM; } SNPRINTF(aorcmd, sizeof(aorcmd), "MA%c" EOM, priv->bank_base1); for (i = 0; i < chan_count / LINES_PER_MA; i++) { retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } for (j = 0; j < LINES_PER_MA; j++) { chan->vfo = RIG_VFO_MEM; chan->channel_num = i * LINES_PER_MA + j; retval = parse_chan_line(rig, chan, chanbuf, &chan_list[0].mem_caps); if (retval == -RIG_ENAVAIL) { retval = RIG_OK; } if (retval != RIG_OK) { return retval; } /* notify the end? */ chan_next = chan_next < chan_list[i].endc ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, vfo, &chan, chan_next, chan_list, arg); if (j >= LINES_PER_MA - 1) { break; } /* * get next line */ retval = read_string(RIGPORT(rig), (unsigned char *) chanbuf, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } } SNPRINTF(aorcmd, sizeof(aorcmd), "MA" EOM); } return RIG_OK; } /* * aor_get_info * Assumes rig!=NULL */ const char *aor_get_info(RIG *rig) { static char infobuf[BUFSZ]; int id_len, frm_len, retval; char idbuf[BUFSZ]; char frmbuf[32]; // only expect 6 chars...please check retval = aor_transaction(rig, "\001" EOM, 2, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } // never executed -- if (retval > 2) { idbuf[2] = '\0'; } retval = aor_transaction(rig, "VR" EOM, 3, frmbuf, &frm_len); if (retval != RIG_OK || frm_len > 16) { return NULL; } frmbuf[frm_len] = '\0'; SNPRINTF(infobuf, sizeof(infobuf), "Remote ID %c%c, Firmware version %s", idbuf[0], idbuf[1], frmbuf); return infobuf; } /* * initrigs_aor is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(aor) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&sr2200_caps); rig_register(&ar2700_caps); rig_register(&ar8200_caps); rig_register(&ar8000_caps); rig_register(&ar8600_caps); rig_register(&ar5000_caps); rig_register(&ar3000a_caps); rig_register(&ar7030_caps); rig_register(&ar3030_caps); rig_register(&ar5000a_caps); rig_register(&ar7030p_caps); return RIG_OK; } hamlib-4.6.5/rigs/aor/ar3030.c0000664000175000017500000004512715056640443011266 /* * Hamlib AOR backend - AR3030 description * Copyright (c) 2000-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "idx_builtin.h" #include "misc.h" static int ar3030_set_vfo(RIG *rig, vfo_t vfo); static int ar3030_get_vfo(RIG *rig, vfo_t *vfo); static int ar3030_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ar3030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ar3030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ar3030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ar3030_set_mem(RIG *rig, vfo_t vfo, int ch); static int ar3030_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ar3030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ar3030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ar3030_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ar3030_init(RIG *rig); static int ar3030_cleanup(RIG *rig); static int ar3030_close(RIG *rig); static int ar3030_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); struct ar3030_priv_data { int curr_ch; int curr_vfo; }; /* * TODO: * set_channel(emulated?),rig_vfo_op * rig_reset(RIG_RESET_MCALL) * quit the remote control mode on close? */ #define AR3030_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_FAX) #define AR3030_FUNC_ALL (RIG_FUNC_NONE) #define AR3030_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define AR3030_PARM (RIG_PARM_NONE) #define AR3030_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) #define AR3030_VFO (RIG_VFO_A|RIG_VFO_MEM) /* * FIXME: */ #define AR3030_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0x3f, 60 } \ } } #define AR3030_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_SET(AR3030_LEVEL), \ .flags = 1, \ } /* * Data was obtained from AR3030 pdf on http://www.aoruk.com * * ar3030 rig capabilities. */ struct rig_caps ar3030_caps = { RIG_MODEL(RIG_MODEL_AR3030), .model_name = "AR3030", .mfg_name = "AOR", .version = "20200113.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 50, /* ms */ .timeout = 500, .retry = 0, .has_get_func = AR3030_FUNC_ALL, .has_set_func = AR3030_FUNC_ALL, .has_get_level = AR3030_LEVEL, .has_set_level = RIG_LEVEL_SET(AR3030_LEVEL), .has_get_parm = AR3030_PARM, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = AR3030_VFO_OPS, .str_cal = AR3030_STR_CAL, .chan_list = { { 0, 99, RIG_MTYPE_MEM, AR3030_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), AR3030_MODES, -1, -1, AR3030_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), AR3030_MODES, -1, -1, AR3030_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a receiver! */ .tuning_steps = { {AR3030_MODES, 10}, {AR3030_MODES, 100}, {AR3030_MODES, kHz(1)}, {AR3030_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW, 500}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .rig_init = ar3030_init, .rig_cleanup = ar3030_cleanup, .rig_close = ar3030_close, .set_freq = ar3030_set_freq, .get_freq = ar3030_get_freq, .set_mode = ar3030_set_mode, .get_mode = ar3030_get_mode, .set_vfo = ar3030_set_vfo, .get_vfo = ar3030_get_vfo, .set_level = ar3030_set_level, .get_level = ar3030_get_level, .set_mem = ar3030_set_mem, .get_mem = ar3030_get_mem, .get_channel = ar3030_get_channel, .vfo_op = ar3030_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* is LF really needed? */ #define CR "\x0d" #define EOM "\x0d\x0a" #define BUFSZ 64 /* * ar3030_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise */ static int ar3030_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); int retry = 3; char tmpdata[BUFSZ]; if (data == NULL) { data = tmpdata; } rig_flush(rp); do { retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block error=%d\n", __func__, retval); return retval; } if (data) { /* expecting 0x0d0x0a on all commands so wait for the 0x0a */ retval = read_string(rp, (unsigned char *) data, BUFSZ, "\x0a", 1, 0, 1); if (retval == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_ERR, "%s:timeout retry=%d\n", __func__, retry); hl_usleep(50000); } } rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d retry=%d\n", __func__, retval, retry); } while ((retval <= 0) && (--retry > 0)); hl_usleep(1000); // 1ms sleep per manual if (data_len != NULL && retval > 0) { *data_len = 0; /* only set data_len non-zero if not a command response */ if (data[0] != 0x00 && data[0] != 0x0d) { *data_len = retval; } } rig_debug(RIG_DEBUG_TRACE, "%s: return data_len=%d retry=%d\n", __func__, data_len ? *data_len : 0, retry); return RIG_OK; } int ar3030_init(RIG *rig) { struct ar3030_priv_data *priv; struct rig_state *rs = STATE(rig); rs->priv = calloc(1, sizeof(struct ar3030_priv_data)); if (!rs->priv) { return -RIG_ENOMEM; } priv = rs->priv; priv->curr_ch = 99; /* huh! FIXME: get_mem in open() ? */ priv->curr_vfo = RIG_VFO_A; return RIG_OK; } int ar3030_cleanup(RIG *rig) { struct ar3030_priv_data *priv = STATE(rig)->priv; free(priv); return RIG_OK; } int ar3030_close(RIG *rig) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); rig_flush(RIGPORT(rig)); retval = ar3030_transaction(rig, "Q" CR, strlen("Q" CR), NULL, NULL); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); return retval; } int ar3030_set_vfo(RIG *rig, vfo_t vfo) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char *cmd = ""; int retval; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: cmd = "D" CR; break; case RIG_VFO_MEM: cmd = "M" CR; break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval == RIG_OK) { priv->curr_vfo = vfo; } return retval; } int ar3030_get_vfo(RIG *rig, vfo_t *vfo) { const struct ar3030_priv_data *priv = (struct ar3030_priv_data *) STATE(rig)->priv; *vfo = priv->curr_vfo; return RIG_OK; } /* * ar3030_set_freq * Assumes rig!=NULL */ int ar3030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char freqbuf[BUFSZ]; int retval; SNPRINTF(freqbuf, sizeof(freqbuf), "%03.6f" CR, ((double)freq) / MHz(1)); retval = ar3030_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; return RIG_OK; } /* * ar3030_get_freq * Assumes rig!=NULL, freq!=NULL */ int ar3030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; long lfreq; /* * D Rn Gn Bn Tn Fnnnnnnnn C * Note: spaces are transmitted. */ retval = ar3030_transaction(rig, "D" CR, 2, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; rfp = strchr(freqbuf, 'F'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%ld", &lfreq); *freq = lfreq; rig_debug(RIG_DEBUG_ERR, "%s: read lfreq=%ld, freq=%.6f\n", __func__, lfreq, *freq); return RIG_OK; } /* * ar3030_set_mode * Assumes rig!=NULL */ int ar3030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; switch (mode) { case RIG_MODE_AM: aormode = 'A'; break; case RIG_MODE_CW: aormode = 'C'; break; case RIG_MODE_USB: aormode = 'U'; break; case RIG_MODE_LSB: aormode = 'L'; break; case RIG_MODE_FM: aormode = 'N'; break; case RIG_MODE_AMS: aormode = 'S'; break; case RIG_MODE_FAX: aormode = 'X'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "%c" CR, aormode); } else { SNPRINTF(mdbuf, sizeof(mdbuf), "%dB%c" CR, width < rig_passband_normal(rig, mode) ? 1 : 0, aormode); } retval = ar3030_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * ar3030_get_mode * Assumes rig!=NULL, mode!=NULL */ int ar3030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int buf_len, retval; char buf[BUFSZ]; /* * D Rn Gn Bn Tn Fnnnnnnnn C * Note: spaces are transmitted */ retval = ar3030_transaction(rig, "D" CR, 2, buf, &buf_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; switch (buf[25]) { case 'A': *mode = RIG_MODE_AM; break; case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'C': *mode = RIG_MODE_CW; break; case 'S': *mode = RIG_MODE_AMS; break; case 'N': *mode = RIG_MODE_FM; break; case 'X': *mode = RIG_MODE_FAX; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, buf[25]); return -RIG_EPROTO; } *width = buf[9] == '1' ? rig_passband_narrow(rig, *mode) : rig_passband_normal(rig, *mode); return RIG_OK; } int ar3030_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int retval = RIG_OK; if (priv->curr_vfo == RIG_VFO_MEM) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" CR, ch); retval = ar3030_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } if (retval == RIG_OK) { priv->curr_ch = ch; } return retval; } int ar3030_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char infobuf[BUFSZ]; int info_len, retval; if (priv->curr_vfo != RIG_VFO_MEM) { *ch = priv->curr_ch; } retval = ar3030_transaction(rig, "M" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } /* * MnnPnRnGnBnTnFnnnnnnnnC */ if (infobuf[0] != 'M') { return -RIG_EPROTO; } /* * Is it a blank mem channel ? */ if (infobuf[1] == '-' && infobuf[2] == '-') { *ch = -1; /* FIXME: return error instead? */ return RIG_OK; } *ch = priv->curr_ch = atoi(infobuf + 1); return RIG_OK; } int ar3030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char *cmd; int retval; switch (level) { case RIG_LEVEL_AGC: /* SLOW otherwise */ cmd = val.i == RIG_AGC_FAST ? "1G" CR : "0G" CR; break; case RIG_LEVEL_ATT: cmd = val.i == 0 ? "0R" CR : (val.i == 1 ? "1R" CR : "2R" CR); break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ar3030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int info_len, retval; char infobuf[BUFSZ], *p; switch (level) { case RIG_LEVEL_ATT: /* * DRnGnBnTnFnnnnnnnnC */ retval = ar3030_transaction(rig, "D" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; p = strchr(infobuf, 'R'); if (!p) { return -RIG_EPROTO; } val->i = p[1] == '0' ? 0 : rig->caps->attenuator[p[1] - '1']; return RIG_OK; case RIG_LEVEL_AGC: /* * DRnGnBnTnFnnnnnnnnC */ retval = ar3030_transaction(rig, "D" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; p = strchr(infobuf, 'G'); if (!p) { return -RIG_EPROTO; } val->i = p[1] == '0' ? RIG_AGC_SLOW : RIG_AGC_FAST; return RIG_OK; case RIG_LEVEL_RAWSTR: retval = ar3030_transaction(rig, "Y" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } infobuf[3] = '\0'; val->i = strtol(infobuf, (char **)NULL, 16); return RIG_OK; default: return -RIG_EINVAL; } return RIG_OK; } int ar3030_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char cmdbuf[BUFSZ], infobuf[BUFSZ]; int info_len, retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" CR, chan->channel_num); retval = ar3030_transaction(rig, cmdbuf, strlen(cmdbuf), infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; /* * MnnPnRnGnBnTnFnnnnnnnnC */ if (infobuf[0] != 'M') { return -RIG_EPROTO; } /* * Is it a blank mem channel ? */ if (infobuf[1] == '-' && infobuf[2] == '-') { chan->freq = RIG_FREQ_NONE; return RIG_OK; } sscanf(infobuf + 14, "%"SCNfreq, &chan->freq); chan->freq *= 10; switch (infobuf[22]) { case 'A': chan->mode = RIG_MODE_AM; break; case 'L': chan->mode = RIG_MODE_LSB; break; case 'U': chan->mode = RIG_MODE_USB; break; case 'C': chan->mode = RIG_MODE_CW; break; case 'S': chan->mode = RIG_MODE_AMS; break; case 'N': chan->mode = RIG_MODE_FM; break; case 'X': chan->mode = RIG_MODE_FAX; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[22]); return -RIG_EPROTO; } chan->width = infobuf[10] == '1' ? rig_passband_narrow(rig, chan->mode) : rig_passband_normal(rig, chan->mode); chan->levels[LVL_ATT].i = infobuf[6] == '0' ? 0 : rig->caps->attenuator[infobuf[4] - '1']; chan->levels[LVL_AGC].i = infobuf[8] == '0' ? RIG_AGC_SLOW : RIG_AGC_FAST; chan->flags = infobuf[4] == '1' ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ar3030_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char buf[16]; int retval; switch (op) { case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), "%02d%%" CR, priv->curr_ch); break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "%02dW" CR, priv->curr_ch); priv->curr_vfo = RIG_VFO_MEM; break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } hamlib-4.6.5/rigs/aor/ar7030p.h0000664000175000017500000016041215056640443011452 /* * Hamlib AOR backend - AR7030 Plus description * Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AR7030P_H #define _AR7030P_H 1 #include "hamlib/rig.h" #include "token.h" /* AR-7030 Computer remote control protocol. Information for firmware releases 1.1A, 1.2A, 1.4A and 1.4B 1) Remote control overview. The AR-7030 receiver allows remote control of all of its functions by means of a direct memory access system. A controlling computer can read and modify the internal memory maps of the receiver to set required parameters and then call for the receiver's control program to process the new settings. Commands to the receiver are byte structured in binary format, so it is not possible to control from a terminal. All multi-byte numbers within the receiver are binary, stored MSB first. 2) Receiver frequency configuration. Receive frequency is set by two oscillators - local and carrier. In AM and FM modes the carrier oscillator is not used, and the final IF frequency is 455 kHz. In Sync mode the carrier oscillator is offset by +20.29kHz before mixing with the IF. The IF frequencies have a fixed inter-conversion frequency of 44.545MHz and, because of the high-side local oscillator, both IF's are inverted. The receiver controller processes the following variables to establish the tuned frequency :- [local offset] Frequency shift applied to local oscillator. [carrier offset] 455.00kHz for LSB, USB, Data and CW modes / 434.71kHz for Sync mode. [filter offset] IF Filter frequency at the (vestigial) carrier position as an offset from 455kHz. [PBS] User set filter shift. [BFO] User set offset between carrier position and frequency display. [TUNE] Receiver tuned frequency as shown on display. The relationship between these variables and the tuning is as follows :- [carrier offset] + [filter offset] + [PBS] + [BFO] ==> Carrier oscillator 45.000MHz + [filter offset] + [PBS] ==> [local offset] [TUNE] + [local offset] ==> Local oscillator 3) Serial data protocol. All data transfers are at 1200 baud, No parity, 8 bits, 1 stop bit (1200 N 8 1). There is no hardware or software flow control other than that inherent in the command structure. The receiver can accept data at any time at full rate provided the IR remote controller is not used or is disabled. A maximum of one byte can be transmitted for each byte received, so data flow into a controlling computer is appropriately limited. Each byte sent to the receiver is a complete command - it is best thought of as two hexadecimal digits - the first digit is the operation code, the second digit is 4-bits of data relating to the operation. Because the receiver operates with 8-bit bytes, intermediate 4-bit values are stored in registers in the receiver for recombination and processing. For example to write into the receiver's memory, the following steps would be followed:- a) Send address high order 4-bits into H-register b) Send address low order 4-bits and set Address register c) Send first data byte high order 4-bits into H-register d) Send first data byte low order 4-bits and execute Write Data Operation e) Send second data byte high order 4-bits into H-register f) Send second data byte low order 4-bits and execute Write Data Operation g) Repeat (e) and (f) for each subsequent byte to be written. 4) Memory organisation. Different memory areas in the receiver are referenced by selecting Pages - up to 16 pages are supported. The memory is broadly divided into 3 sections :- a) Working memory - where all current operating variables are stored and registers and stack are located. This memory is volatile and data is lost when power to the receiver is removed. b) Battery sustained memory - where duplicate parameters are stored for retention when power is removed. This memory area is also used for storage of filter parameters, setup memories and squelch and BFO settings for the frequency memories and contains the real time clock registers. c) EEPROM - where frequency, mode, filter and PBS information for the frequency memories is stored. Additionally S-meter and IF calibration values are stored here. This memory can be read or written to download and upload the receiver's frequency memories, but repetitive writing should be avoided because the memory devices will only support a finite number of write cycles. 5) Variations between A and B types and firmware revisions. Type A firmware supports only basic receiver functions, type B extends operations and includes support for the Notch / Noise Blanker option. The whole of the type A memory map is retained in type B, but more memory and operations are added for the extended functions of type B. In the following information, circled note numbers are included to indicate where items are specific to one type or revision of the firmware:- <1> Applicable to type B firmware only. <2> Applicable to revision 1.4 only, types A and B <3> Function is changed or added to in type B 6) Operation codes. 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) :- Code Ident Operation 0x NOP No Operation 3x SRH Set H-register x => H-register (4-bits) 5x PGE Set page x => Page register (4-bits) 4x ADR Set address 0Hx => Address register (12-bits) 0 => H-register 1x ADH Set address high x => Address register (high 4-bits) 6x WRD Write data Hx => [Page, Address] Address register + 1 => Address register 0 => H-register, 0 => Mask register 9x MSK <1> Set mask Hx => Mask register 0 => H-register 2x EXE Execute routine x Ax BUT <1> Operate button x 7x RDD Read data [Page, Address] => Serial output Address register + x => Address register 8x LOC Set lock level x */ #if 1 #define NOP(x) (unsigned char) ( 0x00 | ( 0x0f & (x) ) ) #define SRH(x) (unsigned char) ( 0x30 | ( 0x0f & (x) ) ) #define PGE(x) (unsigned char) ( 0x50 | ( 0x0f & (x) ) ) #define ADR(x) (unsigned char) ( 0x40 | ( 0x0f & (x) ) ) #define ADH(x) (unsigned char) ( 0x10 | ( 0x0f & (x) ) ) #define WRD(x) (unsigned char) ( 0x60 | ( 0x0f & (x) ) ) #define MSK(x) (unsigned char) ( 0x90 | ( 0x0f & (x) ) ) #define EXE(x) (unsigned char) ( 0x20 | ( 0x0f & (x) ) ) #define BUT(x) (unsigned char) ( 0xa0 | ( 0x0f & (x) ) ) #define RDD(x) (unsigned char) ( 0x70 | ( 0x0f & (x) ) ) #define LOC(x) (unsigned char) ( 0x80 | ( 0x0f & (x) ) ) #endif // 0 enum OPCODE_e { op_NOP = 0x00, op_SRH = 0x30, op_PGE = 0x50, op_ADR = 0x40, op_ADH = 0x10, op_WRD = 0x60, op_MSK = 0x90, op_EXE = 0x20, op_BUT = 0xa0, op_RDD = 0x70, op_LOC = 0x80 }; /* Note that the H-register is zeroed after use, and that the high order 4-bits of the Address register must be set (if non-zero) after the low order 8-bits. The Address register is automatically incremented by one after a write data operation and by x after a read data operation. When writing to any of the EEPROM memory pages a time of 10ms per byte has to be allowed. For this reason it is recommended that instructions SRH and WRD are always used together (even if the SRH is not needed) since this will ensure that the EEPROM has sufficient time to complete its write cycle. Additionally to allow time for local receiver memory updates and SNC detector sampling in addition to the EEPROM write cycle, it is recommended to lock the receiver to level 2 or 3, or add a NOP instruction after each write. This is not required for firmware revision 1.4 but locking is still recommended. The mask operation helps with locations in memory that are shared by two parameters and aids setting and clearing bits. The mask operates only in Page 0. If bits in the mask are set, then a following write operation will leave the corresponding bits unchanged. The mask register is cleared after a write so that subsequent writes are processed normally. Because it defaults to zero at reset, the mask is inoperative unless specifically set. The operate button instruction uses the same button codes as are returned from routine 15 (see section 8), with an additional code of zero which operates the power button, but will not switch the receiver off. Also code 0 will switch the receiver on (from standby state). 7) Memory pages. Page 0 Working memory (RAM) 256 bytes. Page 1 Battery sustained memory (RAM) 256 bytes. Page 2 Non-volatile memory (EEPROM) 512 bytes. Page 3 <1> Non-volatile memory (EEPROM) 4096 bytes. Page 4 <1> Non-volatile memory (EEPROM) 4096 bytes. Pages 5 - 14 Not assigned. Page 15 Receiver Ident (ROM) 8 bytes. */ enum PAGE_e { NONE = -1, WORKING = 0, BBRAM = 1, EEPROM1 = 2, EEPROM2 = 3, EEPROM3 = 4, ROM = 15 }; /* The ident is divided into model number (5 bytes), software revision (2 bytes) and type letter (1 byte). e.g. 7030_14A => Model AR-7030, revision 1.4, type letter A. 8) Lock levels. Level 0 Normal operation. Level 1 IR remote control disabled. Front panel buttons ignored. Front panel spin-wheels logged but not actioned. Display update (frequency & S-meter) continues. Level 2 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 Remote operation exclusively. Lock level 1 is recommended during any multi-byte reads or writes of the receiver's memory to prevent data contention between internal and remote memory access. See also EEPROM notes in section (6) */ enum LOCK_LVL_e { LOCK_0 = 0, LOCK_1 = 1, LOCK_2 = 2, LOCK_3 = 3, LOCK_NONE = 4 }; /* 8) 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. Routine 5 <2> Set audio Setup audio controller from memory register values. Routine 6 <2> Set RF-IF Setup RF Gain, IF Gain and AGC speed. Also sets Notch Filter and Noise Blanker if these options are fitted. Routine 7 Not assigned Routine 8 Not assigned Routine 9 Direct Rx control Program control register from rxcon area. Routine 10 Direct DDS control Program local oscillator and carrier oscillator DDS systems from wbuff area. The 32-bits at wbuff control the carrier frequency, value is 385674.4682 / kHz. The 32 bits at wbuff+4 control the local osc frequency, value is 753270.4456 / MHz. Routine 11 Display menus Display menus from menu1 and menu2 bytes. Routine 12 Display frequency Display frequency from frequ area. Routine 13 Display buffer Display ASCII data in wbuff area. First byte is display address, starting at 128 for the top line and 192 for the bottom line. An address value of 1 clears the display. Data string (max length 24 characters) ends with a zero byte. Routine 14 Read signal strength Transmits byte representing received signal strength (read from AGC voltage). Output is 8-bit binary in range 0 to 255. Routine 15 Read buttons Transmits byte indicating state of front panel buttons. Output is 8-bit binary with an offset of +48 (i.e. ASCII numbers). Buttons held continuously will only be registered once. */ enum ROUTINE_e { RESET = 0, SET_FREQ = 1, SET_MODE = 2, SET_PASS = 3, SET_ALL = 4, SET_AUDIO = 5, SET_RFIF = 6, DIR_RX_CTL = 9, DIR_DDS_CTL = 10, DISP_MENUS = 11, DISP_FREQ = 12, DISP_BUFF = 13, READ_SIGNAL = 14, READ_BTNS = 15 }; /* Button codes :- 0 = None pressed 5 = RF-IF button 1 = Mode up button 6 = Memory button 2 = Mode down button 7 = * button 3 = Fast button 8 = Menu button 4 = Filter button 9 = Power button */ enum BUTTON_e { BTN_NONE = 0, BTN_UP = 1, BTN_DOWN = 2, BTN_FAST = 3, BTN_FILTER = 4, BTN_RFIF = 5, BTN_MEMORY = 6, BTN_STAR = 7, BTN_MENU = 8, BTN_POWER = 9 }; /* Note that the work buffer wbuff area in memory is used continuously by the receiver unless lock levels 2 or 3 are invoked. Lock levels of 1 or more should be used when reading any front panel controls to prevent erratic results. 10) Battery sustained RAM (Memory page 1) Address Ident Length Description 0 0x000 13 bytes Real time clock / timer registers :- 0 0x000 rt_con 1 byte Clock control register 2 0x002 rt_sec 1 byte Clock seconds (2 BCD digits) 3 0x003 rt_min 1 byte Clock minutes (2 BCD digits) 4 0x004 rt_hrs 1 byte Clock hours (2 BCD digits - 24 hr format) 5 0x005 rt_dat 1 byte Clock year (2 bits) and date (2 BCD digits) 6 0x006 rt_mth 1 byte Clock month (2 BCD digits - low 5 bits only) 8 0x008 tm_con 1 byte Timer control register 10 0x00A tm_sec 1 byte Timer seconds (2 BCD digits) 11 0x00B tm_min 1 byte Timer minutes (2 BCD digits) 12 0x00C tm_hrs 1 byte Timer hours (2 BCD digits - 24 hr format) 13 0x00D 15 bytes Power-down save area :- 13 0x00D ph_cal 1 byte Sync detector phase cal value 14 0x00E pd_slp 1 byte Timer run / sleep time in minutes 15 0x00F pd_dly 1 byte Scan delay value x 0.125 seconds 16 0x010 pd_sst 1 byte Scan start channel 17 0x011 pd_ssp 1 byte Scan stop channel 18 0x012 pd_stp 2 bytes Channel step size 20 0x014 pd_sql 1 byte Squelch 21 0x015 pd_ifg 1 byte IF gain 22 0x016 pd_flg 1 byte Flags (from pdflgs) 23 0x017 pd_frq 3 bytes Frequency 26 0x01A pd_mod <3> 1 byte Mode (bits 0-3) and NB threshold (bits 4-7) 27 0x01B pd_vol <3> 1 byte Volume (bits 0-5) and rx memory hundreds (bits 6&7) 28 0x01C 26 bytes Receiver setup save area :- 28 0x01C md_flt 1 byte AM mode : Filter (bits 0-3) and AGC speed (bits 4-7) 29 0x01D md_pbs 1 byte AM mode : PBS value 30 0x01E md_bfo 1 byte AM mode : BFO value 31 0x01F 3 bytes Ditto for Sync mode 34 0x022 3 bytes Ditto for NFM mode - except Squelch instead of BFO 37 0x025 3 bytes Ditto for Data mode 40 0x028 3 bytes Ditto for CW mode 43 0x02B 3 bytes Ditto for LSB mode 46 0x02E 3 bytes Ditto for USB mode 49 0x031 st_aud <3> 1 byte Audio bass setting (bits 0-4) bit 5 Notch auto track enable bit 6 Ident search enable bit 7 Ident preview enable 50 0x032 1 byte Audio treble setting (bits 0-3) and RF Gain (bits 4-7) 51 0x033 1 byte Aux output level - left channel 52 0x034 1 byte Aux output level - right channel 53 0x035 st_flg 1 byte Flags (from stflgs) 54 0x036 26 bytes Setup memory A (configured as above) 80 0x050 26 bytes Setup memory B (configured as above) 106 0x06A 26 bytes Setup memory C (configured as above) 132 0x084 24 bytes Filter data area :- 132 0x084 fl_sel 1 byte Filter 1 : selection bits and IF bandwidth 133 0x085 fl_bw 1 byte Filter 1 : bandwidth (2 BCD digits, x.x kHz) 134 0x086 fl_uso 1 byte Filter 1 : USB offset value x 33.19Hz 135 0x087 fl_lso 1 byte Filter 1 : LSB offset value x 33.19Hz 136 0x088 4 bytes Ditto for filter 2 140 0x08C 4 bytes Ditto for filter 3 144 0x090 4 bytes Ditto for filter 4 148 0x094 4 bytes Ditto for filter 5 152 0x098 4 bytes Ditto for filter 6 156 0x09C mem_sq 100 bytes Squelch / BFO values for frequency memories 0 to 99 (BFO for Data and CW modes, Squelch for others) */ #define MAX_MEM_SQL_PAGE0 (99) enum FILTER_e { FILTER_1 = 1, FILTER_2 = 2, FILTER_3 = 3, FILTER_4 = 4, FILTER_5 = 5, FILTER_6 = 6 }; enum BBRAM_mem_e { RT_CON = 0, RT_SEC = 2, RT_MIN = 3, RT_HRS = 4, RT_DAT = 5, RT_MTH = 6, TM_CON = 8, TM_SEC = 10, TM_MIN = 11, TM_HRS = 12, PH_CAL = 13, PD_SLP = 14, PD_DLY = 15, PD_SST = 16, PD_SSP = 17, PD_STP = 18, PD_SQL = 20, PD_IFG = 21, PD_FLG = 22, PD_FRQ = 23, PD_MOD = 26, PD_VOL = 27, MD_FLT = 28, MD_PBS = 29, MD_BFO = 30, ST_AUD = 49, ST_FLG = 53, FL_SEL = 132, FL_BW = 133, FL_USO = 134, FL_LSO = 135, MEM_SQ = 156 }; /* 11) EEPROM (Memory page 2) Address Ident Length Description 0 0x000 4 bytes Frequency memory data :- 0 0x000 mem_fr 3 bytes Memory 00 : 24-bit frequency 3 0x003 mem_md 1 byte bits 0 - 3 mode bits 4 - 6 filter bit 7 scan lockout 4 0x004 396 bytes Ditto for memories 01 to 99 400 0x190 mem_pb 100 bytes PBS values for frequency memories 0 to 99 500 0x1F4 sm_cal 8 bytes S-meter calibration values :- 500 0x1F4 1 byte RSS offset for S1 level 501 0x1F5 1 byte RSS steps up to S3 level 502 0x1F6 1 byte RSS steps up to S5 level 503 0x1F7 1 byte RSS steps up to S7 level 504 0x1F8 1 byte RSS steps up to S9 level 505 0x1F9 1 byte RSS steps up to S9+10 level 506 0x1FA 1 byte RSS steps up to S9+30 level 507 0x1FB 1 byte RSS steps up to S9+50 level 508 0x1FC if_cal 2 bytes RSS offsets for -20dB and -8dB filter alignment 510 0x1FE if_def 1 byte Default filter numbers for narrow and wide (2 BCD digits) 511 0x1FF option <1> 1 byte Option information :- bit 0 Noise blanker bit 1 Notch filter bit 2 10 dB step attenuator (DX version) */ #define MAX_MEM_FREQ_PAGE2 (99) #define MAX_MEM_PBS_PAGE2 (99) enum EEPROM1_mem_e { MEM_FR = 0, MEM_MD = 3, MEM_PB = 400, SM_CAL = 500, IF_CAL = 508, IF_DEF = 510, OPTION = 511 }; /* 12) EEPROM (Memory page 3) . Address Ident Length Description 0 0x000 4 bytes Frequency memory data :- 0 0x000 mex_fr 3 bytes Memory 100 : 24-bit frequency 3 0x003 mex_md 1 byte bits 0 - 3 mode bits 4 - 6 filter bit 7 scan lockout 4 0x004 1196 bytes Ditto for memories 101 to 399 1200 0x4B0 8 bytes Timer memory data :- 1200 0x4B0 mtm_mn 1 byte Timer memory 0 : minutes (2 BCD digits) 1201 0x4B1 mtm_hr 1 byte hours (2 BCD digits) 1202 0x4B2 mtm_dt 1 byte date (2 BCD digits) 1203 0x4B3 mtm_mt 1 byte month (2 BCD digits) 1204 0x4B4 mtm_ch 2 bytes rx channel (hundreds and 0-99) 1206 0x4B6 mtm_rn 1 byte run time 1207 0x4B7 mtm_ac 1 byte active (0 = not active) 1208 0x4B8 72 bytes Ditto for timer memories 1 to 9 1280 0x500 16 bytes Frequency memory data :- 1280 0x500 mex_sq 1 byte Memory 0 : Squelch / BFO (not used for mems 0 to 99) (BFO for Data and CW modes) 1281 0x501 mex_pb 1 byte PBS value (not used for mems 0 to 99) 1282 0x502 mex_id 14 bytes Text Ident 1296 0x510 2800 bytes Ditto for memories 1 to 175 */ #define MAX_MEM_FREQ_PAGE3 (399) #define MAX_MEM_SQL_PAGE3 (175) #define MAX_MEM_PBS_PAGE3 (175) #define MAX_MEM_ID_PAGE3 (175) enum EEPROM2_mem_e { MEX_FR = 0, MEX_MD = 3, MEM_MN = 1200, MTM_HR = 1201, MTM_DT = 1202, MTM_MT = 1203, MTM_CH = 1204, MTM_RN = 1206, MTM_AC = 1207, MEX_SQ = 1280, MEX_PB = 1281, MEX_ID = 1282 }; /* 13) EEPROM (Memory page 4) <1> Address Ident Length Description 0 0x000 16 bytes Frequency memory data :- 0 0x000 mey_sq 1 byte Memory 176 : Squelch / BFO (BFO for Data and CW modes) 1 0x001 mey_pb 1 byte PBS value 2 0x002 mey_id 14 bytes Text Ident 16 0x010 3568 bytes Ditto for memories 177 to 399 3584 0xE00 mex_hx 400 bytes Frequency fast find index (1 byte for each memory 0 to 399) Index value is bits 9 to 16 of 24-bit frequency stored in each memory. Empty memories (frequency zero) should have a random index byte. 3984 0xF90 112 bytes spare */ enum EEPROM3_mem_e { MEY_SQ = 0, MEY_PB = 1, MEY_ID = 2, MEX_HX = 3584 }; /* 14) Working memory (Memory page 0) Areas not specifically addressed are used as workspace by the internal processor. - Keep out (by order). Address Ident Length Description 16 0x010 snphs 1 byte Sync detector phase offset cal value 17 0x011 slptim 1 byte Sleep time (minutes) 18 0x012 scnst 1 byte Scan start channel 19 0x013 scnsp 1 byte Scan stop channel 20 0x014 scndly 1 byte Scan delay time value x 0.125 seconds 21 0x015 chnstp 2 bytes 16-bit channel step size, value is 376.6352 / kHz 23 0x017 sqlsav 1 byte Squelch save value (non-fm mode) 24 0x018 ifgain 1 byte IF gain value (zero is max gain) 26 0x01A frequ 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz. 29 0x01D mode 1 byte Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB 30 0x01E 10 bytes Audio control registers :- 30 0x01E af_vol 1 byte Main channel volume (6-bits, values 15 to 63) 31 0x01F af_vll 1 byte Left channel balance (5-bits, half of volume value above) 32 0x020 af_vlr 1 byte Right channel balance (as above) 33 0x021 af_bas <1> 1 byte Main channel bass (bits 0-4, values 6 to 25, 15 is flat) bit 5 nchtrk Notch auto track enable bit 6 idauto Ident auto search enable bit 7 idprev Ident auto preview enable 34 0x022 af_trb <3> 1 byte Main channel treble (bits 0-3, values 2 to 10, 6 is flat) bit 4 nb_opt Noise blanker menus enabled bit 5 nt_opt Notch Filter menus enabled bit 6 step10 10 dB RF attenuator fitted 35 0x023 af_axl 1 byte Left aux channel level (bits 0-5, values 27 to 63) 36 0x024 af_axr <3> 1 byte Right aux channel level (bits 0-5, values 27 to 63) bit 7 nchsr Notch search running 37 0x025 af_axs <3> 1 byte Aux channel source (bits 0-3) bit 4 nchen Notch filter active bit 5 nchsig Notch filter signal detected bit 6 axmut Aux output mute bit 7 nchato Notch auto tune active 38 0x026 af_opt <3> 1 byte Option output source (bits 0-3) bit 4 idover Ident on LCD over frequency bit 5 idsrdn Ident search downwards bit 7 idsrch Ident search in progress 39 0x027 af_src 1 byte Main channel source bit 6 afmut Main output mute 40 0x028 rxcon 3 bytes Receiver control register mapping :- byte 1 bit 0 rx_fs3 Filter select : FS3 byte 1 bit 1 rx_fs2 Filter select : FS2 byte 1 bit 2 rx_fs1 Filter select : FS1 byte 1 bit 3 rx_fs4 Filter select : FS4 byte 1 bit 4 rx_pre Preamplifier enable byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB byte 1 bit 6 rx_rff Input filter : 0 = HF / 1 = LF byte 1 bit 7 rx_atn Attenuator enable byte 2 bit 0 rx_as1 AGC speed : 00 = Slow byte 2 bit 1 rx_as2 10 = Med 11 = Fast byte 2 bit 2 rx_agi AGC inhibit byte 2 bit 3 rx_en LO and HET enable byte 2 bit 4 rx_aux Aux relay enable byte 2 bit 5 rx_fs5 Filter select : FS5 byte 2 bit 6 rx_fs6 Filter select : FS6 byte 2 bit 7 rx_ibw IF b/w : 0 = 4kHz / 1 = 10kHz byte 3 bit 0 rx_chg Fast charge enable byte 3 bit 1 rx_pwr PSU enable byte 3 bit 2 rx_svi Sync VCO inhibit byte 3 bit 3 rx_agm AGC mode : 0 = peak / 1 = mean byte 3 bit 4 rx_lr1 LO range : 00 = 17 - 30 MHz byte 3 bit 5 rx_lr2 10 = 10 - 17 MHz 01 = 4 - 10 MHz 11 = 0 - 4 MHz byte 3 bit 6 rx_sbw Sync b/w : 0 = Wide / 1 = Narrow byte 3 bit 7 rx_car Car sel : 0 = AM / 1 = DDS 43 0x02B bits 3 bytes General flags :- byte 1 bit 6 lock1 Level 1 lockout byte 1 bit 7 lock2 Level 2 lockout byte 2 bit 0 upfred Update frequency display byte 2 bit 1 upmend Update menus byte 2 bit 2 tune4x Tune 4 times faster (AM & NFM) byte 2 bit 3 quickly Quick tuning (fast AGC, Sync) byte 2 bit 4 fast Fast tuning mode byte 2 bit 5 sncpt1 Auto sync - frequency lock byte 2 bit 6 sncpt2 Auto sync - phase lock byte 2 bit 7 sncal Sync detector calibrating byte 3 bit 0 sqlch Squelch active (i.e. low signal) byte 3 bit 1 mutsql Mute on squelch (current setting) byte 3 bit 2 bscnmd Scan mode for VFO B byte 3 bit 3 dualw Dual watch active byte 3 bit 4 scan Scan active byte 3 bit 5 memlk Current memory scan lockout byte 3 bit 6 pbsclr Enable PBS CLR from IR remote <2> byte 3 bit 7 memodn MEM button scans downwards 46 0x02E pdflgs 1 byte Flags saved at power-down :- bit 0 power Power on bit 1 flock Tuning locked bit 2 batop Battery operation (for fast chg) <1> bit 3 nben Noise blanker active <1> bit 4 nblong Noise blanker long pulse 47 0x02F stflgs 1 byte Flags saved in setup memories :- bit 0 mutsav Mute on squelch (non-fm mode) bit 1 mutaux Mute aux output on squelch bit 2 axren Aux relay on timer bit 3 axrsql Aux relay on squelch bit 4 snauto Auto sync mode bit 5 snarr Sync detector narrow bandwidth bit 6 scanmd Scan runs irrespective of squelch bit 7 autorf RF gain auto controlled 48 0x030 rfgain 1 byte Current RF gain setting (0 to 5) (0=max gain) 49 0x031 rfagc 1 byte Current RF AGC setting (added to above) 50 0x032 agcspd 1 byte Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off 51 0x033 sqlval 1 byte Squelch value (current setting) 52 0x034 filter 1 byte Current filter number (1 to 6) 53 0x035 pbsval 1 byte PBS offset (x33.19Hz) 54 0x036 bfoval 1 byte BFO offset (x33.19Hz) 55 0x037 fltofs 1 byte Filter centre frequency offset (x33.19Hz) 56 0x038 fltbw 1 byte Filter bandwidth (2 BCD digits : x.x kHz) 57 0x039 ircode: 2 bytes Current / last IR command code 59 0x03B spnpos 1 byte Misc spin-wheel movement } 0 = no movement 60 0x03C volpos 1 byte Volume control movement } +ve = clockwise 61 0x03D tunpos 1 byte Tuning control movement } -ve = anti-clockwise 62 0x03E lstbut 1 byte Last button pressed 63 0x03F smval 2 bytes Last S-meter reading (bars + segments) 65 0x041 mestmr 1 byte Message time-out timer 66 0x042 rfgtmr 1 byte RF gain delay timer 67 0x043 updtmr 1 byte Sustained RAM update timer 68 0x044 agctmr 1 byte AGC speed restore delay timer 69 0x045 snctmr 1 byte Auto sync refresh timer 70 0x046 scntmr 1 byte Scan delay timer 71 0x047 irdly 1 byte IR remote auto repeat delay counter 72 0x048 runtmr 1 byte Sleep mode timer 73 0x049 snfrq 1 byte Sync detector frequency offset cal value 74 0x04A frange 1 byte Input / LO range 75 0x04B menu1 <3> 1 byte Current left menu (type A and B menu numbers are different) 76 0x04C menu2 <3> 1 byte Current right menu (type A and B menu numbers are different) 77 0x04D memno 1 byte Current memory number 78 0x04E setno 1 byte Setup / config selection - load / save 85 0x055 mempg <1> 1 byte Memory page (hundreds - value 0 to 3) 86 0x056 nbthr <1> 1 byte Noise blanker threshold (values 0 to 15) 87 0x057 hshfr <1> 1 byte Current tuned frequ index value (during ident search) 88 0x058 nchtmr <1> 1 byte Notch filter auto tune / search timer 90 0x059 wbuff 26 bytes Work buffer 115 0x073 keymd 1 byte IR remote +/- keys function 116 0x074 keybuf 20 bytes IR remote key input buffer 136 0x088 frofs: 4 bytes 32-bit local osc offset 140 0x08C carofs 4 bytes 32-bit carrier osc offset 144 0x090 smofs 1 byte S-meter starting offset 145 0x091 smscl 7 bytes S-meter segment values 152 0x098 ifcal 2 bytes RSS offsets for -20 dB and -5 dB filter alignment 154 0x09A ifdef 1 byte Default filter numbers for narrow and wide (2 digits) 155 0x09B vfo_b 22 bytes VFO B storage area :- 155 0x09B 1 byte B : Scan delay time 156 0x09C 2 bytes B : Channel step size 158 0x09E 1 byte B : Squelch save value (non-fm mode) 159 0x09F 1 byte B : IF gain value 160 0x0A0 1 byte not used 161 0x0A1 3 bytes B : Tuned frequency 164 0x0A4 1 byte B : Mode 165 0x0A5 1 byte B : Volume 166 0x0A6 1 byte B : Left channel balance 167 0x0A7 1 byte B : Right channel balance 168 0x0A8 1 byte B : Bass response 169 0x0A9 1 byte B : Treble response 170 0x0AA 1 byte B : RF gain 171 0x0AB 1 byte B : RF AGC 172 0x0AC 1 byte B : AGC speed 173 0x0AD 1 byte B : Squelch value 174 0x0AE 1 byte B : Filter number 175 0x0AF 1 byte B : PBS offset 176 0x0B0 1 byte B : BFO offset 218 0x0DA savmnu <1> 1 byte Saved menu 1 number during ident display 219 0x0DB srchm <1> 2 bytes Ident search memory (page and number) 222 0x0DD idtmr <1> 1 byte Auto ident search start timer 223 0x0DE nchfr <1> 2 bytes 16-bit notch filter frequency, value is 6553.6 / kHz */ #define HZ_PBS_STEP \ ((44545000.0 * 25.0)/(16777216.0 * 2.0)) /* 33.1886 Hz/Step */ #define NOTCH_STEP_HZ (6.5536) /* 6.5536 Hz/Step */ #define VOL_MIN (15) #define VOL_MAX (63) #define BASS_MIN (6) #define BASS_MAX (25) #define TREB_MIN (2) #define TREB_MAX (10) #define AUX_MIN (27) #define AUX_MAX (63) enum MODE_e { MODE_NONE = 0, AM = 1, SAM = 2, FM = 3, DATA = 4, CW = 5, LSB = 6, USB = 7 }; enum AGC_decay_e { DECAY_SLOW = 0, DECAY_MED = 2, DECAY_FAST = 3 }; enum LO_range_e { LO_17_30 = 0, LO_4_10 = 1, LO_10_17 = 2, LO_0_4 = 3 }; enum AGC_spd_e { AGC_NONE = -1, AGC_FAST = 0, AGC_MED = 1, AGC_SLOW = 2, AGC_OFF = 3 }; enum WORKING_mem_e { SNPHS = 16, SLPTIM = 17, SCNST = 18, SCNSP = 19, SCNDLY = 20, CHNSTP = 21, SQLSAV = 23, IFGAIN = 24, FREQU = 26, MODE = 29, AF_VOL = 30, AF_VLL = 31, AF_VLR = 32, AF_BAS = 33, AF_TRB = 34, AF_AXL = 35, AF_AXR = 36, AF_AXS = 37, AF_OPT = 38, AF_SRC = 39, RXCON = 40, BITS = 43, PDFLGS = 46, STFLGS = 47, RFGAIN = 48, RFAGC = 49, AGCSPD = 50, SQLVAL = 51, FILTER = 52, PBSVAL = 53, BFOVAL = 54, FLTOFS = 55, FLTBW = 56, IRCODE = 57, SPNPOS = 59, VOLPOS = 60, TUNPOS = 61, LSTBUT = 62, SMVAL = 63, MESTMR = 65, RFGTMR = 66, UPDTMR = 67, AGCTMR = 68, SNCTMR = 69, SCNTMR = 70, IRDLY = 71, RUNTMR = 72, SNFRQ = 73, FRANGE = 74, MENU1 = 75, MENU2 = 76, MEMNO = 77, SETNO = 78, MEMPG = 85, NBTHR = 86, HSHFR = 87, NCHTMR = 88, WBUFF = 90, KEYMD = 115, KEYBUF = 116, FROFS = 136, CAROFS = 140, SMOFS = 144, SMSCL = 145, IFCAL = 152, IFDEF = 154, VFO_B = 155, SCNDLY_B = 155, CHNSTP_B = 156, SQLSAV_B = 158, IFGAIN_B = 159, FREQU_B = 161, MODE_B = 164, AF_VOL_B = 165, AF_VLL_B = 166, AF_VLR_B = 167, AF_BAS_B = 168, AF_TRB_B = 169, RFGAIN_B = 170, RFAGC_B = 171, AGCSPD_B = 172, SQLVAL_B = 173, FILTER_B = 174, PBSVAL_B = 175, BFOVAL_B = 176, SAVMNU = 218, SRCHM = 219, IDTMR = 222, NCHFR = 223 }; enum ROM_mem_e { IDENT = 0 }; #define HZ_PER_STEP ( 44545000.0 / 16777216.0 ) /* 2.655 Hz/Step */ #define STEPS_PER_HZ ( 16777216.0 / 44545000.0 ) /* 0.3766 Steps/Hz */ #define MAX_FREQ (32010000.0) #define MIN_FREQ (10000.0) /* RS232 signal meter reading - additional comments Several commercial organisations are using the AR7030 for signal monitoring purposes and wish to accurately log signal meter level. The information is given in the RS232 PROTOCOL LISTING but the subject is fairly complex. A summary of the required process is given here, the text has been generated by John Thorpe in response to a commercial request for more detailed guidance (November 2001). Reading the input signal strength from the AR7030 is not too difficult, but some maths is needed to convert the level into dBm. Each set is calibrated after manufacture and a set of S-meter calibration values stored in EEPROM in the receiver. This means that the signal strength readings should be quite good and consistent. I think that you should get less than 2dB change with frequency and maybe 3dB with temperature. Initial calibration error should be less than +/- 2dB. I think the sets that you use have been modified for DRM use have some changes in the IF stage. This will require that the sets are re-calibrated if you are to get accurate results. The SM7030 service kit has a calibration program (for PC) and is available from AOR. The signal strength is read from the AGC voltage within the 7030 so AGC should be switched on and RF Gain set to maximum. To read AGC voltage send opcode 02EH (execute routine 14) and the receiver will return a single byte value between 0 and 255 which is the measured AGC voltage. The calibration table is stored in EEPROM, so the control software should read this when connection to the receiver is established and store the data in an array for computing. Calibration data is 8 bytes long and is stored in Page2 at locations 500 (0x01F4) to 507 (0x01FB). Use the PaGE opcode (0x52) then SRH, ADR, ADH to setup the address, then 8 RDD opcodes to read the data, as below :- Opcode Hex Operation PGE 2 0x52 Set page 2 SRH 15 0x3F H register = 15 ADR 4 0x44 Set address 0x0F4 ADH 1 0x11 Set address 0x1F4 RDD +1 0x71 Read byte 1 of cal data RDD +1 0x71 Read byte 2 of cal data . . . RDD +1 0x71 Read byte 8 of cal data PGE 0 0x50 Return to page 0 for subsequent control operations The first byte of calibration data holds the value of the AGC voltage for a signal level of -113dBm (S1). Successive bytes hold the incremental values for 10dB increases in signal level :- Cal data Typical Value RF signal level byte 1 64 -113dBm byte 2 10 -103dBm byte 3 10 -93dBm byte 4 12 -83dBm byte 5 12 -73dBm byte 6 15 -63dBm byte 7 30 -43dBm (note 20dB step) byte 8 20 -23dBm (note 20dB step) */ #define CAL_TAB_LENGTH (8) #define STEP_SIZE_LOW (10) #define STEP_SIZE_HIGH (20) /* To calculate the signal level, table values should be subtracted from the AGC voltage in turn until a negative value would result. This gives the rough level from the table position. The accuracy can be improved by proportioning the remainder into the next table step. See the following example :- A read signal strength operation returns a value of 100 Subtract cal byte 1 (64) leaves 36 level > -113dBm Subtract cal byte 2 (10) leaves 26 level > -103dBm Subtract cal byte 3 (10) leaves 16 level > -93dBm Subtract cal byte 4 (12) leaves 4 level > -83dBm Test cal byte 5 (12) - no subtraction Fine adjustment value = (remainder) / (cal byte 5) * (level step) = 4 / 12 * 10 = 3dB Signal level = -83dBm + 3dB = -80dB The receiver can operate the RF attenuator automatically if the signal level is likely to overload the RF stages. Reading the RFAGC byte (page 0, location 49) gives the attenuation in 10dB steps. This value should be read and added to the value calculated above. Further discussion has taken place on the subject of PC control with the designer, the comments may be of assistance to other operators... As far as I can tell all of the commands and operations work exactly as documented so when the client talks of "the set frequency command doesn't work" they are obviously doing something wrong. Similarly, I am unable to duplicate the effects that they notice with changing audio settings after changing modes. There are some issues with the parameters that they are changing which I will address later, but first they must sort out the basic communication so that the receiver control is as expected. Further issues cannot really be sorted until this is working properly. Programming issues... Since I have no Knowledge of what programming system the client is using these are only general comments. The receiver control is in 8-bit binary code so any communication must maintain all 8 bits (and not truncate bit 7 as some printer outputs do). It is also essential that no extra characters are added to the output stream so check that the software is not adding carriage returns, line feeds, nulls or end-of-file markers to the output. If this might be a problem, monitor the computer to receiver communication with a serial line monitor or another computer running a simple RS-232 reading program. There is some sample BASIC code in the "AR-7030 Computer remote control protocol" document which gives subroutines that cover the commonly used receiver settings. Use this as a starting point for your own routines. The published routines have been thoroughly tested and work without problems. http://www.aoruk.com/pdf/comp.pdf http://www.aoruk.com/7030bulletin.htm#7030_rs232_s-meter With all "buffered" RS-232 connections it is possible for the computer and receiver to get out of step when using two-way communication. For this reason I included some "flush input buffer" routines in the sample code. Using these ensures that missed characters or extra characters inserted due to noise or disconnection do not disrupt communication between the computer and receiver, and a recovery after communications failure can be automatic. Because the receiver's remote control is by direct access to memory and processor it is a very flexible system but is also able to disrupt receiver operation if incorrectly used. Only a few bytes of information stored in the receiver's memory affect S-meter calibration and AOR (UK) hold records of this data for each receiver made so that in the event of corruption it can be re-programmed. See the note that follows regarding AGC calibration. All other working memory contents can be set to sensible values by a "Set defaults" operation from the front panel. Most, but not all, of the working memory is re-established by executing a remote "Reset" command (0x20) which can be done as a last resort after control failure. Specific parameter settings... The client describes the correct operations for setting mode and frequency but if, as he states, the set frequency command (021h) does not work then this needs to be investigated. This may lead to discovering the cause of other problems suffered by the client. Note that changing the frequency in this way re-tunes the receiver but does not update the display on the front panel. A "Display frequency" command is included for this purpose. To set the receiver main volume, three locations need to be written - Page 0, addr 0x1e, 0x1f & 0x20. Details are in the protocol document, note the minimum value (for zero volume) is 15. The aux channel level change is as described by the client and after writing new values into the RAM will need either a "Set audio" command or a "Set all" command to make the change. I can find no reason for, nor duplicate, the effect of changing mode altering the aux level so this effect also needs investigating - maybe the clients "write to memory" is writing too many locations ? To initialise several receiver parameters I would recommend locking the receiver, writing all of the required memory data, sending a "Set all" command and then unlocking if required. There is no need to send individual "Set" commands after each parameter. Unless very special requirements are needed (mainly test, setup and alignment ) the 3 rxcon locations should not be written. When a "Set all" command is sent these will be programmed by the receiver firmware to appropriate values for the mode, frequency and filters selected. Only the parameters that need changing need to be written, all other values will be maintained. The locations that the client needs to program for the parameters he lists are as follows:- (all Page 0) frequency frequ 0x1a 0x1b 0x1c mode mode 0x1d volume af_vol 0x1e 0x1f 0x20 (values=0x0f 0x07 0x07 for min volume) aux level af_axl 0x23 0x24 agc speed agcspd 0x32 squelch sqlval 0x33 filter filter 0x34 IF gain ifgain 0x18 RF gain rfgain 0x30 (value=0x01 for no pre-amp) message wbuff 0x59 (max 26 bytes) If the required parameter values are unknown, I recommend setting the receiver as required through the front panel controls and then reading the value of the memory locations affected using the "read data" operation. 15) Sample routines (in MS QBASIC) REM Sample subroutines for communication with the AR-7030 A-type REM These subroutines use the following variables :- REM rx.freq# frequency in kHz (double precision) REM rx.mode mode number (1 to 7) REM rx.filt filter number (1 to 6) REM rx.mem memory number (0 to 99) REM rx.pbs passband shift value (-4.2 to +4.2 in kHz) REM rx.sql squelch value (0 to 255) REM ident$ -model number, revision and type REM Subroutine to open comms link to receiver open.link: open "com1:1200,n,8,1,cd0,cs0,ds0,rs" for random as #1 len = 1 field #1, 1 as input.byte$ return REM Subroutine to flush QBASIC serial input buffer flush.buffer: print #1,"//"; do time.mark# = timer do while timer - time.mark# < 0.2 loop if eof(1) then exit do get #1 loop return REM Subroutines to lock and unlock receiver controls lock.rx: print #1,chr$(&H81); ' Set lockout level 1 return unlock.rx: print #1,chr$(&H80); ' Lockout level 0 (not locked) return REM Subroutine to read byte from comms link read.byte: read.value = -1 ' Value assigned for read error time.mark# = timer print #1,chr$(&H71); ' Read byte command do while timer - time.mark# < 0.3 if eof(1) = 0 then get #1 read.value = asc(input.byte$) exit do end if loop return REM Subroutine to set receiver frequency and mode tune.rx: gosub lock.rx print #1,chr$(&H50); ' Select working mem (page 0) print #1,chr$(&H31);chr$(&H4A); ' Frequency address = 01AH gosub send.freq ' Write frequency print #1,chr$(&H60+rx.mode); ' Write mode print #1,chr$(&H24); ' Tune receiver gosub unlock.rx return REM Subroutine to store data into receiver's frequency memory set.memory: mem.loc = rx.mem+156 ' Squelch memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H51); ' Select squelch memory (page 1) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H30+int(rx.sql/16)) print #1,chr$(&H60+rx.sql mod 16) ' Write squelch value mem.loc = rx.mem*4 ' Frequency memory origin mem.t = int(mem.loc/256) mem.loc = mem.loc mod 256 mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H52); ' Select frequency memory (page 2) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H10+mem.t); gosub send.freq ' Write frequency print #1,chr$(&H30+rx.filt); print #1,chr$(&H60+rx.mode); ' Write filter and mode mem.loc = rx.mem+400-256 ' PBS memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 pbs.val = 255 and int(rx.pbs/0.033189+0.5) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H11); print #1,chr$(&H30+int(pbs.val/16)) print #1,chr$(&H60+pbs.val mod 16) ' Write passband value return REM Subroutine to read data from receiver's frequency memory read.memory: mem.loc = rx.mem+156 ' Squelch memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H51); ' Select squelch memory (page 1) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address gosub read.byte ' Read squelch value rx.sql = read.value mem.loc = rx.mem*4 ' Frequency memory origin mem.t = int(mem.loc/256) mem.loc = mem.loc mod 256 mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H52); ' Select frequency memory (page 2) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H10+mem.t); gosub read.freq ' Read frequency gosub read.byte ' Read filter and mode if read.value < 0 then return rx.filt = int(read.value/16) rx.mode = read.value mod 16 mem.loc = rx.mem+400-256 ' PBS memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H11); gosub read.byte ' Read passband value if read.value < 0 then return if read.value > 127 then read.value = 256-read.value rx.pbs = read.value*0.033189 return REM Subroutine to read receiver ident string read.ident: print #1,chr$(&H5F); ' Select ident memory (page 15) print #1,chr$(&H40); ' Set address 0 ident$="" for read.loop = 1 to 8 gosub read.byte ' Read 8-byte ident if read.value < 0 then exit for ident$ = ident$+chr$(read.value) next read.loop return REM Subroutine to send frequency (Called only from other routines) send.freq: fr.val# = int(rx.freq#*376.635223+0.5) ' Convert kHz to steps ' Exact multiplicand is ' (2^24)/44545 print #1,chr$(&H30+int(fr.val#/1048576)); fr.val# = fr.val# mod 1048576 ' Write frequency as 6 hex digits print #1,chr$(&H60+int(fr.val#/65536)); fr.val# = fr.val# mod 65536 print #1,chr$(&H30+int(fr.val#/4096)); fr.val# = fr.val# mod 4096 print #1,chr$(&H60+int(fr.val#/256)); fr.val# = fr.val# mod 256 print #1,chr$(&H30+int(fr.val#/16)); print #1,chr$(&H60+(fr.val# mod 16)); return REM Subroutine to read frequency (Called only from other routines) read.freq: fr.val# = 0 for read.loop = 1 to 3 gosub read.byte ' Read frequency as 3 bytes if read.value < 0 then exit for fr.val# = fr.val#*256+read.value next read.loop rx.freq# = fr.val#/376.635223 ' Convert steps to kHz return */ /* * (from http://www.aoruk.com/archive/pdf/ir.pdf) * * AOR AR7030 receiver infrared protocol listing * * There have been two types of IR7030 infrared hand controller employed * by the AR7030. Late in 2005 a VERSION 2 handset (IR7030-2) was adopted * in production. The protocol is slightly different, so a matching CPU * must be employed (firmware 1xA or 1xB uses the original IR7030, * firmware 2xA or 2xB uses the later IR7030-2). * * IR7030 IR7030-2 * NEC protocol 16 bit NEC protocol 16 bit * * Address 026 HEX Address 04D HEX * I.R key Hex value I.R key Hex value * 1 0C 1 11 * 2 11 2 13 * 3 12 3 1C * 4 10 4 15 * 5 19 5 16 * 6 1A 6 14 * 7 18 7 19 * 8 1D 8 17 * 9 1E 9 1B * 0 15 0 1D * . DECIMAL 16 . DECIMAL 12 * CLEAR 13 CLEAR 07 * BACKSPACE 1C BACKSPACE 1F * kHz 17 kHz 1A * MHz 1F MHz 1E * CW/NFM 8 CW/NFM 0F * LSB/USB 0D LSB/USB 10 * AM/SYNC 0E AM/SYNC 18 * + MODIFY 2 + MODIFY 01 * - MODIFY 6 - MODIFY 0B * TUNE UP 3 TUNE UP 04 * TUNE DOWN 7 TUNE DOWN 05 * VOLUME UP 0B VOLUME UP 02 * VOLUME DOWN 0F VOLUME DOWN 03 * PASSBAND MODIFY 0 PASSBAND MODIFY 09 * FILTER MODIFY 1 FILTER MODIFY 08 * BASS MODIFY 5 BASS MODIFY 0A * TREBLE MODIFY 14 TREBLE MODIFY 0C * VFO SELECT A/B 0A VFO SELECT A/B 0E * MEMORY STORE 4 MEMORY STORE 0D * MEMORY PREVIEW 9 MEMORY PREVIEW 00 * MEMORY RECALL 1B MEMORY RECALL 06 * * www.aoruk.com - 25.07.2006 */ /* * These are the translated key codes shown in the last IR code * address 58 in page 0. */ enum IR_CODE_e { IR_ONE = 0x12, IR_TWO = 0x14, IR_THREE = 0x1d, IR_FOUR = 0x16, IR_FIVE = 0x17, IR_SIX = 0x15, IR_SEVEN = 0x1a, IR_EIGHT = 0x18, IR_NINE = 0x1c, IR_ZERO = 0x1e, IR_DOT = 0x13, IR_CLR = 0x08, IR_BS = 0x20, IR_KHZ = 0x1b, IR_MHZ = 0x1f, IR_CWFM = 0x10, IR_LSBUSB = 0x11, IR_AMSYNC = 0x19, IR_PLUS = 0x02, IR_MINUS = 0x0c, IR_TUN_UP = 0x05, IR_TUN_DWN = 0x06, IR_VOL_UP = 0x03, IR_VOL_DWN = 0x04, IR_PBS = 0x0a, IR_TREBLE = 0x0d, IR_BASS = 0x0b, IR_VFO = 0x0f, IR_MEM_STO = 0x0e, IR_MEM_PRE = 0x01, IR_MEM_RCL = 0x07, IR_NONE = -1 }; /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) /* Utility function prototypes */ #if 0 int NOP( RIG *rig, unsigned char x ); int SRH( RIG *rig, unsigned char x ); int PGE( RIG *rig, enum PAGE_e page ); int ADR( RIG *rig, unsigned char x ); int ADH( RIG *rig, unsigned char x ); int WRD( RIG *rig, unsigned char out ); int MSK( RIG *rig, unsigned char mask ); int EXE( RIG *rig, enum ROUTINE_e routine ); int RDD( RIG *rig, unsigned char len ); int LOC( RIG *rig, enum LOCK_LVL_e level ); int BUT( RIG *rig, enum BUTTON_e button ); #endif // 0 int execRoutine( RIG * rig, enum ROUTINE_e rtn ); int writeByte( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char x ); int writeShort( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short x ); int write3Bytes( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x ); int writeInt( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x ); int readByte( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char *x ); int readShort( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short *x ); int read3Bytes( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x ); int readInt( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x ); int readSignal( RIG * rig, unsigned char *x ); int flushBuffer( RIG * rig ); int lockRx( RIG * rig, enum LOCK_LVL_e level ); int bcd2Int( const unsigned char bcd ); unsigned char int2BCD( const unsigned int val ); int getCalLevel( RIG * rig, unsigned char rawAgc, int *dbm ); int getFilterBW( RIG *rig, enum FILTER_e filter ); freq_t ddsToHz( const unsigned int steps ); unsigned int hzToDDS( const freq_t freq ); float pbsToHz( const unsigned char steps ); unsigned char hzToPBS( const float freq ); rmode_t modeToHamlib( const unsigned char mode ); unsigned char modeToNative( const rmode_t mode ); enum agc_level_e agcToHamlib( const unsigned char agc ); unsigned char agcToNative( const enum agc_level_e agc ); int pageSize( const enum PAGE_e page ); int sendIRCode( RIG *rig, enum IR_CODE_e code ); #endif /* _AR7030P_H */ hamlib-4.6.5/rigs/aor/ar8200.c0000664000175000017500000001411415056640443011262 /* * Hamlib AOR backend - AR8200 description * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8200_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8200_FUNC (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8200_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR8200_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8200_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8200_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* TODO: measure and report real values */ /* series-2 (black cabinet), from AR8200 Bulletin page */ #define AR8200_STR_CAL { 12, \ { \ { 0,-54 }, \ { 27,-32 }, \ { 42,-27 }, \ { 55,-22 }, \ { 68,-17 }, \ { 86, -7 }, \ { 97, 3 }, \ { 103, 13 }, \ { 106, 23 }, \ { 109, 33 }, \ { 112, 43 }, \ { 139, 53 }, \ } } #define AR8200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static const struct aor_priv_caps ar8k_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8200 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8200.htm */ struct rig_caps ar8200_caps = { RIG_MODEL(RIG_MODEL_AR8200), .model_name = "AR8200", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8200_FUNC, .has_get_level = AR8200_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8200_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, /* A through J, and a through j */ .chan_desc_sz = 12, .vfo_ops = AR8200_VFO_OPS, .scan_ops = AR8200_SCAN_OPS, .str_cal = AR8200_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR8200_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(2040), AR8200_MODES, -1, -1, AR8200_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2040), AR8200_MODES, -1, -1, AR8200_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8200_MODES, 50}, {AR8200_MODES, 100}, {AR8200_MODES, kHz(1)}, {AR8200_MODES, kHz(5)}, {AR8200_MODES, kHz(9)}, {AR8200_MODES, kHz(10)}, {AR8200_MODES, 12500}, {AR8200_MODES, kHz(20)}, {AR8200_MODES, kHz(25)}, {AR8200_MODES, kHz(100)}, {AR8200_MODES, MHz(1)}, #if 0 {AR8200_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM, kHz(9)}, {RIG_MODE_WFM, kHz(230)}, /* 50kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/aor/README.ar70300000664000175000017500000000264215056640443012000 hamlib-1.2.3 aor ar7030.c 2004.11.26 Parameteraenderung fuer USB-Serial //.post_write_delay = 0, //Device: /dev/ttyS0 //.post_write_delay = 85, //Device: /dev/tts/USB0 < 85 sec 'timedout after 0 chars' Befehle mit rigctl # rigctl -m 503 -r /dev/ttyS0 # rigctl -m 503 -r /dev/tts/USB0 Rig command: F Frequency: 0 .. 32016718 Hz Rig command: f Rig command: \get_freq Rig command: M Mode: FM, AMS, AM, USB, LSB, CW, RTTY Passband: 1 - 6 Rig command: m Passband: 800, 2100, 3700, 5200, 9500, XXXX (Value from RX) Hz Rig command: L Level: AF Value: 0.0 - 1.0 Level: RF Value: 0.1, 0.0 -0.1, -0.2, -0.3, -0.4 > +10, 0 ,-10 , -20, -30, -40 dB Level: SQL Value: 0.0 - 1.0 Level: AGC Value: 0 > OFF, 2 > FAST, 3 > SLOW, 5 > MEDIUM Level: CWPITCH Value: -4248 .. 0 .. 4215 Hz Rig command: l Level: AF Level: RF Level: SQL Level: AGC Level: CWPITCH Level: RAWSTR Level: STRENGTH Value: -121dBm ... -23dBm > S1 ... S9 + 50 dB Rig command: \set_powerstat Status: 0 > Power off, 1 > Power on Rig command: \get_powerstat Rig command: \reset Reset: 1 > Software reset Rig command: Quit Q q Rig command: Quit Q Q Rig command: 1 Caps dump for model 503 Friedrich Melchert (DC9RP) hamlib-4.6.5/rigs/aor/ar7030.c0000664000175000017500000006632415056640443011274 /* * Hamlib AOR backend - AR7030 description * Copyright (c) 2000-2006 by Stephane Fillod & Fritz Melchert * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // // Version 2004.12.13 F.Melchert (DC9RP) // Version 2004.11.29 F.Melchert (DC9RP) // #include #include #include "serial.h" #include "idx_builtin.h" /* * Maintainer wanted! * * TODO: * - everything: this rig has nothing in common with other aor's. * * set_mem, get_mem, set_channel, get_channel */ #define AR7030_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define AR7030_FUNC_ALL (RIG_FUNC_NONE) #define AR7030_LEVEL (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_CWPITCH | RIG_LEVEL_RAWSTR | RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH) #define AR7030_PARM (RIG_PARM_NONE) #define AR7030_VFO_OPS (RIG_OP_NONE) #define AR7030_VFO (RIG_VFO_A|RIG_VFO_B) /* * Data was obtained from AR7030 pdf on http://www.aoruk.com */ /**************************************************************************** * Misc Routines * ****************************************************************************/ static int rxr_writeByte(RIG *rig, unsigned char c) { return write_block(RIGPORT(rig), &c, 1); } static int rxr_readByte(RIG *rig) { unsigned char response[1]; const unsigned char buf[] = {0x71}; // Read command int retval; retval = write_block(RIGPORT(rig), buf, 1); if (retval != RIG_OK) { return retval; } retval = read_block(RIGPORT(rig), response, 1); if (retval != RIG_OK) { return retval; } return response[0]; } /*! Umwandlung von BCD nach char */ static 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 Address *** { rxr_writeByte(rig, 0x30 + (address >> 4)); //Set H-Register 4 Bits rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Address(12 Bits = (4 Bit H Register) + 8 Bit) } else //*** > 8 Bit Address *** { rxr_writeByte(rig, 0x30 + ((address >> 4) & 0x0F)) ;//Set H-Register 4 Bits rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Address(12 Bits = (4 Bit H Register) + 8 Bit) rxr_writeByte(rig, 0x10 + (address >> 8)); //Set Address high(12 Bits=(4 Bit H Register)+8 Bit) } } /**************************************************************************** * Routines * ****************************************************************************/ // Routine 0 Reset Setup receiver as at switch-on. static void Execute_Routine_0(RIG *rig) { //setLock(rig, 1); //Set Lock Level rxr_writeByte(rig, 0x20); //unlock(rig); //Set UnLock Level } // 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. // currently not used #if 0 static void Execute_Routine_2_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, 0x22); unlock(rig); //Set UnLock Level } #endif // Routine 3 Set passband Setup all IF parameters from filter, pbsval and bfoval bytes. static void Execute_Routine_3_1(RIG *rig, char mp, char ad, unsigned 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, 0x23); unlock(rig); //Set UnLock Level } // 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. // currently not used #if 0 static void Execute_Routine_5_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, 0x25); unlock(rig); //Set UnLock Level } #endif // 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, 0x26); unlock(rig); //Set UnLock Level } // Routine 14 Read signal strength // Transmits byte representing received signal strength (read from AGC voltage). // Output is 8-bit binary in range 0 to 255. static int Execute_Routine_14(RIG *rig) { unsigned char response[1]; hamlib_port_t *rp = RIGPORT(rig); const unsigned char buf[] = {0x2e}; // Read command int retval; retval = write_block(rp, buf, 1); if (retval != RIG_OK) { return retval; } retval = read_block(rp, response, 1); if (retval != RIG_OK) { return retval; } return response[0]; } // Operate button x // Button codes :- // 0 = None pressed 5 = RF-IF button // 1 = Mode up button 6 = Memory button // 2 = Mode down button 7 = * button // 3 = Fast button 8 = Menu button // 4 = Filter button 9 = Power button static void Execute_Operate_button(RIG *rig, char button) { // setLock(rig, 1); //Set Lock Level rxr_writeByte(rig, 0xa0 | (0x0F & button)); // unlock(rig); //Set UnLock Level } static int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { // frequ Mem_Page=0 Address=1A // 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz freq = freq * .3766352228; if (freq < 0) {freq = 0;} if (freq > 12058624) {freq = 12058624;} Execute_Routine_4_3(rig, 0, 0x1a, freq); return RIG_OK; } static int ar7030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { // frequ Mem_Page=0 Address=1A // 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz 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 */ static int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int filter_num; // mode Mem_Page=0 Address=1D // Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB. switch (mode) { case RIG_MODE_AM : Execute_Routine_4_1(rig, 0, 0x1d, 1); break; case RIG_MODE_AMS : Execute_Routine_4_1(rig, 0, 0x1d, 2); break; case RIG_MODE_FM : Execute_Routine_4_1(rig, 0, 0x1d, 3); break; case RIG_MODE_RTTY : Execute_Routine_4_1(rig, 0, 0x1d, 4); break; case RIG_MODE_CW : Execute_Routine_4_1(rig, 0, 0x1d, 5); break; case RIG_MODE_LSB : Execute_Routine_4_1(rig, 0, 0x1d, 6); break; case RIG_MODE_USB : Execute_Routine_4_1(rig, 0, 0x1d, 7); break; default : return -RIG_EINVAL; } if (RIG_PASSBAND_NOCHANGE == width) { return RIG_OK; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * pass-through values 1..6, as filter number * Otherwise find out filter number from passband width */ if (width <= 6) { filter_num = width; } else { if (width <= 800) { filter_num = 1; } else if (width <= 2100) { filter_num = 2; } else if (width <= 3700) { filter_num = 3; } else if (width <= 5200) { filter_num = 4; } else if (width <= 9500) { filter_num = 5; } else { filter_num = 6; } } // filter Mem_Page=0 Address=34 // Current filter number (1 to 6). Execute_Routine_4_1(rig, 0, 0x34, filter_num); 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 // Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB. setMemPtr(rig, 0, 0x1d); switch (rxr_readByte(rig)) { case 1: *mode = RIG_MODE_AM; break; case 2: *mode = RIG_MODE_AMS; break; case 3: *mode = RIG_MODE_FM; break; case 4: *mode = RIG_MODE_RTTY; break; case 5: *mode = RIG_MODE_CW; break; case 6: *mode = RIG_MODE_LSB; break; case 7: *mode = RIG_MODE_USB; break; default : return -RIG_EINVAL; } // fltbw Mem_Page=0 Address=38 // Filter bandwidth decimal in Hz. // Filter bandwidth (2 BCD digits : x.x kHz). setMemPtr(rig, 0, 0x38); if ((*width = (pbwidth_t)BCD_To_int(rig, rxr_readByte(rig)) * 100) < 0) { return -RIG_EINVAL; } return RIG_OK; } static int ar7030_set_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 // Main channel volume (6-bits, values 15 to 63) val.f = (val.f * 50) + 15; if (val.f < 15) {val.f = 15;} if (val.f > 63) {val.f = 63;} Execute_Routine_4_1(rig, 0, 0x1e, val.f); return RIG_OK; case RIG_LEVEL_RF : // rfgain Mem_Page=0 Address=30 // Current RF gain setting (0 to 5) (0=max gain) val.f = ((val.f * 10) - 1) * -1; if (val.f < 0) {val.f = 0;} if (val.f > 5) {val.f = 5;} Execute_Routine_6_1(rig, 0, 0x30, val.f) ; return RIG_OK; case RIG_LEVEL_SQL : // sqlval Mem_Page=0 Address=33 // Squelch value (current setting)(values 0 to 150) if (val.f < 0) {val.f = 0;} if (val.f > 1) {val.f = 1;} Execute_Routine_6_1(rig, 0, 0x33, val.f * 150); return RIG_OK; case RIG_LEVEL_CWPITCH : // bfoval Mem_Page=0 Address=36 // BFO offset in Hz (x33.19Hz)(values -4248.320 to 4215.130kHz). val.i = val.i * 100 / 3319; if (val.i < -128) {val.i = -128;} if (val.i > 127) {val.i = 127;} Execute_Routine_3_1(rig, 0, 0x36, val.i); return RIG_OK; case RIG_LEVEL_AGC : //ar7030 agcspd 3 > RIG_AGC_OFF // > RIG_AGC_SUPERFAST //ar7030 agcspd 0 > RIG_AGC_FAST //ar7030 agcspd 2 > RIG_AGC_SLOW // > RIG_AGC_USER /*!< user selectable */ //ar7030 agcspd 1 > RIG_AGC_MEDIUM // agcspd Mem_Page=0 Address=32 // Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off switch (val.i) { case RIG_AGC_OFF: Execute_Routine_6_1(rig, 0, 0x32, 3); break; case RIG_AGC_SLOW: Execute_Routine_6_1(rig, 0, 0x32, 2); break; case RIG_AGC_MEDIUM: Execute_Routine_6_1(rig, 0, 0x32, 1); break; case RIG_AGC_FAST: Execute_Routine_6_1(rig, 0, 0x32, 0); break; default: return -RIG_EINVAL; } return RIG_OK; default : return -RIG_EINVAL; } } static int ar7030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int smval1; int smval2; switch (level) { case RIG_LEVEL_AF : // af_vol Mem_Page=0 Address=1E // Main channel volume (6-bits, values 15 to 63) setMemPtr(rig, 0, 0x1e); val->f = (float)(rxr_readByte(rig) - 15) / 50; return RIG_OK; case RIG_LEVEL_RF : // rfgain Mem_Page=0 Address=30 // Current RF gain setting (0 to 5) (0=max gain) setMemPtr(rig, 0, 0x30); val->f = (float)((rxr_readByte(rig) * -1) + 1) / 10; return RIG_OK; case RIG_LEVEL_SQL : // sqlval Mem_Page=0 Address=33 // Squelch value (current setting)(values 0 to 150) setMemPtr(rig, 0, 0x33); val->f = (float)rxr_readByte(rig) / 150; return RIG_OK; case RIG_LEVEL_CWPITCH : // bfoval Mem_Page=0 Address=36 // BFO offset in Hz (x33.19Hz)(values -4248.320 to 4215.130kHz). setMemPtr(rig, 0, 0x36); val->i = ((char)rxr_readByte(rig) * 3319) / 100; return RIG_OK; case RIG_LEVEL_AGC : //ar7030 agcspd 3 > RIG_AGC_OFF // > RIG_AGC_SUPERFAST, //ar7030 agcspd 0 > RIG_AGC_FAST, //ar7030 agcspd 2 > RIG_AGC_SLOW // > RIG_AGC_USER, //ar7030 agcspd 1 > RIG_AGC_MEDIUM // agcspd Mem_Page=0 Address=32 // Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off setMemPtr(rig, 0, 0x32); switch (rxr_readByte(rig)) { case 0: val->i = RIG_AGC_FAST; break; case 1: val->i = RIG_AGC_MEDIUM; break; case 2: val->i = RIG_AGC_SLOW; break; case 3: val->i = RIG_AGC_OFF; break; default: return -RIG_EINVAL; } return RIG_OK; // case RIG_LEVEL_LINEOUT : // geht nicht in hamlib // // af_axl Mem_Page=0 Address=23 Bit=0 - 5 // setMemPtr(rig ,0 ,0x23); // val->f = ((float)(rxr_readByte(rig) - 27) * 2) / 100; // // af_axr Mem_Page=0 Address=24 Bit=0 - 5 // return RIG_OK; case RIG_LEVEL_RAWSTR : // Routine 14 Read signal strength // Read signal strength Transmits byte representing received signal strength // (read from AGC voltage). Output is 8-bit binary in range 0 to 255 val->i = Execute_Routine_14(rig); return RIG_OK; case RIG_LEVEL_STRENGTH : // smval Mem_Page=0 Address=3F - 40 // 2 bytes Last S-meter reading (bars + segments) setMemPtr(rig, 0, 0x3f); smval1 = (unsigned char)rxr_readByte(rig); smval2 = (unsigned char)rxr_readByte(rig); if (smval1 < 9) { val->i = (smval1 * 6 + smval2) - 127; } else if (smval1 < 11) { /* int ops => int result => round has no effect (besides compiler warning */ //val->i = round((smval1 * 6 + smval2) * 10 / 12) - 118; val->i = ((smval1 * 6 + smval2) * 10 / 12) - 118; } else { /* int ops => int result => round has no effect (besides compiler warning */ //val->i = round((smval1 * 6 + smval2) * 10 / 6) - 173; val->i = ((smval1 * 6 + smval2) * 10 / 6) - 173; } return RIG_OK; default : return -RIG_EINVAL; } } static int ar7030_set_powerstat(RIG *rig, powerstat_t status) { // Radio power state. // 0 > RIG_POWER_OFF Power off // 1 > RIG_POWER_ON Power on // 2 > RIG_POWER_STANDBY Standby switch (status) { case RIG_POWER_OFF: // Operate button 9 = Power button Execute_Operate_button(rig, 9); return RIG_OK; case RIG_POWER_ON: // Operate button 0 = None pressed Execute_Operate_button(rig, 0); return RIG_OK; default: break; } return -RIG_EINVAL; } static int ar7030_get_powerstat(RIG *rig, powerstat_t *status) { // power Mem_Page=0 Address=2E Bit=0 - 0 // Power on setMemPtr(rig, 0, 0x2e); *status = (char)rxr_readByte(rig) & 0x01; return RIG_OK; } static int ar7030_reset(RIG *rig, reset_t reset) { // Reset operation. // 0 > RIG_RESET_NONE No reset // 1 > RIG_RESET_SOFT Software reset // 2 > RIG_RESET_VFO VFO reset // 3 > RIG_RESET_MCALL Memory clear // 4 > RIG_RESET_MASTER Master reset switch (reset) { // Routine 0 Reset Setup receiver as at switch-on. case RIG_RESET_SOFT : Execute_Routine_0(rig) ; return RIG_OK; default: break; } return -RIG_EINVAL; } struct rig_caps ar7030_caps = { RIG_MODEL(RIG_MODEL_AR7030), .model_name = "AR7030", .mfg_name = "AOR", .version = "20200324.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, /* TBC */ .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, .has_set_func = AR7030_FUNC_ALL, .has_get_level = AR7030_LEVEL, .has_set_level = RIG_LEVEL_SET(AR7030_LEVEL), .has_get_parm = AR7030_PARM, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 100, /* FIXME */ .vfo_ops = AR7030_VFO_OPS, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 1000 memories */ .rx_range_list1 = { {kHz(10), MHz(2600), AR7030_MODES, -1, -1, AR7030_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(2600), AR7030_MODES, -1, -1, AR7030_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR7030_MODES, 50}, {AR7030_MODES, 100}, {AR7030_MODES, 200}, {AR7030_MODES, 500}, {AR7030_MODES, kHz(1)}, {AR7030_MODES, kHz(2)}, {AR7030_MODES, kHz(5)}, {AR7030_MODES, kHz(6.25)}, {AR7030_MODES, kHz(9)}, {AR7030_MODES, kHz(10)}, {AR7030_MODES, 12500}, {AR7030_MODES, kHz(20)}, {AR7030_MODES, kHz(25)}, {AR7030_MODES, kHz(30)}, {AR7030_MODES, kHz(50)}, {AR7030_MODES, kHz(100)}, {AR7030_MODES, kHz(200)}, {AR7030_MODES, kHz(250)}, {AR7030_MODES, kHz(500)}, // {AR7030_MODES,0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(0.8)}, /* narrow */ {RIG_MODE_SSB, kHz(4.8)}, /* wide */ {RIG_MODE_CW, kHz(9.5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_FM | RIG_MODE_AM, kHz(30)}, /* wide */ RIG_FLT_END, }, .priv = NULL, /* priv */ // .rig_init = ar7030_init, // .rig_cleanup = ar7030_cleanup, // .rig_open = ar7030_open, // .rig_close = ar7030_close, .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_info = ar7030_get_info, // .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, .reset = ar7030_reset, // .set_channel = ar7030_set_channel, // .get_channel = ar7030_get_channel, // .set_trn = ar7030_set_trn, // .get_trn = ar7030_get_trn, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/aor/ar7030p.c0000664000175000017500000013373715056640443011457 /* * Hamlib AOR backend - AR7030 Plus description * Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Version 2009.11.21 Larry Gadallah (VE6VQ) */ #include #include #include #include #include "hamlib/rig.h" #include "ar7030p.h" #include "idx_builtin.h" #define AR7030P_MODES ( RIG_MODE_AM | \ RIG_MODE_SSB | \ RIG_MODE_CW | \ RIG_MODE_RTTY | \ RIG_MODE_FM | \ RIG_MODE_AMS ) #define AR7030P_FUNC ( RIG_FUNC_FAGC | \ RIG_FUNC_NB | \ RIG_FUNC_ANF | \ RIG_FUNC_AIP | \ RIG_FUNC_MN | \ RIG_FUNC_RF | \ RIG_FUNC_LOCK | \ RIG_FUNC_MUTE | \ RIG_FUNC_SQL ) #define AR7030P_LEVEL ( RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_RF | \ RIG_LEVEL_SQL | \ RIG_LEVEL_PBT_IN | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_NOTCHF | \ RIG_LEVEL_AGC | \ RIG_LEVEL_RAWSTR | \ RIG_LEVEL_STRENGTH ) #define AR7030P_PARM ( RIG_PARM_APO | \ RIG_PARM_TIME | \ RIG_PARM_BAT ) #define AR7030P_VFO_OPS ( RIG_OP_CPY | \ RIG_OP_XCHG | \ RIG_OP_TOGGLE ) #define AR7030P_VFO ( RIG_VFO_A | \ RIG_VFO_B) #define AR7030P_STR_CAL { 8, { \ { 10, -113 }, \ { 10, -103 }, \ { 10, -93 }, \ { 10, -83 }, \ { 10, -73 }, \ { 10, -63 }, \ { 20, -43 }, \ { 20, -23 }, \ } } /* Channel capabilities - Frequency - Mode - Width - Scan lockout - PBT - Squelch - ID */ #define AR7030P_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .funcs = RIG_FUNC_NONE, \ .levels = RIG_LEVEL_SQL | RIG_LEVEL_PBT_IN, \ .flags = 1, \ .channel_desc = 1 \ } struct ar7030p_priv_caps { int max_freq_len; int info_len; int mem_len; int pbs_info_len; int pbs_len; int chan_num; }; static const struct ar7030p_priv_caps ar7030p_priv_caps = { .max_freq_len = 3, .info_len = 14, .mem_len = 17, .pbs_info_len = 1, .pbs_len = 1, .chan_num = 0, }; #define NB_CHAN 400 /* see caps->chan_list */ struct ar7030p_priv_data { vfo_t curr_vfo; vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */ powerstat_t powerstat; int bank; value_t parms[ RIG_SETTING_MAX ]; channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ channel_t vfo_a; channel_t vfo_b; channel_t mem[ NB_CHAN ]; struct ext_list *ext_parms; }; static const struct confparams ar7030p_ext_levels[] = { { TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { RIG_CONF_END, NULL, } }; static const struct confparams ar7030p_ext_parms[] = { { TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* TODO - move this somewhere where it belongs */ static unsigned int filterTab[ 6 + 1 ] = { 0 }; static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan) { assert(NULL != rig); assert(NULL != chan); chan->channel_num = 0; chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); chan->freq = MHz(10); chan->mode = RIG_MODE_AM; chan->width = rig_passband_normal(rig, RIG_MODE_AM); chan->tuning_step = 110; chan->funcs = (setting_t) 0; memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t)); } static struct ext_list *alloc_init_ext(const struct confparams *cfp) { struct ext_list *elp; int i, nb_ext; assert(NULL != cfp); for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++) { ; } elp = calloc((nb_ext + 1), sizeof(struct ext_list)); if (!elp) { return NULL; } for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++) { elp[i].token = cfp[i].token; /* value reset already by calloc */ } /* last token in array is set to 0 by calloc */ return elp; } #if 0 /* unused; re-enabled as needed. */ static struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token) { int i; for (i = 0; elp[ i ].token != 0; i++) { if (elp[ i ].token == token) { return &(elp[ i ]); } } return NULL; } #endif /* unused */ static int ar7030p_init(RIG *rig) { struct ar7030p_priv_data *priv; int rc = RIG_OK; assert(NULL != rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ar7030p_priv_data *) calloc(1, sizeof(struct ar7030p_priv_data)); if (!priv) { rc = -RIG_ENOMEM; } else { int i; STATE(rig)->priv = (void *) priv; RIGPORT(rig)->type.rig = RIG_PORT_SERIAL; priv->powerstat = RIG_POWER_ON; priv->bank = 0; memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); memset(priv->mem, 0, sizeof(priv->mem)); for (i = 0; i < NB_CHAN; i++) { priv->mem[ i ].channel_num = i; priv->mem[ i ].vfo = RIG_VFO_MEM; priv->mem[ i ].ext_levels = alloc_init_ext(ar7030p_ext_levels); if (!priv->mem[ i ].ext_levels) { rc = -RIG_ENOMEM; break; } } if (RIG_OK == rc) { priv->vfo_a.ext_levels = alloc_init_ext(ar7030p_ext_levels); if (!priv->vfo_a.ext_levels) { return -RIG_ENOMEM; } else { priv->vfo_b.ext_levels = alloc_init_ext(ar7030p_ext_levels); } if (!priv->vfo_b.ext_levels) { return -RIG_ENOMEM; } priv->ext_parms = alloc_init_ext(ar7030p_ext_parms); if (!priv->ext_parms) { return -RIG_ENOMEM; } init_chan(rig, RIG_VFO_A, &priv->vfo_a); init_chan(rig, RIG_VFO_B, &priv->vfo_b); priv->curr = &priv->vfo_a; priv->curr_vfo = priv->last_vfo = RIG_VFO_A; } } return (rc); } static int ar7030p_cleanup(RIG *rig) { struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; int rc = RIG_OK; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (priv == NULL) { return RIG_OK; } for (i = 0; i < NB_CHAN; i++) { free(priv->mem[ i ].ext_levels); } free(priv->vfo_a.ext_levels); free(priv->vfo_b.ext_levels); free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return (rc); } /** * \brief Open I/O to receiver * * \param rig Pointer to rig struct * * \return 0 on success, < 0 on failure */ static int ar7030p_open(RIG *rig) { int rc = RIG_OK; unsigned char v; struct rig_state *rs; assert(NULL != rig); rs = STATE(rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { int i; /* Load calibration table */ rs->str_cal.size = rig->caps->str_cal.size; for (i = 0; i < rs->str_cal.size; i++) { rc = readByte(rig, EEPROM1, SM_CAL + i, &v); if (RIG_OK != rc) { break; } rs->str_cal.table[ i ].val = rig->caps->str_cal.table[ i ].val; rs->str_cal.table[ i ].raw = (int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: index %d, val %d, raw %d\n", __func__, i, rs->str_cal.table[ i ].val, rs->str_cal.table[ i ].raw); } if (RIG_OK == rc) { /* Load filter BW table */ for (i = 1; i <= 6; i++) { rc = getFilterBW(rig, i); if (rc < 0) { rig_debug(RIG_DEBUG_ERR, "%s: err in getFilterBW: %s\n", __func__, rigerror(rc)); return rc; } else { filterTab[i] = (unsigned int) rc; } } } rc = lockRx(rig, LOCK_0); rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__); } return (rc); } /** * \brief Close I/O to receiver * * \param rig Pointer to rig struct * * \return 0 on success, < 0 on failure */ // cppcheck-suppress * static int ar7030p_close(RIG *rig) { assert(NULL != rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__); return (RIG_OK); } static const char *ar7030p_get_info(RIG *rig) { static char version[10] = ""; unsigned int i; char *p = &(version[ 0 ]); assert(NULL != rig); for (i = 0; i < pageSize(ROM); i++) { if (RIG_OK != readByte(rig, ROM, i, (unsigned char *) p++)) { p = NULL; break; } } if (NULL != p) { *p++ = '\0'; p = &(version[ 0 ]); rig_debug(RIG_DEBUG_VERBOSE, "%s: ident - %s\n", __func__, version); } return (p); } /* * \brief Set receiver frequency * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param freq Frequency to set * */ static int ar7030p_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int rc = RIG_OK; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { struct rig_caps *caps = rig->caps; if ((caps->rx_range_list1[ 0 ].endf > freq) && (caps->rx_range_list1[ 0 ].startf < freq)) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_A: rc = write3Bytes(rig, WORKING, FREQU, hzToDDS(freq)); break; case RIG_VFO_B: rc = write3Bytes(rig, WORKING, FREQU_B, hzToDDS(freq)); break; default: rc = -RIG_EINVAL; break; } } else { rc = -RIG_EINVAL; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = execRoutine(rig, SET_ALL); if (rc == RIG_OK) { rc = lockRx(rig, LOCK_0); } } return (rc); } /* * \brief Get receiver frequency * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param freq Pointer to hold frequency value (in Hz) * */ static int ar7030p_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int rc = RIG_OK; unsigned int x; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_A: rc = read3Bytes(rig, WORKING, FREQU, &x); if (RIG_OK == rc) { *freq = ddsToHz(x); } break; case RIG_VFO_B: rc = read3Bytes(rig, WORKING, FREQU_B, &x); { *freq = ddsToHz(x); } break; default: rc = -RIG_EINVAL; break; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Set receiver mode * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param mode Mode to set * \param width Bandwidth to set * */ static int ar7030p_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int rc = RIG_OK; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ unsigned char ar_mode = modeToNative(mode); rc = writeByte(rig, WORKING, MODE, ar_mode); if (RIG_OK == rc && width != RIG_PASSBAND_NOCHANGE) { int i; /* TODO - get filter BWs at startup */ unsigned char ar_filter = (unsigned char) 6; for (i = 1; i <= 6; i++) { if (width <= filterTab[ i ]) { if (filterTab[ i ] < filterTab[(int) ar_filter ]) { ar_filter = (unsigned char) i; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: width %d ar_filter %d filterTab[%d] %u\n", __func__, (int)width, ar_filter, i, filterTab[i]); } rc = writeByte(rig, WORKING, FILTER, ar_filter); if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); } } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Get receiver mode and bandwidth * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param mode Pointer to value to hold mode * \param width Pointer to value to hold bandwidth * */ static int ar7030p_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int rc = RIG_OK; unsigned char bcd_bw; unsigned char m; assert(NULL != rig); assert(NULL != mode); assert(NULL != width); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ rc = readByte(rig, WORKING, MODE, &m); if (RIG_OK == rc) { *mode = modeToHamlib(m); rc = readByte(rig, WORKING, FLTBW, &bcd_bw); if (RIG_OK == rc) { *width = (pbwidth_t)((int) bcd2Int(bcd_bw) * 100); } } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Get memory channel parameters * * \param rig Pointer to rig struct * \param chan Channel number (0-399) * \param freq Pointer to frequency value * \param mode Pointer to mode value (1-7) * \param filt Pointer to filter value (1-6) * \param pbs Pointer to passband tuning value * \param sql Pointer to squelch value (0-255) * \param id Pointer to channel ident string (14 chars) * */ #if 0 /* unused; re-enabled as needed. */ static void ar7030p_get_memory(RIG *rig, const unsigned int chan, double *const freq, unsigned char *const mode, unsigned char *const filt, unsigned char *const pbs, unsigned char *const sql, char *const id) { int rc = RIG_OK; unsigned char v; unsigned int f; unsigned char *p = (unsigned char *) id; int i; assert(NULL != rig); assert(NULL != freq); assert(NULL != mode); assert(NULL != filt); assert(NULL != pbs); assert(NULL != sql); assert(NULL != id); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* Squelch values */ if (100 > chan) { rc = readByte(rig, BBRAM, (MEM_SQ + chan), &v); /* mem_sq */ } else if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_SQ + (chan * 16)), &v); /* mex_sq */ } else { rc = readByte(rig, EEPROM3, (MEY_SQ + ((chan - 176) * 16)), &v); /* mey_sq */ } if (RIG_OK == rc) { *sql = v; } /* Frequency, mode and filter values */ if (100 > chan) { rc = read3Bytes(rig, EEPROM2, (MEM_FR + (chan * 4)), &f); /* mem_fr */ rc = readByte(rig, EEPROM2, (MEM_MD + (chan * 4)), &v); /* mem_md */ } else { rc = read3Bytes(rig, EEPROM3, (MEX_FR + ((chan - 100) * 4)), &f); /* mex_fr */ rc = readByte(rig, EEPROM3, (MEX_MD + ((chan - 100) * 4)), &v); /* mex_md */ } if (RIG_OK == rc) { *freq = ddsToHz(f); *mode = (v & 0x07); *filt = ((v & 0x70) >> 4); /* lockout = ( ( v & 0x80 ) >> 7 ); */ } /* PBT values */ if (100 > chan) { rc = readByte(rig, EEPROM1, (MEM_PB + chan), &v); /* mem_pb */ } else if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_PB + (chan * 16)), &v); /* mex_pb */ } else { rc = readByte(rig, EEPROM3, (MEY_PB + ((chan - 176) * 16)), &v); /* mey_pb */ } if (RIG_OK == rc) { *pbs = v; } /* Memory ID values */ for (i = 0; i < 14; i++) { if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_ID + (chan * 16)), p++); /* mex_id */ } else { rc = readByte(rig, EEPROM3, (MEY_ID + ((chan - 176) * 16)), p++); /* mey_id */ } if (RIG_OK != rc) { p = (unsigned char *) id; break; } } *p++ = '\0'; rc = lockRx(rig, LOCK_0); } } #endif /* unused */ /* * \brief Set receiver levels * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param level Level to set * \param val Value to set level to * * \return RIG_OK on success */ static int ar7030p_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int rc = RIG_OK; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ switch (level) { unsigned char v; case RIG_LEVEL_PREAMP: /* Scale parameter */ if (10 <= val.i) { v = (unsigned char) 0; } else { v = (unsigned char) 1; } rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_ATT: /* Scale parameter */ if (10 > val.i) { v = (unsigned char) 1; } else if (20 > val.i) { v = (unsigned char) 2; } else if (40 > val.i) { v = (unsigned char) 3; } else if (80 > val.i) { v = (unsigned char) 4; } else { v = (unsigned char) 5; } rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_AF: /* Scale parameter */ v = (unsigned char)((val.f * (VOL_MAX - VOL_MIN)) + VOL_MIN); v = (v & 0x3f); rc = writeByte(rig, WORKING, AF_VOL, v); /* af_vol */ rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %f (%d)\n", __func__, val.f, v); v = ((v >> 1) & 0x1f); /* half value for L/R volume */ if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLL, v); } /* af_vll */ if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLR, v); } /* af_vlr */ if (rc == RIG_OK) { rc = execRoutine(rig, SET_AUDIO); } break; case RIG_LEVEL_RF: /* Scale parameter, values 0 (99%) to 130 (3%) */ v = (unsigned char)(134U - ((unsigned int)(val.f * 135.0))); rc = writeByte(rig, WORKING, IFGAIN, v); /* ifgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_SQL: /* Scale parameter */ v = (unsigned char)(val.f * 255.0); rc = writeByte(rig, WORKING, SQLVAL, v); /* sqlval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_PBT_IN: /* Scale parameter */ v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5)); rc = writeByte(rig, WORKING, PBSVAL, v); /* pbsval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_CWPITCH: /* Scale parameter */ v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5)); rc = writeByte(rig, WORKING, BFOVAL, v); /* bfoval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_NOTCHF: rc = -RIG_ENIMPL; break; case RIG_LEVEL_AGC: /* Scale parameter */ v = agcToNative(val.i); rc = writeByte(rig, WORKING, AGCSPD, v); /* agcspd */ rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; default: rc = -RIG_EINVAL; break; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Get receiver levels * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param level Level to get * \param val Pointer to value to get * * \return RIG_OK on success */ static int ar7030p_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int rc = RIG_OK; unsigned char v; unsigned short s = 0; int i; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ switch (level) { case RIG_LEVEL_PREAMP: rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */ if (RIG_OK == rc) { /* Scale parameter */ if (0 == v) { val->i = 10; } else { val->i = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_ATT: rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */ if (RIG_OK == rc) { /* Scale parameter */ switch (v) { case 2: val->i = 10; break; case 3: val->i = 20; break; case 4: val->i = 40; break; default: case 0: case 1: val->i = 0; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_AF: rc = readByte(rig, WORKING, AF_VOL, &v); /* af_vol */ if (RIG_OK == rc) { /* Scale parameter */ v = (v & 0x3f); val->f = (((float) v - VOL_MIN) / (VOL_MAX - VOL_MIN)); rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_RF: rc = readByte(rig, WORKING, IFGAIN, &v); /* ifgain */ if (RIG_OK == rc) { /* Scale parameter, values 0 (99%) to 130 (3%) */ val->f = ((float)(134 - v) / 135.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_SQL: rc = readByte(rig, WORKING, SQLVAL, &v); /* sqlval */ if (RIG_OK == rc) { /* Scale parameter */ val->f = ((float)(v) / 255.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_PBT_IN: rc = readByte(rig, WORKING, PBSVAL, &v); /* pbsval */ if (RIG_OK == rc) { /* Scale parameter */ if (127 < v) { v = v | 0xffffff00; } val->f = ((float)(v) * HZ_PER_STEP * 12.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_CWPITCH: rc = readByte(rig, WORKING, BFOVAL, &v); /* bfoval */ if (RIG_OK == rc) { /* Scale parameter */ if (127 < v) { v = v | 0xffffff00; } val->f = ((float)(v) * HZ_PER_STEP * 12.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_NOTCHF: rc = readShort(rig, WORKING, NCHFR, &s); /* nchfr */ if (RIG_OK == rc) { unsigned int x = (unsigned int) s; /* Scale parameter */ val->i = (int)((float)(x) / NOTCH_STEP_HZ); rig_debug(RIG_DEBUG_VERBOSE, "%s: nchfr %u (%d)\n", __func__, x, val->i); } break; case RIG_LEVEL_AGC: rc = readByte(rig, WORKING, AGCSPD, &v); /* agcspd */ if (RIG_OK == rc) { /* Scale parameter */ val->i = agcToHamlib(v); rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_RAWSTR: rc = readSignal(rig, &v); if (RIG_OK == rc) { val->i = (int) v; } break; case RIG_LEVEL_STRENGTH: rc = readSignal(rig, &v); if (RIG_OK == rc) { rc = getCalLevel(rig, v, &i); if (RIG_OK == rc) { val->i = i; } } break; default: rc = -RIG_EINVAL; } if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); } } return (rc); } static int ar7030p_set_vfo(RIG *rig, vfo_t vfo) { int rc = RIG_OK; struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; switch (vfo) { case RIG_VFO_B: if (RIG_VFO_B != priv->curr_vfo) { rc = sendIRCode(rig, IR_VFO); if (RIG_OK == rc) { priv->curr_vfo = RIG_VFO_B; priv->last_vfo = RIG_VFO_A; } } break; case RIG_VFO_A: case RIG_VFO_CURR: if (RIG_VFO_A != priv->curr_vfo) { rc = sendIRCode(rig, IR_VFO); if (RIG_OK == rc) { priv->curr_vfo = RIG_VFO_A; priv->last_vfo = RIG_VFO_B; } } break; default: rc = -RIG_EINVAL; break; } return (rc); } static int ar7030p_get_vfo(RIG *rig, vfo_t *vfo) { int rc = RIG_OK; struct ar7030p_priv_data const *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; assert(NULL != vfo); *vfo = priv->curr_vfo; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_set_parm(RIG *rig, setting_t parm, value_t val) { int rc = -RIG_ENIMPL; assert(NULL != rig); switch (parm) { case RIG_PARM_APO: break; case RIG_PARM_TIME: break; case RIG_PARM_BAT: break; default: break; }; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_get_parm(RIG *rig, setting_t parm, value_t *val) { int rc = -RIG_ENIMPL; assert(NULL != rig); assert(NULL != val); switch (parm) { case RIG_PARM_APO: break; case RIG_PARM_TIME: break; case RIG_PARM_BAT: break; default: break; }; return (rc); } static int ar7030p_set_mem(RIG *rig, vfo_t vfo, int ch) { int rc = RIG_OK; struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; if (RIG_VFO_MEM == priv->curr_vfo) { priv->curr = &priv->mem[ ch ]; } else { priv->curr->channel_num = ch; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, ch); return (rc); } static int ar7030p_get_mem(RIG *rig, vfo_t vfo, int *ch) { int rc = RIG_OK; struct ar7030p_priv_data const *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; const channel_t *curr = priv->curr; assert(NULL != ch); *ch = curr->channel_num; rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, *ch); return (rc); } static int ar7030p_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int rc = -RIG_ENIMPL; assert(NULL != rig); switch (op) { case RIG_OP_CPY: rc = -RIG_ENIMPL; break; case RIG_OP_XCHG: rc = -RIG_ENIMPL; break; case RIG_OP_TOGGLE: rc = sendIRCode(rig, IR_VFO); break; default: break; }; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int rc = -RIG_ENIMPL; assert(NULL != rig); return (rc); } static int ar7030p_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != dcd); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readByte(rig, WORKING, BITS + 2, &v); if (RIG_OK == rc) { if ((v & 0x02)) { if ((v & 0x01)) /* low bit set if Squelch is NOT active/open */ { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } } else { *dcd = RIG_DCD_ON; } } rc = lockRx(rig, LOCK_0); } return (rc); } static int ar7030p_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int rc = RIG_OK; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* Scale parameter */ unsigned short v = (unsigned short)((double)(ts + 1) / HZ_PER_STEP); rc = writeShort(rig, WORKING, CHNSTP, v); /* chnstp */ if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); rig_debug(RIG_DEBUG_VERBOSE, "%s: chnstp %d (%d)\n", __func__, (int)ts, v); } if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); } } return (rc); } /* * \brief Get receiver tuning step size * * \param rig Pointer to rig struct * \param vfo VFO to operate on * \param ts Pointer to tuning step value * * \return RIG_OK on success */ static int ar7030p_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int rc = RIG_OK; unsigned short v; assert(NULL != rig); assert(NULL != ts); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readShort(rig, WORKING, CHNSTP, &v); /* chnstp */ if (RIG_OK == rc) { double x = (double) v; *ts = (shortfreq_t)(x * HZ_PER_STEP); rig_debug(RIG_DEBUG_VERBOSE, "%s: step= %d\n", __func__, (int)*ts); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Set receiver power status * * \param rig Pointer to rig struct * \param status Power status to set * * \return RIG_OK on success */ static int ar7030p_set_powerstat(RIG *rig, powerstat_t status) { int rc; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { switch (status) { case RIG_POWER_OFF: break; case RIG_POWER_ON: break; default: break; } lockRx(rig, LOCK_0); } return (-RIG_ENIMPL); } /* * \brief Get receiver power status * * \param rig Pointer to rig struct * \param status Pointer to power status value * * \return RIG_OK on success */ static int ar7030p_get_powerstat(RIG *rig, powerstat_t *status) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readByte(rig, WORKING, PDFLGS, &v); if (RIG_OK == rc) { if (0 == (v & 0x01)) { *status = RIG_POWER_OFF; } else { *status = RIG_POWER_ON; } } rc = lockRx(rig, LOCK_0); } return (rc); } /* * \brief Reset receiver * * \param rig Pointer to rig struct * \param reset Reset operation to perform * * \return RIG_OK on success */ static int ar7030p_reset(RIG *rig, reset_t reset) { int rc = RIG_OK; assert(NULL != rig); switch (reset) { case RIG_RESET_SOFT: rc = execRoutine(rig, RESET); break; default: rc = -RIG_EINVAL; } return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { assert(NULL != rig); return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { assert(NULL != rig); assert(NULL != status); *status = 0; return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_decode_event(RIG *rig) { assert(NULL != rig); return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { assert(NULL != rig); assert(NULL != chan); return (-RIG_ENIMPL); } static int ar7030p_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int rc = RIG_OK; unsigned char v; unsigned int f; unsigned char *p = NULL; int ch; const struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; const channel_t *curr = priv->curr; assert(NULL != chan); ch = curr->channel_num; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { int i; /* Squelch values */ /* TODO - fix magic numbers */ if (100 > ch) { rc = readByte(rig, BBRAM, (MEM_SQ + ch), &v); /* mem_sq */ } else if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_SQ + (ch * 16)), &v); /* mex_sq */ } else { rc = readByte(rig, EEPROM3, (MEY_SQ + ((ch - 176) * 16)), &v); /* mey_sq */ } if (RIG_OK == rc) { chan->levels[ LVL_SQL ].f = (float) v / 255.0; } /* Frequency, mode and filter values */ if (100 > ch) { rc = read3Bytes(rig, EEPROM1, (MEM_FR + (ch * 4)), &f); /* mem_fr */ if (RIG_OK == rc) { rc = readByte(rig, EEPROM1, (MEM_MD + (ch * 4)), &v); } /* mem_md */ } else { rc = read3Bytes(rig, EEPROM2, (MEX_FR + ((ch - 100) * 4)), &f); /* mex_fr */ if (RIG_OK == rc) { rc = readByte(rig, EEPROM2, (MEX_MD + ((ch - 100) * 4)), &v); } /* mex_md */ } if (RIG_OK == rc) { chan->freq = ddsToHz(f); chan->mode = modeToHamlib((v & 0x07)); chan->width = getFilterBW(rig, ((v & 0x70) >> 4)); if ((v & 0x80) >> 7) { chan->flags = RIG_CHFLAG_SKIP; } else { chan->flags = RIG_CHFLAG_NONE; } } /* PBT values */ if (100 > ch) { rc = readByte(rig, EEPROM1, (MEM_PB + ch), &v); /* mem_pb */ } else if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_PB + (ch * 16)), &v); /* mex_pb */ } else { rc = readByte(rig, EEPROM3, (MEY_PB + ((ch - 176) * 16)), &v); /* mey_pb */ } if (RIG_OK == rc) { chan->levels[ LVL_PBT_IN ].f = pbsToHz(v); } /* Memory ID values */ p = (unsigned char *) chan->channel_desc; for (i = 0; i < 14; i++) { if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_ID + (ch * 16) + i), p++); /* mex_id */ } else { rc = readByte(rig, EEPROM3, (MEY_ID + ((ch - 176) * 16) + i), p++); /* mey_id */ } if (RIG_OK != rc) { p = (unsigned char *) chan->channel_desc; break; } } *p++ = '\0'; rc = lockRx(rig, LOCK_0); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return (rc); } struct rig_caps ar7030p_caps = { RIG_MODEL(RIG_MODEL_AR7030P), .model_name = "AR7030 Plus", .mfg_name = "AOR", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 12, .timeout = 650, .retry = 0, .has_get_func = AR7030P_FUNC, .has_set_func = AR7030P_FUNC, .has_get_level = AR7030P_LEVEL, .has_set_level = RIG_LEVEL_SET(AR7030P_LEVEL), .has_get_parm = AR7030P_PARM, .has_set_parm = RIG_PARM_SET(AR7030P_PARM), .level_gran = { [LVL_PREAMP] = {.min = {.i = 0}, .max = {.i = 10} }, [LVL_ATT] = {.min = {.i = 0}, .max = {.i = 20} }, [LVL_RF] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_AF] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_SQL] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_IF] = {.min = {.i = 255}, .max = {.i = 0} }, [LVL_PBT_IN] = {.min = {.f = -4248.0}, .max = {.f = 4248.0} }, [LVL_CWPITCH] = {.min = {.i = -4248}, .max = {.i = 4248} }, [LVL_NOTCHF] = {.min = {.i = 0}, .max = {.i = 10000} }, [LVL_AGC] = {.min = {.i = 0}, .max = {.i = 10} }, [LVL_BALANCE] = {.min = {.f = -1.0}, .max = {.f = 1.0} }, [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 255} }, [LVL_STRENGTH] = {.min = {.i = 0}, .max = {.i = 255} }, }, .extparms = NULL, .extlevels = NULL, .parm_gran = { [PARM_APO] = {.min = {.i = 1}, .max = {.i = 86400} }, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86400} }, [PARM_BAT] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, }, .preamp = {10, RIG_DBLST_END,}, .attenuator = {10, 20, RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(4248), .announces = RIG_ANN_NONE, .vfo_ops = AR7030P_VFO_OPS, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_MEM | RIG_SCAN_VFO, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 14, .chan_list = {{0, 399, RIG_MTYPE_MEM, AR7030P_MEM_CAP}, RIG_CHAN_END,}, .rx_range_list1 = { { kHz(10), kHz(32010), AR7030P_MODES, -1, -1, AR7030P_VFO }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(10), kHz(32010), AR7030P_MODES, -1, -1, AR7030P_VFO }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {AR7030P_MODES, Hz(10)}, {AR7030P_MODES, Hz(20)}, {AR7030P_MODES, Hz(50)}, {AR7030P_MODES, Hz(100)}, {AR7030P_MODES, Hz(200)}, {AR7030P_MODES, Hz(500)}, {AR7030P_MODES, kHz(1)}, {AR7030P_MODES, kHz(2)}, {AR7030P_MODES, kHz(5)}, {AR7030P_MODES, kHz(6.25)}, {AR7030P_MODES, kHz(9)}, {AR7030P_MODES, kHz(10)}, {AR7030P_MODES, Hz(12500)}, {AR7030P_MODES, kHz(20)}, {AR7030P_MODES, kHz(25)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, kHz(9.5)}, {RIG_MODE_FM, kHz(0)}, {RIG_MODE_FM, kHz(0)}, {RIG_MODE_AMS, kHz(6.5)}, {RIG_MODE_AMS, kHz(5.3)}, {RIG_MODE_AMS, kHz(9.5)}, {RIG_MODE_AM, kHz(5.3)}, {RIG_MODE_AM, kHz(3.7)}, {RIG_MODE_AM, kHz(6.5)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(1.4)}, {RIG_MODE_SSB, kHz(3.7)}, {RIG_MODE_CW, kHz(1.4)}, {RIG_MODE_CW, kHz(0)}, {RIG_MODE_CW, kHz(2.0)}, {RIG_MODE_RTTY, kHz(1.4)}, {RIG_MODE_RTTY, kHz(0)}, {RIG_MODE_RTTY, kHz(2.0)}, RIG_FLT_END, }, .str_cal = AR7030P_STR_CAL, .cfgparams = NULL, .priv = (void *)& ar7030p_priv_caps, .rig_init = ar7030p_init, .rig_cleanup = ar7030p_cleanup, .rig_open = ar7030p_open, .rig_close = ar7030p_close, .set_freq = ar7030p_set_freq, .get_freq = ar7030p_get_freq, .set_mode = ar7030p_set_mode, .get_mode = ar7030p_get_mode, .set_vfo = ar7030p_set_vfo, .get_vfo = ar7030p_get_vfo, .get_dcd = ar7030p_get_dcd, .set_ts = ar7030p_set_ts, .get_ts = ar7030p_get_ts, .set_powerstat = ar7030p_set_powerstat, .get_powerstat = ar7030p_get_powerstat, .reset = ar7030p_reset, .set_level = ar7030p_set_level, .get_level = ar7030p_get_level, .set_func = ar7030p_set_func, .get_func = ar7030p_get_func, .set_parm = ar7030p_set_parm, .get_parm = ar7030p_get_parm, .set_ext_level = RIG_FUNC_NONE, .get_ext_level = RIG_FUNC_NONE, .set_ext_parm = RIG_FUNC_NONE, .get_ext_parm = RIG_FUNC_NONE, .set_conf = RIG_FUNC_NONE, .get_conf = RIG_FUNC_NONE, .set_mem = ar7030p_set_mem, .get_mem = ar7030p_get_mem, .vfo_op = ar7030p_vfo_op, .scan = ar7030p_scan, .decode_event = ar7030p_decode_event, .set_channel = ar7030p_set_channel, .get_channel = ar7030p_get_channel, .get_info = ar7030p_get_info, .set_chan_all_cb = RIG_FUNC_NONE, .get_chan_all_cb = RIG_FUNC_NONE, .set_mem_all_cb = RIG_FUNC_NONE, .get_mem_all_cb = RIG_FUNC_NONE, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/aor/ar8000.c0000664000175000017500000001261115056640443011260 /* * Hamlib AOR backend - AR8000 description * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8000_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8000_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8000_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define AR8000_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8000_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8000_VFO (RIG_VFO_A|RIG_VFO_B) /* TODO: measure and report real values */ #define AR8000_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0xff, 60 } \ } } static const struct aor_priv_caps ar8000_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8000 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8000.htm */ struct rig_caps ar8000_caps = { RIG_MODEL(RIG_MODEL_AR8000), .model_name = "AR8000", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8000_FUNC_ALL, .has_get_level = AR8000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, .chan_desc_sz = 12, .vfo_ops = AR8000_VFO_OPS, .scan_ops = AR8000_SCAN_OPS, .str_cal = AR8000_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 1000 memories */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(1900), AR8000_MODES, -1, -1, AR8000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8000_MODES, 50}, {AR8000_MODES, 100}, {AR8000_MODES, 200}, {AR8000_MODES, 500}, {AR8000_MODES, kHz(1)}, {AR8000_MODES, kHz(2)}, {AR8000_MODES, kHz(5)}, {AR8000_MODES, kHz(6.25)}, {AR8000_MODES, kHz(9)}, {AR8000_MODES, kHz(10)}, {AR8000_MODES, 12500}, {AR8000_MODES, kHz(20)}, {AR8000_MODES, kHz(25)}, {AR8000_MODES, kHz(30)}, {AR8000_MODES, kHz(50)}, {AR8000_MODES, kHz(100)}, {AR8000_MODES, kHz(200)}, {AR8000_MODES, kHz(250)}, {AR8000_MODES, kHz(500)}, #if 0 {AR8000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(2)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_WFM, kHz(180)}, /* 50kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8000_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/aor/Android.mk0000664000175000017500000000054715056640443012120 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p_utils.c sr2200.c aor.c LOCAL_MODULE := aor LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/aor/README.aor0000664000175000017500000000134715056640443011646 hamlib - Copyright (C) 2000 Frank Singleton libaor.so - Copyright (C) 2000 Stephane Fillod This shared library provides an API for communicating via serial interface to an AOR scanner. Reference Documentation ----------------------- AOR RS232 protocol listing for the AR8200 (accompanies the CC8200) Document release V1.3 AOR Ltd. Status ------ This is a WIP. Handles 5% of all opcodes. All primitives are written from spec. In other words, they are totally untested because I don't own an AOR scanner myself. Patches and contributions are welcome! I'm also looking for a real maintainer :) --SF This lib should/will support other AOR models. Warnings -------- 1. NOTHING IS WORKING, this is a WIP. Contributors ------------ hamlib-4.6.5/rigs/aor/Makefile.in0000664000175000017500000005666615056640452012271 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/aor ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_aor_la_LIBADD = am__objects_1 = ar8200.lo ar8000.lo ar5000.lo ar3000.lo ar7030.lo \ ar3030.lo ar2700.lo ar8600.lo ar7030p.lo ar7030p_utils.lo \ sr2200.lo aor.lo am_libhamlib_aor_la_OBJECTS = $(am__objects_1) libhamlib_aor_la_OBJECTS = $(am_libhamlib_aor_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/aor.Plo ./$(DEPDIR)/ar2700.Plo \ ./$(DEPDIR)/ar3000.Plo ./$(DEPDIR)/ar3030.Plo \ ./$(DEPDIR)/ar5000.Plo ./$(DEPDIR)/ar7030.Plo \ ./$(DEPDIR)/ar7030p.Plo ./$(DEPDIR)/ar7030p_utils.Plo \ ./$(DEPDIR)/ar8000.Plo ./$(DEPDIR)/ar8200.Plo \ ./$(DEPDIR)/ar8600.Plo ./$(DEPDIR)/sr2200.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_aor_la_SOURCES) DIST_SOURCES = $(libhamlib_aor_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AORSRCLIST = ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p.h ar7030p_utils.c \ sr2200.c aor.c aor.h noinst_LTLIBRARIES = libhamlib-aor.la libhamlib_aor_la_SOURCES = $(AORSRCLIST) EXTRA_DIST = README.aor README.ar5000 README.ar7030 Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/aor/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/aor/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-aor.la: $(libhamlib_aor_la_OBJECTS) $(libhamlib_aor_la_DEPENDENCIES) $(EXTRA_libhamlib_aor_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_aor_la_OBJECTS) $(libhamlib_aor_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar2700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar3000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar3030.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030p.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030p_utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sr2200.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/aor.Plo -rm -f ./$(DEPDIR)/ar2700.Plo -rm -f ./$(DEPDIR)/ar3000.Plo -rm -f ./$(DEPDIR)/ar3030.Plo -rm -f ./$(DEPDIR)/ar5000.Plo -rm -f ./$(DEPDIR)/ar7030.Plo -rm -f ./$(DEPDIR)/ar7030p.Plo -rm -f ./$(DEPDIR)/ar7030p_utils.Plo -rm -f ./$(DEPDIR)/ar8000.Plo -rm -f ./$(DEPDIR)/ar8200.Plo -rm -f ./$(DEPDIR)/ar8600.Plo -rm -f ./$(DEPDIR)/sr2200.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/aor.Plo -rm -f ./$(DEPDIR)/ar2700.Plo -rm -f ./$(DEPDIR)/ar3000.Plo -rm -f ./$(DEPDIR)/ar3030.Plo -rm -f ./$(DEPDIR)/ar5000.Plo -rm -f ./$(DEPDIR)/ar7030.Plo -rm -f ./$(DEPDIR)/ar7030p.Plo -rm -f ./$(DEPDIR)/ar7030p_utils.Plo -rm -f ./$(DEPDIR)/ar8000.Plo -rm -f ./$(DEPDIR)/ar8200.Plo -rm -f ./$(DEPDIR)/ar8600.Plo -rm -f ./$(DEPDIR)/sr2200.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/aor/README.ar50000000664000175000017500000000142315056640443011767 hamlib-1.2.5 aor.c ar5000.c 2006-10-29 The previous AR5000 could: - get and set frequency. - read mode if radio were not set to SAH, SAL or SAM. - not set mode. Radio did not accept two commands to be sent at once. - not return VFO-name if rig were set to VFO D or VFO E. - not set VFO D or VFO E. - vfo_op Up and Down works, but radio returns a "?", resulting in "Protocol error". - get_info does not work. - not read AGC-level. Now, it: - can get and set frequency. - can read and set (all) modes. - still does not support VFO D & E. I probably have not understood how VFO_N(3) and VFO_N(4) are meant to be used :-( - can read AGC-level. - corrected channel description size from 12 to 8. - filter-list mode/bw rearranged. - list of tuning steps corrected. Gran Sandin, SM6PPS hamlib-4.6.5/rigs/aor/ar7030p_utils.c0000664000175000017500000007573315056640443012700 /* * Hamlib AOR backend - AR7030 Plus utility functions * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Version 2009.12.31 Larry Gadallah (VE6VQ) */ #include #include #include #include #include #include "ar7030p.h" #include "serial.h" static enum PAGE_e curPage = NONE; /* Current memory page */ static unsigned int curAddr = 65535; /* Current page address */ static enum LOCK_LVL_e curLock = LOCK_0; /* Current lock level */ static const unsigned int AR7030_PAGE_SIZE[] = { 256, 256, 512, 4096, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; /* Page size table */ #if 0 /* * Code Ident Operation * 0x NOP No Operation */ int NOP(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_NOP); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 3x SRH Set H-register x -> H-register (4-bits) */ int SRH(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_SRH); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 5x PGE Set page x -> Page register (4-bits) */ int PGE(RIG *rig, enum PAGE_e page) { int rc = RIG_OK; unsigned char op = ((0x0f & page) | op_PGE); assert(NULL != rig); switch (page) { case WORKING: case BBRAM: case EEPROM1: case EEPROM2: case EEPROM3: case ROM: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; case NONE: default: rig_debug(RIG_DEBUG_VERBOSE, "PGE: invalid page %d\n", page); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * 4x ADR Set address 0Hx -> Address register (12-bits) * 0 -> H-register */ int ADR(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_ADR); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 1x ADH Set address high x -> Address register (high 4-bits) */ int ADH(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_ADH); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 6x WRD Write data Hx -> [Page, Address] * Address register + 1 -> Address register * 0 -> H-register, 0 -> Mask register */ int WRD(RIG *rig, unsigned char out) { int rc = RIG_OK; unsigned char op = ((0x0f & out) | op_WRD); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 9x MSK Set mask Hx -> Mask register <1> * 0 -> H-register */ int MSK(RIG *rig, unsigned char mask) { int rc = RIG_OK; unsigned char op = ((0x0f & mask) | op_MSK); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 2x EXE Execute routine x */ int EXE(RIG *rig, enum ROUTINE_e routine) { int rc = RIG_OK; unsigned char op = ((0x0f & routine) | op_EXE); assert(NULL != rig); switch (routine) { case RESET: case SET_FREQ: case SET_MODE: case SET_PASS: case SET_ALL: case SET_AUDIO: case SET_RFIF: case DIR_RX_CTL: case DIR_DDS_CTL: case DISP_MENUS: case DISP_FREQ: case DISP_BUFF: case READ_SIGNAL: case READ_BTNS: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "EXE: invalid routine %d\n", routine); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * 7x RDD Read data [Page, Address] -> Serial output * Address register + x -> Address register */ int RDD(RIG *rig, unsigned char len) { int rc = RIG_OK; unsigned char inChr = 0; unsigned char op = ((0x0f & len) | op_RDD); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } else { rc = read_block(RIGPORT(rig), (char *) &inChr, len); if (1 != rc) { rc = -RIG_EIO; } else { rc = (int) inChr; } } return (rc); } /* * Code Ident Operation * 8x LOC Set lock level x */ int LOC(RIG *rig, enum LOCK_LVL_e level) { int rc = RIG_OK; unsigned char op = ((0x0f & level) | op_LOC); assert(NULL != rig); switch (level) { case LOCK_0: case LOCK_1: case LOCK_2: case LOCK_3: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "LOC: invalid lock level %d\n", level); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * Ax BUT Operate button x <1> */ int BUT(RIG *rig, enum BUTTON_e button) { int rc = RIG_OK; unsigned char op = ((0x0f & button) | op_BUT); assert(NULL != rig); switch (button) { case BTN_NONE: break; case BTN_UP: case BTN_DOWN: case BTN_FAST: case BTN_FILTER: case BTN_RFIF: case BTN_MEMORY: case BTN_STAR: case BTN_MENU: case BTN_POWER: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "BUT: invalid button %d\n", button); rc = -RIG_EINVAL; break; }; return (rc); } #endif // 0 /** * \brief Execute routine * * \param rig Pointer to rig struct * \param rtn Receiver routine to execute * * \return RIG_OK on success, error code on failure * */ int execRoutine(RIG *rig, enum ROUTINE_e rtn) { int rc = -RIG_EIO; unsigned char v = EXE((rtn & 0x0f)); assert(NULL != rig); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: routine %2d\n", __func__, rtn); } return (rc); } /** * \brief Set address for I/O with radio * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * * \return RIG_OK on success, error code on failure * * Statics curPage and curAddr shadow radio's copies so that * page and address are only set when needed */ static int setAddr(RIG *rig, enum PAGE_e page, unsigned int addr) { int rc = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); unsigned char v; assert(NULL != rig); if ((EEPROM3 >= page) || (ROM == page)) { if (AR7030_PAGE_SIZE[page] > addr) { if (curPage != page) { v = PGE(page); if (0 == write_block(rp, &v, 1)) { curPage = page; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set page %2d\n", __func__, page); } else { rc = -RIG_EIO; } } if (curAddr != addr) { v = SRH((0x0f0 & addr) >> 4); rc = write_block(rp, &v, 1); if (rc != RIG_OK) { return -RIG_EIO; } v = ADR((0x00f & addr)); if (0 == write_block(rp, &v, 1)) { if (0xff < addr) { v = ADH((0xf00 & addr) >> 8); if (0 == write_block(rp, &v, 1)) { curAddr = addr; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set addr 0x%04x\n", __func__, addr); } else { rc = -RIG_EIO; } } else { curAddr = addr; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set addr 0x%04x\n", __func__, addr); } } else { rc = -RIG_EIO; } } } else { rc = -RIG_EINVAL; /* invalid address */ } } else { rc = -RIG_EINVAL; /* invalid page */ } return (rc); } /* * \brief Write one byte to the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Value to write to radio * * \return RIG_OK on success, error code on failure * */ int writeByte(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char x) { int rc; hamlib_port_t *rp = RIGPORT(rig); unsigned char hi = SRH((x & 0xf0) >> 4); unsigned char lo = WRD(x & 0x0f); assert(NULL != rig); rc = setAddr(rig, page, addr); if (RIG_OK == rc) { rc = -RIG_EIO; if (0 == write_block(rp, &hi, 1)) { if (0 == write_block(rp, &lo, 1)) { rc = RIG_OK; curAddr++; rig_debug(RIG_DEBUG_VERBOSE, "%s: wrote byte 0x%02x\n", __func__, x); } } } return (rc); } /* * \brief Write two bytes to the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int writeShort(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short x) { int rc; unsigned char v = (unsigned char)((x & 0xff00) >> 8); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x00ff); rc = writeByte(rig, page, addr + 1, v); } return (rc); } /* * \brief Write three bytes to the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int write3Bytes(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x) { int rc; unsigned char v = (unsigned char)((x & 0xff0000) >> 16); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x00ff00) >> 8); rc = writeByte(rig, page, addr + 1, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x0000ff); rc = writeByte(rig, page, addr + 2, v); } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * \brief Write unsigned int (4 bytes) to the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int writeInt(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x) { int rc; unsigned char v = (unsigned char)((x & 0xff000000) >> 24); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x00ff0000) >> 16); rc = writeByte(rig, page, addr + 1, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x0000ff00) >> 8); rc = writeByte(rig, page, addr + 2, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x000000ff); rc = writeByte(rig, page, addr + 3, v); } } } return (rc); } #endif /* * \brief Read one byte from the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readByte(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char *x) { int rc = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); unsigned char v = RDD(1); // Read command assert(NULL != rig); assert(NULL != x); rc = setAddr(rig, page, addr); if (RIG_OK == rc) { rc = -RIG_EIO; if (0 == write_block(rp, &v, 1)) { if (1 == read_block(rp, x, 1)) { curAddr++; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%02x\n", __func__, *x); } } } return (rc); } /* * \brief Read an unsigned short (two bytes) from the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readShort(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short *x) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned short) v << 8; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned short) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%04x\n", __func__, *x); } } return (rc); } /* * \brief Read an unsigned int (three bytes) from the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int read3Bytes(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned int) v << 16; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 8; rc = readByte(rig, page, addr + 2, &v); if (RIG_OK == rc) { *x += (unsigned int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%06x\n", __func__, *x); } } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * \brief Read an unsigned int (four bytes) from the receiver * * \param rig Pointer to rig struct * \param page Memory page number (0-4, 15) * \param addr Address offset within page (0-4095, depending on page) * \param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readInt(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x) { int rc = 0; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned int) v << 24; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 16; rc = readByte(rig, page, addr + 2, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 8; rc = readByte(rig, page, addr + 3, &v); { *x += (unsigned int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%08x\n", __func__, *x); } } } } return (rc); } #endif /* * \brief Read raw AGC value from the radio * * \param rig Pointer to rig struct * * \return RIG_OK on success, error code on failure */ int readSignal(RIG *rig, unsigned char *x) { int rc; assert(NULL != rig); assert(NULL != x); rc = execRoutine(rig, READ_SIGNAL); // Read raw AGC value if (RIG_OK == rc) { if (1 == read_block(RIGPORT(rig), x, 1)) { rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: raw AGC %03d\n", __func__, *x); } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * \brief Flush I/O with radio * * \param rig Pointer to rig struct * */ int flushBuffer(RIG *rig) { int rc = -RIG_EIO; char v = '/'; assert(NULL != rig); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; } return (rc); } #endif /* * \brief Lock receiver for remote operations * * \param rig Pointer to rig struct * \param level Lock level (0-3) * */ int lockRx(RIG *rig, enum LOCK_LVL_e level) { int rc = -RIG_EIO; unsigned char v; assert(NULL != rig); if (LOCK_NONE > level) /* valid level? */ { if (curLock != level) /* need to change level? */ { v = LOC(level); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; curLock = level; } } else { rc = RIG_OK; } } else { rc = -RIG_EINVAL; } return (rc); } /* * \brief Convert one byte BCD value to int * * \param bcd BCD value (0-99) * * \return Integer value of BCD parameter (0-99), -1 on failure */ int bcd2Int(const unsigned char bcd) { int rc = -1; unsigned char hi = ((bcd & 0xf0) >> 4); unsigned char lo = (bcd & 0x0f); if ((unsigned char) 0x0a > hi) { rc = (int) hi * 10; if ((unsigned char) 0x0a > lo) { rc += (int) lo; } else { rc = -1; } } return (rc); } /* * \brief Convert raw AGC value to calibrated level in dBm * * \param rig Pointer to rig struct * \param rawAgc raw AGC value (0-255) * \param tab Pointer to calibration table struct * \param dbm Pointer to value to hold calibrated level (S9 = 0 dBm) * * \return RIG_OK on success, error code on failure * * To calculate the signal level, table values should be subtracted from * the AGC voltage in turn until a negative value would result. This gives * the rough level from the table position. The accuracy can be improved by * proportioning the remainder into the next table step. See the following * example :- * * A read signal strength operation returns a value of 100 * Subtract cal byte 1 (64) leaves 36 level > -113dBm * Subtract cal byte 2 (10) leaves 26 level > -103dBm * Subtract cal byte 3 (10) leaves 16 level > -93dBm * Subtract cal byte 4 (12) leaves 4 level > -83dBm * Test cal byte 5 (12) - no subtraction * Fine adjustment value = (remainder) / (cal byte 5) * (level step) * = 4 / 12 * 10 = 3dB * Signal level = -83dBm + 3dB = -80dB * * The receiver can operate the RF attenuator automatically if the signal * level is likely to overload the RF stages. Reading the RFAGC byte (page 0, * location 49) gives the attenuation in 10dB steps. This value should be * read and added to the value calculated above. */ int getCalLevel(RIG *rig, unsigned char rawAgc, int *dbm) { int rc = RIG_OK; int i; int raw = (int) rawAgc; int step; unsigned char v; struct rig_state *rs; assert(NULL != rig); assert(NULL != dbm); rs = STATE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: raw AGC %03d\n", __func__, rawAgc); for (i = 0; i < rs->str_cal.size; i++) { *dbm = rs->str_cal.table[ i ].val; rig_debug(RIG_DEBUG_VERBOSE, "%s: got cal table[ %d ] dBm value %d\n", __func__, i, *dbm); /* if the remaining difference in the raw value is negative */ if (0 > (raw - rs->str_cal.table[ i ].raw)) { /* calculate step size */ if (0 < i) { step = rs->str_cal.table[ i ].val - rs->str_cal.table[ i - 1 ].val; } else { step = 20; /* HACK - try and fix minimum AGC readings */ } rig_debug(RIG_DEBUG_VERBOSE, "%s: got step size %d\n", __func__, step); /* interpolate the final value */ *dbm -= step; /* HACK - table seems to be off by one index */ *dbm += (int)(((double) raw / (double) rs->str_cal.table[ i ].raw) * (double) step); rig_debug(RIG_DEBUG_VERBOSE, "%s: interpolated dBm value %d\n", __func__, *dbm); /* we're done, stop going through the table */ break; } else { /* calculate the remaining raw value */ raw = raw - rs->str_cal.table[ i ].raw; rig_debug(RIG_DEBUG_VERBOSE, "%s: residual raw value %d\n", __func__, raw); } } /* Factor in Attenuator/preamp settings */ /* 40 0x028 rxcon 3 bytes Receiver control register mapping */ rc = readByte(rig, WORKING, RXCON, &v); if (RIG_OK == rc) { if (0x80 & v) /* byte 1 bit 7 rx_atn Attenuator enable */ { if (0xa0 & v) { /* HACK - Settings menu on radio says Atten step is 10 dB, not 20 dB */ *dbm += 20; /* byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB */ } else { *dbm += 10; /* byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB */ } } if (0x10 & v) /* byte 1 bit 4 rx_pre Preamplifier enable */ { *dbm -= 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: RXCON 0x%02x, adjusted dBm value %d\n", __func__, (int) v, *dbm); } /* Adjust to S9 == 0 scale */ *dbm += 73; /* S9 == -73 dBm */ rig_debug(RIG_DEBUG_VERBOSE, "%s: S9 adjusted dBm value %d\n", __func__, *dbm); return (rc); } /* * \brief Get bandwidth of given filter * * \param rig Pointer to rig struct * \param filter Filter number (1-6) * * \return Filter bandwidth in Hz, -1 on failure */ int getFilterBW(RIG *rig, enum FILTER_e filter) { int rc; unsigned char bw; rc = readByte(rig, BBRAM, (FL_BW + ((filter - 1) * 4)), &bw); if (RIG_OK == rc) { rc = bcd2Int(bw) * 100; } else { rig_debug(RIG_DEBUG_ERR, "%s: readByte err: %s\n", __func__, strerror(rc)); return rc; } rig_debug(RIG_DEBUG_VERBOSE, "%s: filter %1d BW %5d\n", __func__, filter, rc); return (rc); } /* * \brief Convert DDS steps to frequency in Hz * * \param steps DDS count * * \return Frequency in Hz or 0 on failure */ freq_t ddsToHz(const unsigned int steps) { freq_t rc = 0.0; rc = ((freq_t) steps * 44545000.0 / 16777216.0); return (rc); } /* * \brief Convert frequency in Hz to DDS steps * * \param freq Frequency in Hz * * \return DDS steps (24 bits) or 0 on failure */ unsigned int hzToDDS(const freq_t freq) { unsigned int rc = 0; double err[3] = { 0.0, 0.0, 0.0 }; rc = (unsigned int)(freq * 16777216.0 / 44545000.0); /* calculate best DDS count based on bletcherous, irrational tuning step of 2.65508890151977539062 Hz/step (actual ratio is 44545000.0 / 16777216.0) */ err[ 0 ] = fabs(freq - ddsToHz((rc - 1))); err[ 1 ] = fabs(freq - ddsToHz(rc)); err[ 2 ] = fabs(freq - ddsToHz((rc + 1))); if (err[ 0 ] < err[ 1 ] && err[ 0 ] < err[ 2 ]) { rc--; } else if (err[ 2 ] < err[ 1 ] && err[ 2 ] < err[ 0 ]) { rc++; } rig_debug(RIG_DEBUG_VERBOSE, "%s: err[0 - 2] = %f %f %f rc 0x%08x\n", __func__, err[ 0 ], err[ 1 ], err[ 2 ], rc); return (rc); } /* * \brief Convert PBS/BFO steps to frequency in Hz * * \param steps PBS/BFO offset steps * * \return Frequency in Hz or 0 on failure * * Max +ve offset is 127, max -ve offset is 128 * Min -ve offset is 255 */ float pbsToHz(const unsigned char steps) { freq_t rc = 0.0; /* treat steps as a 1's complement signed 8-bit number */ if (128 > steps) { rc = (((float) steps * 12.5 * 44545000.0) / 16777216.0); } else { rc = (((float)(~steps & 0x7f) * -12.5 * 44545000.0) / 16777216.0); } rig_debug(RIG_DEBUG_VERBOSE, "%s: raw %d hz %f\n", __func__, steps, rc); return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * \brief Convert PBS/BFO offset frequency in Hz to steps * * \param freq Offset frequency in Hz * * \return steps (8 bits) or 0 on failure */ unsigned char hzToPBS(const float freq) { unsigned char rc; int steps; if (0 < freq) { steps = (((freq + 0.5) * 16777216.0) / (44545000.0 * 12.5)); } else { steps = (((freq - 0.5) * 16777216.0) / (44545000.0 * 12.5)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: steps %d\n", __func__, steps); if (0 <= steps) { rc = (unsigned char)(steps & 0x7f); } else if (-128 < steps) { rc = (unsigned char)(steps + 255); } else { rc = (unsigned char) 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: hz %f rc %d\n", __func__, freq, rc); return (rc); } #endif /* * \brief Convert native Mode to Hamlib mode * * \param mode Native mode value * * \return Hamlib mode value */ rmode_t modeToHamlib(const unsigned char mode) { rmode_t rc = RIG_MODE_NONE; switch (mode) { case AM: rc = RIG_MODE_AM; break; case SAM: rc = RIG_MODE_AMS; break; case FM: rc = RIG_MODE_FM; break; case DATA: rc = RIG_MODE_RTTY; break; case CW: rc = RIG_MODE_CW; break; case LSB: rc = RIG_MODE_LSB; break; case USB: rc = RIG_MODE_USB; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Native %s, Hamlib %s\n", __func__, rig_strrmode(mode), rig_strrmode(rc)); return (rc); } /* * \brief Convert Hamlib Mode to native mode * * \param mode Hamlib mode value * * \return Native mode value */ unsigned char modeToNative(const rmode_t mode) { unsigned char rc = (unsigned char) MODE_NONE; switch (mode) { case RIG_MODE_AM: rc = (unsigned char) AM; break; case RIG_MODE_AMS: rc = (unsigned char) SAM; break; case RIG_MODE_FM: rc = (unsigned char) FM; break; case RIG_MODE_RTTY: rc = (unsigned char) DATA; break; case RIG_MODE_CW: rc = (unsigned char) CW; break; case RIG_MODE_LSB: rc = (unsigned char) LSB; break; case RIG_MODE_USB: rc = (unsigned char) USB; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib %s, native %d\n", __func__, rig_strrmode(mode), rc); return (rc); } /* * \brief Convert native AGC speed to Hamlib AGC speed * * \param agc Native AGC speed value * * \return Hamlib AGC speed value */ enum agc_level_e agcToHamlib(const unsigned char agc) { enum agc_level_e rc = RIG_AGC_AUTO; switch (agc) { case AGC_FAST: rc = RIG_AGC_FAST; break; case AGC_MED: rc = RIG_AGC_MEDIUM; break; case AGC_SLOW: rc = RIG_AGC_SLOW; break; case AGC_OFF: rc = RIG_AGC_OFF; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Native %d, Hamlib %d\n", __func__, agc, rc); return (rc); } /* * \brief Convert Hamlib AGC speed to native AGC speed * * \param agc Hamlib AGC speed value * * \return Native AGC speed value */ unsigned char agcToNative(const enum agc_level_e agc) { unsigned char rc = (unsigned char) AGC_NONE; switch (agc) { case RIG_AGC_OFF: rc = (unsigned char) AGC_OFF; break; case RIG_AGC_FAST: rc = (unsigned char) AGC_FAST; break; case RIG_AGC_SLOW: rc = (unsigned char) AGC_SLOW; break; case RIG_AGC_MEDIUM: rc = (unsigned char) AGC_MED; break; case RIG_AGC_SUPERFAST: case RIG_AGC_USER: case RIG_AGC_AUTO: default: rc = (unsigned char) AGC_NONE; break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib %d, native %d\n", __func__, agc, rc); return (rc); } /* * \brief Get page size * * \param page Page to get size of * * \return Page size, -1 on error */ int pageSize(const enum PAGE_e page) { int rc = -1; if ((WORKING <= page) && (EEPROM3 >= page)) { rc = (int) AR7030_PAGE_SIZE[ page ]; } else if (ROM == page) { rc = (int) AR7030_PAGE_SIZE[ page ]; } else { rc = -1; } return (rc); } /* * \brief Set and execute IR controller code * * \param code IR code to execute * * \return RIG_OK on success, error code on failure */ int sendIRCode(RIG *rig, enum IR_CODE_e code) { int rc; unsigned char v = (unsigned char) code; assert(NULL != rig); rc = writeByte(rig, WORKING, IRCODE, v); if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); if (RIG_OK == rc) { rig_debug(RIG_DEBUG_VERBOSE, "%s: set IR code %d\n", __func__, code); } } return (rc); } hamlib-4.6.5/rigs/aor/ar2700.c0000664000175000017500000001563315056640443011270 /* * Hamlib AOR backend - AR2700 description * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "aor.h" #define AR2700_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define AR2700_FUNC (RIG_FUNC_ABM) #define AR2700_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR2700_PARM (RIG_PARM_APO) #define AR2700_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN) #define AR2700_SCAN_OPS (RIG_SCAN_MEM) #define AR2700_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) /* TODO: measure and report real values */ #define AR2700_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0x3f, 60 } \ } } #define AR2700_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static int format2700_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); static int parse2700_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static const struct aor_priv_caps ar2700_priv_caps = { .format_mode = format2700_mode, .parse_aor_mode = parse2700_aor_mode, .bank_base1 = '0', .bank_base2 = '0', }; /* * ar2700 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/2700.htm * Interface unit: CU-8232 (or equivalent) */ struct rig_caps ar2700_caps = { RIG_MODEL(RIG_MODEL_AR2700), .model_name = "AR2700", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = AR2700_FUNC, .has_set_func = AR2700_FUNC, .has_get_level = AR2700_LEVEL, .has_set_level = RIG_LEVEL_SET(AR2700_LEVEL), .has_get_parm = AR2700_PARM, .has_set_parm = AR2700_PARM, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 0, .vfo_ops = AR2700_VFO_OPS, .scan_ops = AR2700_SCAN_OPS, .str_cal = AR2700_STR_CAL, .chan_list = { { 0, 499, RIG_MTYPE_MEM, AR2700_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(1300), AR2700_MODES, -1, -1, AR2700_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(1300), AR2700_MODES, -1, -1, AR2700_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {RIG_MODE_AM | RIG_MODE_FM, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(9)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, 12500}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {AR2700_MODES, kHz(50)}, {AR2700_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = (void *)& ar2700_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * modes in use by the "MD" command of AR2700 */ #define AR2700_WFM '0' #define AR2700_NFM '1' #define AR2700_AM '2' int format2700_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: aormode = AR2700_AM; break; case RIG_MODE_WFM: aormode = AR2700_WFM; break; case RIG_MODE_FM: aormode = AR2700_NFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } int parse2700_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case AR2700_NFM: *mode = RIG_MODE_FM; break; case AR2700_WFM: *mode = RIG_MODE_WFM; break; case AR2700_AM: *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } hamlib-4.6.5/rigs/aor/ar5000.c0000664000175000017500000003371715056640443011267 /* * Hamlib AOR backend - AR5000 description * * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "aor.h" #define AR5000_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM| \ RIG_MODE_WFM|RIG_MODE_SAM|RIG_MODE_SAL|RIG_MODE_SAH) #define AR5000_FUNC_ALL (RIG_FUNC_TSQL | RIG_FUNC_ABM) #define AR5000_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RAWSTR) #define AR5000_PARM (RIG_PARM_NONE) #define AR5000_VFO_OPS (RIG_OP_MCL | RIG_OP_UP | RIG_OP_DOWN) #define AR5000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR5000_VFO (RIG_VFO_A | RIG_VFO_B | RIG_VFO_C | RIG_VFO_N(3) | RIG_VFO_N(4)) /* As reported with rigctl 'l RAWSTR' for AR5000A S/n: 171218 on 7040kHz / CW / 3kHz Bw. The data available on http://www.aoruk.com did not match very well on HF */ #define AR5000_STR_CAL { 16, { \ { 0, -60 }, \ { 3, -48 }, \ { 14, -42 }, \ { 26, -36 }, \ { 34, -30 }, \ { 42, -24 }, \ { 52, -18 }, \ { 62, -12 }, \ { 74, -6 }, \ { 87, 0 }, \ { 101, 10 }, \ { 117, 20 }, \ { 135, 30 }, \ { 152, 40 }, \ { 202, 50 }, \ { 255, 60 }, \ } } #define AR5000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT | RIG_LEVEL_AGC, \ .funcs = RIG_FUNC_ABM, \ } static int format5k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); static int parse5k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static const struct aor_priv_caps ar5k_priv_caps = { .format_mode = format5k_mode, .parse_aor_mode = parse5k_aor_mode, .bank_base1 = '0', .bank_base2 = '0', }; /* * ar5000 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/5000.htm * * TODO: retrieve BW info, and rest of commands */ struct rig_caps ar5000_caps = { RIG_MODEL(RIG_MODEL_AR5000), .model_name = "AR5000", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR5000_FUNC_ALL, .has_get_level = AR5000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR5000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = AR5000_VFO_OPS, .scan_ops = AR5000_SCAN_OPS, .str_cal = AR5000_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR5000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(2600), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(2600), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR5000_MODES, 1}, {AR5000_MODES, 10}, {AR5000_MODES, 50}, {AR5000_MODES, 100}, {AR5000_MODES, 500}, {AR5000_MODES, kHz(1)}, {AR5000_MODES, kHz(5)}, {AR5000_MODES, kHz(6.25)}, {AR5000_MODES, kHz(9)}, {AR5000_MODES, kHz(10)}, {AR5000_MODES, kHz(12.5)}, {AR5000_MODES, kHz(20)}, {AR5000_MODES, kHz(25)}, {AR5000_MODES, kHz(30)}, {AR5000_MODES, kHz(50)}, {AR5000_MODES, kHz(100)}, {AR5000_MODES, kHz(500)}, #if 0 {AR5000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_SAL | RIG_MODE_SAH | RIG_MODE_CW, kHz(3)}, {RIG_MODE_CW, Hz(500)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_SAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(3)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SAM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, /* narrow */ {RIG_MODE_FM, kHz(30)}, /* wide */ {RIG_MODE_WFM, kHz(110)}, {RIG_MODE_WFM, kHz(30)}, /* narrow */ {RIG_MODE_WFM, kHz(220)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& ar5k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ar5000a rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/5000.htm * * TODO: retrieve BW info, and rest of commands */ struct rig_caps ar5000a_caps = { RIG_MODEL(RIG_MODEL_AR5000A), .model_name = "AR5000A", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR5000_FUNC_ALL, .has_get_level = AR5000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR5000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = AR5000_VFO_OPS, .scan_ops = AR5000_SCAN_OPS, .str_cal = AR5000_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR5000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(3000), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(3000), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR5000_MODES, 1}, {AR5000_MODES, 10}, {AR5000_MODES, 50}, {AR5000_MODES, 100}, {AR5000_MODES, 500}, {AR5000_MODES, kHz(1)}, {AR5000_MODES, kHz(5)}, {AR5000_MODES, kHz(6.25)}, {AR5000_MODES, kHz(9)}, {AR5000_MODES, kHz(10)}, {AR5000_MODES, kHz(12.5)}, {AR5000_MODES, kHz(20)}, {AR5000_MODES, kHz(25)}, {AR5000_MODES, kHz(30)}, {AR5000_MODES, kHz(50)}, {AR5000_MODES, kHz(100)}, {AR5000_MODES, kHz(500)}, #if 0 {AR5000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_SAL | RIG_MODE_SAH | RIG_MODE_CW, kHz(3)}, {RIG_MODE_CW, Hz(500)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_SAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(3)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SAM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, /* narrow */ {RIG_MODE_FM, kHz(30)}, /* wide */ {RIG_MODE_WFM, kHz(110)}, {RIG_MODE_WFM, kHz(30)}, /* narrow */ {RIG_MODE_WFM, kHz(220)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& ar5k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, }; /* * Function definitions below */ /* * modes in use by the "MD" command of AR5000 */ #define AR5K_FM '0' #define AR5K_AM '1' #define AR5K_LSB '2' #define AR5K_USB '3' #define AR5K_CW '4' #define AR5K_SAM '5' #define AR5K_SAL '6' #define AR5K_SAH '7' int format5k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: aormode = AR5K_AM; break; case RIG_MODE_WFM: case RIG_MODE_FM: aormode = AR5K_FM; break; case RIG_MODE_LSB: aormode = AR5K_LSB; break; case RIG_MODE_USB: aormode = AR5K_USB; break; case RIG_MODE_CW: aormode = AR5K_CW; break; case RIG_MODE_SAM: aormode = AR5K_SAM; break; case RIG_MODE_SAL: aormode = AR5K_SAL; break; case RIG_MODE_SAH: aormode = AR5K_SAH; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { int aorwidth; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } switch (width) { case 500: aorwidth = '0'; break; case s_kHz(3): aorwidth = '1'; break; case s_kHz(6): aorwidth = '2'; break; case s_kHz(15): aorwidth = '3'; break; case s_kHz(30): aorwidth = '4'; break; case s_kHz(110): aorwidth = '5'; break; case s_kHz(220): aorwidth = '6'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c BW%c", aormode, aorwidth); return strlen(buf); } else { SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } } int parse5k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case AR5K_FM: *mode = RIG_MODE_FM; break; case AR5K_AM: *mode = RIG_MODE_AM; break; case AR5K_LSB: *mode = RIG_MODE_LSB; break; case AR5K_USB: *mode = RIG_MODE_USB; break; case AR5K_CW: *mode = RIG_MODE_CW; break; case AR5K_SAM: *mode = RIG_MODE_SAM; break; case AR5K_SAL: *mode = RIG_MODE_SAL; break; case AR5K_SAH: *mode = RIG_MODE_SAH; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } switch (aorwidth) { case '0': *width = 500; break; case '1': *width = s_kHz(3); break; case '2': *width = s_kHz(6); break; case '3': *width = s_kHz(15); break; case '4': *width = s_kHz(30); break; case '5': *width = s_kHz(110); break; case '6': *width = s_kHz(220); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, aorwidth); return -RIG_EPROTO; } return RIG_OK; } hamlib-4.6.5/rigs/aor/ar3000.c0000664000175000017500000002764515056640443011270 /* * Hamlib AOR backend - AR3000 description * Copyright (c) 2000-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include static int ar3k_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ar3k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ar3k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ar3k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ar3k_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int ar3k_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int ar3k_set_mem(RIG *rig, vfo_t vfo, int ch); static int ar3k_set_bank(RIG *rig, vfo_t vfo, int bank); static int ar3k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ar3k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #define AR3000A_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR3000A_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_SQL) #define AR3000A_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define AR3000A_VFO_OPS (RIG_OP_NONE) #define AR3000A_VFO (RIG_VFO_A) #define AR3000A_STR_CAL { 3, \ { \ { '%', -60 }, /* mute */ \ { 'A', -54 }, /* S1 */ \ { 'P', 20 } /* +20 */ \ } } /* * AR3000A rig capabilities. * * info coming from A3000A pdf manual from http://www.aoruk.com/ * * TODO: * set_channel, get_channel, set_func MUTE,SQL, get_dcd, ... */ struct rig_caps ar3000a_caps = { RIG_MODEL(RIG_MODEL_AR3000A), .model_name = "AR3000A", .mfg_name = "AOR", .version = "20061007.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR3000A_FUNC_ALL, .has_get_level = AR3000A_LEVEL, .has_set_level = RIG_LEVEL_SET(AR3000A_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 4, .chan_desc_sz = 0, .vfo_ops = AR3000A_VFO_OPS, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 4x100 memories */ .rx_range_list1 = { {kHz(100), MHz(2036), AR3000A_MODES, -1, -1, AR3000A_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2036), AR3000A_MODES, -1, -1, AR3000A_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR3000A_MODES, 50}, {AR3000A_MODES, kHz(999.95)}, #if 0 {AR3000A_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_WFM, kHz(180)}, RIG_FLT_END, }, .str_cal = AR3000A_STR_CAL, .priv = NULL, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = NULL, .set_freq = ar3k_set_freq, .get_freq = ar3k_get_freq, .set_mode = ar3k_set_mode, .get_mode = ar3k_get_mode, .set_ts = ar3k_set_ts, .get_ts = ar3k_get_ts, .set_mem = ar3k_set_mem, .set_bank = ar3k_set_bank, .set_level = ar3k_set_level, .get_level = ar3k_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * acknowledge is CR * Is \r portable enough? */ #define CR '\r' #define EOM "\x0a\x0d" #define BUFSZ 64 /* * ar3k_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int ar3k_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* will flush data on next transaction */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * ar3k_set_freq * Assumes rig!=NULL */ int ar3k_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int retval; unsigned lowhz; /* * actually, frequency must be like nnnn.nnnnm, * where m must be 0 or 5 (for 50Hz). */ lowhz = ((unsigned)freq) % 100; freq /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } freq = freq * 100 + lowhz; SNPRINTF(freqbuf, sizeof(freqbuf), "%04.5f" EOM, ((double)freq) / MHz(1)); retval = ar3k_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * ar3k_get_freq * Assumes rig!=NULL, freq!=NULL */ int ar3k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strchr(freqbuf, 'Y'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%"SCNfreq, freq); *freq *= 10; return RIG_OK; } /* * ar3k_set_mode * Assumes rig!=NULL */ int ar3k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; switch (mode) { case RIG_MODE_AM: aormode = 'A'; break; case RIG_MODE_CW: aormode = 'C'; break; case RIG_MODE_USB: aormode = 'U'; break; case RIG_MODE_LSB: aormode = 'L'; break; case RIG_MODE_WFM: aormode = 'W'; break; case RIG_MODE_FM: aormode = 'N'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "%c" EOM, aormode); retval = ar3k_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * ar3k_get_mode * Assumes rig!=NULL, mode!=NULL */ int ar3k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *rfp; int buf_len, retval; char buf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, buf, &buf_len); if (retval != RIG_OK) { return retval; } rfp = strchr(buf, 'Y'); if (!rfp) { return -RIG_EPROTO; } rfp += 11; switch (*rfp) { case 'Q': *mode = RIG_MODE_FM; break; case 'R': *mode = RIG_MODE_WFM; break; case 'S': *mode = RIG_MODE_AM; break; case 'T': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'V': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "ar3k_get_mode: unsupported mode '%c'\n", *rfp); return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * ar3k_set_ts * Assumes rig!=NULL */ int ar3k_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char freqbuf[BUFSZ]; int retval; int lowhz; /* * actually, frequency must be like nnn.nm, * where m must be 0 or 5 (for 50Hz). */ lowhz = ts % 100; ts /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } ts = ts * 100 + lowhz; SNPRINTF(freqbuf, sizeof(freqbuf), "%03.2fS" EOM, ((double)ts) / kHz(1)); retval = ar3k_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * ar3k_get_ts * Assumes rig!=NULL, ts!=NULL */ int ar3k_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strchr(freqbuf, 'Z'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%ld", ts); *ts *= 10; return RIG_OK; } int ar3k_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" EOM, ch); retval = ar3k_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } int ar3k_set_bank(RIG *rig, vfo_t vfo, int bank) { char cmdbuf[BUFSZ]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%dX" EOM, bank); retval = ar3k_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } int ar3k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char *cmd; int retval; switch (level) { case RIG_LEVEL_ATT: cmd = val.i ? "R" EOM : "T" EOM; break; default: return -RIG_EINVAL; } retval = ar3k_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ar3k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int info_len, retval; char infobuf[BUFSZ]; switch (level) { case RIG_LEVEL_ATT: /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } val->i = strchr(infobuf, 'W') ? rig->caps->attenuator[1] : 0; return RIG_OK; case RIG_LEVEL_RAWSTR: retval = ar3k_transaction(rig, "Y" EOM, 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } val->i = infobuf[0]; return RIG_OK; default: return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/aor/ar8600.c0000664000175000017500000001433015056640443011266 /* * Hamlib AOR backend - AR8600 description * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8600_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8600_FUNC (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8600_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR8600_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8600_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8600_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Measurement by Mark, WAØTOP, * using a HP8640B signal generator on an AR8600 Mark 2 (sn. 551454). * The mode was AM. The ATT was off. */ #define AR8600_STR_CAL { 12, \ { \ { 0, -54 }, /* 1st point is extrapolated */ \ { 13, -27 }, /* S-pixels: none */ \ { 29, -17 }, \ { 41, - 7 }, \ { 49, 3 }, /* S-pixels: 21 */ \ { 54, 13 }, \ { 59, 23 }, \ { 62, 33 }, /* S-pixels: 30 */ \ { 64, 43 }, \ { 65, 53 }, \ { 68, 63 }, \ { 69, 73 } /* S-pixels: 36 */ \ } } #define AR8600_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static const struct aor_priv_caps ar8600_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8600 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8600.htm */ struct rig_caps ar8600_caps = { RIG_MODEL(RIG_MODEL_AR8600), .model_name = "AR8600", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8600_FUNC, .has_get_level = AR8600_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8600_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, /* A through J, and a through j */ .chan_desc_sz = 12, .vfo_ops = AR8600_VFO_OPS, .scan_ops = AR8600_SCAN_OPS, .str_cal = AR8600_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR8600_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(2040), AR8600_MODES, -1, -1, AR8600_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2040), AR8600_MODES, -1, -1, AR8600_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8600_MODES, 50}, {AR8600_MODES, 100}, {AR8600_MODES, kHz(1)}, {AR8600_MODES, kHz(5)}, {AR8600_MODES, kHz(9)}, {AR8600_MODES, kHz(10)}, {AR8600_MODES, 12500}, {AR8600_MODES, kHz(20)}, {AR8600_MODES, kHz(25)}, {AR8600_MODES, kHz(100)}, {AR8600_MODES, MHz(1)}, #if 0 {AR8600_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(3)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM, kHz(9)}, {RIG_MODE_WFM, kHz(230)}, /* 150kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8600_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/aor/sr2200.c0000664000175000017500000004622715056640443011310 /* * Hamlib AOR backend - SR2200 description * * Copyright (c) 2000-2011 by Stephane Fillod * * Author: Stefano Speretta, Innovative Solutions In Space BV * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "serial.h" #include "aor.h" #define SR2200_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define SR2200_FUNC_ALL () #define SR2200_LEVEL_GET (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_AF | RIG_LEVEL_PREAMP ) #define SR2200_LEVEL_SET (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_AF | RIG_LEVEL_PREAMP) #define SR2200_PARM (RIG_PARM_NONE) #define SR2200_VFO_OPS (RIG_OP_MCL | RIG_OP_UP | RIG_OP_DOWN) #define SR2200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define SR2200_VFO (RIG_VFO_A | RIG_VFO_B | RIG_VFO_C | RIG_VFO_N(3) | RIG_VFO_N(4) \ | RIG_VFO_N(5) | RIG_VFO_N(6) | RIG_VFO_N(7) | RIG_VFO_N(8) \ | RIG_VFO_N(9)) #define SR2200_PREAMP 10 /* The data available on http://www.aoruk.com did not match very well on HF */ #define SR2200_STR_CAL { 16, { \ { 0, -60 }, \ { 3, -48 }, \ { 14, -42 }, \ { 26, -36 }, \ { 34, -30 }, \ { 42, -24 }, \ { 52, -18 }, \ { 62, -12 }, \ { 74, -6 }, \ { 87, 0 }, \ { 101, 10 }, \ { 117, 20 }, \ { 135, 30 }, \ { 152, 40 }, \ { 202, 50 }, \ { 255, 60 }, \ } } #define SR2200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT | RIG_LEVEL_AGC, \ .funcs = RIG_FUNC_ABM, \ } #define CR '\r' #define LF '\n' #define EOM "\r" #define BUFSZ 256 static int sr2200_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int parse_s2200_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static int sr2200_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); static int sr2200_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int sr2200_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int sr2200_get_vfo(RIG *rig, vfo_t *vfo); static int sr2200_set_vfo(RIG *rig, vfo_t vfo); static int sr2200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int sr2200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const struct aor_priv_caps sr2200_priv_caps = { .bank_base1 = '0', .bank_base2 = '0', }; // Derived from AOR AR8200 backend /* * sr2200 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/ * * TODO: retrieve BW info, and rest of commands */ struct rig_caps sr2200_caps = { RIG_MODEL(RIG_MODEL_SR2200), .model_name = "SR2200", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 19200, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = SR2200_LEVEL_GET, .has_set_level = SR2200_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { SR2200_PREAMP, RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = SR2200_VFO_OPS, .scan_ops = SR2200_SCAN_OPS, .str_cal = SR2200_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, SR2200_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(3000), SR2200_MODES, -1, -1, SR2200_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(3000), SR2200_MODES, -1, -1, SR2200_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {SR2200_MODES, 1}, {SR2200_MODES, 100}, {SR2200_MODES, 500}, {SR2200_MODES, kHz(1)}, {SR2200_MODES, kHz(2)}, {SR2200_MODES, kHz(5)}, {SR2200_MODES, kHz(6.25)}, {SR2200_MODES, kHz(9)}, {SR2200_MODES, kHz(10)}, {SR2200_MODES, kHz(12.5)}, {SR2200_MODES, kHz(20)}, {SR2200_MODES, kHz(25)}, {SR2200_MODES, kHz(30)}, {SR2200_MODES, kHz(50)}, {SR2200_MODES, kHz(100)}, #if 0 {SR2200_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM, kHz(15)}, /* narrow */ {RIG_MODE_FM, kHz(6)}, {RIG_MODE_WFM, kHz(300)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& sr2200_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = NULL, .set_freq = sr2200_set_freq, .get_freq = aor_get_freq, .set_mode = sr2200_set_mode, .get_mode = sr2200_get_mode, .set_vfo = sr2200_set_vfo, .get_vfo = sr2200_get_vfo, .set_level = sr2200_set_level, .get_level = sr2200_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * modes in use by the "MD" command of SR2200 */ #define SR2200_FM '0' #define SR2200_WFM '1' #define SR2200_AM '2' #define SR2200_SFM '3' #define SR2200_WAM '4' /* * sr2200_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int sr2200_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char ackbuf[BUFSZ]; int ack_len; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { data = ackbuf; } if (!data_len) { data_len = &ack_len; } /* * Do wait for a reply */ retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } *data_len = retval; if (*data_len < BUFSZ) { data[*data_len] = '\0'; } else { data[BUFSZ - 1] = '\0'; } if (data[0] == '?') { /* command failed? resync with radio */ write_block(rp, (unsigned char *) EOM, 1); return -RIG_EPROTO; } return RIG_OK; } /* * sr2200_set_freq * Assumes rig!=NULL */ int sr2200_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ], ackbuf[BUFSZ], *rfp; int freq_len, ret_freq_len; int retval; ret_freq_len = BUFSZ; if (freq < sr2200_caps.rx_range_list1[0].startf) { rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is lower than minimum supported value (%.0f Hz)\n", __func__, sr2200_caps.rx_range_list1[0].startf); return -RIG_EPROTO; } if (freq > sr2200_caps.rx_range_list1[0].endf) { rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is higher than maximum supported value (%.0f Hz)\n", __func__, sr2200_caps.rx_range_list1[0].endf); return -RIG_EPROTO; } SNPRINTF(freqbuf, sizeof(freqbuf), "RF%010.0f"EOM, freq); freq_len = strlen(freqbuf); strcpy(freqbuf + freq_len, EOM); freq_len += strlen(EOM); retval = sr2200_transaction(rig, freqbuf, freq_len, ackbuf, &ret_freq_len); if (retval != RIG_OK) { return retval; } rfp = strstr(ackbuf, "RF"); if (!rfp) { rig_debug(RIG_DEBUG_WARN, "NO RF in returned string in %s: '%s'\n", __func__, freqbuf); return -RIG_EPROTO; } sscanf(rfp + 2, "%"SCNfreq, &freq); return RIG_OK; } /* * sr2200_set_mode * Assumes rig!=NULL */ int sr2200_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; pbwidth_t normal_width; normal_width = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { width = normal_width; } switch (mode) { case RIG_MODE_AM: aormode = width > normal_width ? SR2200_WAM : SR2200_AM; break; case RIG_MODE_FM: aormode = width >= normal_width ? SR2200_FM : SR2200_SFM; break; case RIG_MODE_WFM: aormode = SR2200_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "MD%c" EOM, aormode); retval = sr2200_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * sr2200_get_mode * Assumes rig!=NULL, mode!=NULL */ int sr2200_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char ackbuf[BUFSZ], *mdp; int ack_len, retval; retval = sr2200_transaction(rig, "MD" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } mdp = strstr(ackbuf, "MD"); if (!mdp) { rig_debug(RIG_DEBUG_ERR, "%s: no MD in returned string: '%s'\n", __func__, ackbuf); return -RIG_EPROTO; } retval = parse_s2200_aor_mode(rig, mdp[2], mdp[2], mode, width); return retval; } int parse_s2200_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case SR2200_FM: *mode = RIG_MODE_FM; break; case SR2200_AM: *mode = RIG_MODE_AM; break; case SR2200_SFM: *mode = RIG_MODE_FM; break; case SR2200_WAM: *mode = RIG_MODE_AM; break; case SR2200_WFM: *mode = RIG_MODE_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } switch (aorwidth) { case SR2200_FM: *width = s_kHz(15); break; case SR2200_AM: *width = s_kHz(6); break; case SR2200_SFM: *width = s_kHz(6); break; case SR2200_WAM: *width = s_kHz(15); break; case SR2200_WFM: *width = s_kHz(300); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, aorwidth); return -RIG_EPROTO; } return RIG_OK; } /* * sr2200_set_vfo * Assumes rig!=NULL */ int sr2200_set_vfo(RIG *rig, vfo_t vfo) { char *vfocmd; switch (vfo) { case RIG_VFO_A: vfocmd = "VA" EOM; break; case RIG_VFO_B: vfocmd = "VB" EOM; break; case RIG_VFO_C: vfocmd = "VC" EOM; break; case RIG_VFO_N(3): vfocmd = "VD" EOM; break; case RIG_VFO_N(4): vfocmd = "VE" EOM; break; case RIG_VFO_N(5): vfocmd = "VF" EOM; break; case RIG_VFO_N(6): vfocmd = "VG" EOM; break; case RIG_VFO_N(7): vfocmd = "VH" EOM; break; case RIG_VFO_N(8): vfocmd = "VI" EOM; break; case RIG_VFO_N(9): vfocmd = "VJ" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_set_vfo: unsupported vfo %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } return sr2200_transaction(rig, vfocmd, strlen(vfocmd), NULL, NULL); } /* * sr2200_get_vfo * Assumes rig!=NULL, freq!=NULL */ int sr2200_get_vfo(RIG *rig, vfo_t *vfo) { int vfo_len, retval; char vfobuf[BUFSZ]; retval = sr2200_transaction(rig, "RX" EOM, 3, vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } switch (vfobuf[1]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; case 'C': *vfo = RIG_VFO_C; break; case 'D': *vfo = RIG_VFO_N(3); break; case 'E': *vfo = RIG_VFO_N(4); break; case 'F': *vfo = RIG_VFO_N(5); break; case 'G': *vfo = RIG_VFO_N(6); break; case 'H': *vfo = RIG_VFO_N(7); break; case 'I': *vfo = RIG_VFO_N(8); break; case 'J': *vfo = RIG_VFO_N(9); break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %c\n", vfobuf[1]); return -RIG_EINVAL; } return RIG_OK; } /* * sr2200_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int sr2200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs; char lvlbuf[BUFSZ]; unsigned i; int agc; unsigned att = 0; rs = STATE(rig); switch (level) { case RIG_LEVEL_AF: if (val.f > 255.0F) { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG255" EOM); } else { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG%03d" EOM, (int)val.f); } break; case RIG_LEVEL_PREAMP: if (val.f > 0) { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM1" EOM); } else { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM0" EOM); } break; case RIG_LEVEL_ATT: for (i = 0; i < HAMLIB_MAXDBLSTSIZ && !RIG_IS_DBLST_END(rs->attenuator[i]); i++) { if (rs->attenuator[i] == val.i) { att = i + 1; break; } } /* should be caught by the front end */ if ((val.i != 0) && (i >= HAMLIB_MAXDBLSTSIZ || RIG_IS_DBLST_END(rs->attenuator[i]))) { return -RIG_EINVAL; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT%u" EOM, att); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = '1'; break; case RIG_AGC_MEDIUM: agc = '3'; break; case RIG_AGC_SLOW: agc = '2'; break; case RIG_AGC_OFF: default: agc = '0'; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC%c" EOM, agc); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported aor_set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return sr2200_transaction(rig, lvlbuf, strlen(lvlbuf), NULL, NULL); } /* * sr2200_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int sr2200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs; char lvlbuf[BUFSZ], ackbuf[BUFSZ]; int ack_len, retval; rs = STATE(rig); switch (level) { case RIG_LEVEL_STRENGTH: SNPRINTF(lvlbuf, sizeof(lvlbuf), "LB" EOM); break; case RIG_LEVEL_ATT: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT" EOM); break; case RIG_LEVEL_AGC: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC" EOM); break; case RIG_LEVEL_AF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG" EOM); break; case RIG_LEVEL_PREAMP: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = sr2200_transaction(rig, lvlbuf, strlen(lvlbuf), ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (level) { float tmp; case RIG_LEVEL_STRENGTH: if (ack_len < 7 || ackbuf[0] != 'L' || ackbuf[1] != 'B') { return -RIG_EPROTO; } sscanf(ackbuf + 3, "%d", &val->i); // calibrate the S-meter -> values should be referred to S9 (-73 dBm) val->i += 73; break; case RIG_LEVEL_ATT: { unsigned att; if (ack_len < 4 || ackbuf[0] != 'A' || ackbuf[1] != 'T') { return -RIG_EPROTO; } att = ackbuf[2] - '0'; if (att == 0) { val->i = 0; break; } if (att > HAMLIB_MAXDBLSTSIZ || rs->attenuator[att - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "Unsupported att %s %u\n", __func__, att); return -RIG_EPROTO; } val->i = rs->attenuator[att - 1]; break; } case RIG_LEVEL_AGC: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'C') { return -RIG_EPROTO; } switch (ackbuf[2]) { case '1': val->i = RIG_AGC_FAST; break; case '3': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case '0': default: val->i = RIG_AGC_OFF; } break; case RIG_LEVEL_AF: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'G') { return -RIG_EPROTO; } sscanf(ackbuf + 2, "%f", &val->f); break; case RIG_LEVEL_PREAMP: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'M') { return -RIG_EPROTO; } sscanf(ackbuf + 2, "%f", &tmp); if (tmp != 0.0) { val->i = SR2200_PREAMP; } else { val->i = 0; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/aor/Makefile.am0000664000175000017500000000045615056640443012242 AORSRCLIST = ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p.h ar7030p_utils.c \ sr2200.c aor.c aor.h noinst_LTLIBRARIES = libhamlib-aor.la libhamlib_aor_la_SOURCES = $(AORSRCLIST) EXTRA_DIST = README.aor README.ar5000 README.ar7030 Android.mk hamlib-4.6.5/rigs/tentec/0000775000175000017500000000000015056640500010754 5hamlib-4.6.5/rigs/tentec/omnivii.c0000664000175000017500000012467715056640443012541 /* * Hamlib TenTenc backend - TT-588 description * Copyright (c) 2003-2009 by Stephane Fillod * Modifications 2014 by Michael Black W9MDB for 1.036 firmware * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "tentec2.h" #include "bandplan.h" struct tt588_priv_data { int ch; /* mem */ vfo_t vfo_curr; }; #define TT588_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_AM) #define TT588_RXMODES (TT588_MODES) #define TT588_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) #define TT588_LEVELS ( RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_SWR| \ RIG_LEVEL_RF| \ RIG_LEVEL_AF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_SWR| \ RIG_LEVEL_ATT \ /*RIG_LEVEL_NB| */ \ /*RIG_LEVEL_IF| */ \ /*RIG_LEVEL_RFPOWER| */ \ /*RIG_LEVEL_KEYSPD| */ \ /*RIG_LEVEL_ANF| */ \ /*RIG_LEVEL_MICGAIN|*/ \ /*RIG_LEVEL_NR| */ \ /*RIG_LEVEL_VOXGAIN| */ \ /*RIG_LEVEL_VOX| */\ /*RIG_LEVEL_COMP|*/ \ ) #define TT588_ANTS (RIG_ANT_1|RIG_ANT_2) #define TT588_PARMS (RIG_PARM_NONE) #define TT588_VFO (RIG_VFO_A|RIG_VFO_B) #define TT588_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define TT588_AM '0' #define TT588_USB '1' #define TT588_LSB '2' #define TT588_CW '3' #define TT588_FM '4' #define TT588_CWR '5' // What would FSK mode match in hamlib? Not implemented. // #define TT588_FSK '6' #define EOM "\015" /* CR */ #define FALSE 0 #define TRUE 1 static int tt588_init(RIG *rig); static int tt588_reset(RIG *rig, reset_t reset); static int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt588_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int tt588_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int tt588_set_vfo(RIG *rig, vfo_t vfo); static int tt588_get_vfo(RIG *rig, vfo_t *vfo); static int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static char which_vfo(const RIG *rig, vfo_t vfo); static int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt588_reset(RIG *rig, reset_t reset); static const char *tt588_get_info(RIG *rig); static int tt588_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int tt588_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int tt588_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); #if 0 // these are example prototypes for remote operation static int tt588_get_ant(RIG *rig, vfo_t vfo, ant_t *ant); static int tt588_set_ant(RIG *rig, vfo_t vfo, ant_t ant); #endif /* * tt588 transceiver capabilities. * * Protocol is documented at the tentec site */ struct rig_caps tt588_caps = { RIG_MODEL(RIG_MODEL_TT588), .model_name = "TT-588 Omni VII", .mfg_name = "Ten-Tec", .version = "20231002.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = TT588_FUNCS, .has_set_func = TT588_FUNCS, .has_get_level = TT588_LEVELS, .has_set_level = RIG_LEVEL_SET(TT588_LEVELS), .has_get_parm = TT588_PARMS, .has_set_parm = TT588_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, /* FIXME: real value */ .attenuator = { 6, 12, 18, RIG_DBLST_END }, .max_rit = Hz(8192), .max_xit = Hz(8192), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(500), MHz(30), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, {MHz(48), MHz(54), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), FRQ_RNG_6m(1, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, {MHz(48), MHz(54), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), {MHz(5.25), MHz(5.40), TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS}, FRQ_RNG_6m(2, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), RIG_FRNG_END, }, .tuning_steps = { {TT588_RXMODES, 1}, {TT588_RXMODES, 10}, {TT588_RXMODES, 100}, {TT588_RXMODES, kHz(1)}, {TT588_RXMODES, kHz(10)}, {TT588_RXMODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, 300}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, 0}, /* 34 filters */ {RIG_MODE_FM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt588_init, .set_freq = tt588_set_freq, .get_freq = tt588_get_freq, .set_vfo = tt588_set_vfo, .get_vfo = tt588_get_vfo, .set_mode = tt588_set_mode, .get_mode = tt588_get_mode, .get_level = tt588_get_level, .set_level = tt588_set_level, .set_split_freq = tt588_set_split_freq, .get_split_freq = tt588_get_split_freq, .set_split_mode = tt588_set_split_mode, .get_split_mode = tt588_get_split_mode, .set_split_vfo = tt588_set_split_vfo, .get_split_vfo = tt588_get_split_vfo, .set_ptt = tt588_set_ptt, .reset = tt588_reset, .get_info = tt588_get_info, .get_xit = tt588_get_xit, .set_xit = tt588_set_xit, .get_rit = tt588_get_xit, .set_rit = tt588_set_rit, // Antenna functions only in remote mode -- prototypes provided //.get_ant = tt588_get_ant, //.set_ant = tt588_set_ant .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* Filter table for 588 receiver support. */ static int tt588_rxFilter[] = { 12000, 9000, 8000, 7500, 7000, 6500, 6000, 5500, 5000, 4500, 4000, 3800, 3600, 3400, 3200, 3000, 2800, 2600, 2500, 2400, 2200, 2000, 1800, 1600, 1400, 1200, 1000, 900, 800, 700, 600, 500, 450, 400, 350, 300, 250, 200 }; /* * Function definitions below */ /* I frequently see the Omni VII and my laptop get out of sync. A response from the 538 isn't seen by the laptop. A few "XX"s sometimes get things going again, hence this hack, er, function. */ /* Note: data should be at least data_len+1 long for null byte insertion */ static int tt588_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, const int *data_len) { int i, retval = -RIG_EINTERNAL; hamlib_port_t *rp = RIGPORT(rig); // The original file had "A few XX's" due to sync problems // So I put this in a try loop which should, hopefully, never be seen for (i = 0; i < 3; ++i) // We'll try 3 times { char xxbuf[32]; rig_flush(rp); // We add 1 to data_len here for the null byte inserted by read_string eventually // That way all the callers can use the expected response length for the cmd_len parameter here // Callers all need to ensure they have enough room in data for this retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval == RIG_OK) { // All responses except from "XX" terminate with EOM (i.e. \r) so that is our stop char char *term = EOM; if (cmd[0] == 'X') // we'll let the timeout take care of this as it shouldn't happen anyways { term = ""; } if (data) { retval = read_string(rp, (unsigned char *) data, (*data_len) + 1, term, strlen(term), 0, 1); if (retval != -RIG_ETIMEOUT) { return RIG_OK; } rig_debug(RIG_DEBUG_ERR, "%s: read_string failed, try#%d\n", __func__, i + 1); return retval; } else { return RIG_OK; // no data wanted so just return } } else { rig_debug(RIG_DEBUG_ERR, "%s: write_block failed, try#%d\n", __func__, i + 1); } write_block(rp, (unsigned char *) "XX" EOM, 3); // we wont' worry about the response here retval = read_string(rp, (unsigned char *) xxbuf, sizeof(xxbuf), "", 0, 0, 1); // this should timeout if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: XX command failed, try#%d\n", __func__, i + 1); } } return retval; } /* * tt588_init: * Basically, it just sets up *priv */ int tt588_init(RIG *rig) { struct tt588_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s:\n", __func__); STATE(rig)->priv = (struct tt588_priv_data *) calloc(1, sizeof( struct tt588_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt588_priv_data)); /* * set arbitrary initial status */ priv->ch = 0; priv->vfo_curr = RIG_VFO_A; return RIG_OK; } static int check_vfo(vfo_t vfo) { switch (vfo) // Omni VII only has A & B { case RIG_VFO_A: break; case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return FALSE; } return TRUE; } // which_vfo returns the only two answers that work for commands // Each calling routine should call check_vfo() before calling this // Anything other than RIG_VFO_B will return 'A' since Omni VII only uses B on split // So 'A' is always the default VFO static char which_vfo(const RIG *rig, vfo_t vfo) { return RIG_VFO_B == vfo ? 'B' : 'A'; } int tt588_get_vfo(RIG *rig, vfo_t *vfo) { static int getinfo = TRUE; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; if (getinfo) // this is the first call to this package so we do this here { getinfo = FALSE; tt588_get_info(rig); } *vfo = priv->vfo_curr; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } /* * tt588_set_vfo * Assumes rig!=NULL */ int tt588_set_vfo(RIG *rig, vfo_t vfo) { struct tt588_priv_data *priv = (struct tt588_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { return RIG_OK; } priv->vfo_curr = vfo; return RIG_OK; } /* * Software restart */ int tt588_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: reset=%d\n", __func__, reset); reset_len = 32; retval = tt588_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /* * tt588_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); resp_len = 6; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if ((respbuf[0] == 'A' || respbuf[0] == 'B') && respbuf[5] == 0x0d) { *freq = (respbuf[1] << 24) + (respbuf[2] << 16) + (respbuf[3] << 8) + respbuf[4]; } else { *freq = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), *freq); return RIG_OK; } /* * tt588_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char bytes[4]; unsigned char cmdbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { int retval; if ((retval = tt588_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } /* Freq is 4 bytes long, MSB sent first. */ bytes[3] = ((int) freq >> 24) & 0xff; bytes[2] = ((int) freq >> 16) & 0xff; bytes[1] = ((int) freq >> 8) & 0xff; bytes[0] = (int) freq & 0xff; SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*%c%c%c%c%c" EOM, which_vfo(rig, vfo), bytes[3], bytes[2], bytes[1], bytes[0]); return tt588_transaction(rig, (char *) cmdbuf, 7, NULL, NULL); } /* * tt588_set_split_freq */ int tt588_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { // VFOB is the split VFO return tt588_set_freq(rig, RIG_VFO_B, tx_freq); } /* * tt588_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ int tt588_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { // VFOB is the split VFO return tt588_get_freq(rig, RIG_VFO_B, tx_freq); } /* * tt588_set_split_mode * assumes rig!=NULL */ int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { // VFOB is the split VFO return tt588_set_mode(rig, RIG_VFO_B, tx_mode, tx_width); } /* * tt588_get_split_mode * assumes rig!=NULL, tx_mode!=NULLm, tx_width!=NULL */ int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { // VFOB is the split VFO return tt588_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); } /* * tt588_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; char ttmode; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } // Query mode SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 4; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (which_vfo(rig, vfo)) { case 'A': ttmode = respbuf[1]; break; case 'B': ttmode = respbuf[2]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; break; } switch (ttmode) { case TT588_AM: *mode = RIG_MODE_AM; break; case TT588_USB: *mode = RIG_MODE_USB; break; case TT588_LSB: *mode = RIG_MODE_LSB; break; case TT588_CW: *mode = RIG_MODE_CW; break; case TT588_CWR: *mode = RIG_MODE_CWR; break; case TT588_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?W" EOM); resp_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (respbuf[1]) { case 0: *width = 12000; break; case 1: *width = 9000; break; case 2: *width = 8000; break; case 3: *width = 7500; break; case 4: *width = 7000; break; case 5: *width = 6500; break; case 6: *width = 6000; break; case 7: *width = 5500; break; case 8: *width = 5000; break; case 9: *width = 4500; break; case 10: *width = 4000; break; case 11: *width = 3800; break; case 12: *width = 3600; break; case 13: *width = 3400; break; case 14: *width = 3200; break; case 15: *width = 3000; break; case 16: *width = 2800; break; case 17: *width = 2600; break; case 18: *width = 2500; break; case 19: *width = 2400; break; case 20: *width = 2200; break; case 21: *width = 2000; break; case 22: *width = 1800; break; case 23: *width = 1600; break; case 24: *width = 1400; break; case 25: *width = 1200; break; case 26: *width = 1000; break; case 27: *width = 900; break; case 28: *width = 800; break; case 29: *width = 700; break; case 30: *width = 600; break; case 31: *width = 500; break; case 32: *width = 450; break; case 33: *width = 400; break; case 34: *width = 350; break; case 35: *width = 300; break; case 36: *width = 250; break; case 37: *width = 200; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", __func__, respbuf[1]); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } /* Find rx filter index of bandwidth the same or larger as requested. */ static int tt588_filter_number(int width) { int i; for (i = 34; i >= 0; i--) if (width <= tt588_rxFilter[i]) { return i; } return 0; /* Widest filter, 8 kHz. */ } /* * tt588_set_mode * Assumes rig!=NULL */ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmdbuf[32], respbuf[32], ttmode; int resp_len, retval; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } /* Query mode for both VFOs. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 4; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || respbuf[3] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (mode) { case RIG_MODE_USB: ttmode = TT588_USB; break; case RIG_MODE_LSB: ttmode = TT588_LSB; break; case RIG_MODE_CW: ttmode = TT588_CW; break; case RIG_MODE_CWR: ttmode = TT588_CWR; break; case RIG_MODE_AM: ttmode = TT588_AM; break; case RIG_MODE_FM: ttmode = TT588_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* Set mode for both VFOs. */ if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, ttmode, respbuf[2]); break; case RIG_VFO_B: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, respbuf[1], ttmode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } retval = tt588_transaction(rig, (char *) cmdbuf, 5, NULL, NULL); if (retval != RIG_OK) { return retval; } /* Set rx filter bandwidth. */ if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } width = tt588_filter_number((int) width); SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*W%c" EOM, (unsigned char) width); return tt588_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); } /* * tt588_get_level * Assumes rig!=NULL, val!=NULL */ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { float fwd, refl; int retval, lvl_len; unsigned char cmdbuf[16], lvlbuf[32]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_SWR: lvl_len = 4; retval = tt588_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } // top bit of lvlbuf[1] should be on if transmitting if (lvlbuf[0] != 'S' || lvlbuf[3] != 0x0d || ((lvlbuf[1] & 0x80) == 0)) { val->f = 99; // infinity rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d buf=%02x %02x %02x %02x\n", __func__, lvl_len, lvlbuf[0], lvlbuf[1], lvlbuf[2], lvlbuf[3]); return -RIG_EPROTO; } /* forward power. */ fwd = (float)(lvlbuf[1] & 0x7f); /* reflected power. */ refl = (float) lvlbuf[2]; if (fwd > 0) { val->f = refl / fwd; // our ratio val->f = (1 + val->f) / (1 - val->f); // SWR formula } else { val->f = 99; } break; case RIG_LEVEL_STRENGTH: lvl_len = 6; retval = tt588_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'S') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } // Reply in the form S0944 for 44 dB over S9 in ASCII // S0600 is S6 (0 db over S9) // S9=34db S0=-20dB // So you can read the exact S-meter from the 1st 2 bytes // 2nd set of bytes is S9-relative if ((lvlbuf[1] & 0x80) == 0) // then we're not in tx mode so we're good { // 1st two bytes are the S-level sscanf((char *)lvlbuf, "S%02d", &val->i); val->i = (val->i - 9) * 6; // convert S meter to dBS9 relative rig_debug(RIG_DEBUG_TRACE, "%s: meter= %ddB\n", __func__, val->i); } else { // transmit reply example S<0x8f><0x01> 0x0f=15 watts, 0x01 // it appears 0x01 reflected = 0W since 0 means not read yet int strength; int reflected = (int)lvlbuf[2]; reflected = reflected > 0 ? reflected - 1 : 0; // computer transmit power strength = (int)(lvlbuf[1] & 0x7f) - reflected; rig_debug(RIG_DEBUG_TRACE, "%s: strength fwd=%d, rev=%d\n", __func__, strength, reflected); if (strength > 0) // convert watts to dbM { val->i = 10 * log10(strength) + 30; // now convert to db over 1uV val->i += 73; } else { val->i = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: strength= %ddB\n", __func__, val->i); } break; case RIG_LEVEL_AGC: /* Read rig's AGC level setting. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?G" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'G' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[1]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_SLOW; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_FAST; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: /* Volume returned as single byte. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?U" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'U' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (float) lvlbuf[1] / 127; break; case RIG_LEVEL_IF: // Omni VII has so such thing rig_debug(RIG_DEBUG_ERR, "%s: no RIG_LEVEL_IF on Omni VII\n", __func__); val->i = 0; break; case RIG_LEVEL_RF: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?I" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = lvlbuf[1] / 127.0f; break; case RIG_LEVEL_ATT: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?J" EOM); lvl_len = 33; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'J' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = (lvlbuf[1] - '0') * 6; // 1=6, 2=12, 3=18 break; #if 0 case RIG_LEVEL_PREAMP: /* Only in remote mode */ val->i = 0; break; #endif case RIG_LEVEL_SQL: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?H" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'H' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = lvlbuf[1] / 127.0f; break; #if 0 case RIG_LEVEL_MICGAIN: /* Only in remote mode */ val->i = 0; break; #endif #if 0 case RIG_LEVEL_COMP: /* Only in remote mode */ val->i = 0; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level)); return RIG_OK; } /* * tt588_set_level * Assumes rig!=NULL, val!=NULL */ int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, ii; unsigned char cmdbuf[16], agcmode; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_AF: /* Volume */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*U%c" EOM, (char)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_RF: /* RF gain. Omni-VII expects value 0 for full gain, and 127 for lowest gain */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*I%c" EOM, 127 - (char)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agcmode = '0'; break; case RIG_AGC_SLOW: agcmode = '1'; break; case RIG_AGC_MEDIUM: agcmode = '2'; break; case RIG_AGC_FAST: agcmode = '3'; break; default: return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*Gx" EOM); cmdbuf[2] = agcmode; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_ATT: /* Attenuation */ ii = -1; /* Request 0-5 dB -> 0, 6-11 dB -> 6, etc. */ while (rig->caps->attenuator[++ii] != RIG_DBLST_END) { if (rig->caps->attenuator[ii] > val.i) { break; } } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*J%c" EOM, ii + '0'); retval = tt588_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_SQL: /* Squelch level, float 0.0 - 1.0 */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*H%c" EOM, (int)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt588_set_split_vfo * Assumes rig!=NULL */ int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval, resp_len; char cmdbuf[16], respbuf[16]; if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s split=%d tx_vfo=%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(tx_vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Nx" EOM "?N" EOM); //if (split == RIG_SPLIT_ON || tx_vfo==RIG_VFO_B) if (split == RIG_SPLIT_ON) { cmdbuf[2] = 1; } else { cmdbuf[2] = 0; } resp_len = 3; retval = tt588_transaction(rig, cmdbuf, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'N' || respbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unknown response to *N%d='%s'\n", __func__, split, respbuf); return -RIG_EINVAL; } return RIG_OK; } /* * tt588_get_split_vfo * Assumes rig!=NULL, split!=NULL, tx_vfo!=NULL */ int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get split on/off SNPRINTF(cmdbuf, sizeof(cmdbuf), "?N" EOM); resp_len = 3; retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); // respbuf returns "N0" or "N1" for split off/on if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'N' || respbuf[2] != 0x0d || (respbuf[1] != 0 && respbuf[1] != 1)) { return -RIG_EPROTO; } *split = respbuf[1] == 0 ? RIG_SPLIT_OFF : RIG_SPLIT_ON; if (*split == RIG_SPLIT_ON) { *tx_vfo = RIG_VFO_B; // Omni VII always transmits on VFO_B when in split } else { *tx_vfo = RIG_VFO_A; // VFO A when not in split } rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d tx_vfo=%s\n", __func__, *split, rig_strvfo(*tx_vfo)); return RIG_OK; } /* * tt588_set_ptt * Assumes rig!=NULL */ int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmdbuf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Txx" EOM); if (ptt) { cmdbuf[2] = 4; cmdbuf[3] = 1; // turn on ethernet RIPing } else { cmdbuf[2] = 0; cmdbuf[3] = 1; // turn on ethernet RIPing } retval = tt588_transaction(rig, cmdbuf, 5, NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt588_get_info * Assumes rig!=NULL * Returns statically allocated buffer */ const char *tt588_get_info(RIG *rig) { static char cmdbuf[16], firmware[64]; int firmware_len = sizeof(firmware), retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?V" EOM); memset(firmware, 0, sizeof(firmware)); rig_debug(RIG_DEBUG_VERBOSE, "%s: firmware_len=%d\n", __func__, firmware_len); retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), firmware, &firmware_len); // Response should be "VER 1010-588 " plus "RADIO x\r" or "REMOTEx\r" // if x=blank ham band transmit only // if x='M' MARS transmit only if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, firmware); return firmware; } /* * tt588_get_xit * tt588_get_rit is linked to this too since it's just one offset and the same command * Assumes rig!=NULL * Note that ?L can't query RIT/XIT separately...there's only one offset */ int tt588_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get xit SNPRINTF(cmdbuf, sizeof(cmdbuf), "?L" EOM); resp_len = 5; retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'L' || respbuf[4] != 0x0d) { return -RIG_EPROTO; } *xit = (respbuf[2] * (short)256) | respbuf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, (int)*xit); return RIG_OK; } // This routine handles both rit and xit setting // Though we can turn on both (which=3) there's no obvious condition for doing so // We can only query the one offset and don't really know for which it was set // And is there any reason to turn on both? If so, hamblib doesn't seem to support that. // static int set_rit_xit(RIG *rig, vfo_t vfo, shortfreq_t rit, int which) { int retval; char cmdbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, (int)rit); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // For some reason need an extra \r on here // This is with version 1.036 -- it appears to want 7 chars instead of 6 SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Lxxx" EOM EOM); cmdbuf[2] = which; // set xit bit. 0=off,1=rit, 2=xit, 3=both cmdbuf[3] = rit >> 8; cmdbuf[4] = rit & 0xff; retval = tt588_transaction(rig, cmdbuf, 6, NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt588_set_xit * Assumes rig!=NULL */ int tt588_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { return set_rit_xit(rig, vfo, xit, 2); // bit 2 is xit } /* * tt588_set_xit * Assumes rig!=NULL */ int tt588_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { return set_rit_xit(rig, vfo, rit, 1); // bit 1 is rit } #if 0 // commenting out prototypes that are only for remote use /* * This is a prototype function as C1V is only available in remote mode * tt588_get_ant * Assumes rig!=NULL */ int tt588_get_ant(RIG *rig, vfo_t vfo, ant_t *ant) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get xit SNPRINTF(cmdbuf, sizeof(cmdbuf), "*C1V" EOM); resp_len = 5; // this should be the only line needing change for remote operation retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (resp_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: bad response length, expected %d, got %d\n", __func__, 5, resp_len); } if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'C' || respbuf[4] != 0x0d) { return -RIG_EPROTO; } *ant = respbuf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, *ant); return RIG_OK; } /* * This is a prototype function as C1V is only available in remote mode * tt588_set_ant * Assumes rig!=NULL */ int tt588_set_ant(RIG *rig, vfo_t vfo, ant_t ant) { int retval, cmd_len; char cmdbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ant=%d\n", __func__, ant); SNPRINTF(cmdbuf, sizeof(cmdbuf), "*C1Vx" EOM); // 0 = RX=TX=ANT1 // 1 = RX=TX=ANT2 // 2 = RX=RXAUX, TX=ANT1 // 3 = RX=RXAUC, TX=ANT2 cmdbuf[4] = ant; // this should be the only line needing change for remote operation retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } #endif hamlib-4.6.5/rigs/tentec/tentec2.c0000664000175000017500000003441615056640443012422 /* * Hamlib Tentec backend - Argonaut, Jupiter, RX-350 * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Module rewritten and tested by Dave Freese, W1HKJ * Tested using the distributed test program "rigctl" to control an Argonaut V xcvr. * Linked to digital modem program, "gmfsk" and bench tested and used on-air * Linked to experimental digital modem program "fldigi", bench tested * and used on-air. * * Note for anyone wishing to expand on the command set. * Recommend using the * * tentec_transaction (rig, sendbuf, sendlen, rcvbuf, &rcv_len) * * function to send the command and receive the response. * * The Argo V always sends a response and ends the response with a "G\r" to * indicate that the command was accepted. A rejected command is responded to by a * two character sequence "Z\r". You should always expect a maximum response equal * to the number of data bytes plus two. * * For example: * A request for the present receiver filter bandwidth is the the string: * "?W\r" which is 3 bytes in length * The response from the Argonaut V will be: * "Wn\rG\r" which is 5 bytes in length, where n is an unsigned char (byte) * If the transceiver failed to receive the command correctly it will respond: * "Z\r" ----> you need to check for that condition * * The tentec_transaction(...) function will always terminate the rcvbuf with a null * character. The pointer to the receive buffer length MUST be initialized to the * length of the max # chars for that command PLUS 1 for the terminator. * For the above command, rcv_len should be 6. */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "tentec.h" #include "tentec2.h" #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' /************************************************************************************* * * Specs from http://www.rfsquared.com * * TODO: [sg]et_split * [sg]et_level: ATT, NB, PBT, KEYER_SPD, RFPOWER, SWR, SQL, STRENGTH, .. * vfo_op: TO_VFO, FROM_VFO + emulated set_mem/get_mem */ /* * tentec_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tentec2_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval, ret_len; char freqbuf[16] = "*Axxxx\r"; unsigned long f = (unsigned long)freq; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_B: freqbuf[1] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } freqbuf[2] = (f >> 24) & 0xFF; freqbuf[3] = (f >> 16) & 0xFF; freqbuf[4] = (f >> 8) & 0xFF; freqbuf[5] = f & 0xFF; // Argo V will respond // "G\r" or "Z\r" ret_len = 3; retval = tentec_transaction(rig, freqbuf, 7, freqbuf, &ret_len); if (retval != RIG_OK) { return -RIG_EINVAL; } if (ret_len != 2 || freqbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_freq * Assumes rig!=NULL, freq!=NULL */ int tentec2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval, ret_len; char freqbuf[16] = "?A\r"; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_B: freqbuf[1] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // Argo V will respond with 8 characters // "Annnn\rG\r" or "Bnnnn\rG\r" // or it will respond // "Z\r" meaning the command was rejected ret_len = 9; retval = tentec_transaction(rig, freqbuf, 3, freqbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len == 2 && freqbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 8) { return -RIG_EINVAL; } *freq = (unsigned int)((freqbuf[1] & 0x0FF) << 24) + (unsigned int)((freqbuf[2] & 0x0FF) << 16) + (unsigned int)((freqbuf[3] & 0x0FF) << 8) + (unsigned int)(freqbuf[4] & 0x0FF); return RIG_OK; } /* * tentec2_set_vfo * Assumes rig!=NULL */ int tentec2_set_vfo(RIG *rig, vfo_t vfo) { int retval, ret_len; char vfobuf[16] = "*EVA\r"; if ((vfo & ~RIG_VFO_MEM) == RIG_VFO_NONE || vfo == RIG_VFO_VFO) { vfo_t cvfo; retval = tentec2_get_vfo(rig, &cvfo); if (retval != RIG_OK) { return retval; } vfo = (cvfo & (RIG_VFO_A | RIG_VFO_B)) | (vfo & RIG_VFO_MEM); } if (vfo & RIG_VFO_MEM) { vfobuf[2] = 'M'; } switch (vfo & ~RIG_VFO_MEM) { case RIG_VFO_A: break; case RIG_VFO_B: vfobuf[3] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } ret_len = 3; retval = tentec_transaction(rig, vfobuf, 5, vfobuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || vfobuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_vfo * Assumes rig!=NULL */ int tentec2_get_vfo(RIG *rig, vfo_t *vfo) { int ret_len, retval; unsigned char vfobuf[16] = "?E\r"; ret_len = 7; retval = tentec_transaction(rig, (char *) vfobuf, 3, (char *) vfobuf, &ret_len); if (retval != RIG_OK) { return retval; } // ArgoV sends back 6 character string // "EVA\rG\r" or "EVB\rG\r" // or 2 character failure string // "Z\r" if (ret_len == 2 && vfobuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 6) { return -RIG_EPROTO; } *vfo = vfobuf[2] == 'A' ? RIG_VFO_A : RIG_VFO_B; if (vfobuf[1] == 'M') { *vfo |= RIG_VFO_MEM; } return RIG_OK; } /* * tentec2_set_split_vfo * Assumes rig!=NULL */ int tentec2_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval, ret_len; char retbuf[10] = "*Ox\r"; if (split == RIG_SPLIT_ON) { retbuf[2] = 1; } else { retbuf[2] = 0; } ret_len = 3; retval = tentec_transaction(rig, retbuf, 4, retbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || retbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_split_vfo * Assumes rig!=NULL */ int tentec2_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret_len, retval; char splitbuf[16] = "?O\r"; /* * TODO: handle tx_vfo */ ret_len = 6; retval = tentec_transaction(rig, splitbuf, 3, splitbuf, &ret_len); // Argo V returns // "On\rG\r" or // "Z\r" if (retval != RIG_OK) { return retval; } if (ret_len == 2 && splitbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 5) { return -RIG_EPROTO; } *split = splitbuf[1] == 0 ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } /* * tentec2_set_mode * Assumes rig!=NULL */ int tentec2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char ttmode; int ttfilter, retval, ret_len; char mdbuf[16]; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* get the mode because we want to leave other VFO unchanged */ ret_len = 7; retval = tentec_transaction(rig, "?M\r", 3, &mdbuf[1], &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 6) { return -RIG_EPROTO; } mdbuf[0] = '*'; switch (vfo) { case RIG_VFO_A: mdbuf[2] = ttmode; break; case RIG_VFO_B: mdbuf[3] = ttmode; break; default: return -RIG_EINVAL; } ret_len = 3; retval = tentec_transaction(rig, mdbuf, 5, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || mdbuf[0] != 'G') { return -RIG_ERJCTED; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* * Filter 0: 200 * .. * Filter 16: 1000 * .. * Filter 36: 3000 */ if (width < 200) { ttfilter = 0; } else if (width > 3000) { ttfilter = 36; } else if (width < 1000) { ttfilter = (width / 50) - 4; } else { ttfilter = (width / 100) + 6; } strcpy(mdbuf, "*Wn\r"); mdbuf[2] = ttfilter; ret_len = 3; retval = tentec_transaction(rig, mdbuf, 4, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || mdbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_mode * Assumes rig!=NULL, mode!=NULL */ int tentec2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ttfilter, retval, ret_len; char mdbuf[16]; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } // response to "?M\r" command: // "M00" -> AM, "M1" -> USB, "M2" -> LSB, "M3" -> CW, "M4" -> FM ret_len = 7; retval = tentec_transaction(rig, "?M\r", 3, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 6) { return -RIG_EPROTO; } if (vfo != RIG_VFO_A && vfo != RIG_VFO_B) { return -RIG_EINVAL; } switch (mdbuf[vfo == RIG_VFO_A ? 1 : 2]) { case TT_USB: *mode = RIG_MODE_USB; break; case TT_LSB: *mode = RIG_MODE_LSB; break; case TT_CW: *mode = RIG_MODE_CW; break; case TT_AM: *mode = RIG_MODE_AM; break; case TT_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, mdbuf[vfo == RIG_VFO_A ? 1 : 2]); return -RIG_EPROTO; } ret_len = 6; retval = tentec_transaction(rig, "?W\r", 3, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len == 2 && mdbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 5) { return -RIG_EPROTO; } /* * Filter 0: 200 * .. * Filter 16: 1000 * .. * Filter 36: 3000 */ ttfilter = mdbuf[1]; if (ttfilter < 0 || ttfilter > 36) { return -RIG_EPROTO; } if (ttfilter < 16) { *width = ((long)ttfilter + 4L) * 50L; } else { *width = ((long)ttfilter - 6L) * 100L; } return RIG_OK; } /* * tentec2_set_ptt * Assumes rig!=NULL */ int tentec2_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval, ret_len; char retbuf[10]; ret_len = 3; retval = tentec_transaction(rig, ptt == RIG_PTT_ON ? "#1\r" : "#0\r", 3, retbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || retbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_ptt * Assumes rig!=NULL */ int tentec2_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret_len, retval; char buf[7] = "?C\r"; ret_len = 7; retval = tentec_transaction(rig, buf, 3, buf, &ret_len); if (retval != RIG_OK) { return retval; } // ArgoV sends back 6 character string // "Cnn\rG\r" where nn is the status word // or 2 character failure string // "Z\r" if (ret_len == 2 && buf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 6) { return -RIG_EPROTO; } *ptt = (buf[2] & 0x01) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * Software restart */ int tentec2_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 32; retval = tentec_transaction(rig, "*X\r", 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { return -RIG_EPROTO; } return RIG_OK; } /* * tentec2_get_info * Assumes rig!=NULL */ const char *tentec2_get_info(RIG *rig) { static char buf[100]; /* FIXME: reentrancy */ int firmware_len, retval; /* * protocol version */ buf[0] = 0; firmware_len = 100; retval = tentec_transaction(rig, "?V\r", 3, buf, &firmware_len); /* "VER 1010-516" */ if (retval != RIG_OK || firmware_len != 12) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.5/rigs/tentec/argonaut.c0000664000175000017500000001273515056640443012676 /* * Hamlib TenTenc backend - TT-516 PC-Radio description * Copyright (c) 2003-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tentec2.h" #include "bandplan.h" #include "idx_builtin.h" #define TT516_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB) #define TT516_RXMODES (TT516_MODES|RIG_MODE_AM) #define TT516_FUNCS (RIG_FUNC_NONE) #define TT516_LEVELS (RIG_LEVEL_RAWSTR|/* RIG_LEVEL_NB| */ \ RIG_LEVEL_SQL|/*RIG_LEVEL_PBT|*/ \ RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) #define TT516_ANTS RIG_ANT_1 #define TT516_VFO (RIG_VFO_A|RIG_VFO_B) // Taken from RX320_STR_CAL -- unknown if accurate for TT516 #define TT516_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * tt516 receiver capabilities. * * protocol is documented at * http://www.rfsquared.com/ * */ struct rig_caps tt516_caps = { RIG_MODEL(RIG_MODEL_TT516), .model_name = "TT-516 Argonaut V", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = TT516_FUNCS, .has_set_func = TT516_FUNCS, .has_get_level = TT516_LEVELS, .has_set_level = RIG_LEVEL_SET(TT516_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(500), MHz(30), TT516_RXMODES, -1, -1, TT516_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT516_MODES, W(1), W(20), TT516_VFO, TT516_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(1), W(5), TT516_VFO, TT516_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TT516_RXMODES, -1, -1, TT516_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT516_MODES, W(1), W(20), TT516_VFO, TT516_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(1), W(5), TT516_VFO, TT516_ANTS), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 10}, /* {RIG_MODE_SSB|RIG_MODE_CW,kHz(1)}, */ {RIG_MODE_AM, 100}, /* {RIG_MODE_AM,kHz(5)}, */ {RIG_MODE_FM, kHz(2.5)}, /* {RIG_MODE_FM,kHz(5)}, */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* FIXME: add increments -> 34 filters? */ {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_SSB, 200}, {RIG_MODE_CW | RIG_MODE_SSB, 0}, /* Filters are 200 Hz to 1000 Hz in 50 Hz steps, 1000 to 2800 Hz in 100 Hz steps */ {RIG_MODE_AM, kHz(4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = TT516_STR_CAL, .priv = (void *)NULL, .set_freq = tentec2_set_freq, .get_freq = tentec2_get_freq, .set_vfo = tentec2_set_vfo, .get_vfo = tentec2_get_vfo, .set_mode = tentec2_set_mode, .get_mode = tentec2_get_mode, .set_split_vfo = tentec2_set_split_vfo, .get_split_vfo = tentec2_get_split_vfo, .set_ptt = tentec2_set_ptt, .get_ptt = tentec2_get_ptt, .reset = tentec2_reset, .get_info = tentec2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/tentec/rx340.c0000664000175000017500000003275715056640443011744 /* * Hamlib TenTenc backend - RX-340 description * Copyright (c) 2003-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "num_stdio.h" #define RX340_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_DSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX340_FUNCS (RIG_FUNC_NB) #define RX340_LEVELS (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL| \ RIG_LEVEL_CWPITCH|RIG_LEVEL_AGC| \ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define RX340_ANTS (RIG_ANT_1) #define RX340_PARMS (RIG_PARM_NONE) #define RX340_VFO (RIG_VFO_A) #define RX340_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* TODO: levels.. */ #define RX340_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } #if 0 static int rx340_init(RIG *rig); static int rx340_cleanup(RIG *rig); #endif static int rx340_open(RIG *rig); static int rx340_close(RIG *rig); static int rx340_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int rx340_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int rx340_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int rx340_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int rx340_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int rx340_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *rx340_get_info(RIG *rig); /* * RX340 receiver capabilities. * * Protocol is documented at * http://radio.tentec.com/downloads/receivers/RX340 * * TODO: from/to memory, scan, get_level, .. * supposes non-multidrop */ struct rig_caps rx340_caps = { RIG_MODEL(RIG_MODEL_RX340), .model_name = "RX-340", .mfg_name = "Ten-Tec", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = RX340_FUNCS, .has_set_func = RX340_FUNCS, .has_get_level = RX340_LEVELS, .has_set_level = RIG_LEVEL_SET(RX340_LEVELS), .has_get_parm = RX340_PARMS, .has_set_parm = RX340_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, RX340_MEM_CAP }, }, .rx_range_list1 = { {kHz(0), MHz(30), RX340_MODES, -1, -1, RX340_VFO, RX340_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(0), MHz(30), RX340_MODES, -1, -1, RX340_VFO, RX340_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX340_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX340_MODES, kHz(3.2)}, {RX340_MODES, Hz(100)}, {RX340_MODES, kHz(16)}, {RX340_MODES, 0}, RIG_FLT_END, }, .priv = (void *)NULL, .rig_open = rx340_open, .rig_close = rx340_close, .set_freq = rx340_set_freq, .get_freq = rx340_get_freq, .set_mode = rx340_set_mode, .get_mode = rx340_get_mode, .set_level = rx340_set_level, .get_level = rx340_get_level, .get_info = rx340_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define BUFSZ 128 #define EOM "\015" /* CR */ #define RX340_AM '1' #define RX340_FM '2' #define RX340_CW '3' #define RX340_CW1 '4' #define RX340_ISB '5' #define RX340_LSB '6' #define RX340_USB '7' #define RX340_SAM '8' /* * rx340_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ static int rx340_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } #if 0 /* * rx340_init: * Basically, it just sets up *priv */ int rx340_init(RIG *rig) { struct rx340_priv_data *priv; priv = (struct rx340_priv_data *)calloc(1, sizeof(struct rx340_priv_data)); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } memset(priv, 0, sizeof(struct rx340_priv_data)); /* * set arbitrary initial status */ STATE(rig)->priv = (rig_ptr_t)priv; return RIG_OK; } /* * Tentec generic rx340_cleanup routine * the serial port is closed by the frontend */ int rx340_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } #endif int rx340_open(RIG *rig) { #define REMOTE_CMD "*R1"EOM return write_block(RIGPORT(rig), (unsigned char *) REMOTE_CMD, strlen(REMOTE_CMD)); } int rx340_close(RIG *rig) { #define LOCAL_CMD "*R0"EOM return write_block(RIGPORT(rig), (unsigned char *) LOCAL_CMD, strlen(LOCAL_CMD)); } /* * rx340_set_freq */ int rx340_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char freqbuf[16]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%.6f" EOM, freq / 1e6); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); return retval; } /* * rx340_get_freq * Assumes rig!=NULL, freq!=NULL */ int rx340_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[BUFSZ]; int buf_len = 0; int retval; double f; #define REPORT_FREQ "TF"EOM retval = rx340_transaction(rig, REPORT_FREQ, strlen(REPORT_FREQ), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 2 || buf[0] != 'F' || num_sscanf(buf + 1, "%lf", &f) != 1) { return -RIG_EPROTO; } *freq = f * 1e6; return RIG_OK; } /* * rx340_set_mode * Assumes rig!=NULL */ int rx340_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char dmode; int retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: dmode = RX340_USB; break; case RIG_MODE_LSB: dmode = RX340_LSB; break; case RIG_MODE_CW: dmode = RX340_CW; break; case RIG_MODE_FM: dmode = RX340_FM; break; case RIG_MODE_AM: dmode = RX340_AM; break; case RIG_MODE_AMS: dmode = RX340_SAM; break; case RIG_MODE_DSB: dmode = RX340_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * Set DETECTION MODE and IF FILTER */ SNPRINTF(mdbuf, sizeof(mdbuf), "D%cI%.02f" EOM, dmode, (float)width / 1e3); } else { /* * Set DETECTION MODE */ SNPRINTF(mdbuf, sizeof(mdbuf), "D%c" EOM, dmode); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, strlen(mdbuf)); return retval; } /* * rx340_get_mode * Assumes rig!=NULL, mode!=NULL */ int rx340_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ]; int buf_len = 0; int retval; double f; #define REPORT_MODEFILTER "TDI"EOM retval = rx340_transaction(rig, REPORT_MODEFILTER, strlen(REPORT_MODEFILTER), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 4 || buf[0] != 'D' || buf[2] != 'I') { return -RIG_EPROTO; } switch (buf[1]) { case RX340_USB: *mode = RIG_MODE_USB; break; case RX340_LSB: *mode = RIG_MODE_LSB; break; case RX340_CW1: case RX340_CW: *mode = RIG_MODE_CW; break; case RX340_FM: *mode = RIG_MODE_FM; break; case RX340_AM: *mode = RIG_MODE_AM; break; case RX340_SAM: *mode = RIG_MODE_AMS; break; case RX340_ISB: *mode = RIG_MODE_DSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode '%c'\n", __func__, buf[1]); return -RIG_EPROTO; } if (num_sscanf(buf + 3, "%lf", &f) != 1) { return -RIG_EPROTO; } *width = f * 1e3; return RIG_OK; } /* * rx340_set_level * Assumes rig!=NULL * cannot support PREAMP and ATT both at same time (make sense though) */ int rx340_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval = RIG_OK; char cmdbuf[32]; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%c" EOM, val.i ? '3' : '1'); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%c" EOM, val.i ? '2' : '1'); break; case RIG_LEVEL_AGC: /* default to MEDIUM */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%c" EOM, val.i == RIG_AGC_SLOW ? '3' : ( val.i == RIG_AGC_FAST ? '1' : '2')); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d" EOM, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "Q%d" EOM, 150 - (int)(val.f * 150)); break; case RIG_LEVEL_NOTCHF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "N%f" EOM, ((float)val.i) / 1e3); break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%f" EOM, ((float)val.i) / 1e3); break; case RIG_LEVEL_CWPITCH: /* only in CW mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%f" EOM, ((float)val.i) / 1e3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); return retval; } /* * rx340_get_level * Assumes rig!=NULL, val!=NULL */ int rx340_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char lvlbuf[BUFSZ]; switch (level) { case RIG_LEVEL_STRENGTH: #define REPORT_STRENGTH "X"EOM retval = rx340_transaction(rig, REPORT_STRENGTH, strlen(REPORT_STRENGTH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 2 || lvlbuf[0] != 'X') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } /* range 0-150 covering the dynamic range * of receiver -140..+10dBm */ val->i = atoi(lvlbuf + 1) - 140 + 73; break; case RIG_LEVEL_AGC: case RIG_LEVEL_ATT: case RIG_LEVEL_PREAMP: case RIG_LEVEL_RF: case RIG_LEVEL_IF: case RIG_LEVEL_SQL: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * rx340_get_info * Assumes rig!=NULL */ const char *rx340_get_info(RIG *rig) { static char buf[BUFSZ]; /* FIXME: reentrancy */ int firmware_len = 0, retval; #define REPORT_FIRM "V"EOM retval = rx340_transaction(rig, REPORT_FIRM, strlen(REPORT_FIRM), buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.5/rigs/tentec/tt550.c0000664000175000017500000012151515056640443011734 /* * Hamlib Tentec Pegasus TT550 backend - main file * Heavily modified for 550 support from the original tentec.c * (c) Oct 2002, Jan,Feb 2004- Ken Koster N7IPB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* Standard C library */ #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "serial.h" #include "misc.h" #include "tt550.h" /* * Filter table for 550 receiver support */ static int tt550_filters[] = { 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 8000 }; /* * Filter table for 550 transmit support - The 550 allows the transmitter audio * filter bandwidth to be changed, but the filters allowed are only a subset of the * receive filters. This table is used to restrict the filters to the allowable * range. */ static int tt550_tx_filters[] = { 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050 }; /***************************Support Functions********************************/ /* * tt550_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ int tt550_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); /* * set_transaction_active keeps the asynchronous decode routine from being called * when we get data back from a normal command. */ set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { set_transaction_inactive(rig); return retval; } /* * no data expected, TODO: flush input? */ if (!data || !data_len) { set_transaction_inactive(rig); return 0; } retval = read_string(rp, (unsigned char *) data, *data_len, NULL, 0, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; set_transaction_inactive(rig); return RIG_OK; } /* * tt550_tx_control - The 550 has a number of operations that control * the transmitter. Commands like enable/disable tx, enable/disable * amplifier loop, enable/disable keep alive, etc. * This function provides for these commands. */ int tt550_tx_control(RIG *rig, char oper) { int retval; char cmdbuf[4]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "#%c" EOM, oper); retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); /* * if (retval == RIG_OK) not currently saving the state of these operations I'm * not sure we need to, but if so, this is where it would go. */ return retval; } /* * tt550_ldg_control - The 550 has a builtin LDG antenna tuner option. * This function controls the tuner operations. * * * The LDG tuner listens on the Pegasus' RS-232 * Rx Data line. The interface is one-way. The tuner can't * respond at all. The Pegasus will respond with Z when * it sees the commands meant for the tuner. This is normal. * The LDG tuner is only listening on the serial line * when RF is applied. Therefore, RF must be applied before * the tuner will do anything. * * $0 = Place tuner in bypass mode * $1 = Start Tune process * $3 = Cap Up * $4 = Cap Dn * $5 = Inductor Up * $6 = Inductor Dn * This function provides for these commands. */ int tt550_ldg_control(RIG *rig, char oper) { int retval, lvl_len; char cmdbuf[4], lvlbuf[32]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%c" EOM, oper); lvl_len = 3; retval = tt550_transaction(rig, cmdbuf, 3, lvlbuf, &lvl_len); /* * if (retval == RIG_OK) not currently saving the state of these operations I'm * not sure we need to, but if so, this is where it would go. */ return retval; } /* * Tuning Factor Calculations * Used by both receive and transmit vfo routines * to calculate the desired tuning parameters. * tx - 0 for receive tuning, 1 for transmit tuning * Thanks to the unknown author of the GPL'd windows program * found on the Ten-Tec site. Having working examples of the * calculations was invaluable. */ static void tt550_tuning_factor_calc(RIG *rig, int tx) { struct tt550_priv_data *priv; int Bfo = 700; double TFreq = 0, IVal, radio_freq = 0; int NVal, FVal; // N value/finetune value int TBfo = 0; // temporary BFO int IBfo = 1500; // Intermediate BFO Freq int FilterBw; // Filter Bandwidth determined from table int Mode, PbtAdj, RitAdj, XitAdj; priv = (struct tt550_priv_data *) STATE(rig)->priv; Mode = (tx ? priv->tx_mode : priv->rx_mode); radio_freq = ((tx ? priv->tx_freq : priv->rx_freq)) / (double) MHz(1); FilterBw = priv->width; PbtAdj = priv->pbtadj; RitAdj = priv->rit; XitAdj = priv->xit; if (tx) { int bwBFO = (FilterBw / 2) + 200; IBfo = (bwBFO > IBfo) ? bwBFO : IBfo; if (Mode == RIG_MODE_USB) { TFreq = radio_freq + (double)(IBfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(IBfo * 2.73); } if (Mode == RIG_MODE_LSB) { TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(IBfo * 2.73); } if (Mode == RIG_MODE_CW) { // CW Mode uses LSB Mode IBfo = 1500; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(Bfo * 2.73); } if (Mode == RIG_MODE_FM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = 0; } if (Mode == RIG_MODE_AM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = 0; } } else { radio_freq = radio_freq + (double)(RitAdj / 1e6); if (Mode == RIG_MODE_USB) { IBfo = (FilterBw / 2) + 200; TFreq = radio_freq + (double)(IBfo / 1e6) + (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } if (Mode == RIG_MODE_LSB) { IBfo = (FilterBw / 2) + 200; TFreq = radio_freq - (double)(IBfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } if (Mode == RIG_MODE_CW) { /* CW Mode uses LSB Mode */ if (((FilterBw / 2) + 300) <= Bfo) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + Bfo + PbtAdj; } else { IBfo = (FilterBw / 2) + 300; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } } if (Mode == RIG_MODE_FM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = 0; } if (Mode == RIG_MODE_AM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = 0; } } TFreq = TFreq - 0.00125; NVal = (int)(TFreq * 400); IVal = (double)((TFreq * 400.0) - NVal); FVal = (int)(IVal * 2500.0 * 5.46); NVal = (NVal + 18000); TBfo = (tx ? IBfo : (int)(((double) IBfo + 8000.0) * 2.73)); priv->ctf = NVal; priv->ftf = FVal; priv->btf = TBfo; } /*************************End of Support Functions**************************/ /* * tt550_init: * Basically, it just sets up *priv with some sane defaults * */ int tt550_init(RIG *rig) { struct tt550_priv_data *priv; STATE(rig)->priv = (struct tt550_priv_data *) calloc(1, sizeof( struct tt550_priv_data)); if (!STATE(rig)->priv) { /* * whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt550_priv_data)); /* * set arbitrary initial status */ priv->rx_freq = MHz(3.985); priv->tx_freq = MHz(3.985); priv->rx_mode = RIG_MODE_LSB; priv->tx_mode = RIG_MODE_LSB; priv->width = kHz(2.4); priv->tx_width = kHz(2.4); priv->tx_cwbfo = priv->cwbfo = kHz(0.7); priv->agc = 2; /* medium */ priv->lineout = priv->spkvol = 0.0; /* mute */ priv->stepsize = 100; /* default to 100Hz tuning step */ return RIG_OK; } /* * Tentec generic tt550_cleanup routine * the serial port is closed by the frontend */ int tt550_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Software restart */ int tt550_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 16; retval = tt550_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } reset_len = 16; if (strstr(reset_buf, "DSP START")) { retval = tt550_transaction(rig, "P1" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } } if (!strstr(reset_buf, "RADIO START")) { return -RIG_EPROTO; } return RIG_OK; } /* * Tentec 550 transceiver open routine * Restart and set program to execute. */ int tt550_trx_open(RIG *rig) { struct tt550_priv_data *priv; priv = (struct tt550_priv_data *) STATE(rig)->priv; /* * Reset the radio and start its program running * We'll try twice to reset before giving up */ if (tt550_reset(rig, RIG_RESET_SOFT) != RIG_OK) { if (tt550_reset(rig, RIG_RESET_SOFT) != RIG_OK) { return -RIG_EPROTO; } } #ifdef BYPASS_KEEPALIVE /* * Temporarily Disable the transmitter Keep alive. The 550 expects the software * to execute a serial command at least once every two seconds or it will * disable TX. */ tt550_tx_control(rig, DISABLE_KEEPALIVE); #endif /* * Program the radio with the default mode,freq,filter */ tt550_set_tx_mode(rig, RIG_VFO_CURR, priv->tx_mode, priv->tx_width); tt550_set_rx_mode(rig, RIG_VFO_CURR, priv->rx_mode, priv->width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); tt550_set_rx_freq(rig, RIG_VFO_CURR, priv->rx_freq); /* * Enable TX */ tt550_tx_control(rig, ENABLE_TX); /* * Bypass automatic tuner */ tt550_ldg_control(rig, '0'); return RIG_OK; } /* * tt550_set_freq * Set the receive frequency to that requested and if * Split mode is OFF do the transmitter too */ int tt550_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; retval = tt550_set_rx_freq(rig, vfo, freq); if (retval != RIG_OK) { return retval; } if (priv->split == RIG_SPLIT_OFF) { return tt550_set_tx_freq(rig, vfo, freq); } return retval; } /* * tt550_get_freq * Get the current receive frequency */ int tt550_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; *freq = priv->rx_freq; return RIG_OK; } /* * tt550_set_mode * Set the receive mode and if NOT in split mode * set the transmitter to the same mode/width */ int tt550_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; retval = tt550_set_rx_mode(rig, vfo, mode, width); if (retval != RIG_OK) { return retval; } if (priv->split == RIG_SPLIT_OFF) { return tt550_set_tx_mode(rig, vfo, mode, width); } return retval; } /* * tt550_get_mode * GET the current receive mode/width */ int tt550_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; *mode = priv->rx_mode; *width = priv->width; return RIG_OK; } /* * tt550_set_rx_freq * Set the receiver to the requested frequency */ int tt550_set_rx_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt550_priv_data *priv; int retval; char freqbuf[16]; priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->rx_freq = freq; tt550_tuning_factor_calc(rig, RECEIVE); SNPRINTF(freqbuf, sizeof(freqbuf), "N%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt550_set_tx_freq * Set the current transmit frequency */ int tt550_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt550_priv_data *priv; int retval; char freqbuf[16]; priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->tx_freq = freq; tt550_tuning_factor_calc(rig, TRANSMIT); SNPRINTF(freqbuf, sizeof(freqbuf), "T%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt550_get_tx_freq * Get the current transmit frequency */ int tt550_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *freq = priv->tx_freq; return RIG_OK; } /* * tt550_set_rx_mode * SET the current receive mode */ int tt550_set_rx_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[48]; /* * Find mode for receive */ switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* * backup current values in case we fail to write to port */ saved_mode = priv->rx_mode; saved_width = priv->width; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tt550_filters[ttfilter] != 0; ttfilter++) { if (tt550_filters[ttfilter] == width) { break; } } if (tt550_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } priv->width = width; } priv->rx_mode = mode; tt550_tuning_factor_calc(rig, RECEIVE); SNPRINTF(mdbuf, sizeof(mdbuf), "M%c%c" EOM, ttmode, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->rx_mode = saved_mode; priv->width = saved_width; return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "W%c" EOM "N%c%c%c%c%c%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->width = saved_width; return retval; } } return RIG_OK; } /* * tt550_set_tx_mode * Set the current transmit mode/filter * Since the transmitter uses a subset of the filters used * by the receiver we set the filter if possible, if not we use * the nearest value. */ int tt550_set_tx_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[48]; switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* * backup current values in case we fail to write to port */ saved_mode = priv->tx_mode; saved_width = priv->tx_width; if (width != RIG_PASSBAND_NOCHANGE) { /* * Limit the transmitter bandwidth - it's not the same as the receiver */ if (width < 1050) { width = 1050; } if (width > 3900) { width = 3900; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tt550_tx_filters[ttfilter] != 0; ttfilter++) { if (tt550_tx_filters[ttfilter] == width) { break; } } if (tt550_tx_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx width %d,%d\n", __func__, (int)width, ttfilter); return -RIG_EINVAL; } /* * The tx filter array contains just the allowed filter values, but the * command assumes that the first allowed value is at offset 7. We add * 7 to compensate for the array difference */ ttfilter += 7; priv->tx_width = width; } priv->tx_mode = mode; tt550_tuning_factor_calc(rig, TRANSMIT); SNPRINTF(mdbuf, sizeof(mdbuf), "M%c%c" EOM, ttmode, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->tx_mode = saved_mode; priv->tx_width = saved_width; return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "C%c" EOM "T%c%c%c%c%c%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->tx_width = saved_width; return retval; } } return RIG_OK; } /* * tt550_get_tx_mode */ int tt550_get_tx_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *mode = priv->tx_mode; *width = priv->tx_width; return RIG_OK; } /* * Set the RIT value and force receive frequency to change */ int tt550_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->rit = rit; tt550_set_rx_freq(rig, vfo, priv->rx_freq); return RIG_OK; } /* * Get The current RIT value */ int tt550_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *rit = priv->rit; return RIG_OK; } /* * Set the XIT value and force the Transmit frequency to change */ int tt550_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->xit = xit; tt550_set_tx_freq(rig, vfo, priv->tx_freq); return RIG_OK; } /* * Get the Current XIT value */ int tt550_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *xit = priv->xit; return RIG_OK; } /* * tt550_set_level */ int tt550_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval, ditfactor, dahfactor, spcfactor; char cmdbuf[32]; switch (level) { case RIG_LEVEL_AGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%c" EOM, val.i >= 3 ? '3' : (val.i < 2 ? '1' : '2')); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->agc = val.i; } return retval; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "V%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->spkvol = val.f; } return retval; #ifdef RIG_LEVEL_LINEOUT case RIG_LEVEL_LINEOUT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "L%c" EOM, (int)(val.f * 63)); retval = write_block(rp, cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->lineout = val.f; } return retval; #endif case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->rflevel = val.f; } return retval; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "S%c" EOM, (int)(val.f * 19)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->sql = val.f; } return retval; case RIG_LEVEL_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "D%c" EOM, (int)(val.f * 7)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->nr = val.f; } return retval; case RIG_LEVEL_ATT: /* * attenuator is either on or off */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%c" EOM, val.i < 15 ? '0' : '1'); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->att = val.i; } return retval; case RIG_LEVEL_KEYSPD: ditfactor = spcfactor = (int)(((double) 0.50 / (val.i * (double) 0.4166 * (double) 0.0001667))); dahfactor = ditfactor * 3; SNPRINTF(cmdbuf, sizeof(cmdbuf), "E%c%c%c%c%c%c" EOM, ditfactor >> 8, ditfactor & 0xff, dahfactor >> 8, dahfactor & 0xff, spcfactor >> 8, spcfactor & 0xff); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->keyspd = val.i; } return retval; case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->rfpower = val.f; } return retval; case RIG_LEVEL_VOXGAIN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UG%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->voxgain = val.f; } return retval; case RIG_LEVEL_VOXDELAY: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UH%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->voxdelay = val.f; } return retval; case RIG_LEVEL_ANTIVOX: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UA%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->antivox = val.f; } return retval; case RIG_LEVEL_COMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "Y%c" EOM, (int)(val.f * 127)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->speechcomp = val.f; } return retval; case RIG_LEVEL_MICGAIN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "O1%c%c" EOM, 0, (int)(val.f * 15)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->mikegain = val.f; } return retval; case RIG_LEVEL_BKINDL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UQ%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->bkindl = val.f; } return retval; case RIG_LEVEL_IF: priv->pbtadj = val.i; retval = tt550_set_rx_freq(rig, vfo, priv->tx_freq); return retval; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_get_level */ int tt550_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; int retval, lvl_len; char lvlbuf[32]; switch (level) { case RIG_LEVEL_STRENGTH: /* * read A/D converted value */ lvl_len = 7; retval = tt550_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "tt550_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * Crude but it should work, the first and second digits are * the ascii value for the S number (0x30 = S0 etc.) followed by * a two byte fractional binary portion - We only use the first * portion for now. */ val->i = (((lvlbuf[2] - 0x30) * 6) - 54); break; case RIG_LEVEL_RAWSTR: /* * read A/D converted value */ lvl_len = 6; retval = tt550_transaction(rig, "?X" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "tt550_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = (lvlbuf[1] << 8) + lvlbuf[2]; break; case RIG_LEVEL_AGC: val->f = priv->agc; break; case RIG_LEVEL_AF: val->f = priv->spkvol; break; #ifdef RIG_LEVEL_LINEOUT case RIG_LEVEL_LINEOUT: val->f = priv->lineout; break; #endif case RIG_LEVEL_RF: val->f = priv->rflevel; break; case RIG_LEVEL_SQL: val->f = priv->sql; break; case RIG_LEVEL_ATT: val->i = priv->att; break; case RIG_LEVEL_KEYSPD: val->i = priv->keyspd; break; case RIG_LEVEL_NR: val->f = priv->nr; break; case RIG_LEVEL_RFPOWER: val->f = priv->rfpower; break; case RIG_LEVEL_VOXGAIN: val->f = priv->voxgain; break; case RIG_LEVEL_VOXDELAY: val->f = priv->voxdelay; break; case RIG_LEVEL_ANTIVOX: val->f = priv->antivox; break; case RIG_LEVEL_COMP: val->f = priv->speechcomp; break; case RIG_LEVEL_MICGAIN: val->f = priv->mikegain; break; case RIG_LEVEL_BKINDL: val->f = priv->bkindl; break; case RIG_LEVEL_IF: val->i = priv->pbtadj; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_get_info */ const char * tt550_get_info(RIG *rig) { static char buf[16]; int firmware_len, retval; /* * protocol version */ firmware_len = 10; retval = tt550_transaction(rig, "?V" EOM, 3, buf, &firmware_len); if (retval != RIG_OK || firmware_len != 9) { rig_debug(RIG_DEBUG_ERR, "tt550_get_info: ack NG, len=%d\n", firmware_len); return NULL; } buf[firmware_len] = '\0'; return buf; } /* * tt550_set_ptt */ int tt550_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdbuf[16]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "Q%c" EOM, ptt == 0 ? '0' : '1'); return (write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf))); } /* * tt550_get_ptt */ int tt550_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { static char buf[10]; int len, retval; /* * The 550 doesn't have an explicit command to return ptt status, so we fake it * with the request for signal strength which returns a 'T' for the first * character if we're transmitting */ len = 7; retval = tt550_transaction(rig, "?S" EOM, 3, buf, &len); if (retval != RIG_OK) { return retval; } /* * buf should contain either Sxx for Receive Signal strength * or Txx for Transmit power/reflected power */ *ptt = buf[0] == 'T' ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * tt550_set_split_vfo */ int tt550_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->split = split; return RIG_OK; } /* * tt550_get_split_vfo */ int tt550_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *split = priv->split; return RIG_OK; } int tt550_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char fctbuf[16]; struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_VOX: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "U%c" EOM, status == 0 ? '0' : '1'); priv->vox = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_NR: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "K%c%c" EOM, status == 0 ? '0' : '1', priv->anf == 0 ? '0' : '1'); priv->en_nr = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_ANF: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "K%c%c" EOM, priv->en_nr == 0 ? '0' : '1', status == 0 ? '0' : '1'); priv->anf = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_TUNER: priv->tuner = status; if (status == '0') { tt550_ldg_control(rig, 0); } return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } int tt550_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_VOX: *status = priv->vox; break; case RIG_FUNC_NR: *status = priv->en_nr; break; case RIG_FUNC_ANF: *status = priv->anf; break; case RIG_FUNC_TUNER: *status = priv->tuner; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_set_tuning_step */ int tt550_set_tuning_step(RIG *rig, vfo_t vfo, shortfreq_t stepsize) { struct tt550_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_set_tuning_step - %d\n", __func__, (int)stepsize); priv->stepsize = stepsize; return RIG_OK; } /* * tt550_get_tuning_step */ int tt550_get_tuning_step(RIG *rig, vfo_t vfo, shortfreq_t *stepsize) { struct tt550_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_get_tuning_step - %d\n", __func__, (int)priv->stepsize); *stepsize = priv->stepsize; return RIG_OK; } /* * Tune the radio using the LDG antenna tuner */ int tt550_tune(RIG *rig) { value_t current_power; rmode_t current_mode; value_t lowpower; const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; /* Set our lowpower level to about 10 Watts */ lowpower.f = 0.12; /* Get the current power and save it, */ current_power.f = priv->rfpower; /* Set power to approx 10w */ tt550_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, lowpower); /* Get the current mode, and save */ current_mode = priv->tx_mode; /* Set the mode to cw, keep the old frequency and bandwidth */ tt550_set_tx_mode(rig, RIG_VFO_CURR, RIG_MODE_CW, priv->tx_width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); /* key the radio */ tt550_set_ptt(rig, RIG_VFO_CURR, 1); /* Wait long enough for the transmitter to key up */ sleep(1); /* Start the tuner */ tt550_ldg_control(rig, '1'); /* * Wait for tuner to finish * NOTE: Using sleep and blocking like this is BAD, we * really should have a way to tell that the tuner is finished. * What we should be doing here is probably: * 1. wait one second for tuner to start. * 2. Unkey the radio - the LDG tuner will keep it keyed until * it is done. (I think) * NOTE: I was wrong, the LDG does not key the rig so this won't work. * Have to come up with something else. * 3. Keep checking for the Radio to be unkeyed * 4. Stop the tuner and restore everything. * The above should all be done asynchronous to this function so * that we don't stall the calling routine. */ sleep(4); /* Unkey the Radio */ tt550_set_ptt(rig, RIG_VFO_CURR, 0); /* Restore the mode and frequency */ tt550_set_tx_mode(rig, RIG_VFO_CURR, current_mode, priv->tx_width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); /* Restore the original Power setting */ tt550_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, current_power); return RIG_OK; } /* * tt550_vfo_op */ int tt550_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_TUNE: tt550_tune(rig); break; default: rig_debug(RIG_DEBUG_ERR, "tt550_vfo_op: unsupported op %#x\n", op); return -RIG_EINVAL; } return RIG_OK; } #define MAXFRAMELEN 7 /* * tt550_decode is called by sa_sigio, when asynchronous data * has been received from the rig * * A lot more can be done in this routine. Things like allowing F2 * to switch the encoder between frequency, audio, power control. Or * letting a function key cycle thru various bands. * For now it just handles the encoder for frequency change and F1 for * changing the step size. */ int tt550_decode_event(RIG *rig) { struct tt550_priv_data *priv; struct rig_state *rs; unsigned char buf[MAXFRAMELEN]; int data_len; // char key; rig_debug(RIG_DEBUG_VERBOSE, "%s/tt: tt550_decode_event called\n", __func__); rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; data_len = read_string(RIGPORT(rig), buf, MAXFRAMELEN, "\n\r", 2, 0, 1); if (data_len == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_decode got a timeout before the first character\n", __func__); return RIG_OK; } rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_decode %p\n", __func__, &buf); /* * The first byte must be either 'U' for keypad operations * or '!' for encoder operations. */ switch (*buf) { /* * For now we'll assume that the encoder is only used for * frequency control, but since it's really a general purpose * device we could later use it for other purposes. * Tied in with priv->stepsize to allow the step rate to change */ case '!': if (rig->callbacks.freq_event) { int movement = buf[1] << 8; movement = movement | buf[2]; // key = buf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: Step Direction = %d\n", __func__, movement); if (movement > 0) { priv->rx_freq += priv->stepsize; } if (movement < 0) { priv->rx_freq -= priv->stepsize; } rig->callbacks.freq_event(rig, RIG_VFO_CURR, priv->rx_freq, rig->callbacks.freq_arg); } break; /* * Keypad Function Key support - for now only F1 * Numeric pad can be done later */ case 'U': switch (buf[1]) { case KEY_F1_DOWN: /* F1 changes the Step size from 1hz to 1mhz */ if (priv->stepsize < 10000) { /* In powers of ten */ priv->stepsize = priv->stepsize * 10; } else { priv->stepsize = 1; } break; case KEY_F2_DOWN: case KEY_F3_DOWN: case KEY_F1_UP: case KEY_F2_UP: case KEY_F3_UP: default: rig_debug(RIG_DEBUG_VERBOSE, "tt550_decode: KEY " "unsupported %d\n", buf[1]); return -RIG_ENIMPL; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "tt550_decode: response " "unsupported %s\n", buf); return -RIG_ENIMPL; } return RIG_OK; } hamlib-4.6.5/rigs/tentec/tentec.c0000664000175000017500000003245115056640443012335 /* * Hamlib Tentec backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "tentec.h" static void tentec_tuning_factor_calc(RIG *rig); #define EOM "\015" /* CR */ #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' static int tentec_filters[] = { 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 8000 }; /* * tentec_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ int tentec_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, *data_len, NULL, 0, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * tentec_init: * Basically, it just sets up *priv */ int tentec_init(RIG *rig) { struct tentec_priv_data *priv; STATE(rig)->priv = (struct tentec_priv_data *)calloc(1, sizeof( struct tentec_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tentec_priv_data)); /* * set arbitrary initial status */ priv->freq = MHz(10); priv->mode = RIG_MODE_AM; priv->width = kHz(6); priv->pbt = 0; priv->cwbfo = 1000; priv->agc = RIG_AGC_MEDIUM; /* medium */ priv->lnvol = priv->spkvol = 0.0; /* mute */ /* tentec_tuning_factor_calc needs STATE(rig)->priv */ tentec_tuning_factor_calc(rig); return RIG_OK; } /* * Tentec generic tentec_cleanup routine * the serial port is closed by the frontend */ int tentec_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Tentec transceiver only open routine * Restart and set program to execute. */ int tentec_trx_open(RIG *rig) { int retval; /* * be kind: use XX first, and do 'Dsp Program Execute' only * in " DSP START" state. */ retval = tentec_transaction(rig, "P1" EOM, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * Tuning Factor Calculations * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in supported modes. */ static void tentec_tuning_factor_calc(RIG *rig) { struct tentec_priv_data *priv; freq_t tfreq; int adjtfreq, mcor, fcor, cwbfo; priv = (struct tentec_priv_data *)STATE(rig)->priv; cwbfo = 0; /* computed fcor only used if mode is not CW */ fcor = (int)floor((double)priv->width / 2.0) + 200; switch (priv->mode) { case RIG_MODE_AM: case RIG_MODE_FM: mcor = 0; break; case RIG_MODE_CW: mcor = -1; cwbfo = priv->cwbfo; fcor = 0; break; case RIG_MODE_LSB: mcor = -1; break; case RIG_MODE_USB: mcor = 1; break; default: rig_debug(RIG_DEBUG_BUG, "%s: invalid mode %s\n", __func__, rig_strrmode(priv->mode)); mcor = 1; break; } tfreq = priv->freq / (freq_t)Hz(1); adjtfreq = (int)tfreq - 1250 + (int)(mcor * (fcor + priv->pbt)); priv->ctf = (adjtfreq / 2500) + 18000; priv->ftf = (int)floor((double)(adjtfreq % 2500) * 5.46); priv->btf = (int)floor((double)(fcor + priv->pbt + cwbfo + 8000) * 2.73); } /* * tentec_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tentec_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tentec_priv_data *priv; int retval; char freqbuf[16]; freq_t old_freq; priv = (struct tentec_priv_data *)STATE(rig)->priv; old_freq = priv->freq; priv->freq = freq; tentec_tuning_factor_calc(rig); SNPRINTF(freqbuf, sizeof(freqbuf), "N%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { priv->freq = old_freq; return retval; } return RIG_OK; } /* * tentec_get_freq * Assumes rig!=NULL, freq!=NULL */ int tentec_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; *freq = priv->freq; return RIG_OK; } /* * tentec_set_mode * Assumes rig!=NULL */ int tentec_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tentec_priv_data *priv = (struct tentec_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* backup current values * in case we fail to write to port */ saved_mode = priv->mode; saved_width = priv->width; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tentec_filters[ttfilter] != 0; ttfilter++) { if (tentec_filters[ttfilter] == width) { break; } } if (tentec_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } priv->width = width; } priv->mode = mode; tentec_tuning_factor_calc(rig); if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "W%c" EOM "N%c%c%c%c%c%c" EOM "M%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->mode = saved_mode; priv->width = saved_width; return retval; } } else { SNPRINTF(mdbuf, sizeof(mdbuf), "N%c%c%c%c%c%c" EOM "M%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->mode = saved_mode; return retval; } } return RIG_OK; } /* * tentec_get_mode * Assumes rig!=NULL, mode!=NULL */ int tentec_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; *mode = priv->mode; *width = priv->width; return RIG_OK; } /* * tentec_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int tentec_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct tentec_priv_data *priv = (struct tentec_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval = RIG_OK; char cmdbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_AGC: /* default to MEDIUM */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%c" EOM, val.i == RIG_AGC_SLOW ? '1' : ( val.i == RIG_AGC_FAST ? '3' : '2')); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->agc = val.i; } return retval; case RIG_LEVEL_AF: /* FIXME: support also separate Lineout setting * -> need to create RIG_LEVEL_LINEOUT ? */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "C\x7f%c" EOM, (int)((1.0 - val.f) * 63.0)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->lnvol = priv->spkvol = val.f; } return retval; case RIG_LEVEL_IF: priv->pbt = val.i; retval = tentec_set_freq(rig, vfo, priv->freq); return retval; case RIG_LEVEL_CWPITCH: priv->cwbfo = val.i; if (priv->mode == RIG_MODE_CW) { retval = tentec_set_freq(rig, vfo, priv->freq); } return retval; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tentec_get_level * Assumes rig!=NULL, val!=NULL */ int tentec_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; int retval, lvl_len; unsigned char lvlbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ lvl_len = 4; retval = tentec_transaction(rig, "X" EOM, 2, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "tentec_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "tentec_get_level: cmd=%c,hi=%d,lo=%d\n", lvlbuf[0], lvlbuf[1], lvlbuf[2]); val->i = (lvlbuf[1] << 8) + lvlbuf[2]; break; case RIG_LEVEL_AGC: val->i = priv->agc; break; case RIG_LEVEL_AF: val->f = priv->spkvol; break; case RIG_LEVEL_IF: val->i = priv->pbt; break; case RIG_LEVEL_CWPITCH: val->i = priv->cwbfo; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tentec_get_info * Assumes rig!=NULL */ const char *tentec_get_info(RIG *rig) { static char buf[100]; /* FIXME: reentrancy */ int firmware_len, retval; /* * protocol version */ firmware_len = 10; retval = tentec_transaction(rig, "?" EOM, 2, buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "tentec_get_info: ack NG, len=%d\n", firmware_len); return NULL; } return buf; } /* * initrigs_tentec is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(tentec) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&tt550_caps); rig_register(&tt516_caps); rig_register(&tt565_caps); rig_register(&tt538_caps); rig_register(&tt585_caps); rig_register(&tt588_caps); rig_register(&tt599_caps); rig_register(&rx320_caps); rig_register(&rx331_caps); rig_register(&rx340_caps); rig_register(&rx350_caps); return RIG_OK; } hamlib-4.6.5/rigs/tentec/Android.mk0000664000175000017500000000055715056640443012622 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := rx320.c rx340.c rx350.c rx331.c \ pegasus.c argonaut.c orion.c jupiter.c omnivii.c paragon.c \ tentec.c tentec2.c tt550.c LOCAL_MODULE := tentec LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/tentec/rx331.h0000664000175000017500000000200215056640443011725 /* * Hamlib Tentec backend - RX331 header * Copyright (c) 2010 by Berndt Josef Wulf * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RX331_H #define _RX331_H #include "token.h" #define TOK_RIGID TOKEN_BACKEND(1) struct rx331_priv_data { unsigned int receiver_id; }; #endif hamlib-4.6.5/rigs/tentec/README.tentec0000664000175000017500000000611115056640443013042 Jupiter (538) (29 February 2012, AA6E) The Jupiter needs current firmware, at least version 1,18. Earlier firmware apparently had a different command protocol. Most available commands are now implemented, with exception of NB, NR, and AN. Omni VI (563), VI Plus (564) (26 March 2008, AA6E) Note that the Omni uses an Icom-style command interface. The Omni backend lives in the ../icom directory! Omni (hardware) menu selections: The Omni's device address must be set to '04'. The 563 and 564 provide 1200, 2400, 4800, 9600, and 19200 baud rates. Notes on 563 (Omni VI) vs. 564 (Omni VI Plus) Omni VI Plus (Hamlib model 351) backend can be used with the Omni VI, subject to its hardware limitations. Orion (TT 565, 565AT) and Orion II (TT 566, 566AT) (14 February 2008) Improved serial I/O transfer reliability, better error handling V1 and V2 firmware are autorecognized in the tt565_open routine. Version 2.xxx is now the default for Orion. (5 November 2007) The S-meter behavior has changed for Version 2.xxx of firmware for Orion. Orion II presumably also has a different calibration. We will recalibrate, but it is not clear if Orion and Orion II will produce the same readings. :-( Please send calibration info to me as indicated on the Hamlib FAQ at http://hamlib.sourceforge.net/faq.html . (23 April 2006) These are all covered by the TT565 backend (model 1608). This backend is functioning for basic HF work, although memory, multi-VFO, and antenna selection, etc. are left for the future. All testing to date has been on a model 565AT, running v 1.372 firmware. All reports of success/failure (especially for the Orion 2) are welcome -- Martin, aa6e@arrl.net (26 Feb 2006) tt550 TODO (Ken, N7IPB): Support for multiple VFO's and Memories. The TT550 doesn't really have VFO's or Memories since it's strictly a software controlled radio, but they can easily be simulated in software. I already support a split mode since the TX and RX control is separate. Adding support for VFO-A, VFO-B and memory channels will be done next. The optional encoder with keypad is supported for changing frequency only, along with F1 changing the stepsize. The other function keys have no current assignments. I can add hard-coded Function keys as I did with F1 but maybe a more generic solution can be determined. In addition the keypad is not supported. Hamlib has no apparent way to make use of the numeric keys. We probably need to add a callback for key data. IF-Shift: IF-Shift code is in place but I see no way in hamlib to make use of it. The Icom dual pass-band tuning is supported, but not just simple IF shift. Or maybe I just missed something. TX Audio Monitor Volume - no hamlib support - RIG_LEVEL_TX_MON? CW Sidetone Volume - no hamlib support - RIG_LEVEL_SIDETONE? Transmit Audio Source and Volume select - no hamlib support - RIG_LEVEL_LINEIN? CW Spot Level - no hamlib support - RIG_LEVEL_CW_SPOT? Enable/Disable Amplifier keying loop - no hamlib support - RIG_FUNC_AMP? hamlib-4.6.5/rigs/tentec/rx320.c0000664000175000017500000001244415056640443011731 /* * Hamlib TenTenc backend - RX-320 PC-Radio description * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tentec.h" #define RX320_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) /* TODO: LINEOUT */ #define RX320_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_AF|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR|RIG_LEVEL_CWPITCH) #define RX320_VFO (RIG_VFO_A) /* * Modified 11/18/2008, Josh Rovero, KK1D * Calibration via comparison with JRC NRD-525. * Highy non-linear.... */ #define RX320_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * rx320 receiver capabilities. * * protocol is documented at * http://www.tentec.com/rx320prg.zip * * TODO: */ struct rig_caps rx320_caps = { RIG_MODEL(RIG_MODEL_RX320), .model_name = "RX-320", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, /* * Added S-meter read support, Josh Rovero KK1D * Only get_level is for RIG_LEVEL_RAWSTR */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RX320_LEVELS, .has_set_level = RIG_LEVEL_SET(RX320_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 10000 } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0 / 64 } }, [LVL_IF] = { .min = { .i = -2000 }, .max = { .i = 2000 }, .step = { .i = 10} }, [LVL_CWPITCH] = { .min = { .i = 0}, .max = { .i = 2000 }, .step = { .i = 100} } }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), RX320_MODES, -1, -1, RX320_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), RX320_MODES, -1, -1, RX320_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX320_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, 300}, {RIG_MODE_CW, 450}, {RIG_MODE_CW, 600}, {RIG_MODE_CW, 750}, {RIG_MODE_CW, 900}, {RIG_MODE_CW, kHz(1.2)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(4.2)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(5.1)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(8)}, RIG_FLT_END, }, .str_cal = RX320_STR_CAL, .rig_init = tentec_init, .rig_cleanup = tentec_cleanup, .set_freq = tentec_set_freq, .get_freq = tentec_get_freq, .set_mode = tentec_set_mode, .get_mode = tentec_get_mode, .set_level = tentec_set_level, .get_level = tentec_get_level, .get_info = tentec_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/tentec/orion.c0000664000175000017500000017644115056640443012211 /* * Hamlib TenTenc backend - TT-565 description * Copyright (c) 2024 by Michael Black W9MDB * Copyright (c) 2004-2011 by Martin Ewing * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Edits by Martin Ewing AA6E, 23 Mar 2005 --> ?? * Added valid length settings before tentec_transaction calls. * Added vfo_curr initialization to VFO A * Fixed up VSWR & S-meter, set ATT, set AGC, add rough STR_CAL func. * Use local tt565_transaction due to quirky serial interface * Variable-length transaction read ok. * Calibrated S-meter response with signal generator. * Read re-tries implemented. * Added RIG_LEVEL_CWPITCH, RIG_LEVEL_KEYSPD, send_morse() * Added RIG_FUNC_TUNER, RIG_FUNC_LOCK and RIG_FUNC_VOX, fixed MEM_CAP. * Added VFO_OPS * Support LEVEL_VOX, VOXGAIN, ANTIVOX * Support LEVEL_NR as Orion NB setting (firmware bug), FUNC_NB -> NB=0,4 * Add get_, set_ant (ignores rx only ant) * Use binary mode for VFO read / write, for speed. * November, 2007: * Add RIG_LEVEL_STRENGTH capability (should have been there all along) * Implement auto-detect of firmware for S-meter cal, etc. * Fixed bug in tt565_reset (to send "XX" instead of "X") * Filtered rig info string to ensure all graphics. * Big reliability improvement (for fldigi, v 2.062a) 2/15/2008 * Jan., 2009: * Remove RIG_LEVEL_STRENGTH, so that frontend can handle it. * Dec., 2011: Implement VFO range checking. Adjust range_lists for max coverage. * Fix tt565_transaction for case of Morse (/) command. */ /* Known issues & to-do list: * Memory channels - emulate a more complete memory system? * Send_Morse() - needs to buffer more than 20 chars? * Figure out "granularities". * XCHG or other "fancy" VFO & MEM operations? */ /** * \addtogroup tentec_orion * @{ */ /** * \file orion.c * \brief Backend for Tentec Orion 565 / 566 * * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. * \n This backend tested mostly with firmware versions 1.372 and 2.062a */ #include #include #include #include #include /* String function definitions */ #include #include #include "serial.h" #include "misc.h" #include "orion.h" #ifdef TT565_TIME /** * \returns current time in secs/microsecs */ double tt565_timenow() /* returns current time in secs+microsecs */ { struct timeval tv; gettimeofday(&tv, NULL); return (double)tv.tv_sec + ((double)tv.tv_usec) / 1.0e+6; } #endif /** * \param rig Rig descriptor * \param cmd command to send * \param cmd_len length of command string * \param data string to receive return data from Orion (NULL if no return desired) * \param data_len length of data string * \returns RIG_OK or < 0 if error * \brief tt565_transaction, adapted from tentec_transaction (tentec.c) * * This is the basic I/O transaction to/from the Orion. * \n Read variable number of bytes, up to buffer size, if data & data_len != NULL. * \n We assume that rig!=NULL, STATE(rig)!= NULL. * Otherwise, you'll get a nice seg fault. You've been warned! */ static int tt565_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int data_len_init, itry; hamlib_port_t *rp = RIGPORT(rig); static int passcount = 0; #ifdef TT565_TIME double ft1, ft2; #endif MUTEX_LOCK(mutex); passcount++; // for debugging /* Capture buffer length for possible read re-try. */ data_len_init = (data && data_len) ? *data_len : 0; /* Allow transaction re-tries according to capabilities. */ for (itry = 0; itry < rig->caps->retry; itry++) { int retval; rig_flush(rp); /* discard pending i/p */ retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { MUTEX_UNLOCK(mutex); return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { /* If it's not a 'write' to rig or a Morse command, there must be data. */ if ((*cmd != '*') && (*cmd != '/')) { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 1\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; } MUTEX_UNLOCK(mutex); return RIG_OK; /* normal exit if write, but no read */ } #ifdef TT565_TIME ft1 = tt565_timenow(); #endif *data_len = data_len_init; /* restore orig. buffer length */ read_string(rp, (unsigned char *) data, *data_len, EOM, strlen(EOM), 0, 1); *data_len = strlen(data); rig_debug(RIG_DEBUG_ERR, "%s: data_len = %d\n", __func__, *data_len); if (!strncmp(data, "Z!", 2)) // command unrecognized?? { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 2\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; // what is a better error return? } /* XX and ?V are oddball commands. Thanks, Ten-Tec! */ if (!strncmp(cmd, "XX", 2)) // Was it a firmware reset cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // Then we accept the response. } if (!strncmp(cmd, "?V", 2)) // Was it a read firmware version cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // ditto } if (cmd[0] != '?') // was this a read cmd? { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 3\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; // No, but it should have been! } else // Yes, it was a 'read', phew! { if (strncmp(data + 1, cmd + 1, cmd_len - 2) == 0) //response matches cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // all is well, normal exit } else { /* The command read back does not match the command that was written. We report the problem if debugging, and issue another read in hopes of eventual success. */ rig_debug(RIG_DEBUG_WARN, "** retry after delay (io=%d, retry=%d) **\n", passcount, itry); *data_len = data_len_init; /* restore orig. buffer length */ read_string(rp, (unsigned char *) data, *data_len, EOM, strlen(EOM), 0, 1); // purge the input stream... continue; // now go retry the full command } } #ifdef TT565_TIME ft2 = tt565_timenow(); if (*data_len == -RIG_ETIMEOUT) rig_debug(RIG_DEBUG_ERR, "Timeout %d: Elapsed = %f secs.\n", itry, ft2 - ft1); else rig_debug(RIG_DEBUG_ERR, "Other Error #%d, itry=%d: Elapsed = %f secs.\n", *data_len, itry, ft2 - ft1); #endif } /* end of itry loop */ rig_debug(RIG_DEBUG_ERR, "** Ran out of retries io=%d **\n", passcount); MUTEX_UNLOCK(mutex); return -RIG_ETIMEOUT; } /** * \param rig * \returns RIG_OK or < 0 * \brief Basically, it just sets up *priv */ int tt565_init(RIG *rig) { struct tt565_priv_data *priv; STATE(rig)->priv = (struct tt565_priv_data *)calloc(1, sizeof( struct tt565_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } /* no memory available */ priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt565_priv_data)); priv->ch = 0; /* set arbitrary initial status */ priv->vfo_curr = RIG_VFO_A; return RIG_OK; } int tt565_close(RIG *rig) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->threadrun = 0; pthread_join(priv->threadid, NULL); return RIG_OK; } /** * \param rig * \brief tt565_cleanup routine * * the serial port is closed by the frontend */ int tt565_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } static void *read_device(void *p) { RIG *rig = p; struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->threadrun = 1; while (priv->threadrun) { tt565_get_freq(rig, RIG_VFO_A, &priv->freqA); tt565_get_mode(rig, RIG_VFO_A, &priv->mode, &priv->width); tt565_get_freq(rig, RIG_VFO_B, &priv->freqB); tt565_get_split_vfo(rig, RIG_VFO_A, &priv->tx_vfo, &priv->split); hl_usleep(100 * 1000); } return NULL; } static void start_thread(RIG *rig) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; pthread_attr_t attr; int ret; pthread_attr_init(&attr); ret = pthread_create(&priv->threadid, &attr, read_device, rig); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Orion unable to start thread\n", __func__); } } /** * \param rig * \brief tt565_open routine * * Open the rig - check f * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. irmware version issues */ int tt565_open(RIG *rig) { cal_table_t cal1 = TT565_STR_CAL_V1, cal2 = TT565_STR_CAL_V2; char *buf; /* Detect version 1 or version 2 firmware. V2 is default. */ /* The only difference for us is the S-meter cal table */ /* Get Orion's Version string (?V command response) */ buf = (char *)tt565_get_info(rig); /* Is Orion firmware version 1.* or 2.*? */ if (!strstr(buf, "1.")) { /* Not v1 means probably v2 */ memcpy(&STATE(rig)->str_cal, &cal2, sizeof(cal_table_t)); } else { memcpy(&STATE(rig)->str_cal, &cal1, sizeof(cal_table_t)); } start_thread(rig); return RIG_OK; } /** * \param rig * \param vfo RIG_VFO_MAIN or RIG_VFO_SUB * \returns 'M' or 'S' for main or subreceiver or <0 error * \brief vfo must be RIG_VFO_MAIN or RIG_VFO_SUB * * Note that Orion's "VFO"s are supposed to be logically independent * of the main/sub receiver selection. (In reality, they are not quite * independent.) */ static char which_receiver(const RIG *rig, vfo_t vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MAIN: return 'M'; case RIG_VFO_SUB: return 'S'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported Receiver %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } /** * \param rig * \param vfo RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE * \returns 'A' or 'B' or 'N' for VFO A, B, or null VFO, or <0 error * \brief vfo must be RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE. */ static char which_vfo(const RIG *rig, vfo_t vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: return 'A'; case RIG_VFO_B: return 'B'; case RIG_VFO_NONE: return 'N'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } /** * \param rig must != NULL * \param vfo RIG_VFO_A or RIG_VFO_B * \param freq * \brief Set a frequency into the specified VFO * * assumes STATE(rig)->priv!=NULL * \n assumes priv->mode in AM,CW,LSB or USB. */ int tt565_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval, i, in_range; freq_range_t this_range; char cmdbuf[TT565_BUFSIZE]; /* Check for valid frequency request. * Find freq range that includes current request and * matches the VFO A/B setting. c.f. rig_get_range(). * Recall VFOA = ham only, VFOB = gen coverage for Hamlib. * (We assume VFOA = Main RXTX and VFOB = Sub RX.) * If outside range, return RIG_ERJECTED for compatibility vs icom.c etc. */ in_range = FALSE; for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { this_range = STATE(rig)->rx_range_list[i]; if (this_range.startf == 0 && this_range.endf == 0) { break; /* have come to early end of range list */ } /* We don't care about mode setting, but vfo must match. */ if (freq >= this_range.startf && freq <= this_range.endf && (this_range.vfo == STATE(rig)->current_vfo)) { in_range = TRUE; break; } } if (!in_range) { return -RIG_ERJCTED; } /* Sorry, invalid freq request */ #ifdef TT565_ASCII_FREQ /* Use ASCII mode to set frequencies */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*%cF%"PRIll EOM, which_vfo(rig, vfo), (int64_t)freq); #else /* Use binary mode */ /* Set frequency using Orion's binary mode (short) sequence. The short sequence transfers faster and may require less Orion firmware effort, but some bugs are reported. */ /* Construct command packet by brute force. */ unsigned int myfreq; myfreq = freq; cmdbuf[0] = '*'; cmdbuf[1] = which_vfo(rig, vfo); cmdbuf[2] = (myfreq & 0xff000000) >> 24; cmdbuf[3] = (myfreq & 0x00ff0000) >> 16; cmdbuf[4] = (myfreq & 0x0000ff00) >> 8; cmdbuf[5] = myfreq & 0x000000ff; cmdbuf[6] = '\r'; /* i.e. EOM */ cmdbuf[7] = 0; #endif retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); if (retval == RIG_OK) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_A) { priv->freqA = freq; } else if (vfo == RIG_VFO_B) { priv->freqB = freq; } } return retval; } /** * \param rig must != NULL * \param vfo RIG_VFO_A or RIG_VFO_B * \param freq must != NULL * \brief Get the frequency currently set in the specified VFO (A or B) * * Performs query on physical rig */ int tt565_get_freq_cache(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { *freq = priv->freqB; } else { *freq = priv->freqA; } return RIG_OK; } int tt565_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; unsigned int binf; #ifdef TT565_ASCII_FREQ /* use ASCII mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?%cF" EOM, which_vfo(rig, vfo)); #else /* Get freq with Orion binary mode short sequence. */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); #endif resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } #ifdef TT565_ASCII_FREQ respbuf[12] = '\0'; sscanf(respbuf + 3, "%8u", &binf); *freq = (freq_t) binf; #else /* Test for valid binary mode return. */ if (respbuf[1] != which_vfo(rig, vfo) || resp_len <= 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } /* Convert binary to integer, endedness independent */ binf = (unsigned char)respbuf[2] << 24 | (unsigned char)respbuf[3] << 16 | (unsigned char)respbuf[4] << 8 | (unsigned char)respbuf[5]; *freq = (freq_t) binf; #endif return RIG_OK; } /** * \param rig must != NULL * \param vfo RIG_VFO_MAIN or RIG_VFO_SUB * \returns RIG_OK or < 0 * \brief set RIG_VFO_CURR and send info to physical rig. * * Places Orion into Main or Sub Rx active state */ int tt565_set_vfo(RIG *rig, vfo_t vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { return RIG_OK; } if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) { char vfobuf[TT565_BUFSIZE]; /* Select Sub or Main RX */ SNPRINTF(vfobuf, sizeof(vfobuf), "*K%c" EOM, vfo == RIG_VFO_SUB ? 'S' : 'M'); return tt565_transaction(rig, vfobuf, strlen(vfobuf), NULL, NULL); } priv->vfo_curr = vfo; return RIG_OK; } /** * \param rig must != NULL * \param vfo Set = stored state of current VFO state * \returns RIG_OK */ int tt565_get_vfo(RIG *rig, vfo_t *vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *vfo = priv->vfo_curr; return RIG_OK; } /** * \param rig must != NULL * \param vfo Rx vfo specifier token * \param split * \param tx_vfo Tx vfo specifier token * \returns RIG_OK or < 0 * \brief Set split operating mode * * Sets Main Rx to "vfo"( A or B) , Main Tx to "tx_vfo" (A, B, or N). * \n Sub Rx is set to "None". That should be fixed! */ int tt565_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*KV%c%c%c" EOM, which_vfo(rig, vfo), 'N', /* FIXME */ which_vfo(rig, RIG_SPLIT_ON == split ? tx_vfo : vfo)); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param c * \returns RIG_VFO_x, x= A, B, or NONE * \brief Translate an Orion command character to internal token form. */ static vfo_t tt2vfo(char c) { switch (c) { case 'A': return RIG_VFO_A; case 'B': return RIG_VFO_B; case 'N': return RIG_VFO_NONE; } return RIG_VFO_NONE; } /** * \param rig must != NULL * \param vfo * \param split Returned with RIG_SPLIT_ON if Tx <> Rx vfo, .._OFF otherwise * \param tx_vfo Returned RIG_VFO_x, signifying selected Tx vfo * \returns RIG_OK or < 0 * \brief Get the current split status and Tx vfo selection. */ int tt565_get_split_vfo_cache(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = priv->tx_vfo; return RIG_OK; } int tt565_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; char ttreceiver; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?KV" EOM); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[2] != 'V' || resp_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } ttreceiver = vfo == RIG_VFO_SUB ? respbuf[4] : respbuf[3]; *tx_vfo = tt2vfo(respbuf[5]); *split = ttreceiver == respbuf[5] ? RIG_SPLIT_OFF : RIG_SPLIT_ON; priv->tx_vfo = *tx_vfo; priv->split = *split; return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param mode * \param width passband in Hz or = RIG_PASSBAND_NORMAL (=0) which gives a nominal value * \brief Set operating mode to RIG_MODE_x with indicated passband width. * * Supported modes x= USB, LSB, CW, CWR, AM, FM, RTTY * \n This applies to currently selected receiver (Main Rx=Tx or Sub Rx) * \sa tt565_set_vfo * * \remarks Note widespread confusion between "VFO" and "Receiver". The Orion * has VFOs A and B which may be mapped to Main and Sub Receivers independently. * But Hamlib may have different ideas! */ int tt565_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; char ttmode, ttreceiver; int retval; char mdbuf[TT565_BUFSIZE]; switch (mode) { case RIG_MODE_USB: ttmode = TT565_USB; break; case RIG_MODE_LSB: ttmode = TT565_LSB; break; case RIG_MODE_CW: ttmode = TT565_CW; break; case RIG_MODE_CWR: ttmode = TT565_CWR; break; case RIG_MODE_AM: ttmode = TT565_AM; break; case RIG_MODE_FM: ttmode = TT565_FM; break; case RIG_MODE_RTTY: ttmode = TT565_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } ttreceiver = which_receiver(rig, vfo); if (rig->caps->rig_model == RIG_MODEL_TT599) { // Additional R%CF0 puts bandwidth control back to bandwidth knob SNPRINTF(mdbuf, sizeof(mdbuf), "*R%cM%c" EOM "*R%cF%d" EOM "R%cF0" EOM, ttreceiver, ttmode, ttreceiver, (int)width, ttreceiver ); } else { SNPRINTF(mdbuf, sizeof(mdbuf), "*R%cM%c" EOM "*R%cF%d" EOM, ttreceiver, ttmode, ttreceiver, (int)width ); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, strlen(mdbuf)); priv->mode = mode; priv->width = width; return retval; } /** * \param rig must != NULL * \param vfo * \param mode Receives current mode setting, must be != NULL * \param width Receives current bandwidth setting, must be != NULL * \returns RIG_OK or < 0 * \brief Get op. mode and bandwidth for selected vfo * * \remarks Confusion of VFO and Main/Sub TRx/Rx. See tt565_set_mode. */ int tt565_get_mode_cache(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *mode = priv->mode; *width = priv->width; return RIG_OK; } int tt565_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; char ttmode, ttreceiver; int retry; int timeout; int widthOld = CACHE(rig)->widthMainA; struct rig_state *rs = STATE(rig); ttreceiver = which_receiver(rig, vfo); /* Query mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cM" EOM, ttreceiver); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tt565_transaction failed\n", __func__); return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'M' || resp_len <= 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } ttmode = respbuf[4]; switch (ttmode) { case TT565_USB: *mode = RIG_MODE_USB; break; case TT565_LSB: *mode = RIG_MODE_LSB; break; case TT565_CW: *mode = RIG_MODE_CW; break; case TT565_CWR: *mode = RIG_MODE_CWR; break; case TT565_AM: *mode = RIG_MODE_AM; break; case TT565_FM: *mode = RIG_MODE_FM; break; case TT565_RTTY: *mode = RIG_MODE_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ // since this fails at 80ms sometimes we won't retry and will reduce the timeout // Normally this comes back in about 30ms retry = rs->retry; timeout = rs->timeout; rs->retry = 0; rs->timeout = 100; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cF" EOM, ttreceiver); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); rs->retry = retry; rs->timeout = timeout; if (retval != RIG_OK) { // if the width call fails we will just reuse the old width *width = widthOld; return RIG_OK; } if (respbuf[1] != 'R' || respbuf[3] != 'F' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *width = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param ts Tuning Step, Hz * \returns RIG_OK or < 0 * \brief Set Tuning Step for VFO A or B. */ int tt565_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cI%d" EOM, which_receiver(rig, vfo), (int)ts); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param ts Receives Tuning Step, Hz * \returns RIG_OK or < 0 * \brief Get Tuning Step for VFO A or B. */ int tt565_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cI" EOM, which_receiver(rig, vfo)); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'I' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *ts = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param rit Rx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Set Rx incremental tuning * Note: command rit != 0 ==> rit "on"; rit == 0 ==> rit "off" */ int tt565_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cR%d" EOM, which_receiver(rig, vfo), (int)rit); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param rit Receives Rx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Get Rx incremental tuning */ int tt565_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cR" EOM, which_receiver(rig, vfo)); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'R' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *rit = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param xit Tx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Set Tx incremental tuning (Main TRx only) * Note: command xit != 0 ==> xit "on"; xit == 0 ==> xit "off" */ int tt565_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int retval; char cmdbuf[TT565_BUFSIZE]; /* Sub receiver does not contain an XIT setting */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cX%d" EOM, 'M', (int)xit); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param xit Receives Tx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Get Tx incremental tuning (Main TRx only) */ int tt565_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cX" EOM, 'M'); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'X' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *xit = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param ptt RIG_PTT_ON or RIG_PTT_OFF * \returns RIG_OK or < 0 * \brief Set push to talk (Tx on/off) */ int tt565_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; int retval = write_block(RIGPORT(rig), (unsigned char *)(ptt == RIG_PTT_ON ? "*TK" EOM : "*TU" EOM), 4); if (retval == RIG_OK) { priv->ptt = ptt; } return retval; } /** * \param rig must != NULL * \param vfo * \param ptt Receives RIG_PTT_ON or RIG_PTT_OFF * \returns RIG_OK or < 0 * \brief Get push to talk (Tx on/off) */ int tt565_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *ptt = priv->ptt; return RIG_OK; } /** * \param rig must != NULL * \param reset (not used) * \returns RIG_OK or < 0 * \brief Restart Orion firmware * * Sends an "X" command and listens for reply = "ORION START". This only * seems to test for healthy connection to the firmware. There is no effect * on Orion's state, AFAIK. */ int tt565_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[TT565_BUFSIZE]; if (reset == RIG_RESET_NONE) { return RIG_OK; } /* No operation requested. */ reset_len = sizeof(reset_buf); retval = tt565_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "ORION START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /** * \param rig must != NULL * \returns firmware identification string or NULL * \brief Get firmware identification, e.g., "Version 1.372" * * Re-entrancy issue (what else is new?) */ const char *tt565_get_info(RIG *rig) { static char buf[TT565_BUFSIZE]; /* FIXME: reentrancy */ int firmware_len, retval, i; firmware_len = sizeof(buf); retval = tt565_transaction(rig, "?V" EOM, 3, buf, &firmware_len); if (retval != RIG_OK || firmware_len < 8) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); buf[0] = '\0'; return buf; } buf[firmware_len] = '\0'; /* filter out any non-graphic characters */ for (i = 0; i < strlen(buf); i++) if (!isgraph((int)buf[i])) { buf[i] = ' '; } // bad chars -> spaces return buf; } /** * \param rig must != NULL * \param vfo * \param level A level id token, e.g. RIG_LEVEL_AF * \param val Value for the level, on a scale or via a token * \returns RIG_OK or < 0 * \brief Sets any of Orion's "Level" adjustments * * Unfortunately, "val" type is not well defined. Sometimes it is a float (AF gain), * an integer (RF Atten.), or an enum (RIG_AGC_FAST)... * * Supported Levels and Units * \n -RIG_LEVEL_RFPOWER, float 0.0 - 1.0 * \n -RIG_LEVEL_AGC, int RIG_AGC_x, x= OFF, FAST, MEDIUM, SLOW, USER * \n -RIG_LEVEL_AF, float 0.0 - 1.0 * \n -RIG_LEVEL_IF, passband tuning, int Hz * \n -RIG_LEVEL_RF, IF gain (!), float 0.0 - 1.0 * \n -RIG_LEVEL_ATT, Atten. setting, int dB (we pick 0, 6, 12, or 18 dB) * \n -RIG_LEVEL_PREAMP, Preamp on/off, 0-1 (main Rx only) * \n -RIG_LEVEL_SQL, squelch, float 0.0 - 1.0 * \n -RIG_LEVEL_MICGAIN, float 0.0 - 1.0 * \n -RIG_LEVEL_COMP, speech compression, float 0.0 - 1.0 * \n -RIG_LEVEL_CWPITCH, int Hz * \n -RIG_LEVEL_KEYSPD, int wpm * \n -RIG_LEVEL_NR, noise reduction/blank, float 0.0 - 1.0 * \n -RIG_LEVEL_VOXDELAY, vox delay, float x 1/10 second * \n -RIG_LEVEL_VOXGAIN, float 0.0 - 1.0 * \n -RIG_LEVEL_ANTIVOX, float 0.0 - 1.0 * * \n FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int tt565_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, ii; char cmdbuf[TT565_BUFSIZE], cc; switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TP%d" EOM, (int)(val.f * 100)); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: cc = 'O'; break; case RIG_AGC_FAST: cc = 'F'; break; case RIG_AGC_MEDIUM: cc = 'M'; break; case RIG_AGC_SLOW: cc = 'S'; break; case RIG_AGC_USER: cc = 'P'; break; default: cc = 'M'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cA%c" EOM, which_receiver(rig, vfo), cc); break; case RIG_LEVEL_AF: /* AF Gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*U%c%d" EOM, which_receiver(rig, vfo), (int)(val.f * 255)); break; case RIG_LEVEL_IF: /* This is passband tuning int Hz */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cP%d" EOM, which_receiver(rig, vfo), val.i); break; case RIG_LEVEL_RF: /* This is IF Gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cG%d" EOM, which_receiver(rig, vfo), (int)(val.f * 100)); break; case RIG_LEVEL_ATT: /* RF Attenuator, int dB */ ii = -1; /* Request 0-5 dB -> 0, 6-11 dB -> 6, etc. */ while (rig->caps->attenuator[++ii] != RIG_DBLST_END) { if (rig->caps->attenuator[ii] > val.i) { break; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cT%d" EOM, which_receiver(rig, vfo), ii); break; case RIG_LEVEL_PREAMP: /* Sub receiver does not contain a Preamp */ if (which_receiver(rig, vfo) == 'S') { return -RIG_EINVAL; } /* RF Preamp (main Rx), int 0 or 1 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*RME%d" EOM, val.i == 0 ? 0 : 1); break; case RIG_LEVEL_SQL: /* Squelch level, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cS%d" EOM, which_receiver(rig, vfo), (int)((val.f * 127) - 127)); break; case RIG_LEVEL_MICGAIN: /* Mic gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TM%d" EOM, (int)(val.f * 100)); break; case RIG_LEVEL_COMP: /* Speech Processor, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TS%d" EOM, (int)(val.f * 9)); break; case RIG_LEVEL_CWPITCH: /* "CWPITCH" is the "Tone" button on the Orion. Manual menu adjustment works down to 100 Hz, but not via computer. int Hz. */ if (val.i > TT565_TONE_MAX) { val.i = TT565_TONE_MAX; } else if (val.i < TT565_TONE_MIN) { val.i = TT565_TONE_MIN; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*CT%d" EOM, val.i); break; case RIG_LEVEL_KEYSPD: /* Keyer speed setting does not imply Keyer = "on". That is a command which should be a hamlib function, but is not. Keyer speed determines the rate of computer sent CW also. */ if (val.i > TT565_CW_MAX) { val.i = TT565_CW_MAX; } else if (val.i < TT565_CW_MIN) { val.i = TT565_CW_MIN; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*CS%d" EOM, val.i); break; case RIG_LEVEL_NR: if (rig->caps->rig_model == RIG_MODEL_TT599) { ii = (int)(val.f * 10); if (ii > 9) { ii = 9; } // cannot set NR level 10 apparently SNPRINTF(cmdbuf, sizeof(cmdbuf), "*RMNN%c" EOM, ii); } else { /* Noise Reduction (blanking) Float 0.0 - 1.0 For some reason NB setting is supported in 1.372, but NR, NOTCH, and AN are not. FOR NOW -- RIG_LEVEL_NR controls the Orion NB setting */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cNB%d" EOM, which_receiver(rig, vfo), (int)(val.f * 9)); } break; case RIG_LEVEL_VOXDELAY: /* VOX delay, float tenths of seconds */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TH%4.2f" EOM, 0.1 * val.f); break; case RIG_LEVEL_VOXGAIN: /* Float, 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TG%d" EOM, (int)(100.0 * val.f)); break; case RIG_LEVEL_ANTIVOX: /* Float, 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TA%d" EOM, (int)(100.0 * val.f)); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must be != NULL * \param vfo * \param level identifier for level of interest * \param val Receives level's value, must != NULL * \brief Get the current value of an Orion "level" * * \sa tt565_get_level * Supported rx levels: * \n -RIG_LEVEL_SWR * \n -RIG_LEVEL_RAWSTR, int raw rx signal strength (rig units) * \n -RIG_LEVEL_RFPOWER * \n -RIG_LEVEL_AGC * \n -RIG_LEVEL_AF * \n -RIG_LEVEL_IF * \n -RIG_LEVEL_RF * \n -RIG_LEVEL_ATT * \n -RIG_LEVEL_PREAMP * \n -RIG_LEVEL_SQL * \n -RIG_LEVEL_MICGAIN * \n -RIG_LEVEL_COMP * \n -RIG_LEVEL_CWPITCH * \n -RIG_LEVEL_KEYSPED * \n -RIG_LEVEL_NR * \n -RIG_LEVEL_VOX * \n -RIG_LEVEL_VOXGAIN * \n -RIG_LEVEL_ANTIVOX * * (RIG_LEVEL_STRENGTH, int calibrated signal strength (dB, S9 = 0) is * handled in settings.c) */ int tt565_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char cmdbuf[TT565_BUFSIZE], lvlbuf[TT565_BUFSIZE]; /* Optimize: sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_SWR: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_TT599) { /* in Xmit, response is @STF99R10 99 watts forward,1.0 watt reflected uu = fwd watts vv = rev watts x 10 in Rcv, response is @SRM16 Indicates 16 dbm uuu = 000-100 (apx) Main S meter */ if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'T') { double fwd, ref; ref = atof(strchr(lvlbuf + 2, 'R') + 1) / 10.0; /* reflected power */ fwd = atof(strchr(lvlbuf + 2, 'F') + 1); /* forward power */ if (fwd == 0.0) { val->f = 0.0; /* no forward power */ } else if (fwd == ref) /* too high SWR */ { val->f = 9.99; } else { val->f = (1 + sqrt(ref / fwd)) / (1 - sqrt(ref / fwd)); /* calculate SWR */ } if (val->f < 1.0) { val->f = 9.99; } /* high VSWR */ } else { val->f = 0.0; } /* SWR in Receive = 0.0 */ } else { /* in Xmit, response is @STFuuuRvvvSwww (or ...Swwww) uuu = 000-100 (apx) fwd watts vvv = 000-100 rev watts www = 256-999 256 * VSWR in Rcv, response is @SRMuuuSvvv uuu = 000-100 (apx) Main S meter vvv = 000-100 (apx) Sub S meter */ if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'T') { val->f = atof(strchr(lvlbuf + 5, 'S') + 1) / 256.0; if (val->f < 1.0) { val->f = 9.99; } /* high VSWR */ } else { val->f = 0.0; } /* SWR in Receive = 0.0 */ } break; case RIG_LEVEL_RAWSTR: /* provide uncalibrated raw strength, int */ /* NB: RIG_LEVEL_STRENGTH is handled in the frontend */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'R') { char *raw_field; /* response is @SRMnnnSnnn, incl main & sub rx. */ /* TT's spec indicates variable length data 1-3 digits */ if (vfo == RIG_VFO_SUB) /* look at sub rx info */ { raw_field = strchr(lvlbuf + 3, 'S') + 1; /* length may vary */ } else /* look at main rx info */ { char *raw_field2; raw_field = lvlbuf + 4; raw_field2 = strchr(raw_field, 'S'); /* position may vary */ if (raw_field2) { *raw_field2 = '\0'; } /* valid string */ } val->i = atoi(raw_field); /* get raw value */ } else { val->i = 0; } /* S-meter in xmit => 0 */ break; case RIG_LEVEL_RFPOWER: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TP" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'P' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 100.0; break; case RIG_LEVEL_AGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cA" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'A' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[4]) { case 'O': val->i = RIG_AGC_OFF; break; case 'F': val->i = RIG_AGC_FAST; break; case 'M': val->i = RIG_AGC_MEDIUM; break; case 'S': val->i = RIG_AGC_SLOW; break; case 'P': val->i = RIG_AGC_USER; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?U%c" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'U' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 255.0; break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cP" EOM, /* passband tuning */ which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'P' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 4); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cG" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'G' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 4) / 100.0; break; case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cT" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'T' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[4] == '0') { val->i = 0; } else { val->i = rig->caps->attenuator[lvlbuf[4] - '1']; } break; case RIG_LEVEL_PREAMP: /* Sub receiver does not contain a Preamp */ if (which_receiver(rig, vfo) == 'S') { val->i = 0; break; } lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?RME" EOM, 5, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'E' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = lvlbuf[4] == '0' ? 0 : rig->caps->preamp[0]; break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cS" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (atof(lvlbuf + 4) + 127.0) / 127.0; break; case RIG_LEVEL_MICGAIN: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TM" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'M' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 100.0; break; case RIG_LEVEL_COMP: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'S' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 9.0; break; case RIG_LEVEL_CWPITCH: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?CT" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'C' || lvlbuf[2] != 'T' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_KEYSPD: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?CS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'C' || lvlbuf[2] != 'S' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_NR: /* RIG_LEVEL_NR controls Orion NB setting - TEMP */ if (rig->caps->rig_model == RIG_MODEL_TT599) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "?RMNN" EOM) } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cNB" EOM, which_receiver(rig, vfo)); } lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvl_len < 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } sscanf(lvlbuf + 5, "%f", &val->f); val->f /= 10.0; break; case RIG_LEVEL_VOXDELAY: /* =VOXDELAY, tenths of secs. */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TH" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'H' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 10.0 * atof(lvlbuf + 3); break; case RIG_LEVEL_VOXGAIN: /* Float, 0.0 - 1.0 */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TG" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'G' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 0.01 * atof(lvlbuf + 3); break; case RIG_LEVEL_ANTIVOX: /* Float, 0.0 - 1.0 */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TA" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'A' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 0.01 * atof(lvlbuf + 3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /** * \param rig !=NULL * \param vfo * \param ch Channel number * \returns RIG_OK * \brief This only sets the current memory channel locally. No Orion I/O. * * Use RIG_OP_TO_VFO and RIG_OP_FROM_VFO to get/store a freq in the channel. * \sa tt565_vfo_op */ int tt565_set_mem(RIG *rig, vfo_t vfo, int ch) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->ch = ch; /* See RIG_OP_TO/FROM_VFO */ return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ch to receive the current channel number * \returns RIG_OK * \brief Get the current memory channel number (only) */ int tt565_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *ch = priv->ch; return RIG_OK; } /** * \param rig != NULL * \param vfo * \param op Operation to perform, a RIG_OP token * \returns RIG_OK or < 0 * \brief perform a RIG_OP operation * * Supported operations: * \n RIG_OP_TO_VFO memory channel to VFO (includes bw, mode, etc) * \n RIG_OP_FROM_VFO stores VFO (& other data) to memory channel * \n RIG_OP_TUNE initiates a tuner cycle (if tuner present) MAY BE BROKEN * \n RIG_OP_UP increment VFO freq by tuning step * \n RIG_OP_DOWN decrement VFO freq by tuning step */ int tt565_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; char cmdbuf[TT565_BUFSIZE]; int retval; switch (op) { case RIG_OP_TO_VFO: case RIG_OP_FROM_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*K%c%c%d" EOM, op == RIG_OP_TO_VFO ? 'R' : 'W', which_vfo(rig, vfo), priv->ch); break; case RIG_OP_TUNE: strcpy(cmdbuf, "*TTT" EOM); break; case RIG_OP_UP: case RIG_OP_DOWN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*%cS%c1" EOM, which_vfo(rig, vfo), op == RIG_OP_UP ? '+' : '-'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported op %d\n", __func__, op); return -RIG_EINVAL; } retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig * \param vfo * \param msg A message string (<= 20 char) * \returns RIG_OK * \brief Send a string as morse characters * * Orion keyer must be on for morse, but we do not have a "keyer on" function in * hamlib (yet). Keyer will be forced on. * * Orion can queue up to about 20 characters. * We could batch a longer message into 20 char chunks, but there is no * simple way to tell if message has completed. We could calculate a * duration based on keyer speed and the text that was sent, but * what we really need is a handshake for "message complete". * Without it, you can't easily use the Orion as a code practice machine. * For now, we let the user do the batching. * Note that rig panel is locked up for duration of message. */ int tt565_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int msg_len, retval, ic; char morsecmd[8]; static int keyer_set = FALSE; /*Shouldn't be here!*/ /* Force keyer on. */ if (!keyer_set) { retval = tt565_transaction(rig, "*CK1" EOM, 5, NULL, NULL); if (retval != RIG_OK) { return retval; } keyer_set = TRUE; hl_usleep(100000); /* 100 msec - guess */ } msg_len = strlen(msg); if (msg_len > 20) { msg_len = 20; } /* sanity limit 20 chars */ for (ic = 0; ic < msg_len; ic++) { SNPRINTF(morsecmd, sizeof(morsecmd), "/%c" EOM, msg[ic]); retval = tt565_transaction(rig, morsecmd, strlen(morsecmd), NULL, NULL); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /** * \param rig != NULL * \param vfo * \param func Identifier for function to be performed * \param status data for function * \returns RIG_OK or < 0 * \brief Set an Orion "function" * * Note that vfo must == RIG_VFO_CURR * * Supported functions & data * \n RIG_FUNC_TUNER, off/on, 0/1 * \n RIG_FUNC_VOX, off/on, 0/1 * \n RIG_FUNC_LOCK, unlock/lock, 0/1 * \n RIG_FUNC_NB, off/on, 0/1 (sets Orion NB=0 or =4), compare RIG_LEVEL_NR * */ int tt565_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fcmdbuf[TT565_BUFSIZE]; int retval; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TUNER: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*TT%c" EOM, !status ? 0 : 1); break; case RIG_FUNC_VOX: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*TV%c" EOM, !status ? 0 : 1); break; case RIG_FUNC_LOCK: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*%c%c" EOM, which_vfo(rig, vfo), !status ? 'U' : 'L'); break; case RIG_FUNC_NB: /* NB "on" sets Orion NB=4; "off" -> NB=0. See also RIG_LEVEL_NR which maps to NB setting due to firmware limitation. */ SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*R%cNB%c" EOM, which_receiver(rig, vfo), !status ? '0' : '4'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /** * \param rig != NULL * \param vfo must == RIG_VFO_CURR * \param func * \param status receives result of function query * \returns RIG_OK or < 0 * \brief get state of an Orion "function" * * \sa tt565_set_func */ int tt565_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fcmdbuf[TT565_BUFSIZE], frespbuf[TT565_BUFSIZE]; int retval, fresplen; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TUNER: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?TT" EOM); break; case RIG_FUNC_VOX: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?TV" EOM); break; case RIG_FUNC_LOCK: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?%cU" EOM, which_vfo(rig, vfo)); /* needs special treatment */ fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } /* response is @AL @AU or @BL @BU */ *status = frespbuf[ 2 ] == 'L' ? 1 : 0; return RIG_OK; case RIG_FUNC_NB: /* Note NB should be a LEVEL for Orion. It is also available through LEVEL_NR */ SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?R%cNB" EOM, which_receiver(rig, vfo)); /* needs special treatment */ fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } /* response is @RxNBn, n=0--9. Return 0 iff receive NB=0 */ *status = frespbuf[ 5 ] == '0' ? 0 : 1; return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 3 ] == '1' ? 1 : 0; return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ant antenna identifier RIG_ANT_1 or RIG_ANT_2 * \returns RIG_OK or < 0 * \brief Antenna selection for Orion * * We support Ant_1 and Ant_2 for M and S receivers. * \n Note that Rx-only antenna (Ant_3?) is not supported at this time. * \n Orion command assigns MSBN (main rtx, sub rx, both, or none) to each ant, * but hamlib wants to assign an ant to rx/tx! * The efficient way would be to keep current config in rig priv area, but we will * ask the rig what its state is each time... */ int tt565_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char respbuf[TT565_BUFSIZE]; int resp_len, retval; ant_t main_ant, sub_ant; /* First, find out what antenna config is now. */ resp_len = sizeof(respbuf); retval = tt565_transaction(rig, "?KA" EOM, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (resp_len != 7 || respbuf[1] != 'K' || respbuf[2] != 'A') { rig_debug(RIG_DEBUG_ERR, "%s; tt565_set_ant: ?KA NG %s\n", __func__, respbuf); return -RIG_EPROTO; } /* respbuf="@KAxxx" * x='M'|'S'|'B'|'N'=main/sub/both/none for ants 1,2,3. * but hardware will not permit all combinations! * respbuf [3,4] can be MS, SM, BN, NB * decode to rx-centric view */ if (respbuf[3] == 'M' || respbuf[3] == 'B') { main_ant = RIG_ANT_1; } else { main_ant = RIG_ANT_2; } if (respbuf[3] == 'S' || respbuf[3] == 'B') { sub_ant = RIG_ANT_1; } else { sub_ant = RIG_ANT_2; } switch (which_receiver(rig, vfo)) { case 'M': main_ant = ant; break; case 'S': sub_ant = ant; break; default: { /* no change? */ } } /* re-encode ant. settings into command */ if (main_ant == RIG_ANT_1) { if (sub_ant == RIG_ANT_1) { respbuf[3] = 'B'; respbuf[4] = 'N'; } else { respbuf[3] = 'M'; respbuf[4] = 'S'; } } else if (sub_ant == RIG_ANT_2) { respbuf[3] = 'N'; respbuf[4] = 'B'; } else { respbuf[3] = 'S'; respbuf[4] = 'M'; } respbuf[0] = '*'; /* respbuf becomes a store command */ respbuf[5] = 'N'; /* Force no rx on Ant 3 */ respbuf[6] = EOM[0]; respbuf[7] = 0; retval = tt565_transaction(rig, respbuf, 7, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ant receives antenna identifier * \returns RIG_OK or < 0 * \brief Find what antenna is "attached" to our vfo * * \sa tt565_set_ant */ int tt565_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char respbuf[TT565_BUFSIZE]; int resp_len, retval; resp_len = sizeof(respbuf); retval = tt565_transaction(rig, "?KA" EOM, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'K' || respbuf[2] != 'A' || resp_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s; tt565_get_ant: NG %s\n", __func__, respbuf); return -RIG_EPROTO; } /* Look for first occurrence of M or S in ant 1, 2, 3 characters */ if (respbuf[3] == which_receiver(rig, vfo) || respbuf[3] == 'B') { *ant_curr = RIG_ANT_1; return RIG_OK; } if (respbuf[4] == which_receiver(rig, vfo) || respbuf[4] == 'B') { *ant_curr = RIG_ANT_2; return RIG_OK; } *ant_curr = RIG_ANT_NONE; /* ignore possible RIG_ANT_3 = rx only ant */ return RIG_OK; } /* End of orion.c */ /** @} */ hamlib-4.6.5/rigs/tentec/Makefile.in0000664000175000017500000005721615056640453012763 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tentec ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tentec_la_LIBADD = am__objects_1 = rx320.lo rx340.lo rx350.lo rx331.lo tt550.lo \ pegasus.lo argonaut.lo orion.lo jupiter.lo omnivii.lo \ paragon.lo tentec.lo tentec2.lo am_libhamlib_tentec_la_OBJECTS = $(am__objects_1) libhamlib_tentec_la_OBJECTS = $(am_libhamlib_tentec_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/argonaut.Plo ./$(DEPDIR)/jupiter.Plo \ ./$(DEPDIR)/omnivii.Plo ./$(DEPDIR)/orion.Plo \ ./$(DEPDIR)/paragon.Plo ./$(DEPDIR)/pegasus.Plo \ ./$(DEPDIR)/rx320.Plo ./$(DEPDIR)/rx331.Plo \ ./$(DEPDIR)/rx340.Plo ./$(DEPDIR)/rx350.Plo \ ./$(DEPDIR)/tentec.Plo ./$(DEPDIR)/tentec2.Plo \ ./$(DEPDIR)/tt550.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tentec_la_SOURCES) DIST_SOURCES = $(libhamlib_tentec_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TENTECSRC = rx320.c rx340.c rx350.c rx331.c rx331.h tt550.c tt550.h \ pegasus.c argonaut.c orion.c orion.h jupiter.c omnivii.c paragon.c \ tentec.c tentec.h tentec2.c tentec2.h noinst_LTLIBRARIES = libhamlib-tentec.la libhamlib_tentec_la_SOURCES = $(TENTECSRC) EXTRA_DIST = README.tentec Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tentec/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tentec/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-tentec.la: $(libhamlib_tentec_la_OBJECTS) $(libhamlib_tentec_la_DEPENDENCIES) $(EXTRA_libhamlib_tentec_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tentec_la_OBJECTS) $(libhamlib_tentec_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argonaut.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jupiter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omnivii.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orion.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paragon.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pegasus.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx320.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx331.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx340.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx350.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tentec.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tentec2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt550.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/argonaut.Plo -rm -f ./$(DEPDIR)/jupiter.Plo -rm -f ./$(DEPDIR)/omnivii.Plo -rm -f ./$(DEPDIR)/orion.Plo -rm -f ./$(DEPDIR)/paragon.Plo -rm -f ./$(DEPDIR)/pegasus.Plo -rm -f ./$(DEPDIR)/rx320.Plo -rm -f ./$(DEPDIR)/rx331.Plo -rm -f ./$(DEPDIR)/rx340.Plo -rm -f ./$(DEPDIR)/rx350.Plo -rm -f ./$(DEPDIR)/tentec.Plo -rm -f ./$(DEPDIR)/tentec2.Plo -rm -f ./$(DEPDIR)/tt550.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/argonaut.Plo -rm -f ./$(DEPDIR)/jupiter.Plo -rm -f ./$(DEPDIR)/omnivii.Plo -rm -f ./$(DEPDIR)/orion.Plo -rm -f ./$(DEPDIR)/paragon.Plo -rm -f ./$(DEPDIR)/pegasus.Plo -rm -f ./$(DEPDIR)/rx320.Plo -rm -f ./$(DEPDIR)/rx331.Plo -rm -f ./$(DEPDIR)/rx340.Plo -rm -f ./$(DEPDIR)/rx350.Plo -rm -f ./$(DEPDIR)/tentec.Plo -rm -f ./$(DEPDIR)/tentec2.Plo -rm -f ./$(DEPDIR)/tt550.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/tentec/orion.h0000664000175000017500000004712615056640443012213 /* * Hamlib TenTenc backend - TT-565 headers * Copyright (c) 2004-2011 by Stephane Fillod * Copyright (c) 2004-2011 by Martin Ewing * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup tentec_orion * @{ */ /** * \file orion.h * \brief Backend for Tentec Orion 565 / 566 * * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. */ #include #include "bandplan.h" #include "rig.h" #include "riglist.h" #include "mutex.h" #define BACKEND_VER "20240621" #define TRUE 1 #define FALSE 0 #define TT565_BUFSIZE 32 /** * \brief Memory capability * * Orion's own memory channel holds a freq, mode, and bandwidth. * May be captured from VFO A or B and applied to VFO A or B. * It cannot directly be read or written from the computer! */ #define TT565_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } static int tt565_init(RIG *rig); static int tt565_open(RIG *rig); static int tt565_close(RIG *rig); static int tt565_cleanup(RIG *rig); static int tt565_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt565_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt565_get_freq_cache(RIG *rig, vfo_t vfo, freq_t *freq); static int tt565_set_vfo(RIG *rig, vfo_t vfo); static int tt565_get_vfo(RIG *rig, vfo_t *vfo); static int tt565_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tt565_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt565_get_mode_cache(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt565_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tt565_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt565_get_split_vfo_cache(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt565_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt565_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int tt565_reset(RIG *rig, reset_t reset); static int tt565_set_mem(RIG * rig, vfo_t vfo, int ch); static int tt565_get_mem(RIG * rig, vfo_t vfo, int *ch); static int tt565_vfo_op(RIG * rig, vfo_t vfo, vfo_op_t op); static int tt565_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int tt565_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int tt565_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); static int tt565_get_rit(RIG * rig, vfo_t vfo, shortfreq_t *rit); static int tt565_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit); static int tt565_get_xit(RIG * rig, vfo_t vfo, shortfreq_t *xit); static int tt565_set_level(RIG * rig, vfo_t vfo, setting_t level, value_t val); static int tt565_get_level(RIG * rig, vfo_t vfo, setting_t level, value_t *val); static const char* tt565_get_info(RIG *rig); static int tt565_send_morse(RIG *rig, vfo_t vfo, const char *msg); static int tt565_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tt565_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int tt565_set_ant(RIG * rig, vfo_t vfo, ant_t ant, value_t option); static int tt565_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); /** \brief Orion private data */ struct tt565_priv_data { int ch; /*!< memory channel */ vfo_t vfo_curr; /*!< Currently selected VFO */ int ptt; freq_t freqA, freqB; rmode_t mode; pbwidth_t width; pthread_t threadid; split_t split; vfo_t tx_vfo; int threadrun; }; MUTEX(mutex); /** \brief Orion Supported Modes */ #define TT565_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_AM) /** \brief Orion Receiver Modes */ #define TT565_RXMODES (TT565_MODES) /** \brief Orion Supported Functions */ #define TT565_FUNCS (RIG_FUNC_LOCK|RIG_FUNC_TUNER|RIG_FUNC_VOX|RIG_FUNC_NB) /** \brief Orion Supported Levels */ #define TT565_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_SQL|RIG_LEVEL_IF| \ RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_RF|RIG_LEVEL_NR| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_COMP|RIG_LEVEL_PREAMP| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) /** \brief Orion Tx/Rx Antennas*/ #define TT565_ANTS (RIG_ANT_1|RIG_ANT_2) /** \brief Orion Rx Antennas*/ #define TT565_RXANTS (TT565_ANTS|RIG_ANT_3) /** \brief Orion Parameters */ #define TT565_PARMS (RIG_PARM_NONE) /** * \brief Orion VFOs - A and B */ #define TT565_VFO (RIG_VFO_A|RIG_VFO_B) /** * \brief Orion VFO Operations * * Allowed operations */ #define TT565_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO| \ RIG_OP_TUNE) /** * \brief S-Meter Calibration list * * List format: { hardware units, dB relative to S9} * * These alternate tables must be of equal size, because they may be * switched depending on firmware version detection. * * Note high end of scale is severely compressed in v1 * Table corrected against v 1.372, 11/2007 */ #define TT565_STR_CAL_V1 { 14, { \ { 1, -47 }, /* padding to match lengths with v2 */ \ { 10, -47 }, \ { 13, -42 }, \ { 18, -37 }, \ { 22, -32 }, \ { 27, -27 }, \ { 32, -18 }, \ { 37, -11 }, \ { 42, -4 }, \ { 47, -1 }, \ { 52, 10 }, \ { 57, 20 }, \ { 65, 30 }, \ { 74, 40 }, \ } } /** * Calibration for Version 2.062a firmware, from Rigserve project. * Again, this is approximate based on one measurement. */ #define TT565_STR_CAL_V2 { 14, { \ { 10., -48. }, /* S1 = min. indication */ \ { 24., -42. }, \ { 38., -36. }, \ { 47., -30. }, \ { 61., -24. }, \ { 70., -18. }, \ { 79., -12. }, \ { 84., -6. }, \ { 94., 0. }, /* S9 */ \ { 103., 10. }, \ { 118., 20. }, \ { 134., 30. }, \ { 147., 40. }, \ { 161., 50. }, \ } } #undef TT565_TIME /* Define to enable time checks */ #define TT565_ASCII_FREQ /* select ascii mode for vfo commands */ /* Note: Binary mode seems buggy at certain freqs like 7015679 < freq < 7015936, etc. Use ascii mode. */ /** * \brief tt565 transceiver capabilities. * * All of the Orion's personality is defined here! * * Protocol is documented at Tentec's firmware site * http://www.rfsquared.com/ */ struct rig_caps tt565_caps = { RIG_MODEL(RIG_MODEL_TT565), .model_name = "TT-565/566 Orion I/II", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, /* no delay between characters written */ .post_write_delay = 0, /* ms delay between writes DEBUGGING HERE */ .timeout = 200, /* ms */ .retry = 1, .has_get_func = TT565_FUNCS, .has_set_func = TT565_FUNCS, .has_get_level = TT565_LEVELS, .has_set_level = RIG_LEVEL_SET(TT565_LEVELS), .has_get_parm = TT565_PARMS, .has_set_parm = TT565_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END }, .attenuator = { 6, 12, 18, RIG_DBLST_END }, .max_rit = kHz(8), .max_xit = kHz(8), .max_ifshift = kHz(8), .vfo_ops = TT565_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, TT565_MEM_CAP }, }, /* Note Orion's ranges correspond to the hardware capability - same in * regions 1 and 2. Band edges (VFOA) are wider than legal bands. * VFOB is used for general coverage receive. */ .rx_range_list1 = { /* FRQ_RNG_HF(1,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS), */ {kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS}, RIG_FRNG_END, }, .tx_range_list1 = { /* FRQ_RNG_HF(1,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS), */ {kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, RIG_FRNG_END, }, .rx_range_list2 = { /* FRQ_RNG_HF(2,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS), {MHz(5.25),MHz(5.40),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, */ {kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS}, RIG_FRNG_END, }, .tx_range_list2 = { /* FRQ_RNG_HF(2,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS), {MHz(5.25),MHz(5.40),TT565_MODES,W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, */ {kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT565_RXMODES,1}, {TT565_RXMODES,10}, {TT565_RXMODES,100}, {TT565_RXMODES,kHz(1)}, {TT565_RXMODES,kHz(10)}, {TT565_RXMODES,kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* 9MHz IF filters: 15kHz, 6kHz, 2.4kHz, 1.0kHz */ /* opt: 1.8kHz, 500Hz, 250Hz */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 100}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(6)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 0}, /* 590 filters */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void*)NULL, .rig_init = tt565_init, .rig_cleanup = tt565_cleanup, .rig_open = tt565_open, .rig_close = tt565_close, .set_freq = tt565_set_freq, #if defined(HAVE_PTHREAD) .get_freq = tt565_get_freq_cache, #else .get_freq = tt565_get_freq, #endif .set_vfo = tt565_set_vfo, .get_vfo = tt565_get_vfo, .set_mode = tt565_set_mode, #if defined(HAVE_PTHREAD) .get_mode = tt565_get_mode_cache, #else .get_mode = tt565_get_mode, #endif .set_split_vfo = tt565_set_split_vfo, #if defined(HAVE_PTHREAD) .get_split_vfo = tt565_get_split_vfo_cache, #else .get_split_vfo = tt565_get_split_vfo, #endif .set_level = tt565_set_level, .get_level = tt565_get_level, .set_mem = tt565_set_mem, .get_mem = tt565_get_mem, .set_ptt = tt565_set_ptt, .get_ptt = tt565_get_ptt, .vfo_op = tt565_vfo_op, .set_ts = tt565_set_ts, .get_ts = tt565_get_ts, .set_rit = tt565_set_rit, .get_rit = tt565_get_rit, .set_xit = tt565_set_xit, .get_xit = tt565_get_xit, .reset = tt565_reset, .get_info = tt565_get_info, .send_morse = tt565_send_morse, .wait_morse = rig_wait_morse, .get_func = tt565_get_func, .set_func = tt565_set_func, .get_ant = tt565_get_ant, .set_ant = tt565_set_ant, /* V2 is default. S-Meter cal table may be changed if V1 firmware detected. */ .str_cal = TT565_STR_CAL_V2, }; /* * Eagle TT-599 share the same ability as Orion's */ #define TT599_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ /* optional */ RIG_MODE_AM|RIG_MODE_FM) #define TT599_RXMODES TT599_MODES #define TT599_FUNCS (RIG_FUNC_ANF) #define TT599_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER| \ RIG_LEVEL_NR|RIG_LEVEL_AGC| \ RIG_LEVEL_PREAMP|RIG_LEVEL_ATT) #define TT599_PARMS (RIG_PARM_NONE) #define TT599_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ } #define TT599_ANTS (RIG_ANT_1) #define TT599_RXANTS TT599_ANTS #define TT599_VFO (RIG_VFO_A|RIG_VFO_B) #define TT599_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* * Random guess, to be measured. See FAQ at http://hamlib.org */ #define TT599_STR_CAL { 3, { \ { 10., -48. }, /* S1 = min. indication */ \ { 94., 0. }, /* S9 */ \ { 161., 50. }, \ } } /** * \brief tt599 transceiver capabilities. * * All of the Eagle's personality is defined here! * * Protocol is documented in Programmers Reference Manual V1.001 at * http://www.tentec.com/index.php?id=360#down * */ struct rig_caps tt599_caps = { RIG_MODEL(RIG_MODEL_TT599), .model_name = "TT-599 Eagle", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, /* no delay between characters written */ .post_write_delay = 0, /* ms delay between writes DEBUGGING HERE */ .timeout = 2000, /* ms */ .retry = 4, .has_get_func = TT599_FUNCS, .has_set_func = TT599_FUNCS, .has_get_level = TT599_LEVELS|RIG_LEVEL_RF, .has_set_level = RIG_LEVEL_SET(TT599_LEVELS), .has_get_parm = TT599_PARMS, .has_set_parm = TT599_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 12, RIG_DBLST_END }, .max_rit = kHz(0), .max_xit = kHz(0), .max_ifshift = kHz(0), .vfo_ops = TT599_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, TT599_MEM_CAP }, }, .rx_range_list1 = { FRQ_RNG_HF(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), FRQ_RNG_6m(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), {kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), FRQ_RNG_6m(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { FRQ_RNG_HF(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), FRQ_RNG_6m(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), {MHz(5.25),MHz(5.40),TT599_RXMODES,-1,-1,RIG_VFO_N(0),TT599_RXANTS}, {kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), FRQ_RNG_6m(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), {MHz(5.25),MHz(5.40),TT599_MODES,W(5),W(100),RIG_VFO_N(0),TT599_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT599_RXMODES,1}, {TT599_RXMODES,10}, {TT599_RXMODES,100}, {TT599_RXMODES,kHz(1)}, {TT599_RXMODES,kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* 15kHz, 6kHz, 2.4kHz, 1.0kHz */ /* 9MHz IF filters: 2.4K standard */ /* optional = 300, 600, 1.8k, 6k, 15k */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 600}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 300}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(6)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 0}, /* 127 filters */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void*)NULL, .rig_init = tt565_init, .rig_cleanup = tt565_cleanup, .rig_open = tt565_open, .set_freq = tt565_set_freq, .get_freq = tt565_get_freq, .set_vfo = tt565_set_vfo, .get_vfo = tt565_get_vfo, .set_mode = tt565_set_mode, .get_mode = tt565_get_mode, .set_split_vfo = tt565_set_split_vfo, .get_split_vfo = tt565_get_split_vfo, .set_level = tt565_set_level, .get_level = tt565_get_level, .set_mem = tt565_set_mem, .get_mem = tt565_get_mem, .set_ptt = tt565_set_ptt, .get_ptt = tt565_get_ptt, .vfo_op = tt565_vfo_op, .get_info = tt565_get_info, .get_func = tt565_get_func, .set_func = tt565_set_func, .str_cal = TT599_STR_CAL, }; /* * Function definitions below */ /** \brief End of command marker */ #define EOM "\015" /* CR */ /** \brief USB Mode */ #define TT565_USB '0' /** \brief LSB Mode */ #define TT565_LSB '1' /** \brief CW normal Mode */ #define TT565_CW '2' /** \brief CW reverse Mode */ #define TT565_CWR '3' /** \brief AM Mode */ #define TT565_AM '4' /** \brief FM Mode */ #define TT565_FM '5' /** \brief RTTY Mode */ #define TT565_RTTY '6' /** \brief minimum sidetone freq., Hz */ #define TT565_TONE_MIN 300 /** \brief maximum sidetone freq., Hz */ #define TT565_TONE_MAX 1200 /** \brief minimum CW keyer rate, wpm */ #define TT565_CW_MIN 10 /** \brief maximum CW keyer rate, wpm */ #define TT565_CW_MAX 60 /** @} */ hamlib-4.6.5/rigs/tentec/tentec2.h0000664000175000017500000000401115056640443012413 /* * Hamlib Tentec backend - Argonaut, Jupiter, RX-350 header * Copyright (c) 2001-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TENTEC2_H #define _TENTEC2_H 1 #include // The include order will determine which BACKEND_VER is used // tentec.h may also be included and the last include is the BACKEND_VER used #undef BACKEND_VER #define BACKEND_VER "20191208" /* * Mem caps to be checked.. */ #define TT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ } int tentec2_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tentec2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int tentec2_set_vfo(RIG *rig, vfo_t vfo); int tentec2_get_vfo(RIG *rig, vfo_t *vfo); int tentec2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tentec2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int tentec2_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int tentec2_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int tentec2_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int tentec2_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int tentec2_reset(RIG *rig, reset_t reset); const char* tentec2_get_info(RIG *rig); #endif /* _TENTEC2_H */ hamlib-4.6.5/rigs/tentec/rx331.c0000664000175000017500000005416115056640443011735 /* * Hamlib Tentec backend - RX331 description * Copyright (c) 2010 by Berndt Josef Wulf * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "num_stdio.h" #include "rx331.h" static const struct confparams rx331_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 99, 1 } } }, { RIG_CONF_END, NULL, } }; #define RX331_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_DSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX331_FUNCS (RIG_FUNC_NB) #define RX331_LEVELS (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL| \ RIG_LEVEL_CWPITCH|RIG_LEVEL_AGC| \ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define RX331_ANTS (RIG_ANT_1) #define RX331_PARMS (RIG_PARM_NONE) #define RX331_VFO (RIG_VFO_A) #define RX331_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* TODO: levels.. */ #define RX331_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } static int rx331_init(RIG *rig); static int rx331_cleanup(RIG *rig); static int rx331_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int rx331_get_conf(RIG *rig, hamlib_token_t token, char *val); static int rx331_open(RIG *rig); static int rx331_close(RIG *rig); static int rx331_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int rx331_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int rx331_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int rx331_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int rx331_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int rx331_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int rx331_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static const char *rx331_get_info(RIG *rig); /* * RX331 receiver capabilities. * * Protocol is documented at * http://radio.tentec.com/downloads/receivers/RX331 * * TODO: from/to memory */ struct rig_caps rx331_caps = { RIG_MODEL(RIG_MODEL_RX331), .model_name = "RX-331", .mfg_name = "Ten-Tec", .version = "20200911.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = RX331_FUNCS, .has_set_func = RX331_FUNCS, .has_get_level = RX331_LEVELS, .has_set_level = RIG_LEVEL_SET(RX331_LEVELS), .has_get_parm = RX331_PARMS, .has_set_parm = RX331_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .vfo_ops = RX331_VFO_OPS, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, RX331_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(0), MHz(30), RX331_MODES, -1, -1, RX331_VFO, RX331_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(0), MHz(30), RX331_MODES, -1, -1, RX331_VFO, RX331_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX331_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX331_MODES, kHz(3.2)}, {RX331_MODES, Hz(100)}, {RX331_MODES, kHz(16)}, {RX331_MODES, 0}, RIG_FLT_END, }, .priv = (void *)NULL, .cfgparams = rx331_cfg_params, .rig_init = rx331_init, .rig_cleanup = rx331_cleanup, .rig_open = rx331_open, .rig_close = rx331_close, .set_conf = rx331_set_conf, .get_conf = rx331_get_conf, .set_freq = rx331_set_freq, .get_freq = rx331_get_freq, .set_mode = rx331_set_mode, .get_mode = rx331_get_mode, .set_level = rx331_set_level, .get_level = rx331_get_level, .vfo_op = rx331_vfo_op, .get_info = rx331_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define BUFSZ 128 #define EOM "\015" /* CR */ #define RX331_AM '1' #define RX331_FM '2' #define RX331_CW '3' #define RX331_CW1 '4' #define RX331_ISB '5' #define RX331_LSB '6' #define RX331_USB '7' #define RX331_SAM '8' #define RX331_PREAMP_OFF 0x1 #define RX331_PREAMP_ON 0x2 #define RX331_ATT_OFF 0x1 #define RX331_ATT_ON 0x3 #define RX331_AGC_FAST 0x1 #define RX331_AGC_MEDIUM 0x2 #define RX331_AGC_SLOW 0x3 #define RX331_AGC_PROG 0x4 #define REPORT_FREQ "TF"EOM #define REPORT_MODEFILTER "TDI"EOM #define REPORT_FIRM "V"EOM #define REPORT_STRENGTH "X"EOM #define REPORT_AGC "TM"EOM #define REPORT_ATT "TK"EOM #define REPORT_PREAMP "TK"EOM #define REPORT_RF "TA"EOM #define REPORT_IF "TP"EOM #define REPORT_SQL "TQ"EOM #define REPORT_CWPITCH "TB"EOM #define REPORT_NOTCHF "TN"EOM /* * rx331_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ static int rx331_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int rig_id; int retval; char str[BUFSZ]; char fmt[16]; hamlib_port_t *rp = RIGPORT(rig); const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; rig_flush(rp); num_snprintf(str, BUFSZ, "$%u%s", priv->receiver_id, cmd); retval = write_block(rp, (unsigned char *) str, strlen(str)); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, 1, 0, 1); if (retval < 0) { return retval; } SNPRINTF(fmt, sizeof(fmt) - 1, "%%i%%%ds", BUFSZ); sscanf(data + 1, fmt, &rig_id, data); if (rig_id != priv->receiver_id) { return -RIG_EPROTO; } *data_len = retval; return RIG_OK; } /* * rx331_init: * Basically, it just sets up *priv */ int rx331_init(RIG *rig) { struct rx331_priv_data *priv; STATE(rig)->priv = (struct rx331_priv_data *)calloc(1, sizeof( struct rx331_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct rx331_priv_data)); return RIG_OK; } /* * Tentec generic rx331_cleanup routine * the serial port is closed by the frontend */ int rx331_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int rx331_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int rx331_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int rx331_get_conf(RIG *rig, hamlib_token_t token, char *val) { return rx331_get_conf2(rig, token, val, 128); } // cppcheck-suppress constParameterCallback int rx331_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_close */ // cppcheck-suppress constParameterCallback int rx331_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } int rx331_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; int freq_len, retval; char freqbuf[16]; freq_len = num_snprintf(freqbuf, sizeof(freqbuf), "$%uF%.6f" EOM, priv->receiver_id, freq / 1e6); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, freq_len); return retval; } /* * rx331_get_freq * Assumes rig!=NULL, freq!=NULL */ int rx331_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[BUFSZ]; int buf_len; int retval; double f; retval = rx331_transaction(rig, REPORT_FREQ, strlen(REPORT_FREQ), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 2 || buf[0] != 'F' || num_sscanf(buf + 1, "%lf", &f) != 1) { return -RIG_EPROTO; } *freq = f * 1e6; return RIG_OK; } /* * rx331_set_mode * Assumes rig!=NULL */ int rx331_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; char dmode; int mdbuf_len, retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: dmode = RX331_USB; break; case RIG_MODE_LSB: dmode = RX331_LSB; break; case RIG_MODE_CW: dmode = RX331_CW; break; case RIG_MODE_FM: dmode = RX331_FM; break; case RIG_MODE_AM: dmode = RX331_AM; break; case RIG_MODE_AMS: dmode = RX331_SAM; break; case RIG_MODE_DSB: dmode = RX331_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * Set DETECTION MODE and IF FILTER */ mdbuf_len = num_snprintf(mdbuf, sizeof(mdbuf), "$%uD%cI%.02f" EOM, priv->receiver_id, dmode, (float)width / 1e3); } else { /* * Set DETECTION MODE */ mdbuf_len = num_snprintf(mdbuf, sizeof(mdbuf), "$%uD%c" EOM, priv->receiver_id, dmode); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, mdbuf_len); return retval; } /* * rx331_get_mode * Assumes rig!=NULL, mode!=NULL */ int rx331_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ]; int buf_len; int retval; double f; retval = rx331_transaction(rig, REPORT_MODEFILTER, strlen(REPORT_MODEFILTER), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 4 || buf[0] != 'D' || buf[2] != 'I') { return -RIG_EPROTO; } switch (buf[1]) { case RX331_USB: *mode = RIG_MODE_USB; break; case RX331_LSB: *mode = RIG_MODE_LSB; break; case RX331_CW1: case RX331_CW: *mode = RIG_MODE_CW; break; case RX331_FM: *mode = RIG_MODE_FM; break; case RX331_AM: *mode = RIG_MODE_AM; break; case RX331_SAM: *mode = RIG_MODE_AMS; break; case RX331_ISB: *mode = RIG_MODE_DSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode '%c'\n", __func__, buf[1]); return -RIG_EPROTO; } if (num_sscanf(buf + 3, "%lf", &f) != 1) { return -RIG_EPROTO; } *width = f * 1e3; return RIG_OK; } /* * rx331_set_level * Assumes rig!=NULL * cannot support PREAMP and ATT both at same time (make sense though) */ int rx331_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; int retval = RIG_OK; char cmdbuf[32]; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uK%i" EOM, priv->receiver_id, val.i ? RX331_ATT_ON : RX331_ATT_OFF); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uK%i" EOM, priv->receiver_id, val.i ? RX331_PREAMP_ON : RX331_PREAMP_OFF); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: val.i = RX331_AGC_FAST; break; case RIG_AGC_MEDIUM: val.i = RX331_AGC_MEDIUM; break; case RIG_AGC_SLOW: val.i = RX331_AGC_SLOW; break; case RIG_AGC_USER: val.i = RX331_AGC_PROG; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %d\n", __func__, val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uM%i" EOM, priv->receiver_id, val.i); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uA%d" EOM, priv->receiver_id, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uQ%d" EOM, priv->receiver_id, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_NOTCHF: num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uN%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; case RIG_LEVEL_IF: num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uP%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; case RIG_LEVEL_CWPITCH: /* only in CW mode */ num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uB%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); return retval; } /* * rx331_get_level * Assumes rig!=NULL, val!=NULL */ int rx331_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; double f; char lvlbuf[BUFSZ]; switch (level) { case RIG_LEVEL_STRENGTH: retval = rx331_transaction(rig, REPORT_STRENGTH, strlen(REPORT_STRENGTH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 2 || lvlbuf[0] != 'X') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } // Range is 0-120 covering the 120dB range of the receiver if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } val->i = val->i - 120; break; case RIG_LEVEL_AGC: retval = rx331_transaction(rig, REPORT_AGC, strlen(REPORT_AGC), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'M') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } switch (atoi(lvlbuf + 1)) { case RX331_AGC_FAST: val->i = RIG_AGC_FAST; break; case RX331_AGC_MEDIUM: val->i = RIG_AGC_MEDIUM; break; case RX331_AGC_SLOW: val->i = RIG_AGC_SLOW; break; case RX331_AGC_PROG: val->i = RIG_AGC_USER; break; default: rig_debug(RIG_DEBUG_ERR, "%s:Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } break; case RIG_LEVEL_ATT: retval = rx331_transaction(rig, REPORT_ATT, strlen(REPORT_ATT), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'K') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%i", &val->i) != 1) { return -RIG_EPROTO; } val->i = (val->i == RX331_ATT_ON); break; case RIG_LEVEL_PREAMP: retval = rx331_transaction(rig, REPORT_PREAMP, strlen(REPORT_PREAMP), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'K') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%i", &val->i) != 1) { return -RIG_EPROTO; } val->i = (val->i == RX331_PREAMP_ON); break; case RIG_LEVEL_RF: retval = rx331_transaction(rig, REPORT_RF, strlen(REPORT_RF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'A') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } f = val->i / 120.0; val->f = 1.0 - f; break; case RIG_LEVEL_IF: retval = rx331_transaction(rig, REPORT_IF, strlen(REPORT_IF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'P') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = (int)f; break; case RIG_LEVEL_SQL: retval = rx331_transaction(rig, REPORT_SQL, strlen(REPORT_SQL), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'Q') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } f = val->i / 120.0; val->f = 1.0 - f; break; case RIG_LEVEL_CWPITCH: retval = rx331_transaction(rig, REPORT_CWPITCH, strlen(REPORT_CWPITCH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'B') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = f; break; case RIG_LEVEL_NOTCHF: retval = rx331_transaction(rig, REPORT_NOTCHF, strlen(REPORT_NOTCHF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'N') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * rx331_vfo_op * Assumes rig!=NULL */ int rx331_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { return -RIG_ENIMPL; } /* * rx331_get_info * Assumes rig!=NULL */ const char *rx331_get_info(RIG *rig) { static char buf[BUFSZ]; /* FIXME: reentrancy */ int firmware_len = sizeof(buf), retval; retval = rx331_transaction(rig, REPORT_FIRM, strlen(REPORT_FIRM), buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.5/rigs/tentec/rx350.c0000664000175000017500000001136115056640443011731 /* * Hamlib TenTenc backend - RX-350 description * Copyright (c) 2003-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tentec2.h" #define RX350_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX350_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) #define RX350_LEVELS (RIG_LEVEL_RAWSTR|/*RIG_LEVEL_NB|*/ \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_SQL|RIG_LEVEL_ATT) #define RX350_ANTS (RIG_ANT_1) #define RX350_PARMS (RIG_PARM_TIME) #define RX350_VFO (RIG_VFO_A|RIG_VFO_B) #define RX350_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // Taken from RX320_STR_CAL -- unknown if accurate for RX350 #define RX350_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * RX350 receiver capabilities. * * Protocol is documented at * http://www.rfsquared.com/ * * Only set_freq is supposed to work. * This is a skeleton. */ struct rig_caps rx350_caps = { RIG_MODEL(RIG_MODEL_RX350), .model_name = "RX-350", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = RX350_FUNCS, .has_set_func = RX350_FUNCS, .has_get_level = RX350_LEVELS, .has_set_level = RIG_LEVEL_SET(RX350_LEVELS), .has_get_parm = RX350_PARMS, .has_set_parm = RX350_PARMS, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } } }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 8, .chan_desc_sz = 15, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30), RX350_MODES, -1, -1, RX350_VFO, RX350_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), RX350_MODES, -1, -1, RX350_VFO, RX350_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX350_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX350_MODES, kHz(2.4)}, {RX350_MODES, 300}, {RX350_MODES, kHz(8)}, {RX350_MODES, 0}, /* 34 filters */ RIG_FLT_END, }, .str_cal = RX350_STR_CAL, .priv = (void *)NULL, .set_freq = tentec2_set_freq, .get_freq = tentec2_get_freq, .set_vfo = tentec2_set_vfo, .get_vfo = tentec2_get_vfo, .set_mode = tentec2_set_mode, .get_mode = tentec2_get_mode, .reset = tentec2_reset, .get_info = tentec2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/tentec/paragon.c0000664000175000017500000003666515056640443012515 /* * Hamlib TenTenc backend - TT-585 Paragon description * Copyright (c) 2003-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "bandplan.h" #include "iofunc.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" struct tt585_priv_data { unsigned char status_data[30]; struct timeval status_tv; int channel_num; }; /* RIG_MODE_FM is optional */ #define TT585_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define TT585_RXMODES (TT585_MODES|RIG_MODE_AM) #define TT585_FUNCS (RIG_FUNC_NONE) #define TT585_LEVELS (RIG_LEVEL_NONE) #define TT585_ANTS (RIG_ANT_1) #define TT585_PARMS (RIG_PARM_ANN|RIG_PARM_TIME) #define TT585_VFO (RIG_VFO_A|RIG_VFO_B) #define TT585_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|\ RIG_OP_CPY|RIG_OP_MCL|RIG_OP_TOGGLE|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TUNE) #define TT585_CACHE_TIMEOUT 500 /* ms */ /* * Mem caps to be checked, maybe more like split.. */ #define TT585_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .channel_desc = 1, \ } static int tt585_init(RIG *rig); static int tt585_cleanup(RIG *rig); static int tt585_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt585_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt585_set_vfo(RIG *rig, vfo_t vfo); static int tt585_get_vfo(RIG *rig, vfo_t *vfo); static int tt585_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); static int tt585_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); static int tt585_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt585_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tt585_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int tt585_set_parm(RIG *rig, setting_t parm, value_t val); static int tt585_set_mem(RIG *rig, vfo_t vfo, int ch); static int tt585_get_mem(RIG *rig, vfo_t vfo, int *ch); static int tt585_get_status_data(RIG *rig); /* * tt585 transceiver capabilities, * with the optional model 258 RS232 Interface board. */ struct rig_caps tt585_caps = { RIG_MODEL(RIG_MODEL_TT585), .model_name = "TT-585 Paragon", .mfg_name = "Ten-Tec", .version = "20200305.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 100, /* instead of 20 ms */ .post_write_delay = 200, /* FOR T=1 TO 200 on a 4.77 MHz PC */ .timeout = 1000, .retry = 0, .has_get_func = TT585_FUNCS, .has_set_func = TT585_FUNCS, .has_get_level = TT585_LEVELS, .has_set_level = RIG_LEVEL_SET(TT585_LEVELS), .has_get_parm = TT585_PARMS, .has_set_parm = TT585_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = TT585_VFO_OPS, .chan_list = { { 0, 61, RIG_MTYPE_MEM, TT585_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30) - 10, TT585_RXMODES, -1, -1, TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30) - 10, TT585_RXMODES, -1, -1, TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS), {MHz(5.25), MHz(5.40), TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT585_RXMODES, 10}, {TT585_RXMODES, 20}, {TT585_RXMODES, 50}, {TT585_RXMODES, 100}, {TT585_RXMODES, 500}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(1.8)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, 500}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, 250}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt585_init, .rig_cleanup = tt585_cleanup, .set_freq = tt585_set_freq, .get_freq = tt585_get_freq, .set_vfo = tt585_set_vfo, .get_vfo = tt585_get_vfo, .set_split_vfo = tt585_set_split_vfo, .get_split_vfo = tt585_get_split_vfo, .vfo_op = tt585_vfo_op, .set_mode = tt585_set_mode, .get_mode = tt585_get_mode, .set_parm = tt585_set_parm, .set_mem = tt585_set_mem, .get_mem = tt585_get_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * tt585_init: * Basically, it just sets up *priv */ int tt585_init(RIG *rig) { struct tt585_priv_data *priv; STATE(rig)->priv = (struct tt585_priv_data *) calloc(1, sizeof( struct tt585_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt585_priv_data)); return RIG_OK; } int tt585_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); STATE(rig)->priv = NULL; } return RIG_OK; } int tt585_get_vfo(RIG *rig, vfo_t *vfo) { struct tt585_priv_data *priv = (struct tt585_priv_data *) STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } *vfo = (priv->status_data[9] & 0x08) ? RIG_VFO_A : RIG_VFO_B; return RIG_OK; } /* * tt585_set_vfo * Assumes rig!=NULL */ int tt585_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curr_vfo; int ret; ret = tt585_get_vfo(rig, &curr_vfo); if (ret < 0) { return ret; } if (vfo == curr_vfo || vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) { return RIG_OK; } /* toggle VFOs */ return write_block(RIGPORT(rig), (unsigned char *) "F", 1); } int tt585_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { split_t curr_split; vfo_t curr_txvfo; int ret; ret = tt585_get_split_vfo(rig, vfo, &curr_split, &curr_txvfo); if (ret < 0) { return ret; } if (split == curr_split) { return RIG_OK; } /* toggle split mode */ return write_block(RIGPORT(rig), (unsigned char *) "J", 1); } int tt585_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } *split = (priv->status_data[9] & 0x02) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *txvfo = RIG_VFO_B; return RIG_OK; } /* * tt585_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt585_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; unsigned char *p; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } p = priv->status_data; *freq = ((((((p[0] * 10 + p[1]) * 10 + p[2]) * 10 + p[3]) * 10 + p[4]) * 10 + p[5]) * 10 + p[6]) * 10; return RIG_OK; } /* * tt585_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tt585_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; #define FREQBUFSZ 16 char buf[FREQBUFSZ], *p; num_snprintf(buf, FREQBUFSZ - 1, "%.5f@", (double)freq / MHz(1)); buf[FREQBUFSZ - 1] = '\0'; /* replace decimal point with W */ p = strchr(buf, '.'); *p = 'W'; rig_force_cache_timeout(&priv->status_tv); return write_block(RIGPORT(rig), (unsigned char *) buf, strlen(buf)); } /* * tt585_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt585_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } if (priv->status_data[7] & 0x02) { *mode = RIG_MODE_CW; } else if (priv->status_data[7] & 0x04) { *mode = RIG_MODE_USB; } else if (priv->status_data[7] & 0x08) { *mode = RIG_MODE_LSB; } else if (priv->status_data[7] & 0x10) { *mode = RIG_MODE_AM; } else if (priv->status_data[7] & 0x20) { *mode = RIG_MODE_FM; } else if (priv->status_data[7] & 0x40) { *mode = RIG_MODE_RTTY; } else { *mode = RIG_MODE_NONE; } if (priv->status_data[8] & 0x08) { *width = 250; } else if (priv->status_data[8] & 0x10) { *width = 500; } else if (priv->status_data[8] & 0x20) { *width = 1800; } else if (priv->status_data[8] & 0x40) { *width = 2400; } else if (priv->status_data[8] & 0x80) { *width = 6000; } else { *width = 0; } return RIG_OK; } /* * tt585_set_mode * Assumes rig!=NULL */ int tt585_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; const char *mcmd, *wcmd; int ret; hamlib_port_t *rp = RIGPORT(rig); switch (mode) { case RIG_MODE_LSB: mcmd = "N"; break; case RIG_MODE_USB: mcmd = "O"; break; case RIG_MODE_CW: mcmd = "P"; break; case RIG_MODE_FM: mcmd = "L"; break; case RIG_MODE_AM: mcmd = "M"; break; case RIG_MODE_RTTY: mcmd = "XP"; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } rig_force_cache_timeout(&priv->status_tv); ret = write_block(rp, (unsigned char *) mcmd, strlen(mcmd)); if (ret < 0) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } if (width <= 250) { wcmd = "V"; } else if (width <= 500) { wcmd = "U"; } else if (width <= 1800) { wcmd = "T"; } else if (width <= 2400) { wcmd = "S"; } else /* 6000 (or FM?) */ { wcmd = "R"; } return write_block(rp, (unsigned char *) wcmd, strlen(mcmd)); } int tt585_set_mem(RIG *rig, vfo_t vfo, int ch) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; char buf[16]; if (ch < 0 || ch > 61) { return -RIG_EINVAL; } priv->channel_num = ch; /* does it work without a command after the channel number? */ SNPRINTF(buf, sizeof(buf), ":%02d", ch); return write_block(RIGPORT(rig), (unsigned char *) buf, strlen(buf)); } int tt585_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct tt585_priv_data *priv = (struct tt585_priv_data *) STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } /* 63 means not in MEM mode, 0xfe means mem full */ if (priv->status_data[11] > 61) { return -RIG_ERJCTED; } *ch = priv->status_data[11]; return RIG_OK; } /* * private helper function. Retrieves status data from rig. * using buffer indicated in *priv struct. * * need to use this when doing tt585_get_* stuff */ int tt585_get_status_data(RIG *rig) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; hamlib_port_t *rigport; int ret; rigport = RIGPORT(rig); if (!rig_check_cache_timeout(&priv->status_tv, TT585_CACHE_TIMEOUT)) { return RIG_OK; } rig_flush(rigport); /* send STATUS command to fetch data*/ ret = write_block(rigport, (unsigned char *) "\\", 1); if (ret < 0) { return ret; } ret = read_block(rigport, (unsigned char *)(char *) priv->status_data, sizeof(priv->status_data)); if (ret < 0) { return ret; } /* update cache date */ gettimeofday(&priv->status_tv, NULL); return RIG_OK; } int tt585_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; switch (parm) { case RIG_PARM_ANN: /* FIXME: > is a toggle command only */ ret = write_block(RIGPORT(rig), (unsigned char *) ">", 1); if (ret < 0) { return ret; } /* exact additional delay TBC */ sleep(1); return RIG_OK; /* TODO: RIG_PARM_TIME */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * tt585_vfo_op * Assumes rig!=NULL */ int tt585_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; const char *cmd; char buf[16]; switch (op) { case RIG_OP_TUNE: cmd = "Q"; break; case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), ":%02dXD", priv->channel_num); cmd = buf; break; case RIG_OP_TO_VFO: SNPRINTF(buf, sizeof(buf), ":%02d", priv->channel_num); cmd = buf; break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "<%02d", priv->channel_num); cmd = buf; break; case RIG_OP_CPY: cmd = "E"; break; case RIG_OP_TOGGLE: cmd = "F"; break; case RIG_OP_DOWN: cmd = "]"; break; case RIG_OP_UP: cmd = "["; break; case RIG_OP_BAND_DOWN: cmd = "XY"; break; case RIG_OP_BAND_UP: cmd = "XZ"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } rig_force_cache_timeout(&priv->status_tv); return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } hamlib-4.6.5/rigs/tentec/jupiter.c0000664000175000017500000010051615056640443012533 /* * Hamlib TenTenc backend - TT-538 description * Copyright (c) 2003-2012 by Stephane Fillod, Martin Ewing * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Extended and corrected by Martin Ewing AA6E 2/2012 * This backend tested with firmware v 1.330. * Firmware version >=1.18 is probably required. * Reference: Jupiter Model 538 Programmer's Reference Guide Rev. 1.1 * v 0.7 - 2012-07-15 - correct RAWSTR processing, add cal table for RIG_LEVEL_STRENGTH * 2012-08-02 - Add support for "IF" (passband tuning), NB, NR, ANF * 2012-12-04 - Revise reported bandwidth code */ /* to do: * implement dual VFO & split capability */ #include #include #include #include #include "tentec2.h" #include "tentec.h" #include "bandplan.h" struct tt538_priv_data { int ch; /* mem */ vfo_t vfo_curr; }; #define TT538_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM) #define TT538_RXMODES (TT538_MODES) #define TT538_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_NB) #define TT538_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) #define TT538_LEVELS_SET (RIG_LEVEL_SQL|RIG_LEVEL_RF| \ RIG_LEVEL_AF|RIG_LEVEL_IF| \ RIG_LEVEL_AGC|RIG_LEVEL_ATT) #define TT538_ANTS (RIG_ANT_1) #define TT538_PARMS (RIG_PARM_NONE) #define TT538_VFO (RIG_VFO_A|RIG_VFO_B) #define TT538_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define TT538_AM '0' #define TT538_USB '1' #define TT538_LSB '2' #define TT538_CW '3' #define TT538_FM '4' #define EOM "\015" /* CR */ /* Jupiter's RAWSTR is S-meter reading in S value + fractional S value, times 256 */ #define TT538_STR_CAL { 18, { \ { 256, -48 }, \ { 512, -42 }, \ { 768, -36 }, \ { 1024, -30 }, \ { 1280, -24 }, \ { 1536, -18 }, \ { 1792, -12 }, \ { 2048, -6 }, \ { 2304, 0 }, \ { 2560, 6 }, \ { 2816, 12 }, \ { 3072, 18 }, \ { 3328, 24 }, \ { 3584, 30 }, \ { 3840, 36 }, \ { 4096, 42 }, \ { 4352, 48 }, \ { 4608, 54 }, \ } } static int tt538_init(RIG *rig); static int tt538_reset(RIG *rig, reset_t reset); static int tt538_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt538_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt538_set_vfo(RIG *rig, vfo_t vfo); static int tt538_get_vfo(RIG *rig, vfo_t *vfo); static int tt538_set_split_vfo(RIG *rig, vfo_t vfo, split_t, vfo_t tx_vfo); static int tt538_get_split_vfo(RIG *rig, vfo_t vfo, split_t *, vfo_t *tx_vfo); static int tt538_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static char which_vfo(const RIG *rig, vfo_t vfo); static int tt538_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tt538_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tt538_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); /* * tt538 transceiver capabilities. * * Protocol is documented at * http://www.rfsquared.com/ */ struct rig_caps tt538_caps = { RIG_MODEL(RIG_MODEL_TT538), .model_name = "TT-538 Jupiter", .mfg_name = "Ten-Tec", .version = "20240913.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = TT538_FUNCS, .has_set_func = TT538_FUNCS, .has_get_level = TT538_LEVELS, .has_set_level = TT538_LEVELS_SET, .has_get_parm = TT538_PARMS, .has_set_parm = TT538_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30), TT538_RXMODES, -1, -1, TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TT538_RXMODES, -1, -1, TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS), {MHz(5.25), MHz(5.40), TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT538_RXMODES, 1}, {TT538_RXMODES, 10}, {TT538_RXMODES, 100}, {TT538_RXMODES, kHz(1)}, {TT538_RXMODES, kHz(10)}, {TT538_RXMODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, 300}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, 0}, /* 34 filters */ {RIG_MODE_FM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt538_init, .set_freq = tt538_set_freq, .get_freq = tt538_get_freq, .set_vfo = tt538_set_vfo, .get_vfo = tt538_get_vfo, .set_mode = tt538_set_mode, .get_mode = tt538_get_mode, .get_level = tt538_get_level, .set_level = tt538_set_level, .get_func = tt538_get_func, .set_func = tt538_set_func, .set_split_vfo = tt538_set_split_vfo, .get_split_vfo = tt538_get_split_vfo, .set_ptt = tt538_set_ptt, .reset = tt538_reset, .get_info = tentec2_get_info, .str_cal = TT538_STR_CAL, // This signals front-end support of level STRENGTH .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* Filter table for 538 receiver support. */ static int tt538_rxFilter[] = { 8000, 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 260, 225, 180, 165, 150 }; #define JUPITER_TT538_RXFILTERS ( sizeof(tt538_rxFilter) / sizeof(tt538_rxFilter[0]) ) /* * Function definitions below */ /* I frequently see the Jupiter and my laptop get out of sync. A response from the 538 isn't seen by the laptop. A few "XX"s sometimes get things going again, hence this hack, er, function. */ static int tt538_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { char reset_buf[32]; int i, reset_len, retval; retval = tentec_transaction(rig, cmd, cmd_len, data, data_len); if (data == NULL || (data != NULL && data_len > 0)) { return retval; } /* Try a few times to do a DSP reset to resync things. */ for (i = 0; i < 3; i++) { reset_len = 32; retval = tentec_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { continue; /* Try again. This 1 didn't work. */ } if (strstr(reset_buf, "RADIO START")) { break; /* DSP reset successful! */ } } /* Try real command one last time... */ return tentec_transaction(rig, cmd, cmd_len, data, data_len); } /* * tt538_init: * Basically, it just sets up *priv */ int tt538_init(RIG *rig) { struct tt538_priv_data *priv; STATE(rig)->priv = (struct tt538_priv_data *) calloc(1, sizeof( struct tt538_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt538_priv_data)); /* * set arbitrary initial status */ priv->ch = 0; priv->vfo_curr = RIG_VFO_A; return RIG_OK; } static char which_vfo(const RIG *rig, vfo_t vfo) { const struct tt538_priv_data *priv = (struct tt538_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: return 'A'; case RIG_VFO_B: return 'B'; case RIG_VFO_NONE: return 'N'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } int tt538_get_vfo(RIG *rig, vfo_t *vfo) { const struct tt538_priv_data *priv = (struct tt538_priv_data *) STATE( rig)->priv; *vfo = priv->vfo_curr; return RIG_OK; } /* * tt538_set_vfo * Assumes rig!=NULL */ int tt538_set_vfo(RIG *rig, vfo_t vfo) { struct tt538_priv_data *priv = (struct tt538_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { return RIG_OK; } priv->vfo_curr = vfo; return RIG_OK; } /* * Software restart */ int tt538_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 32; retval = tt538_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /* * tt538_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt538_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char curVfo; int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); resp_len = 7; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } curVfo = which_vfo(rig, vfo); if (respbuf[0] != curVfo) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } if (resp_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected length '%d'\n", __func__, resp_len); return -RIG_EPROTO; } *freq = (respbuf[1] << 24) + (respbuf[2] << 16) + (respbuf[3] << 8) + respbuf[4]; return RIG_OK; } /* * tt538_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tt538_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char bytes[4]; unsigned char cmdbuf[16]; int retval = -RIG_EINTERNAL; int retry = STATE(rig)->retry; freq_t freqchk = 0; /* Freq is 4 bytes long, MSB sent first. */ bytes[3] = ((unsigned int) freq >> 24) & 0xff; bytes[2] = ((unsigned int) freq >> 16) & 0xff; bytes[1] = ((unsigned int) freq >> 8) & 0xff; bytes[0] = ((unsigned int) freq) & 0xff; do { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*%c%c%c%c%c" EOM, which_vfo(rig, vfo), bytes[3], bytes[2], bytes[1], bytes[0]); retval = tt538_transaction(rig, (char *) cmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { continue; } retval = tt538_get_freq(rig, vfo, &freqchk); if (retval != RIG_OK) { return retval; } } while (freq != freqchk && --retry >= 0); return retval; } /* * tt538_set_split_vfo * assumes rig!=NULL */ int tt538_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { return tentec_transaction(rig, RIG_SPLIT_ON == split ? "*O1\r" : "*O0\r", 4, NULL, NULL); } /* * tt538_get_split_vfo * assumes rig!=NULL */ int tt538_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval, ret_len; char buf[4] = "?O\r"; ret_len = 4; retval = tentec_transaction(rig, buf, 3, buf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 3) { return -RIG_EPROTO; } *split = buf[1] == '0' ? RIG_SPLIT_OFF : RIG_SPLIT_ON; *tx_vfo = RIG_VFO_A; return RIG_OK; } /* * tt538_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt538_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; int rpb; unsigned char cmdbuf[16], respbuf[32]; char ttmode; /* Find bandwidth according to response from table. */ const static int pbwidth[39] = { 8000, 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 260, 225, 180, 165, 150 }; /* Query mode */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || resp_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (which_vfo(rig, vfo)) { case 'A': ttmode = respbuf[1]; break; case 'B': ttmode = respbuf[2]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; break; } switch (ttmode) { case TT538_AM: *mode = RIG_MODE_AM; break; case TT538_USB: *mode = RIG_MODE_USB; break; case TT538_LSB: *mode = RIG_MODE_LSB; break; case TT538_CW: *mode = RIG_MODE_CW; break; case TT538_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?W" EOM); resp_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'W' && resp_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } rpb = respbuf[1]; if (rpb <= 38) { *width = pbwidth[rpb]; } else { rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", __func__, respbuf[1]); return -RIG_EPROTO; } return RIG_OK; } /* Find rx filter index of bandwidth the same or larger as requested. */ static int tt538_filter_number(int width) { int i; for (i = JUPITER_TT538_RXFILTERS - 1; i >= 0; i--) { if (width <= tt538_rxFilter[i]) { return i; } } return 0; /* Widest filter, 8 kHz. */ } /* * tt538_set_mode * Assumes rig!=NULL */ int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmdbuf[32], respbuf[32], ttmode; int resp_len, retval; const struct tt538_priv_data *priv = (struct tt538_priv_data *) STATE( rig)->priv; /* Query mode for both VFOs. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || resp_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (mode) { case RIG_MODE_USB: ttmode = TT538_USB; break; case RIG_MODE_LSB: ttmode = TT538_LSB; break; case RIG_MODE_CW: ttmode = TT538_CW; break; case RIG_MODE_AM: ttmode = TT538_AM; break; case RIG_MODE_FM: ttmode = TT538_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* Set mode for both VFOs. */ if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, ttmode, respbuf[2]); break; case RIG_VFO_B: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, respbuf[1], ttmode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* Set rx filter bandwidth. */ width = tt538_filter_number((int) width); SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*W%c" EOM, (unsigned char) width); return tt538_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); return RIG_OK; } /* * tt538_set_ptt * Assumes rig!=NULL */ int tt538_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { return tentec_transaction(rig, ptt == RIG_PTT_ON ? "Q1\r" : "Q0\r", 3, NULL, NULL); } /* * tt538_get_level * Assumes rig!=NULL, val!=NULL */ int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { float fwd, refl; float ratio, swr; int retval, lvl_len; unsigned char cmdbuf[16], lvlbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_SWR: /* Get forward power. */ lvl_len = 4; retval = tt538_transaction(rig, "?F" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'F' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } fwd = (float) lvlbuf[1]; /* Get reflected power. */ lvl_len = 4; retval = tt538_transaction(rig, "?R" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'R' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } refl = (float) lvlbuf[1]; ratio = refl / fwd; if (ratio > 0.9) { swr = 10.0; /* practical maximum SWR, avoid div by 0 */ } else { swr = 1.0 / (1.0 - ratio); } val->f = swr; break; case RIG_LEVEL_RAWSTR: lvl_len = 7; retval = tt538_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'S' || lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } /* Jupiter returns actual S value in 1/256s of an S unit, in ascii hex digits. We convert those digits to binary and return that integer (S units * 256) */ { char hex[5]; int i; unsigned int ival; for (i = 0; i < 4; i++) { hex[i] = lvlbuf[i + 1]; } hex[4] = '\0'; sscanf(hex, "%4x", &ival); val->i = ival; /* S-units+fract * 256 */ } break; case RIG_LEVEL_AGC: /* Read rig's AGC level setting. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?G" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'G' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[1] & 0xf) { /* Prog. Man. claims Jupiter returns '1', '2', and '3', but not so if AGC was set by program! So look at 2nd hex digit only. */ case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: /* Volume returned as single byte. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?U" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'U' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (float) lvlbuf[1] / 127; break; case RIG_LEVEL_RF: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?I" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } /* Note: Any RF gain over "50%" on front panel returns 1.00 (firmware 1.281) on test rig. However RF set level seems OK. Firmware problem? -AA6E */ val->f = 1 - (float) lvlbuf[1] / 0xff; break; case RIG_LEVEL_IF: /* IF passband tuning, Hz */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?P" EOM); lvl_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, & lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'P' || lvl_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = (int) lvlbuf[1] * 256 + (int) lvlbuf[2]; break; case RIG_LEVEL_ATT: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?J" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'J' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = lvlbuf[1]; break; case RIG_LEVEL_SQL: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?H" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'H' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = ((float) lvlbuf[1] / 127); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt538_set_level * Assumes rig!=NULL, val!=NULL */ int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cc, cmdbuf[32], c1, c2; int retval; int len; switch (level) { case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: cc = '3'; break; case RIG_AGC_MEDIUM: cc = '2'; break; case RIG_AGC_SLOW: cc = '1'; break; default: cc = '2'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*G%c" EOM, cc); len = 4; break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*U%c" EOM, (int)(127 * val.f)); len = 4; break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*I%c" EOM, (int)(127 * val.f)); len = 4; break; case RIG_LEVEL_IF: c1 = val.i >> 8; c2 = val.i & 0xff; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*P%c%c" EOM, c1, c2); len = 5; break; case RIG_LEVEL_ATT: if (val.i) { cc = '1'; } else { cc = '0'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*J%c" EOM, cc); len = 4; break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*H%c" EOM, (int)(127 * val.f)); len = 4; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = tt538_transaction(rig, cmdbuf, len, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tt538_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char frespbuf[32]; int retval, fresplen; switch (func) { case RIG_FUNC_NR: /* ?K gets nb(0-7), an, nr according to prog ref guide, but it's really nb, nr, an */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 2 ] == 1; return RIG_OK; case RIG_FUNC_ANF: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 3 ] == 1; return RIG_OK; case RIG_FUNC_NB: /* Based on research by AA6E - * Data transferred from rig: * * |__|__|__| (a 3 bit value, 0 - 7 indicating NB "strength" * 4 2 1 * * Apparently the "ON" / "OFF" state of the NB is NOT available for reading. This * state is visible in the Jupiter's menu. Hamlib does not support a "level" for * NB. We only recognize zero (off) or non-zero (on) for this function on read. */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = (frespbuf[ 1 ] != 0); /* non-zero value -> "on" */ return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } int tt538_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fcmdbuf[32], frespbuf[32]; int retval, fresplen, i; switch (func) { case RIG_FUNC_NB: /* Jupiter combines, nb, nr, and anf in one command, so we need to retrieve them all before changing one of them */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[2] = status ? 5 : 1; /* Based on AA6E research (no thanks to errors in TT Prog Ref Manual!) * The "set" function (*K command) uses a different data format from the ?K get function. * Data transferred to rig: * +--+--+----------NB value (0-7) * v v v +-------NB "on/off" bit * |__|__|__|__| * 8 4 2 1 * The NB on/off bit corresponds to the "Noise Blanker" item in the Jupiter menu. * The value is show in the "NB selection" item in the Jupiter menu. * Note that if all zeroes are sent, the NB does shut off, but the NB value * is unchanged. If you want to change the NB value, the on/off bit must be set. * Because the on/off status cannot (apparently) be read back by software, we will * leave NB always on, but set to zero value when NB "off" is desired. It is not clear * if NB on/off makes a difference if the value is zero. (ver 1330-538 firmware) */ /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; case RIG_FUNC_NR: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[3] = status ? 1 : 0; /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; case RIG_FUNC_ANF: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[4] = status ? 1 : 0; /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } hamlib-4.6.5/rigs/tentec/tt550.h0000664000175000017500000001321415056640443011735 /* * Hamlib Tentec backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TT550_H #define _TT550_H 1 #include #define EOM "\015" /* CR */ #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' /* * Transmit and receive flags used by tt550_tuning_factor_calc * to modify behavior for transmit versus receive vfo's */ #define RECEIVE 0 #define TRANSMIT 1 /* * Transmitter control operations */ #define DISABLE_TX '0' #define ENABLE_TX '1' #define DISABLE_AMP '2' #define ENABLE_AMP '3' #define ENABLE_KEYER '6' #define DISABLE_KEYER '7' #define DISABLE_KEEPALIVE '8' #define ENABLE_KEEPALIVE '9' /* This is needed until we come up with a way to guarantee that the ** KEEPALIVE mechanism of the Pegasus is met. */ #define BYPASS_KEEPALIVE 1 #define KEY_F1_DOWN 0x11 #define KEY_F2_DOWN 0x12 #define KEY_F3_DOWN 0x13 #define KEY_F1_UP 0x91 #define KEY_F2_UP 0x92 #define KEY_F3_UP 0x93 struct tt550_priv_data { rmode_t tx_mode; /* transmitter mode - may be different from receiver in split mode */ rmode_t rx_mode; /* Current RX Mode */ freq_t tx_freq; /* tuned transmitter frequency - may be different from * 'freq' when in split mode */ freq_t rx_freq; /* Current RX Frequency */ shortfreq_t rit; /* Current RIT Value */ shortfreq_t xit; /* Current XIT Value */ shortfreq_t pbtadj; /* Current pass band tuning value */ pbwidth_t width; /* filter bandwidth in Hz */ pbwidth_t tx_width; /* transmit filter bandwidth in Hz */ int pb; /* RX passband offset in Hz 0 [0-10000] */ int cwbfo; /* BFO frequency: 700 [0-2000Hz] */ int tx_cwbfo; /* TX_BFO frequency: 700 [0-2000Hz] */ float lineout; /* line-out volume: 30 [0..63] */ float spkvol; /* speaker volume: 30 [0..63] */ int agc; /* AGC: medium */ float rflevel; /* RF Gain Level: [0..255] */ float sql; /* Squelch: [0..255] */ int att; /* Attenuator level [0..1] */ int keyspd; /* Keyer speed: [0..255] */ float nr; /* Noise reduction: [0..1] */ float autonotch; /* Autonotch filter: [0..1] */ float rfpower; /* RF Power: [0..255] */ float speechcomp; /* Speech compressor: [0..127] */ float voxgain; /* Vox Gain: [0..255] */ float voxdelay; /* Vox delay: [0..255] */ float antivox; /* AntiVox gain: [0..255] */ float mikegain; /* Microphone gain: [0..15] */ float bkindl; /* CW QSK level */ int split; /* split - ON/OFF */ shortfreq_t stepsize; /*current step size */ int anf; /* ANF on/off 1/0 */ int en_nr; /* Noise Reduction on/off 1/0 */ int tuner; /* automatic tuner on/off 1/0 */ int vox; /* VOX on/off 1/0 */ /* calculated by tt550_tuning_factor_calc() */ int ctf; /* Coarse Tune Factor */ int ftf; /* Fine Tune Factor */ int btf; /* Bfo Tune Factor, btval is ignored by RX-320 in AM MODE */ /* S-meter calibration data */ cal_table_t str_cal; }; int tt550_init (RIG * rig); int tt550_cleanup (RIG * rig); int tt550_trx_open (RIG * rig); int tt550_reset(RIG * rig, reset_t reset); int tt550_set_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val); int tt550_get_level (RIG * rig, vfo_t vfo, setting_t level, value_t * val); int tt550_set_ptt (RIG * rig, vfo_t vfo, ptt_t ptt); int tt550_get_ptt (RIG * rig, vfo_t vfo, ptt_t * ptt); int tt550_decode_event (RIG * rig); const char *tt550_get_info (RIG * rig); int tt550_set_tx_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_tx_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_rx_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_rx_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_tx_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_tx_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_set_rx_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_rx_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_get_split_vfo (RIG * rig, vfo_t vfo, split_t * split, vfo_t * tx_vfo); int tt550_set_split_vfo (RIG * rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int tt550_get_tuning_step (RIG * rig, vfo_t vfo, shortfreq_t * stepsize); int tt550_set_tuning_step (RIG * rig, vfo_t vfo, shortfreq_t stepsize); int tt550_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int tt550_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int tt550_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int tt550_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int tt550_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int tt550_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int tt550_get_xit(RIG *rig, vfo_t vfo, shortfreq_t * rit); #endif /* _TT550_H */ hamlib-4.6.5/rigs/tentec/tentec.h0000664000175000017500000000556315056640443012346 /* * Hamlib Tentec backend - main header * Copyright (c) 2001-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup tentec * @{ */ /** * \file tentec.h * \brief Includes for Tentec Backends */ #ifndef _TENTEC_H #define _TENTEC_H 1 #include // The include order will determine which BACKEND_VER is used // tentec2.h may also be included and the last include is the BACKEND_VER used #undef BACKEND_VER #define BACKEND_VER "20200113" /** * \brief Private tentec info */ struct tentec_priv_data { rmode_t mode; /*!< detection mode */ freq_t freq; /*!< tuned frequency */ pbwidth_t width; /*!< filter bandwidth in Hz */ int cwbfo; /*!< BFO frequency: 1000 [0-2000Hz] */ int pbt; /*!< Passband Tuning, IF shift: 0 [-2000Hz to 2000Hz] */ float lnvol; /*!< line-out volume: 30 [0..63] */ float spkvol; /*!< speaker volume: 30 [0..63] */ int agc; /*!< AGC: medium */ /* calculated by tentec_tuning_factor_calc() */ int ctf; /*!< Coarse Tune Factor */ int ftf; /*!< Fine Tune Factor */ int btf; /*!< Bfo Tune Factor, btval is ignored by RX-320 in AM MODE */ }; int tentec_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int tentec_init(RIG *rig); int tentec_cleanup(RIG *rig); int tentec_trx_open(RIG *rig); int tentec_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tentec_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int tentec_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tentec_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int tentec_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int tentec_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char* tentec_get_info(RIG *rig); extern struct rig_caps rx320_caps; extern struct rig_caps rx340_caps; extern struct rig_caps rx350_caps; extern struct rig_caps tt516_caps; extern struct rig_caps tt538_caps; extern struct rig_caps tt585_caps; extern struct rig_caps tt588_caps; extern struct rig_caps tt550_caps; extern struct rig_caps tt565_caps; extern struct rig_caps tt599_caps; extern struct rig_caps rx331_caps; #endif /* _TENTEC_H */ /** @} */ hamlib-4.6.5/rigs/tentec/pegasus.c0000664000175000017500000002152215056640443012517 /* * Hamlib TenTenc backend - TT-550 PC-Radio description * Copyright (c) 2002-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tt550.h" #define TT550_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_AM) #define TT550_RXMODES (TT550_MODES) #define TT550_FUNCS (RIG_FUNC_VOX|RIG_FUNC_ANF|RIG_FUNC_TUNER| \ RIG_FUNC_NR|RIG_FUNC_VOX) #define TT550_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_AF|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_COMP|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT|RIG_LEVEL_NR|RIG_LEVEL_IF| \ RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX) #define TT550_VFO (RIG_VFO_A ) #define TT550_VFO_OPS (RIG_OP_TUNE) /* * a bit coarse, but I don't have a TT550, and the manual is not * verbose on the subject. Please test it and report! --SF */ #define TT550_STR_CAL { 2, { \ { 0, -60 }, \ { 10000, 20 }, \ } } /* * tt550 receiver capabilities. * * protocol is documented at * http://www.tentec.com/550/550prg2.pdf * * TODO: */ struct rig_caps tt550_caps = { RIG_MODEL(RIG_MODEL_TT550), .model_name = "TT-550", .mfg_name = "Ten-Tec", .version = "20190817.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 100, .retry = 4, .has_get_func = TT550_FUNCS, .has_set_func = TT550_FUNCS, .has_get_level = TT550_LEVELS, .has_set_level = RIG_LEVEL_SET(TT550_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 65535}}, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {20, RIG_DBLST_END}, .max_rit = Hz(10000), .max_xit = Hz(10000), .max_ifshift = Hz(2000), .targetable_vfo = RIG_TARGETABLE_ALL, .vfo_ops = TT550_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = {RIG_FRNG_END,}, /* FIXME: enter region 1 setting */ .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { {kHz(100), MHz(30), TT550_RXMODES, -1, -1, TT550_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(3500), MHz(4) - 1, TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(5330), kHz(5407) - 1, RIG_MODE_USB, 5000, 50000, TT550_VFO}, {MHz(7), kHz(7300), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(10100), kHz(10150), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(14), kHz(14350), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(18068), kHz(18168), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(21), kHz(21450), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(24890), kHz(24990), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(28), kHz(29700), TT550_MODES, 5000, 100000, TT550_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TT550_RXMODES, RIG_TS_ANY}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, Hz(450)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_CW, Hz(750)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_FM, Hz(4200)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2700)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2100)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5700)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5100)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4800)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4500)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4200)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3900)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3600)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3300)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2850)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(8000)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2550)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2250)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(6000)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1950)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1800)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1650)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1500)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1350)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1200)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1050)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(900)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(750)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(675)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(600)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(525)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(450)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(375)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(330)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(300)}, RIG_FLT_END, }, .str_cal = TT550_STR_CAL, .rig_init = tt550_init, .rig_cleanup = tt550_cleanup, .rig_open = tt550_trx_open, .reset = tt550_reset, .set_freq = tt550_set_freq, .get_freq = tt550_get_freq, .set_mode = tt550_set_mode, .get_mode = tt550_get_mode, .set_func = tt550_set_func, .get_func = tt550_get_func, .set_level = tt550_set_level, .get_level = tt550_get_level, .get_info = tt550_get_info, .set_ptt = tt550_set_ptt, .get_ptt = tt550_get_ptt, .set_split_freq = tt550_set_tx_freq, .get_split_freq = tt550_get_tx_freq, .set_split_mode = tt550_set_tx_mode, .get_split_mode = tt550_get_tx_mode, .set_split_vfo = tt550_set_split_vfo, .get_split_vfo = tt550_get_split_vfo, .decode_event = tt550_decode_event, .set_ts = tt550_set_tuning_step, .get_ts = tt550_get_tuning_step, .vfo_op = tt550_vfo_op, .set_rit = tt550_set_rit, .get_rit = tt550_get_rit, .set_xit = tt550_set_xit, .get_xit = tt550_get_xit, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/tentec/Makefile.am0000664000175000017500000000045715056640443012744 TENTECSRC = rx320.c rx340.c rx350.c rx331.c rx331.h tt550.c tt550.h \ pegasus.c argonaut.c orion.c orion.h jupiter.c omnivii.c paragon.c \ tentec.c tentec.h tentec2.c tentec2.h noinst_LTLIBRARIES = libhamlib-tentec.la libhamlib_tentec_la_SOURCES = $(TENTECSRC) EXTRA_DIST = README.tentec Android.mk hamlib-4.6.5/rigs/pcr/0000775000175000017500000000000015056640477010273 5hamlib-4.6.5/rigs/pcr/pcr100.c0000664000175000017500000001232015056640443011353 /* * Hamlib PCR backend - PCR-100 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR100_MODES ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR100_FUNC ( RIG_FUNC_TSQL ) #define PCR100_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR ) static const struct confparams pcr_ext_levels[] = { { TOK_EL_ANL, "ANL", "Auto Noise Limiter", "Auto Noise Limiter", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct pcr_priv_caps pcr100_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR100 rigs capabilities. */ struct rig_caps pcr100_caps = { RIG_MODEL(RIG_MODEL_PCR100), .model_name = "IC-PCR100", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* slower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 12, .post_write_delay = 2, .timeout = 400, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = PCR100_FUNC, .has_get_level = PCR100_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR100_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = { }, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(10), GHz(1.3), PCR100_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(10), MHz(824) - 10, PCR100_MODES, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR100_MODES, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR100_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR100_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! * first one is the default mode, the one given back * by rig_mode_normal(), the others must be sorted. */ .filters = { { RIG_MODE_AM | RIG_MODE_FM, kHz(15) }, { RIG_MODE_AM, kHz(2.8) }, { RIG_MODE_AM | RIG_MODE_FM, kHz(6) }, { RIG_MODE_AM | RIG_MODE_FM, kHz(50) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr100_priv, /* XXX verify */ .str_cal = { 7, { { 0, -60 }, { 160, 0 }, { 176, 20 }, { 192, 30 }, { 208, 40 }, { 224, 50 }, { 240, 60 }, } }, .extlevels = pcr_ext_levels, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ext_level = pcr_set_ext_level, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/pcr/pcr.c0000664000175000017500000013743615056640443011152 /* * Hamlib PCR backend - main file * Copyright (c) 2001-2005 by Darren Hatcher * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (C) 2007-09 by Alessandro Zummo * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Tested on * * (402) PCR100 fw 1.2, proto 1.0 (usb-to-serial) by IZ1PRB * (401) PCR1000 fw 1.0, proto 1.0 (serial) by KM3T * (403) PCR1500 fw 2.0, proto 2.0 (usb) by KM3T * */ #include #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "cal.h" #include "pcr.h" /* * modes in use by the "MD" command */ #define MD_LSB '0' #define MD_USB '1' #define MD_AM '2' #define MD_CW '3' #define MD_FM '5' #define MD_WFM '6' #define MD_DSTAR '7' /* PCR-2500 Only */ #define MD_P25 '8' /* PCR-2500 Only */ /* define 2.8kHz, 6kHz, 15kHz, 50kHz, and 230kHz */ #define FLT_2_8kHz '0' #define FLT_6kHz '1' #define FLT_15kHz '2' #define FLT_50kHz '3' #define FLT_230kHz '4' /* as returned by GD? */ #define OPT_UT106 (1 << 0) #define OPT_UT107 (1 << 4) /* * CTCSS sub-audible tones for PCR100 and PCR1000 * Don't even touch a single bit! indexes will be used in the protocol! * 51 tones, the 60.0 Hz tone is missing. */ tone_t pcr_ctcss_list[] = { 670, 693, 710, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* * DTCS SQL code list * Don't even touch a single bit! indexes will be used in the protocol! * 104 codes */ tone_t pcr_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; struct pcr_country { int id; char *name; }; struct pcr_country pcr_countries[] = { { 0x00, "Japan" }, { 0x01, "USA" }, { 0x02, "EUR/AUS" }, { 0x03, "FRA" }, { 0x04, "DEN" }, { 0x05, "CAN" }, { 0x06, "Generic 1" }, { 0x07, "Generic 2" }, { 0x08, "FCC Japan" }, { 0x09, "FCC USA" }, { 0x0A, "FCC EUR/AUS" }, { 0x0B, "FCC FRA" }, { 0x0C, "FCC DEN" }, { 0x0D, "FCC CAN" }, { 0x0E, "FCC Generic 1" }, { 0x0F, "FCC Generic 2" }, }; static int pcr_set_volume(RIG *rig, vfo_t vfo, float level); static int pcr_set_squelch(RIG *rig, vfo_t vfo, float level); static int pcr_set_if_shift(RIG *rig, vfo_t vfo, int level); static int pcr_set_agc(RIG *rig, vfo_t vfo, int status); // J45xx static int pcr_set_afc(RIG *rig, vfo_t vfo, int status); // LD820xx static int pcr_set_nb(RIG *rig, vfo_t vfo, int status); // J46xx static int pcr_set_attenuator(RIG *rig, vfo_t vfo, int status); // J47xx static int pcr_set_anl(RIG *rig, vfo_t vfo, int status); // J4Dxx static int pcr_set_diversity(RIG *rig, vfo_t vfo, int status); // J00xx on PCR-2500 static int pcr_set_bfo_shift(RIG *rig, vfo_t vfo, int level); // J4Axx static int pcr_set_vsc(RIG *rig, vfo_t vfo, int level); // J50xx static int pcr_set_dsp(RIG *rig, vfo_t vfo, int level); // J80xx static int pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level); // J8100=off J8101=on #if 1 /* unused; re-enabled as needed. */ static int pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level); // J82xx #endif /* unused */ static int pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int level); // J83xx static int pcr_check_ok(RIG *rig); static int is_sub_rcvr(RIG *rig, vfo_t vfo); #define PCR_COUNTRIES (sizeof(pcr_countries) / sizeof(struct pcr_country)) #define is_valid_answer(x) \ ((x) == 'I' || (x) == 'G' || (x) == 'N' || (x) == 'H') static int pcr_read_block(RIG *rig, char *rxbuffer, size_t count) { int read = 0, tries = 4; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); const struct pcr_priv_caps *caps = pcr_caps(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); /* already in sync? */ if (priv->sync && !caps->always_sync) { return read_block(rp, (unsigned char *) rxbuffer, count); } /* read first char */ do { char *p = &rxbuffer[0]; /* read first char */ int err = read_block(rp, (unsigned char *) p, 1); if (err < 0) { return err; } if (err != 1) { return -RIG_EPROTO; } /* validate */ if (*p != 0x0a && !is_valid_answer(*p)) { continue; } /* sync ok, read remaining chars */ read++; count--; p++; err = read_block(rp, (unsigned char *) p, count); if (err < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read failed - %s\n", __func__, strerror(errno)); return err; } if (err == count) { read += err; priv->sync = 1; } rig_debug(RIG_DEBUG_TRACE, "%s: RX %d bytes\n", __func__, read); return read; } while (--tries > 0); return -RIG_EPROTO; } /* expects a 4 byte buffer to parse */ static int pcr_parse_answer(RIG *rig, char *buf, int len) { struct rig_state *rs = STATE(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: len = %d\n", __func__, len); if (len < 4) { priv->sync = 0; return -RIG_EPROTO; } if (strncmp("G000", buf, 4) == 0) { return RIG_OK; } if (strncmp("G001", buf, 4) == 0) { return -RIG_ERJCTED; } if (strncmp("H101", buf, 4) == 0) { return RIG_OK; } if (strncmp("H100", buf, 4) == 0) { return -RIG_ERJCTED; } if (buf[0] == 'I') { switch (buf[1]) { /* Main receiver */ case '0': sscanf(buf, "I0%02X", &priv->main_rcvr.squelch_status); return RIG_OK; case '1': sscanf(buf, "I1%02X", &priv->main_rcvr.raw_level); return RIG_OK; case '2': rig_debug(RIG_DEBUG_VERBOSE, "%s: Signal centering %c%c\n", __func__, buf[2], buf[3]); return RIG_OK; case '3': rig_debug(RIG_DEBUG_WARN, "%s: DTMF %c\n", __func__, buf[3]); return RIG_OK; /* Sub receiver (on PCR-2500..) - TBC */ case '4': sscanf(buf, "I4%02X", &priv->sub_rcvr.squelch_status); return RIG_OK; case '5': sscanf(buf, "I5%02X", &priv->sub_rcvr.raw_level); return RIG_OK; case '6': rig_debug(RIG_DEBUG_VERBOSE, "%s: Signal centering %c%c (Sub)\n", __func__, buf[2], buf[3]); return RIG_OK; case '7': rig_debug(RIG_DEBUG_WARN, "%s: DTMF %c (Sub)\n", __func__, buf[3]); return RIG_OK; } } else if (buf[0] == 'G') { switch (buf[1]) { case '2': /* G2 */ sscanf((char *) buf, "G2%d", &priv->protocol); return RIG_OK; case '4': /* G4 */ sscanf((char *) buf, "G4%d", &priv->firmware); return RIG_OK; case 'D': /* GD */ sscanf((char *) buf, "GD%d", &priv->options); return RIG_OK; case 'E': /* GE */ sscanf((char *) buf, "GE%d", &priv->country); return RIG_OK; } } priv->sync = 0; return -RIG_EPROTO; /* XXX bandscope */ } static int pcr_send(RIG *rig, const char *cmd) { int err; struct rig_state *rs = STATE(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; int len = strlen(cmd); rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, len = %d\n", __func__, cmd, len); /* XXX check max len */ memcpy(priv->cmd_buf, cmd, len); /* append cr */ /* XXX not required in auto update mode? (should not harm) */ priv->cmd_buf[len + 0] = 0x0a; rs->transaction_active = 1; err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_buf, len + 1); rs->transaction_active = 0; return err; } static int pcr_transaction(RIG *rig, const char *cmd) { int err; struct rig_state *rs = STATE(rig); struct pcr_priv_caps *caps = pcr_caps(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s\n", __func__, cmd); if (!priv->auto_update) { rig_flush(RIGPORT(rig)); } pcr_send(rig, cmd); /* the pcr does not give ack in auto update mode */ if (priv->auto_update) { return RIG_OK; } err = pcr_read_block(rig, priv->reply_buf, caps->reply_size); if (err < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read error, %s\n", __func__, strerror(errno)); return err; } if (err != caps->reply_size) { priv->sync = 0; return -RIG_EPROTO; } return pcr_parse_answer(rig, &priv->reply_buf[caps->reply_offset], err); } static int pcr_set_comm_speed(RIG *rig, int rate) { int err; const char *rate_cmd; /* limit maximum rate */ if (rate > 38400) { rate = 38400; } switch (rate) { case 300: rate_cmd = "G100"; break; case 1200: rate_cmd = "G101"; break; case 2400: rate_cmd = "G102"; break; case 9600: default: rate_cmd = "G103"; break; case 19200: rate_cmd = "G104"; break; case 38400: rate_cmd = "G105"; break; } rig_debug(RIG_DEBUG_VERBOSE, "%s: setting speed to %d with %s\n", __func__, rate, rate_cmd); /* the answer will be sent at the new baudrate, * so we do not use pcr_transaction */ err = pcr_send(rig, rate_cmd); if (err != RIG_OK) { return err; } RIGPORT(rig)->parm.serial.rate = rate; serial_setup(RIGPORT(rig)); /* check if the pcr is still alive */ return pcr_check_ok(rig); } /* Basically, it sets up *priv */ int pcr_init(RIG *rig) { struct pcr_priv_data *priv; if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct pcr_priv_data *) calloc(1, sizeof(struct pcr_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct pcr_priv_data)); /* * FIXME: how can we retrieve initial status? * The protocol doesn't allow this. */ /* Some values are already at zero due to the memset above, * but we reinitialize here for sake of completeness */ priv->country = -1; priv->sync = 0; priv->power = RIG_POWER_OFF; priv->main_rcvr.last_att = 0; priv->main_rcvr.last_agc = 0; priv->main_rcvr.last_ctcss_sql = 0; priv->main_rcvr.last_freq = MHz(145); priv->main_rcvr.last_mode = MD_FM; priv->main_rcvr.last_filter = FLT_15kHz; priv->main_rcvr.volume = 0.25; priv->main_rcvr.squelch = 0.00; priv->sub_rcvr = priv->main_rcvr; priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * PCR Generic pcr_cleanup routine * the serial port is closed by the frontend */ int pcr_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * pcr_open * - send power on * - set auto update off * * Assumes rig!=NULL */ int pcr_open(RIG *rig) { struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; int err; int wanted_serial_rate; int startup_serial_rate; /* * initial communication is at 9600bps for PCR 100/1000 * once the power is on, the serial speed can be changed with G1xx */ if (rig->caps->rig_model == RIG_MODEL_PCR1500 || rig->caps->rig_model == RIG_MODEL_PCR2500) { startup_serial_rate = 38400; } else { startup_serial_rate = 9600; } wanted_serial_rate = rp->parm.serial.rate; rp->parm.serial.rate = startup_serial_rate; serial_setup(rp); /* let the pcr settle and flush any remaining data*/ hl_usleep(100 * 1000); rig_flush(rp); /* try powering on twice, sometimes the pcr answers H100 (off) */ pcr_send(rig, "H101"); hl_usleep(100 * 250); pcr_send(rig, "H101"); hl_usleep(100 * 250); rig_flush(rp); /* return RIG_ERJCTED if power is off */ err = pcr_transaction(rig, "H1?"); if (err != RIG_OK) { return err; } priv->power = RIG_POWER_ON; /* turn off auto update (just to be sure) */ err = pcr_transaction(rig, "G300"); if (err != RIG_OK) { return err; } /* set squelch and volume */ err = pcr_set_squelch(rig, RIG_VFO_MAIN, priv->main_rcvr.squelch); if (err != RIG_OK) { return err; } err = pcr_set_volume(rig, RIG_VFO_MAIN, priv->main_rcvr.volume); if (err != RIG_OK) { return err; } /* get device features */ pcr_get_info(rig); /* tune to last freq */ err = pcr_set_freq(rig, RIG_VFO_MAIN, priv->main_rcvr.last_freq); if (err != RIG_OK) { return err; } if ((STATE(rig)->vfo_list & RIG_VFO_SUB) == RIG_VFO_SUB) { err = pcr_set_squelch(rig, RIG_VFO_SUB, priv->sub_rcvr.squelch); if (err != RIG_OK) { return err; } err = pcr_set_volume(rig, RIG_VFO_SUB, priv->sub_rcvr.volume); if (err != RIG_OK) { return err; } err = pcr_set_freq(rig, RIG_VFO_SUB, priv->sub_rcvr.last_freq); if (err != RIG_OK) { return err; } pcr_set_vfo(rig, RIG_VFO_MAIN); } /* switch to different speed if requested */ if (wanted_serial_rate != startup_serial_rate && wanted_serial_rate >= 300) { return pcr_set_comm_speed(rig, wanted_serial_rate); } return RIG_OK; } /* * pcr_close - send power off * Assumes rig!=NULL */ int pcr_close(RIG *rig) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; /* when the pcr turns itself off sometimes we receive * a malformed answer, so don't check for it. */ priv->power = RIG_POWER_OFF; return pcr_send(rig, "H100"); } /* * pcr_set_vfo * * Only useful on PCR-2500 which is a double receiver. * Simply remember what the current VFO is for RIG_VFO_CURR. */ int pcr_set_vfo(RIG *rig, vfo_t vfo) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo = %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_SUB: break; default: return -RIG_EINVAL; } priv->current_vfo = vfo; return RIG_OK; } int pcr_get_vfo(RIG *rig, vfo_t *vfo) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; *vfo = priv->current_vfo; return RIG_OK; } /* * pcr_set_freq * Assumes rig!=NULL * * K0GMMMKKKHHHmmff00 * GMMMKKKHHH is frequency GHz.MHz.KHz.Hz * mm is the mode setting * 00 = LSB * 01 = USB * 02 = AM * 03 = CW * 04 = Not used or Unknown * 05 = NFM * 06 = WFM * ff is the filter setting * 00 = 2.8 Khz (CW USB LSB AM) * 01 = 6.0 Khz (CW USB LSB AM NFM) * 02 = 15 Khz (AM NFM) * 03 = 50 Khz (AM NFM WFM) * 04 = 230 Khz (WFM) * */ int pcr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct pcr_priv_data *priv; struct pcr_rcvr *rcvr; unsigned char buf[20]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo = %s, freq = %.0f\n", __func__, rig_strvfo(vfo), freq); priv = (struct pcr_priv_data *) STATE(rig)->priv; rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) freq, rcvr->last_mode, rcvr->last_filter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } rcvr->last_freq = freq; return RIG_OK; } /* * pcr_get_freq * frequency can't be read back, so report the last one that was set. * Assumes rig != NULL, freq != NULL */ int pcr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *freq = rcvr->last_freq; return RIG_OK; } /* * pcr_set_mode * Assumes rig != NULL */ int pcr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; unsigned char buf[20]; int err; int pcrmode; rig_debug(RIG_DEBUG_VERBOSE, "%s: mode = %s, width = %d\n", __func__, rig_strrmode(mode), (int)width); /* XXX? */ if (mode == RIG_MODE_NONE) { mode = RIG_MODE_FM; } /* * not so sure about modes and filters * as I write this from manual (no testing) --SF */ switch (mode) { case RIG_MODE_CW: pcrmode = MD_CW; break; case RIG_MODE_USB: pcrmode = MD_USB; break; case RIG_MODE_LSB: pcrmode = MD_LSB; break; case RIG_MODE_AM: pcrmode = MD_AM; break; case RIG_MODE_WFM: pcrmode = MD_WFM; break; case RIG_MODE_FM: pcrmode = MD_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { int pcrfilter; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } rig_debug(RIG_DEBUG_VERBOSE, "%s: will set to %d\n", __func__, (int)width); switch (width) { /* nop, pcrfilter already set * TODO: use rig_passband_normal instead? */ case s_kHz(2.8): pcrfilter = FLT_2_8kHz; break; case s_kHz(6): pcrfilter = FLT_6kHz; break; case s_kHz(15): pcrfilter = FLT_15kHz; break; case s_kHz(50): pcrfilter = FLT_50kHz; break; case s_kHz(230): pcrfilter = FLT_230kHz; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: filter set to %d (%c)\n", __func__, (int)width, pcrfilter); SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) rcvr->last_freq, pcrmode, pcrfilter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } rcvr->last_filter = pcrfilter; } else { SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) rcvr->last_freq, pcrmode, rcvr->last_filter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } } rcvr->last_mode = pcrmode; return RIG_OK; } /* * hack! pcr_get_mode * Assumes rig!=NULL, mode!=NULL */ int pcr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct pcr_priv_data *priv; struct pcr_rcvr *rcvr; priv = (struct pcr_priv_data *) STATE(rig)->priv; rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s, last_mode = %c, last_filter = %c\n", __func__, rcvr->last_mode, rcvr->last_filter); switch (rcvr->last_mode) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_WFM: *mode = RIG_MODE_WFM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "pcr_get_mode: unsupported mode %d\n", rcvr->last_mode); return -RIG_EINVAL; } switch (rcvr->last_filter) { case FLT_2_8kHz: *width = kHz(2.8); break; case FLT_6kHz: *width = kHz(6); break; case FLT_15kHz: *width = kHz(15); break; case FLT_50kHz: *width = kHz(50); break; case FLT_230kHz: *width = kHz(230); break; default: rig_debug(RIG_DEBUG_ERR, "pcr_get_mode: unsupported " "width %d\n", rcvr->last_filter); return -RIG_EINVAL; } return RIG_OK; } /* * pcr_get_info * Assumes rig!=NULL */ const char * pcr_get_info(RIG *rig) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; char *country = NULL; pcr_transaction(rig, "G2?"); /* protocol */ pcr_transaction(rig, "G4?"); /* firmware */ pcr_transaction(rig, "GD?"); /* options */ pcr_transaction(rig, "GE?"); /* country */ /* translate country id to name */ if (priv->country > -1) { int i; for (i = 0; i < PCR_COUNTRIES; i++) { if (pcr_countries[i].id == priv->country) { country = pcr_countries[i].name; break; } } if (country == NULL) { country = "Unknown"; rig_debug(RIG_DEBUG_ERR, "%s: unknown country code %#x, " "please report to Hamlib maintainer\n", __func__, priv->country); } } else { country = "Not queried yet"; } SNPRINTF(priv->info, sizeof(priv->info), "Firmware v%d.%d, Protocol v%d.%d, " "Optional devices:%s%s%s, Country: %s", priv->firmware / 10, priv->firmware % 10, priv->protocol / 10, priv->protocol % 10, (priv->options & OPT_UT106) ? " DSP" : "", (priv->options & OPT_UT107) ? " DARC" : "", priv->options ? "" : " none", country); rig_debug(RIG_DEBUG_VERBOSE, "%s: Firmware v%d.%d, Protocol v%d.%d, " "Optional devices:%s%s%s, Country: %s\n", __func__, priv->firmware / 10, priv->firmware % 10, priv->protocol / 10, priv->protocol % 10, (priv->options & OPT_UT106) ? " DSP" : "", (priv->options & OPT_UT107) ? " DARC" : "", priv->options ? "" : " none", country); return priv->info; } /* *********************************************************************** */ /* load of new stuff added in by Darren Hatcher - G0WCW */ /* *********************************************************************** */ /* * pcr_set_level called by generic set level handler * * We are missing a way to set the BFO on/off here, */ int pcr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int err = -RIG_ENIMPL; if (RIG_LEVEL_IS_FLOAT(level)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: level = %s, val = %f\n", __func__, rig_strlevel(level), val.f); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: level = %s, val = %d\n", __func__, rig_strlevel(level), val.i); } switch (level) { case RIG_LEVEL_ATT: /* This is only on or off, but hamlib forces to use set level * and pass as a float. Here we'll use 0 for off and 1 for on. * If someone finds out how to set the ATT for the PCR in dB, let us * know and the function can be changed to allow a true set level. * * Experiment shows it seems to have an effect, but unsure by how many db */ return pcr_set_attenuator(rig, vfo, val.i); case RIG_LEVEL_IF: return pcr_set_if_shift(rig, vfo, val.i); case RIG_LEVEL_CWPITCH: /* BFO */ return pcr_set_bfo_shift(rig, vfo, val.i); case RIG_LEVEL_AGC: /* Only AGC on/off supported by PCR's */ return pcr_set_agc(rig, vfo, val.i == RIG_AGC_OFF ? 0 : 1); /* floats */ case RIG_LEVEL_AF: /* "val" can be 0.0 to 1.0 float which is 0 to 255 levels * 0.3 seems to be ok in terms of loudness */ return pcr_set_volume(rig, vfo, val.f); case RIG_LEVEL_SQL: /* "val" can be 0.0 to 1.0 float * .... rig supports 0 to FF - look at function for * squelch "bands" */ return pcr_set_squelch(rig, vfo, val.f); case RIG_LEVEL_NR: /* This selectss the DSP unit - this isn't a level per se, * but in the manual it says that we have to switch it on first * we'll assume 1 is for the UT-106, and anything else as off * * Later on we can set if the DSP features are on or off in set_func */ /* return pcr_set_dsp(rig, vfo, (int) val.f); */ return pcr_set_dsp_noise_reducer(rig, vfo, val.f); } return err; } /* * pcr_get_level * * This needs a set of stored variables as the PCR doesn't return the current status of settings. * So we'll need to store them as we go along and keep them in sync. */ int pcr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; // rig_debug(RIG_DEBUG_TRACE, "%s: level = %d\n", __func__, level); switch (level) { case RIG_LEVEL_SQL: val->f = rcvr->squelch; return RIG_OK; case RIG_LEVEL_AF: val->f = rcvr->volume; return RIG_OK; case RIG_LEVEL_STRENGTH: if (priv->auto_update == 0) { err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I5?" : "I1?"); if (err != RIG_OK) { return err; } } val->i = rig_raw2val(rcvr->raw_level, &STATE(rig)->str_cal); /* rig_debug(RIG_DEBUG_TRACE, "%s, raw = %d, converted = %d\n", __func__, rcvr->raw_level, val->i); */ return RIG_OK; case RIG_LEVEL_RAWSTR: if (priv->auto_update == 0) { err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I5?" : "I1?"); if (err != RIG_OK) { return err; } } val->i = rcvr->raw_level; return RIG_OK; case RIG_LEVEL_IF: val->i = rcvr->last_shift; return RIG_OK; case RIG_LEVEL_ATT: val->i = rcvr->last_att; return RIG_OK; case RIG_LEVEL_AGC: val->i = rcvr->last_agc; return RIG_OK; } return -RIG_ENIMPL; } /* * pcr_set_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * This is missing a way to call the set DSP noise reducer, as we don't have a func to call it * based on the flags in rig.h -> see also missing a flag for setting the BFO. */ int pcr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d, func = %s\n", __func__, status, rig_strfunc(func)); switch (func) { case RIG_FUNC_NR: /* sets DSP noise reduction on or off */ /* status = 00 for off or 01 for on * always enable the DSP unit * even if only to turn it off */ if (status == 1) { pcr_set_dsp(rig, vfo, 1); return pcr_set_dsp_state(rig, vfo, 1); } else { pcr_set_dsp(rig, vfo, 1); return pcr_set_dsp_state(rig, vfo, 0); } break; case RIG_FUNC_ANF: /* DSP auto notch filter */ if (status == 1) { return pcr_set_dsp_auto_notch(rig, vfo, 1); } else { return pcr_set_dsp_auto_notch(rig, vfo, 0); } break; case RIG_FUNC_NB: /* noise blanker */ if (status == 0) { return pcr_set_nb(rig, vfo, 0); } else { return pcr_set_nb(rig, vfo, 1); } break; case RIG_FUNC_AFC: /* Tracking Filter */ if (status == 0) { return pcr_set_afc(rig, vfo, 0); } else { return pcr_set_afc(rig, vfo, 1); } break; case RIG_FUNC_TSQL: if (rcvr->last_mode != MD_FM) { return -RIG_ERJCTED; } if (status == 0) { return pcr_set_ctcss_sql(rig, vfo, 0); } else { return pcr_set_ctcss_sql(rig, vfo, rcvr->last_ctcss_sql); } case RIG_FUNC_VSC: /* Voice Scan Control */ if (status == 0) { return pcr_set_vsc(rig, vfo, 0); } else { return pcr_set_vsc(rig, vfo, 1); } break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: default\n", __func__); return -RIG_EINVAL; } } /* * pcr_get_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * This will need similar variables/flags as get_level. The PCR doesn't offer much in the way of * confirmation of current settings (according to the docs). */ int pcr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { /* stub here ... */ return -RIG_ENIMPL; } int pcr_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tok = %s\n", __func__, rig_strlevel(token)); switch (token) { case TOK_EL_ANL: /* automatic noise limiter */ return pcr_set_anl(rig, vfo, (0 == val.i) ? 0 : 1); case TOK_EL_DIVERSITY: /* antenna diversity */ return pcr_set_diversity(rig, vfo, (0 == val.i) ? 0 : 2); default: rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown token: %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* --------------------------------------------------------------------------------------- */ /* The next functions are all "helper types". These are called by the base functions above */ /* --------------------------------------------------------------------------------------- */ /* * Asks if the rig is ok = G0? response is G000 if ok or G001 if not * * Is only useful in fast transfer mode (when the CR/LF is stripped off all commands) ... * but also works on standard mode. */ static int pcr_check_ok(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return pcr_transaction(rig, "G0?"); } static int is_sub_rcvr(RIG *rig, vfo_t vfo) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; return vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && priv->current_vfo == RIG_VFO_SUB); } static int pcr_set_level_cmd(RIG *rig, const char *base, int level) { char buf[12]; rig_debug(RIG_DEBUG_TRACE, "%s: base is %s, level is %d\n", __func__, base, level); if (level < 0x0) { rig_debug(RIG_DEBUG_ERR, "%s: too low: %d\n", __func__, level); return -RIG_EINVAL; } else if (level > 0xff) { rig_debug(RIG_DEBUG_ERR, "%s: too high: %d\n", __func__, level); return -RIG_EINVAL; } SNPRINTF(buf, 12, "%s%02X", base, level); buf[11] = '\0'; return pcr_transaction(rig, buf); } /* * Sets the volume of the rig to the level specified in the level integer. * Format is J40xx - where xx is 00 to FF in hex, and specifies 255 volume levels */ static int pcr_set_volume(RIG *rig, vfo_t vfo, float level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level = %f\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J60" : "J40", level * 0xff); if (err == RIG_OK) { rcvr->volume = level; } return err; } /* * pcr_set_squelch * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Format is J41xx - where xx is 00 to FF in hex, and specifies 255 squelch levels * * Sets the squelch of the rig to the level specified in the level integer. * There are some bands though ... * 00 Tone squelch clear and squelch open * 01-3f Squelch open * 40-7f Noise squelch * 80-ff Noise squelch + S meter squelch ... * Comparative S level = (squelch setting - 128) X 2 * * Could do with some constants to add together to allow better (and more accurate) * use of Hamlib API. Otherwise may get unexpected squelch settings if have to do by hand. */ static int pcr_set_squelch(RIG *rig, vfo_t vfo, float level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level = %f\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J61" : "J41", level * 0xff); if (err == RIG_OK) { rcvr->squelch = level; } return err; } /* * pcr_set_if_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the IF shift of the rig to the level specified in the level integer. * IF-SHIFT position (in 256 stages, 80 = centre): * * < 80 Minus shift (in 10 Hz steps) * > 80 Plus shift (in 10 Hz steps) * 80 Centre * * Format is J43xx - where xx is 00 to FF in hex * */ int pcr_set_if_shift(RIG *rig, vfo_t vfo, int level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J63" : "J43", (level / 10) + 0x80); if (err == RIG_OK) { rcvr->last_shift = level; } return err; } /* * pcr_set_agc * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the AGC on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * * Format is J45xx - where xx is 00 to 01 in hex * */ int pcr_set_agc(RIG *rig, vfo_t vfo, int status) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J65" : "J45", status ? 1 : 0); if (err == RIG_OK) { rcvr->last_agc = status ? 1 : 0; } return err; } /* * pcr_set_afc(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the Tracking Filter on or off based on the status argument. * 00 = on, 01 (non zero) is off * * Format is LD820xx - where xx is 00 to ff in hex * */ int pcr_set_afc(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, "LD820", status ? 0 : 1); } /* * pcr_set_nb(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the noise blanker on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * * Format is J46xx - where xx is 00 to 01 in hex * */ int pcr_set_nb(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J66" : "J46", status ? 1 : 0); } /* Automatic Noise Limiter - J4Dxx - 00 off, 01 on */ int pcr_set_anl(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, "J4D", status ? 1 : 0); } /* Antenna Diversity/Tuners - J00xx - * 02=Dual Diversity ON, 1 display using 2 tuners * 01=Single Diversity OFF, 1 display using 1 tuner * 00=OFF Diversity OFF, 2 displays using 2 tuners */ int pcr_set_diversity(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); if (status < 0 || status > 2) { return -RIG_EINVAL; } return pcr_set_level_cmd(rig, "J00", status); } /* * pcr_set_attenuator(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the attenuator on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * The attenuator seems to be fixed at ~ -20dB * * Format is J47xx - where xx is 00 to 01 in hex * */ int pcr_set_attenuator(RIG *rig, vfo_t vfo, int status) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J67" : "J47", status ? 1 : 0); if (err == RIG_OK) { rcvr->last_att = status; } return err; } /* * pcr_set_bfo_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the BFO of the rig to the level specified in the level integer. * BFO-SHIFT position (in 256 stages, 80 = centre): * * < 80 Minus shift (in 10 Hz steps) * > 80 Plus shift (in 10 Hz steps) * 80 Centre * * Format is J4Axx - where xx is 00 to FF in hex, and specifies 255 levels * XXX command undocumented? */ int pcr_set_bfo_shift(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J6A" : "J4A", 0x80 + level / 10); } /* * pcr_set_dsp(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP to UT106 (01) or off (non 01) * */ int pcr_set_dsp(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J80", level); } /* * pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP on or off (> 0 = on, 0 = off) * */ int pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J81", level); } /* * pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP noise reducer on or off (0x01 = on, 0x00 = off) * the level of NR set by values 0x01 to 0x10 (1 to 16 inclusive) */ #if 1 /* unused; re-enabled as needed. */ int pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J82", level); } #endif /* unused */ /* * pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the auto notch on or off (1 = on, 0 = off) */ int pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int status) // J83xx { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, status); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J83", status ? 1 : 0); } int pcr_set_vsc(RIG *rig, vfo_t vfo, int status) // J50xx { /* Not sure what VSC for so skipping the function here ... */ return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J70" : "J50", status ? 1 : 0); } int pcr_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *tone = rcvr->last_ctcss_sql; return RIG_OK; } int pcr_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int i, err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: tone = %u\n", __func__, tone); if (tone == 0) { return pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "J7100" : "J5100"); } for (i = 0; rig->caps->ctcss_list[i] != 0; i++) { if (rig->caps->ctcss_list[i] == tone) { break; } } rig_debug(RIG_DEBUG_TRACE, "%s: index = %d, tone = %u\n", __func__, i, rig->caps->ctcss_list[i]); if (rig->caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J71" : "J51", i + 1); if (err == RIG_OK) { rcvr->last_ctcss_sql = tone; } return RIG_OK; } int pcr_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *tone = rcvr->last_dcs_sql; return RIG_OK; } int pcr_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t tone) { int i, err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: tone = %u\n", __func__, tone); if (tone == 0) { return pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "J720000" : "J520000"); } for (i = 0; rig->caps->dcs_list[i] != 0; i++) { if (rig->caps->dcs_list[i] == tone) { break; } } rig_debug(RIG_DEBUG_TRACE, "%s: index = %d, tone = %u\n", __func__, i, rig->caps->dcs_list[i]); if (rig->caps->dcs_list[i] != tone) { return -RIG_EINVAL; } err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J7200" : "J5200", i + 1); if (err == RIG_OK) { rcvr->last_dcs_sql = tone; } return RIG_OK; } int pcr_set_trn(RIG *rig, int trn) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: trn = %d\n", __func__, trn); if (trn == RIG_TRN_OFF) { priv->auto_update = 0; return pcr_transaction(rig, "G300"); } else if (trn == RIG_TRN_RIG) { priv->auto_update = 1; return pcr_send(rig, "G301"); } else { return -RIG_EINVAL; } } int pcr_decode_event(RIG *rig) { int err; char buf[4]; /* XXX check this */ err = pcr_read_block(rig, buf, 4); if (err == 4) { return pcr_parse_answer(rig, buf, 4); } return RIG_OK; } int pcr_set_powerstat(RIG *rig, powerstat_t status) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; if (status == priv->power) { return RIG_OK; } if (status == RIG_POWER_ON) { return pcr_open(rig); } else if (status == RIG_POWER_OFF) { return pcr_close(rig); } return -RIG_ENIMPL; } int pcr_get_powerstat(RIG *rig, powerstat_t *status) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; int err; /* return RIG_ERJCTED if power is off */ err = pcr_transaction(rig, "H1?"); if (err != RIG_OK && err != -RIG_ERJCTED) { return err; } priv->power = err == RIG_OK ? RIG_POWER_ON : RIG_POWER_OFF; *status = priv->power; return RIG_OK; } int pcr_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; if (priv->auto_update == 0) { int err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I4?" : "I0?"); if (err != RIG_OK) { return err; } } /* 04 = Closed, 07 = Open * * Bit 0: busy * Bit 1: AF open (CTCSS open) * Bit 2: VSC open * Bit 3: RX error (not ready to receive) */ *dcd = (rcvr->squelch_status & 0x02) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* ********************************************************************************************* * int pcr_set_comm_mode(RIG *rig, int mode_type); // Set radio to fast/diagnostic mode G3xx * int pcr_soft_reset(RIG *rig); // Ask rig to reset itself H0xx ********************************************************************************************* */ DECLARE_INITRIG_BACKEND(pcr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: init called\n", __func__); rig_register(&pcr100_caps); rig_register(&pcr1000_caps); rig_register(&pcr1500_caps); rig_register(&pcr2500_caps); return RIG_OK; } hamlib-4.6.5/rigs/pcr/Android.mk0000664000175000017500000000043315056640443012115 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c LOCAL_MODULE := pcr LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/pcr/Makefile.in0000664000175000017500000005374315056640453012266 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/pcr ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_pcr_la_LIBADD = am__objects_1 = pcr1000.lo pcr100.lo pcr1500.lo pcr2500.lo pcr.lo am_libhamlib_pcr_la_OBJECTS = $(am__objects_1) libhamlib_pcr_la_OBJECTS = $(am_libhamlib_pcr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pcr.Plo ./$(DEPDIR)/pcr100.Plo \ ./$(DEPDIR)/pcr1000.Plo ./$(DEPDIR)/pcr1500.Plo \ ./$(DEPDIR)/pcr2500.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_pcr_la_SOURCES) DIST_SOURCES = $(libhamlib_pcr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PCRSRC = pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c pcr.h noinst_LTLIBRARIES = libhamlib-pcr.la libhamlib_pcr_la_SOURCES = $(PCRSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/pcr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/pcr/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-pcr.la: $(libhamlib_pcr_la_OBJECTS) $(libhamlib_pcr_la_DEPENDENCIES) $(EXTRA_libhamlib_pcr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_pcr_la_OBJECTS) $(libhamlib_pcr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr1000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr1500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr2500.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pcr.Plo -rm -f ./$(DEPDIR)/pcr100.Plo -rm -f ./$(DEPDIR)/pcr1000.Plo -rm -f ./$(DEPDIR)/pcr1500.Plo -rm -f ./$(DEPDIR)/pcr2500.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pcr.Plo -rm -f ./$(DEPDIR)/pcr100.Plo -rm -f ./$(DEPDIR)/pcr1000.Plo -rm -f ./$(DEPDIR)/pcr1500.Plo -rm -f ./$(DEPDIR)/pcr2500.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/pcr/pcr.h0000664000175000017500000000677615056640443011161 /* * Hamlib PCR backend - main header * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _PCR_H #define _PCR_H 1 #include "hamlib/rig.h" #include "token.h" /* ext_level's tokens */ #define TOK_EL_ANL TOKEN_BACKEND(1) #define TOK_EL_DIVERSITY TOKEN_BACKEND(2) #define BACKEND_VER "20200323" #define PCR_MAX_CMD_LEN 32 struct pcr_priv_data { struct pcr_rcvr { freq_t last_freq; int last_mode; int last_filter; int last_shift; int last_att; int last_agc; tone_t last_ctcss_sql; tone_t last_dcs_sql; float volume; float squelch; unsigned int raw_level; unsigned int squelch_status; } main_rcvr, sub_rcvr; vfo_t current_vfo; int auto_update; char info[100]; char cmd_buf[PCR_MAX_CMD_LEN]; char reply_buf[PCR_MAX_CMD_LEN]; int protocol; int firmware; int country; int options; int sync; powerstat_t power; }; struct pcr_priv_caps { unsigned int reply_size; unsigned int reply_offset; unsigned int always_sync; }; #define pcr_caps(rig) ((struct pcr_priv_caps *)(rig)->caps->priv) extern tone_t pcr_ctcss_list[]; extern tone_t pcr_dcs_list[]; int pcr_init(RIG *rig); int pcr_cleanup(RIG *rig); int pcr_open(RIG *rig); int pcr_close(RIG *rig); int pcr_set_vfo(RIG * rig, vfo_t vfo); int pcr_get_vfo(RIG * rig, vfo_t *vfo); int pcr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int pcr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int pcr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int pcr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); const char *pcr_get_info(RIG *rig); /* Added - G0WCW */ int pcr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int pcr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int pcr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int pcr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int pcr_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int pcr_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int pcr_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int pcr_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *tone); int pcr_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t tone); int pcr_set_trn(RIG * rig, int trn); int pcr_decode_event(RIG *rig); int pcr_set_powerstat(RIG * rig, powerstat_t status); int pcr_get_powerstat(RIG * rig, powerstat_t *status); int pcr_get_dcd(RIG * rig, vfo_t vfo, dcd_t *dcd); /* ------------------------------------------------------------------ */ // int pcr_get_param(RIG *rig, setting_t parm, value_t *val); // int pcr_set_param(RIG *rig, setting_t parm, value_t *val); extern struct rig_caps pcr1000_caps; extern struct rig_caps pcr100_caps; extern struct rig_caps pcr1500_caps; extern struct rig_caps pcr2500_caps; #endif /* _PCR_H */ hamlib-4.6.5/rigs/pcr/pcr2500.c0000664000175000017500000001415715056640443011453 /* * Hamlib PCR backend - PCR-2500 description * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR2500_MODES_WIDE ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR2500_MODES_NAR ( RIG_MODE_CW | RIG_MODE_SSB ) #define PCR2500_MODES ( PCR2500_MODES_NAR | PCR2500_MODES_WIDE ) #define PCR2500_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR2500_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct confparams pcr2500_ext_levels[] = { { TOK_EL_DIVERSITY, "DIV", "Diversity", "Antenna/tuner diversity", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct pcr_priv_caps pcr2500_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR2500 rigs capabilities. */ struct rig_caps pcr2500_caps = { RIG_MODEL(RIG_MODEL_PCR2500), .model_name = "IC-PCR2500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* lower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = PCR2500_FUNC, .has_set_func = PCR2500_FUNC, .has_get_level = PCR2500_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR2500_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = pcr_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(100), GHz(1.3), PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { kHz(10), GHz(3.3) - kHz(1), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(50), GHz(1.3), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_SUB, RIG_ANT_2 }, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(495), MHz(824) - 10, PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(849) + 10, MHz(869) - 10, PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(894) + 10, GHz(1.3), PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { kHz(10), MHz(824) - 10, PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(849) + 10, MHz(869) - 10, PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(894) + 10, GHz(3.3) - kHz(1), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(50), GHz(1.3), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_SUB, RIG_ANT_2 }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR2500_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8)}, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM | RIG_MODE_FM, kHz(6) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .extlevels = pcr2500_ext_levels, .priv = (void *)& pcr2500_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_vfo = pcr_set_vfo, .get_vfo = pcr_get_vfo, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_ext_level = pcr_set_ext_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_dcs_sql = pcr_set_dcs_sql, .get_dcs_sql = pcr_get_dcs_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .get_dcd = pcr_get_dcd, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/pcr/pcr1000.c0000664000175000017500000001170015056640443011434 /* * Hamlib PCR backend - PCR-1000 description * Copyright (c) 2001-2009 by Stephane Fillod and Darren Hatcher * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR1000_MODES ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_CW | RIG_MODE_SSB ) #define PCR1000_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR1000_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct pcr_priv_caps pcr1000_priv = { .reply_size = 6, .reply_offset = 1, .always_sync = 0, }; /* * IC PCR1000 rigs capabilities. */ struct rig_caps pcr1000_caps = { RIG_MODEL(RIG_MODEL_PCR1000), .model_name = "IC-PCR1000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* slower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 12, .post_write_delay = 2, .timeout = 400, .retry = 3, .has_get_func = PCR1000_FUNC, .has_set_func = PCR1000_FUNC, .has_get_level = PCR1000_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR1000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(10), GHz(1.3), PCR1000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(10), MHz(824) - 10, PCR1000_MODES, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1000_MODES, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR1000_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR1000_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_FM | RIG_MODE_AM, kHz(6) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr1000_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/pcr/pcr1500.c0000664000175000017500000001265215056640443011450 /* * Hamlib PCR backend - PCR-1500 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR1500_MODES_WIDE ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR1500_MODES_NAR ( RIG_MODE_CW | RIG_MODE_SSB ) #define PCR1500_MODES ( PCR1500_MODES_NAR | PCR1500_MODES_WIDE ) #define PCR1500_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR1500_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct pcr_priv_caps pcr1500_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR1500 rigs capabilities. */ struct rig_caps pcr1500_caps = { RIG_MODEL(RIG_MODEL_PCR1500), .model_name = "IC-PCR1500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* lower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = PCR1500_FUNC, .has_set_func = PCR1500_FUNC, .has_get_level = PCR1500_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR1500_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 1 } }, [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 16.0 }, .step = { .f = 1.0 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(495), GHz(1.3), PCR1500_MODES_NAR, -1, -1, RIG_VFO_A}, { kHz(10), GHz(3.3) - kHz(1), PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A}, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(495), MHz(824) - 10, PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { kHz(10), MHz(824) - 10, PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(3.3) - kHz(1), PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR1500_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8)}, { RIG_MODE_FM | RIG_MODE_AM, kHz(6) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr1500_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/pcr/Makefile.am0000664000175000017500000000024115056640443012235 PCRSRC = pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c pcr.h noinst_LTLIBRARIES = libhamlib-pcr.la libhamlib_pcr_la_SOURCES = $(PCRSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/rigs/kenwood/0000775000175000017500000000000015056640477011155 5hamlib-4.6.5/rigs/kenwood/th.c0000664000175000017500000016505415056640443011660 /* * Hamlib Kenwood backend - TH handheld primitives * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (C) 2010 by Alessandro Zummo * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" #include "num_stdio.h" /* Note: Currently the code assumes the command termination is a * single character. */ #define ACKBUF_LEN 64 /* * th_decode_event is called by sa_sigio, when some asynchronous * data has been received from the rig. */ int th_decode_event(RIG *rig) { char asyncbuf[128]; int retval; int async_len; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); async_len = strlen(asyncbuf); if (async_len > 3 && asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') { vfo_t vfo; freq_t freq, offset; int mode; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; retval = num_sscanf(asyncbuf, "BUF %u,%"SCNfreq",%X,%d,%d,%d,%d,,%d,,%d,%"SCNfreq",%d", &vfo, &freq, (unsigned int *)&step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset, &mode); if (retval != 11) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } /* Calibration and conversions */ vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; mode = (mode == 0) ? RIG_MODE_FM : RIG_MODE_AM; rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (vfo %u, freq %"PRIfreq" Hz, mode %d)\n", __func__, vfo, freq, mode); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, vfo, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } } else if (async_len > 2 && asyncbuf[0] == 'S' && asyncbuf[1] == 'M') { vfo_t vfo; int lev; retval = sscanf(asyncbuf, "SM %u,%d", &vfo, &lev); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } /* Calibration and conversions */ vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; 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, vfo, (float)(lev / 5.0), rig->callbacks.strength_arg); #endif } else if (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') { vfo_t vfo; int busy; retval = sscanf(asyncbuf, "BY %u,%d", &vfo, &busy); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; 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 (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'C') { vfo_t vfo; retval = sscanf(asyncbuf, "BC %u", &vfo); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BC message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: VFO event - vfo = %u\n", __func__, vfo); if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } } else { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } return RIG_OK; } static int kenwood_wrong_vfo(const char *func, vfo_t vfo) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", func, rig_strvfo(vfo)); return -RIG_ENTARGET; } /* * th_set_freq * Assumes rig!=NULL */ int th_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char buf[20]; int step; freq_t freq5, freq625, freq_sent; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (fabs(freq5 - freq) < fabs(freq625 - freq)) { step = 0; freq_sent = freq5; } else { step = 1; freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ step = freq_sent >= MHz(470) ? 4 : step; freq_sent = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; SNPRINTF(buf, sizeof(buf), "FQ %011"PRIll",%X\r", (int64_t) freq_sent, step); return kenwood_transaction(rig, buf, buf, strlen(buf)); } /* * th_get_freq * Assumes rig!=NULL, freq!=NULL */ int th_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[20]; int retval, step; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } *freq = 0; retval = kenwood_safe_transaction(rig, "FQ", buf, sizeof(buf), 16); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FQ %"SCNfreq",%x", freq, (unsigned *)&step); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } /* * th_set_mode * Assumes rig!=NULL */ int th_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char kmode, mdbuf[8]; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } if (priv->mode_table) { kmode = rmode2kenwood(mode, priv->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unsupported Mode value '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } kmode += '0'; } else { switch (mode) { case RIG_MODE_FM: kmode = '0'; break; /* TH-D7A(G) modes */ case RIG_MODE_AM: kmode = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } } SNPRINTF(mdbuf, sizeof(mdbuf), "MD %c", kmode); return kenwood_transaction(rig, mdbuf, mdbuf, strlen(mdbuf)); } /* * th_get_mode * Assumes rig!=NULL, mode!=NULL */ int th_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[ACKBUF_LEN]; int retval; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, "MD", buf, sizeof(buf), 4); if (retval != RIG_OK) { return retval; } if (buf[3] < '0' || buf[3] > '9') { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } if (priv->mode_table) { *mode = kenwood2rmode(buf[3] - '0', priv->mode_table); if (*mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode (table)value '%c'\n", __func__, buf[3]); return -RIG_EINVAL; } } else { switch (buf[3]) { case '0': *mode = RIG_MODE_FM; break; /* TH-D7A(G) modes */ case '1': *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode value '%c'\n", __func__, buf[3]); return -RIG_EINVAL; } } if (width) { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } /* * th_set_vfo * Apply to non-split models: TH-F7, TH-D7 * * Assumes rig!=NULL */ int th_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd[8]; char cmdbuf[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* from thf7.c * The band must be active before selecting VFO or MEM. * The dilemma is whether MEM should be applied to Band A or Band B. * Remember, not all bands have the same capability * TODO: if (RIG_VFO_MEM) query current band with BC, then do appropriate VMC */ /* set band */ if (vfo != RIG_VFO_MEM) { switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: strncpy(cmd, "BC 0", sizeof(cmd)); break; case RIG_VFO_B: case RIG_VFO_SUB: strncpy(cmd, "BC 1", sizeof(cmd)); break; default: return kenwood_wrong_vfo(__func__, vfo); } return kenwood_transaction(rig, cmd, cmd, strlen(cmd)); } /* No "VMC" cmd on THD72A/THD74 */ if (rig->caps->rig_model == RIG_MODEL_THD72A || rig->caps->rig_model == RIG_MODEL_THD74) { return RIG_OK; } /* set vfo */ switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: strncpy(cmd, "VMC 0,0", sizeof(cmd)); break; case RIG_VFO_B: case RIG_VFO_SUB: strncpy(cmd, "VMC 1,0", sizeof(cmd)); break; case RIG_VFO_MEM: strncpy(cmd, "BC", sizeof(cmd)); retval = kenwood_transaction(rig, cmd, cmd, 7); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { SNPRINTF(cmd, sizeof(cmd), "VMC %c,1", cmd[3]); } else { SNPRINTF(cmd, sizeof(cmd), "VMC %c,2", cmd[3]); } break; default: return kenwood_wrong_vfo(__func__, vfo); } return kenwood_transaction(rig, cmd, cmdbuf, strlen(cmd)); } int th_get_vfo_char(RIG *rig, vfo_t *vfo, char *vfoch) { char cmdbuf[10], buf[10], vfoc; int retval; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_transaction(rig, "BC", buf, 7); if (retval != RIG_OK) { return retval; } length = strlen(buf); switch (length) { case 4: /*original case BC 0*/ vfoc = buf[3]; break; case 6: /*intended for D700 BC 0,0*/ if ((buf[0] == 'B') && (buf[1] == 'C') && (buf[2] == ' ') && (buf[4] == ',')) { vfoc = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer format '%s'\n", __func__, buf); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; break; } switch (vfoc) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); return -RIG_EVFO; } /* No "VMC" on THD72A/THD74 */ if (rig->caps->rig_model == RIG_MODEL_THD72A || rig->caps->rig_model == RIG_MODEL_THD74) { *vfoch = '0'; /* FIXME: fake */ return RIG_OK; } /* Get mode of the VFO band */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "VMC %c", vfoc); retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 7); if (retval != RIG_OK) { return retval; } *vfoch = buf[6]; return RIG_OK; } /* * th_get_vfo * Assumes rig!=NULL */ int th_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '1' : break; case '2' : *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * tm_set_vfo_bc2 * Apply to split-capable models (with BC command taking 2 args): TM-V7, TM-D700 * * Assumes rig!=NULL */ int tm_set_vfo_bc2(RIG *rig, vfo_t vfo) { struct rig_state *rs = STATE(rig); const struct kenwood_priv_data *priv = rs->priv; char cmd[16]; int vfonum, txvfonum, vfomode = 0; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = 0; /* put back split mode when toggling */ txvfonum = (priv->split == RIG_SPLIT_ON && rs->tx_vfo == RIG_VFO_B) ? 1 : vfonum; break; case RIG_VFO_B: vfonum = 1; /* put back split mode when toggling */ txvfonum = (priv->split == RIG_SPLIT_ON && rs->tx_vfo == RIG_VFO_A) ? 0 : vfonum; break; case RIG_VFO_MEM: /* get current band */ SNPRINTF(cmd, sizeof(cmd), "BC"); retval = kenwood_transaction(rig, cmd, cmd, 7); if (retval != RIG_OK) { return retval; } txvfonum = vfonum = cmd[3] - '0'; vfomode = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %u\n", __func__, vfo); return -RIG_EVFO; } SNPRINTF(cmd, sizeof(cmd), "VMC %d,%d", vfonum, vfomode); retval = kenwood_transaction(rig, cmd, cmd, 8); if (retval != RIG_OK) { return retval; } if (vfo == RIG_VFO_MEM) { return RIG_OK; } SNPRINTF(cmd, sizeof(cmd), "BC %d,%d", vfonum, txvfonum); return kenwood_transaction(rig, cmd, cmd, 7); } int th_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char vfobuf[16]; int vfonum, txvfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &vfo); if (retval != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = 0; if (split == RIG_SPLIT_ON && txvfo != RIG_VFO_B) { return -RIG_EINVAL; } txvfonum = split == RIG_SPLIT_ON ? 1 : vfonum; break; case RIG_VFO_B: vfonum = 1; if (split == RIG_SPLIT_ON && txvfo != RIG_VFO_A) { return -RIG_EINVAL; } txvfonum = split == RIG_SPLIT_ON ? 0 : vfonum; break; default: return -RIG_EINVAL; } /* Set VFO mode. To be done for TX vfo also? */ SNPRINTF(vfobuf, sizeof(vfobuf), "VMC %d,0", vfonum); retval = kenwood_transaction(rig, vfobuf, vfobuf, strlen(vfobuf)); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC %d,%d", vfonum, txvfonum); retval = kenwood_transaction(rig, vfobuf, vfobuf, 7); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for th_set_vfo */ priv->split = split; return RIG_OK; } int th_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } *split = (buf[3] == buf[5]) ? RIG_SPLIT_OFF : RIG_SPLIT_ON; /* Remember whether split is on, for th_set_vfo */ priv->split = *split; return RIG_OK; } /* * th_set_trn * Assumes rig!=NULL */ int th_set_trn(RIG *rig, int trn) { char buf[5]; SNPRINTF(buf, sizeof(buf), "AI %c", RIG_TRN_RIG == trn ? '1' : '0'); return kenwood_transaction(rig, buf, buf, strlen(buf)); } /* * th_get_trn * Assumes rig!=NULL */ int th_get_trn(RIG *rig, int *trn) { char buf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "AI", buf, 5); if (retval != RIG_OK) { return retval; } if (strlen(buf) != 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } *trn = (buf[2] != '0') ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * th_get_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int th_get_kenwood_func(RIG *rig, const char *cmd, int *status) { char buf[8]; int retval, len, expected; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); len = strlen(cmd); expected = len + 2; retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), expected); if (retval != RIG_OK) { return retval; } if (status) { *status = (buf[len + 1] == '0') ? 0 : 1; } return RIG_OK; }; /* * th_get_func * Assumes rig!=NULL, status!=NULL * * Assumes vfo == RIG_VFO_CURR, any other value is handled by the frontend. */ int th_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_MUTE: return th_get_kenwood_func(rig, "MUTE", status); case RIG_FUNC_MON: return th_get_kenwood_func(rig, "MON", status); case RIG_FUNC_TONE: return th_get_kenwood_func(rig, "TO", status); case RIG_FUNC_TSQL: return th_get_kenwood_func(rig, "CT", status); case RIG_FUNC_REV: return th_get_kenwood_func(rig, "REV", status); case RIG_FUNC_ARO: return th_get_kenwood_func(rig, "ARO", status); case RIG_FUNC_AIP: return th_get_kenwood_func(rig, "AIP", status); case RIG_FUNC_LOCK: return th_get_kenwood_func(rig, "LK", status); case RIG_FUNC_BC: return th_get_kenwood_func(rig, "BC", status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } static int th_tburst(RIG *rig, vfo_t vfo, int status) { return kenwood_transaction(rig, (status == 1) ? "TT" : "RX", NULL, 0); } /* * th_set_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int th_set_kenwood_func(RIG *rig, const char *cmd, int status) { #define BUFSZ 16 char buf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, status = %d\n", __func__, cmd, status); strncpy(buf, cmd, BUFSZ - 2); buf[BUFSZ - 1] = '\0'; strncat(buf, status ? " 1" : " 0", BUFSZ - 1); return kenwood_transaction(rig, buf, NULL, 0); } /* * th_get_func * Assumes rig!=NULL, status!=NULL * * Assumes vfo == RIG_VFO_CURR, any other value is handled by the frontend. */ int th_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_MUTE: return th_set_kenwood_func(rig, "MUTE", status); case RIG_FUNC_MON: return th_set_kenwood_func(rig, "MON", status); case RIG_FUNC_TONE: return th_set_kenwood_func(rig, "TO", status); case RIG_FUNC_TSQL: return th_set_kenwood_func(rig, "CT", status); case RIG_FUNC_REV: return th_set_kenwood_func(rig, "REV", status); case RIG_FUNC_ARO: return th_set_kenwood_func(rig, "ARO", status); case RIG_FUNC_AIP: return th_set_kenwood_func(rig, "AIP", status); case RIG_FUNC_LOCK: return th_set_kenwood_func(rig, "LK", status); case RIG_FUNC_BC: return th_set_kenwood_func(rig, "NSFT", status); case RIG_FUNC_TBURST: return th_tburst(rig, vfo, status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } int th_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04x)\n", __func__, scan); return th_set_kenwood_func(rig, "SC", scan == RIG_SCAN_STOP ? 0 : 1); } /* * th_get_parm * Assumes rig!=NULL, status!=NULL */ int th_get_parm(RIG *rig, setting_t parm, value_t *val) { char buf[16]; int ret, status; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strparm(parm)); switch (parm) { case RIG_PARM_BEEP: ret = th_get_kenwood_func(rig, "BEP", &status); if (ret != RIG_OK) { return ret; } val->i = status ? 1 : 0; return RIG_OK; case RIG_PARM_APO: ret = kenwood_safe_transaction(rig, "APO", buf, sizeof(buf), 5); if (ret != RIG_OK) { return ret; } val->i = (buf[4] - '0') * 30; return RIG_OK; case RIG_PARM_BACKLIGHT: if (rig->caps->rig_model == RIG_MODEL_TMD700) { ret = kenwood_safe_transaction(rig, "DIM", buf, sizeof(buf), 4); if (ret != RIG_OK) { return ret; } val->f = buf[4] == '0' ? 0 : (float)(5 - (buf[4] - '0')) / 4.; } else { ret = th_get_kenwood_func(rig, "LMP", &status); if (ret != RIG_OK) { return ret; } val->f = status ? 1.0 : 0; } return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } int th_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: if (rig->caps->rig_model == RIG_MODEL_TMD700) { return th_set_kenwood_func(rig, "DIM", (val.f > 0) ? 1 : 0); /* FIXME */ } else { return th_set_kenwood_func(rig, "LMP", (val.f > 0) ? 1 : 0); } case RIG_PARM_BEEP: return th_set_kenwood_func(rig, "BEP", val.i); case RIG_PARM_APO: if (val.i > 30) { return kenwood_transaction(rig, "APO 2", NULL, 0); } else if (val.i > 0) { return kenwood_transaction(rig, "APO 1", NULL, 0); } else { return kenwood_transaction(rig, "APO 0", NULL, 0); } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * th_get_level * Assumes rig!=NULL, val!=NULL */ int th_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char vch, buf[10], ackbuf[20]; int retval, v; unsigned int l; struct rig_state *rs = STATE(rig); vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? rs->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: vch = '0'; break; case RIG_VFO_B: vch = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } switch (level) { case RIG_LEVEL_RAWSTR: SNPRINTF(buf, sizeof(buf), "SM %c", vch); // XXX use kenwood_safe_transaction retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SM %d,%u", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_RAWSTR].min.i || l > rig->caps->level_gran[LVL_RAWSTR].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } val->i = l; break; case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), "SQ %c", vch); retval = kenwood_safe_transaction(rig, buf, ackbuf, 10, 7); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SQ %d,%x", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_SQL].min.i || l > rig->caps->level_gran[LVL_SQL].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_SQL].min.i) / (float)(rig->caps->level_gran[LVL_SQL].max.i - rig->caps->level_gran[LVL_SQL].min.i); break; case RIG_LEVEL_AF: SNPRINTF(buf, sizeof(buf), "AG %c", vch); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "AG %d,%x", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_AF].min.i || l > rig->caps->level_gran[LVL_AF].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_AF].min.i) / (float)(rig->caps->level_gran[LVL_AF].max.i - rig->caps->level_gran[LVL_AF].min.i); break; case RIG_LEVEL_RFPOWER: SNPRINTF(buf, sizeof(buf), "PC %c", vch); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "PC %d,%u", &v, &l); if ((retval != 2) || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_RFPOWER].min.i) / (float)(rig->caps->level_gran[LVL_RFPOWER].max.i - rig->caps->level_gran[LVL_RFPOWER].min.i); break; case RIG_LEVEL_BALANCE: retval = kenwood_safe_transaction(rig, "BAL", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '8') { return -RIG_EPROTO; } val->f = (float)('4' - ackbuf[4]) / ('4' - '0'); break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "ATT", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '8') { return -RIG_EPROTO; } if (ackbuf[4] == '0') { val->i = 0; } else { val->i = rs->attenuator[ackbuf[4] - '1']; } break; case RIG_LEVEL_VOXGAIN: retval = kenwood_safe_transaction(rig, "VXG", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '9') { return -RIG_EPROTO; } val->f = (ackbuf[4] == '0') / 9; break; case RIG_LEVEL_VOXDELAY: /* "VXD" */ return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int th_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char vch, buf[12]; vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: vch = '0'; break; case RIG_VFO_B: vch = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } switch (level) { case RIG_LEVEL_RFPOWER : SNPRINTF(buf, sizeof(buf), "PC %c,%01d", vch, (int)(val.f * (rig->caps->level_gran[LVL_RFPOWER].max.i - rig->caps->level_gran[LVL_RFPOWER].min.i)) + rig->caps->level_gran[LVL_RFPOWER].min.i); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_SQL : SNPRINTF(buf, sizeof(buf), "SQ %c,%02x", vch, (int)(val.f * (rig->caps->level_gran[LVL_SQL].max.i - rig->caps->level_gran[LVL_SQL].min.i)) + rig->caps->level_gran[LVL_SQL].min.i); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_AF : SNPRINTF(buf, sizeof(buf), "AG %c,%02x", vch, (int)(val.f * 32.0)); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_ATT : SNPRINTF(buf, sizeof(buf), "ATT %c", val.i ? '1' : '0'); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_BALANCE : SNPRINTF(buf, sizeof(buf), "BAL %c", '4' - (int)(val.f * ('4' - '0'))); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_VOXGAIN: SNPRINTF(buf, sizeof(buf), "VXG %d", (int)(val.f * 9)); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_VOXDELAY: /* "VXD" */ return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } } #ifndef RIG_TONEMAX #define RIG_TONEMAX 38 #endif /* * th_set_ctcss_tone * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int th_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; 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-D7A index anomaly */ SNPRINTF(tonebuf, sizeof(tonebuf), "TN %02d", i); return kenwood_transaction(rig, tonebuf, tonebuf, sizeof(tonebuf)); } /* * th_get_ctcss_tone * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "TN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "TN %d", (int *)&tone_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify tone index for TH-7DA rig */ if (tone_idx == 0 || tone_idx == 2 || tone_idx > 39) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected CTCSS tone no (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } tone_idx -= (tone_idx == 1) ? 1 : 2; /* Correct for TH-D7A index anomaly */ *tone = caps->ctcss_list[tone_idx]; return RIG_OK; } /* * th_set_ctcss_sql * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int th_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; 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-D7A index anomaly */ SNPRINTF(tonebuf, sizeof(tonebuf), "CTN %02d", i); return kenwood_transaction(rig, tonebuf, tonebuf, sizeof(tonebuf)); } /* * thd7_get_ctcss_sql * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "CTN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "CTN %d", (int *)&tone_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify tone index for TH-7DA rig */ if (tone_idx == 0 || tone_idx == 2 || tone_idx > 39) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected CTCSS no (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } tone_idx -= (tone_idx == 1) ? 1 : 2; /* Correct for TH-7DA index anomaly */ *tone = caps->ctcss_list[tone_idx]; return RIG_OK; } #ifndef RIG_CODEMAX #define RIG_CODEMAX 104 #endif /* * th_set_dcs_sql * Assumes rig!=NULL, rig->caps->dcs_list != NULL */ int th_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct rig_caps *caps; char codebuf[16]; int i, retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; if (code == 0) { SNPRINTF(codebuf, sizeof(codebuf), "DCS 0"); return kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf)); } for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { return -RIG_EINVAL; } SNPRINTF(codebuf, sizeof(codebuf), "DCS 1"); if ((retval = kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf))) != RIG_OK) { return retval; } SNPRINTF(codebuf, sizeof(codebuf), "DCSN %04d", (i + 1) * 10); return kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf)); } /* * th_get_dcs_sql * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int code_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "DCS", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "DCSN %d", (int *)&code_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } if (code_idx == 0) { *code = 0; /* disabled */ return RIG_OK; } retval = kenwood_transaction(rig, "DCSN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "DCSN %d", (int *)&code_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify code index for TM-D700 rig */ if (code_idx <= 10 || code_idx > 1040) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected DCS no (%04u)\n", __func__, code_idx); return -RIG_EPROTO; } code_idx = (code_idx / 10) - 1; *code = caps->dcs_list[code_idx]; return RIG_OK; } const char * th_get_info(RIG *rig) { static char firmbuf[50]; int retval; size_t firm_len; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "ID", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len < 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%d\n", __func__, firmbuf, (int)firm_len); return NULL; } return &firmbuf[2]; } /* * th_set_mem * Assumes rig!=NULL */ int th_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char vsel; char membuf[10]; int retval; vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_A: vsel = '0'; break; case RIG_VFO_B: vsel = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } if ((retval = rig_set_vfo(rig, RIG_VFO_MEM)) != RIG_OK) { return retval; } SNPRINTF(membuf, sizeof(membuf), "MC %c,%03i", vsel, ch); return kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); } /* Get mem works only when the display is * in memory mode */ int th_get_mem(RIG *rig, vfo_t vfo, int *ch) { char *membuf, buf[10]; int retval; vfo_t tvfo, cvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* store current VFO */ cvfo = STATE(rig)->current_vfo; /* check if we should switch VFO */ if (cvfo != RIG_VFO_MEM) { retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) { return retval; } } tvfo = (vfo == RIG_VFO_CURR) ? cvfo : vfo; switch (tvfo) { case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_A: membuf = "MC 0"; break; case RIG_VFO_B: membuf = "MC 1"; break; default: return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, membuf, buf, 10, 8); if (retval != RIG_OK) { return retval; } *ch = atoi(&buf[5]); /* switch back if appropriate */ if (cvfo != RIG_VFO_MEM) { retval = rig_set_vfo(rig, cvfo); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int th_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char buf[3]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", buf, sizeof(buf)); } int th_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char *cmd, buf[8]; int retval; if (vfo == RIG_VFO_CURR) { retval = th_get_vfo(rig, &vfo); if (retval != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: case RIG_VFO_MAIN: cmd = "BY 0"; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd = "BY 1"; break; default: return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0' : *dcd = RIG_DCD_OFF; return RIG_OK; case '1' : *dcd = RIG_DCD_ON; return RIG_OK; default : rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s'\n", __func__, buf); } return -RIG_ERJCTED; } int th_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); case RIG_OP_TO_VFO: return kenwood_transaction(rig, "MSH", NULL, 0); default: return -RIG_EINVAL; } } /* get and set channel tested on thg71&thf7e */ /* must work on other th and tm kenwood rigs */ /* --------------------------------------------------------------------- */ int th_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char membuf[64], ackbuf[ACKBUF_LEN]; int retval; freq_t freq, offset; char req[32], scf[128]; int step, shift, rev, tone, ctcss, tonefq, ctcssfq, dcs, dcscode, mode, lockout; const char *mr_extra; int channel_num; vfo_t vfotmp; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; const chan_t *chan_caps; if (chan->vfo == RIG_VFO_MEM) { chan_caps = rig_lookup_mem_caps(rig, chan->channel_num); if (!chan_caps) { return -RIG_ECONF; } } else { /* TODO: stuff channel_num (out of current freq) and chan_caps */ return -RIG_ENIMPL; } channel_num = chan->channel_num; vfotmp = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = channel_num; chan->vfo = vfotmp; if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { mr_extra = ""; } else { mr_extra = "0, "; } channel_num -= chan_caps->startc; switch (chan_caps->type) { case RIG_MTYPE_MEM: if (chan_caps[1].type == RIG_MTYPE_PRIO) { /* Info */ SNPRINTF(req, sizeof(req), "MR %s0,I-%01d", mr_extra, channel_num); } else { SNPRINTF(req, sizeof(req), "MR %s0,%03d", mr_extra, channel_num); } break; case RIG_MTYPE_EDGE: if (chan_caps[1].type == RIG_MTYPE_EDGE) { SNPRINTF(req, sizeof(req), "MR %s0,L%01d", mr_extra, channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d", channel_num); } else { SNPRINTF(req, sizeof(req), "MR %s0,U%01d", mr_extra, channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d", channel_num); } break; case RIG_MTYPE_PRIO: if (chan_caps->startc == chan_caps->endc) { SNPRINTF(req, sizeof(req), "MR %s0,PR", mr_extra); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Pr"); } else { SNPRINTF(req, sizeof(req), "MR %s0,PR%01d", mr_extra, channel_num + 1); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Pr%01d", channel_num + 1); } break; case RIG_MTYPE_CALL: SNPRINTF(req, sizeof(req), "CR 0,%01d", channel_num); if (chan->channel_num == chan_caps->startc) { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call V"); } else if (chan->channel_num == chan_caps->endc) { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call U"); } else { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call"); } break; case RIG_MTYPE_BAND: SNPRINTF(req, sizeof(req), "VR %01X", channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "BAND %01X", channel_num); break; default: return -RIG_EINVAL; } SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } /* * TODO: dcs/mode/lockout are not there on TH-G71 */ mode = RIG_MODE_NONE; rev = lockout = dcs = dcscode = 0; strcpy(scf, req); if (chan_caps->mem_caps.dcs_sql) { /* Step can be hexa * Lockout is optional on some channels */ strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d"); retval = num_sscanf(ackbuf, scf, &freq, &step, &shift, &rev, &tone, &ctcss, &dcs, &tonefq, &ctcssfq, &dcscode, &offset, &mode, &lockout); if (retval < 12) { rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval); return -RIG_EPROTO; } } else { strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,,%d,,%d,%"SCNfreq); retval = num_sscanf(ackbuf, scf, &freq, &step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset); if (retval != 9) { rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval); } } chan->funcs = rev ? RIG_FUNC_REV : 0; chan->flags = lockout ? RIG_CHFLAG_SKIP : 0; chan->freq = freq; chan->vfo = RIG_VFO_MEM; chan->tuning_step = STATE(rig)->tuning_steps[step].ts; if (priv->mode_table) { chan->mode = kenwood2rmode(mode, priv->mode_table); if (chan->mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode value '%d'\n", __func__, mode); return -RIG_EPROTO; } } else { /* No mode info (TH-G71, TMV7,..), * guess it from current freq */ chan->mode = (freq < MHz(136)) ? RIG_MODE_AM : RIG_MODE_FM; } chan->width = rig_passband_normal(rig, chan->mode); 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; offset = -offset; break; default: rig_debug(RIG_DEBUG_ERR, "%s: not supported shift %d\n", __func__, shift); chan->rptr_shift = RIG_RPT_SHIFT_NONE; } chan->rptr_offs = offset; /* FIXME: ctcss_list for t[fm]*.c */ //chan->ctcss_tone=rig->caps->ctcss_list[tonefq==1?0:tonefq-2]; // chan->ctcss_sql=rig->caps->ctcss_list[ctcssfq==1?0:ctcssfq-2]; if (tone) { chan->ctcss_tone = rig->caps->ctcss_list[tonefq]; } else { chan->ctcss_tone = 0; } if (ctcss) { chan->ctcss_sql = rig->caps->ctcss_list[ctcssfq]; } else { chan->ctcss_sql = 0; } if (dcs) { chan->dcs_sql = chan->dcs_code = rig->caps->dcs_list[dcscode]; } else { chan->dcs_sql = chan->dcs_code = 0; } chan->tx_freq = RIG_FREQ_NONE; if (shift == RIG_RPT_SHIFT_NONE && ((chan_caps->type == RIG_MTYPE_MEM && chan_caps->startc == 0) || chan_caps->type == RIG_MTYPE_CALL)) { /* split ? */ req[3 + strlen(mr_extra)] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval == RIG_OK) { strcpy(scf, req); strcat(scf, ",%"SCNfreq",%x"); retval = num_sscanf(ackbuf, scf, &freq, &step); chan->tx_freq = freq; chan->split = RIG_SPLIT_ON; } } /* If not set already by special channels.. */ if (chan->channel_desc[0] == '\0') { size_t ack_len; if (chan_caps[1].type == RIG_MTYPE_PRIO) { SNPRINTF(membuf, sizeof(membuf), "MNA %sI-%01d", mr_extra, channel_num); } else { SNPRINTF(membuf, sizeof(membuf), "MNA %s%03d", mr_extra, channel_num); } /* Get memory name */ retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } ack_len = strlen(ackbuf); if (ack_len > rig->caps->chan_desc_sz) { ack_len = rig->caps->chan_desc_sz; } strncpy(chan->channel_desc, ackbuf + strlen(membuf) + 1, ack_len); chan->channel_desc[ack_len] = '\0'; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } static int find_tone_index(const tone_t *tone_list, tone_t tone) { int i; for (i = 0; tone_list[i] != 0; i++) { if (tone_list[i] == tone) { return i; } } return -1; } /* --------------------------------------------------------------------- */ int th_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[256]; int retval; char req[64]; char lockoutstr[8]; int channel_num, step, shift, rev, tone, ctcss, tonefq, ctcssfq, dcs, dcscode, lockout; const char *mr_extra; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; const chan_t *chan_caps; const char *channel_desc; channel_num = chan->channel_num; for (step = 0; STATE(rig)->tuning_steps[step].ts != 0; step++) if (chan->tuning_step <= STATE(rig)->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 %d\n", __func__, chan->rptr_shift); return -RIG_EINVAL; } if (chan->ctcss_tone == 0) { tone = 0; tonefq = 8; } else { tone = 1; tonefq = find_tone_index(rig->caps->ctcss_list, chan->ctcss_tone); if (tonefq == -1) { return -RIG_EINVAL; } tonefq++; } if (chan->ctcss_sql == 0) { ctcss = 0; ctcssfq = 8; } else { ctcss = 1; ctcssfq = find_tone_index(rig->caps->ctcss_list, chan->ctcss_sql); if (tonefq == -1) { return -RIG_EINVAL; } ctcssfq++; } if (chan->dcs_code == 0 && chan->dcs_sql == 0) { dcs = 0; dcscode = 0; } else { dcs = 1; dcscode = find_tone_index(rig->caps->dcs_list, chan->dcs_sql); if (dcscode == -1) { return -RIG_EINVAL; } } if (chan->vfo == RIG_VFO_MEM) { chan_caps = rig_lookup_mem_caps(rig, chan->channel_num); if (!chan_caps) { return -RIG_ECONF; } channel_num -= chan_caps->startc; } else { return -RIG_ENIMPL; } if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { mr_extra = ""; } else { mr_extra = "0, "; } channel_desc = NULL; switch (chan_caps->type) { case RIG_MTYPE_MEM: if (chan_caps[1].type == RIG_MTYPE_PRIO) { /* Info */ SNPRINTF(req, sizeof(req), "MW %s0,I-%01d", mr_extra, channel_num); channel_desc = chan->channel_desc; } else { /* Regular */ SNPRINTF(req, sizeof(req), "MW %s0,%03d", mr_extra, channel_num); channel_desc = chan->channel_desc; } break; case RIG_MTYPE_EDGE: if (chan_caps[1].type == RIG_MTYPE_EDGE) { SNPRINTF(req, sizeof(req), "MW %s0,L%01d", mr_extra, channel_num); } else { SNPRINTF(req, sizeof(req), "MW %s0,U%01d", mr_extra, channel_num); } break; case RIG_MTYPE_PRIO: if (chan_caps->startc == chan_caps->endc) { SNPRINTF(req, sizeof(req), "MW %s0,PR", mr_extra); } else { SNPRINTF(req, sizeof(req), "MW %s0,PR%01d", mr_extra, channel_num + 1); } break; case RIG_MTYPE_CALL: SNPRINTF(req, sizeof(req), "CW 0,%01d", channel_num); break; case RIG_MTYPE_BAND: SNPRINTF(req, sizeof(req), "VW %01X", channel_num); break; default: return -RIG_EINVAL; } rev = (chan->funcs & RIG_FUNC_REV) ? 1 : 0; lockout = (chan->flags & RIG_CHFLAG_SKIP) ? 1 : 0; if (chan_caps->mem_caps.flags) { SNPRINTF(lockoutstr, sizeof(lockoutstr), ",%d", lockout); } else { strcpy(lockoutstr, ""); } if (chan_caps->mem_caps.flags && chan_caps->mem_caps.dcs_sql) { int mode; if (!priv->mode_table) { rig_debug(RIG_DEBUG_ERR, "%s: buggy backend, no mode_table '%d'\n", __func__, (int)chan->mode); return -RIG_ENIMPL; } mode = rmode2kenwood(chan->mode, priv->mode_table); if (mode == -1) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode value '%d'\n", __func__, (int)chan->mode); return -RIG_EINVAL; } /* Step can be hexa */ SNPRINTF(membuf, sizeof(membuf), "%8s,%011"PRIll",%X,%d,%d,%d,%d,%d,%02d,%02d,%03d,%09"PRIll",%d%10s", req, (int64_t)chan->freq, step, shift, rev, tone, ctcss, dcs, tonefq, ctcssfq, dcscode, (int64_t)labs((long)(chan->rptr_offs)), mode, lockoutstr ); } else { /* Without DCS,mode */ SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%X,%d,%d,%d,%d,,%02d,,%02d,%09"PRIll"%s", req, (int64_t)chan->freq, step, shift, rev, tone, ctcss, tonefq, ctcssfq, (int64_t)labs((long)(chan->rptr_offs)), lockoutstr ); } retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } /* split ? */ if (chan->tx_freq != RIG_FREQ_NONE && ((chan_caps->type == RIG_MTYPE_MEM && chan_caps->startc == 0) || chan_caps->type == RIG_MTYPE_CALL)) { req[3 + strlen(mr_extra)] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%X", req, (int64_t)chan->tx_freq, step); retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } } if (channel_desc) { /* Memory name */ /* TODO: check strlen(channel_desc) < rig->caps->chan_desc_sz */ if (chan_caps[1].type == RIG_MTYPE_PRIO) { SNPRINTF(membuf, sizeof(membuf), "MNA %sI-%01d,%s", mr_extra, channel_num, channel_desc); } else { SNPRINTF(membuf, sizeof(membuf), "MNA %s%03d,%s", mr_extra, channel_num, channel_desc); } retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * set the aerial/antenna to use */ int th_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[6]; rig_debug(RIG_DEBUG_TRACE, "%s: ant = %u\n", __func__, ant); switch (ant) { case RIG_ANT_1: strncpy(cmd, "ANT 0", sizeof(cmd)); break; case RIG_ANT_2: strncpy(cmd, "ANT 1", sizeof(cmd)); break; case RIG_ANT_3: strncpy(cmd, "ANT 2", sizeof(cmd)); break; default: return -RIG_EINVAL; } return kenwood_transaction(rig, cmd, cmd, sizeof(cmd)); } /* * get the aerial/antenna in use */ int th_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char buf[8]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); retval = kenwood_safe_transaction(rig, "ANT", buf, sizeof(buf), 5); if (retval != RIG_OK) { return retval; } if (buf[4] < '0' || buf[4] > '9') { return -RIG_EPROTO; } *ant_curr = RIG_ANT_N(buf[4] - '0'); rig_debug(RIG_DEBUG_TRACE, "%s: ant = %u\n", __func__, *ant_curr); return RIG_OK; } /* TH-F7: 1 VFO, 2 Menu, 3 Full */ /* TM-D700: 1 Master! */ int th_reset(RIG *rig, reset_t reset) { switch (reset) { case RIG_RESET_VFO: return kenwood_transaction(rig, "SR 1", NULL, 0); case RIG_RESET_MASTER: return kenwood_transaction(rig, "SR 3", NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } hamlib-4.6.5/rigs/kenwood/ts790.c0000664000175000017500000001517215056640443012126 /* * Hamlib Kenwood backend - TS-790 description * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "kenwood.h" #define TS790_ALL_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM) #define TS790_HI_MODES (RIG_MODE_CW|RIG_MODE_FM) #define TS790_LO_MODES (RIG_MODE_SSB) /* func and levels to be checked */ #define TS790_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define TS790_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS790_VFO (RIG_VFO_A|RIG_VFO_B) #define TS790_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS790_SCAN_OP (RIG_SCAN_VFO) #define TS790_CHANNEL_CAPS \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP, \ .ctcss_tone=1 /* * Function definitions below */ static struct kenwood_priv_caps ts790_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * TS790 A/E rig capabilities. * Interface provided by optional IF-232C * * TODO: get_ts, ctcss_sql, set_rptr_shift * * part of infos comes from http://www.kenwood.net/ */ struct rig_caps ts790_caps = { RIG_MODEL(RIG_MODEL_TS790), .model_name = "TS-790", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = TS790_FUNC_ALL, .has_set_func = TS790_FUNC_ALL, .has_get_level = TS790_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS790_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .vfo_ops = TS790_VFO_OP, .scan_ops = TS790_SCAN_OP, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { /* 12, */ RIG_DBLST_END, }, .max_rit = kHz(9.9), /* this is for FM, SSB/CW is 1.9kHz */ .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 59, RIG_MTYPE_MEM, { TS790_CHANNEL_CAPS } }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), TS790_ALL_MODES, -1, -1, TS790_VFO}, {MHz(430), MHz(440), TS790_ALL_MODES, -1, -1, TS790_VFO}, #if 0 /* 23 cm option */ {MHz(1240), MHz(1300), TS790_ALL_MODES, -1, -1, TS790_VFO}, #endif RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TS790_LO_MODES, W(5), W(35), TS790_VFO}, {MHz(144), MHz(146), TS790_HI_MODES, W(5), W(45), TS790_VFO}, {MHz(430), MHz(440), TS790_LO_MODES, W(5), W(30), TS790_VFO}, {MHz(430), MHz(440), TS790_HI_MODES, W(5), W(40), TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, W(5), W(10), TS790_VFO}, #endif RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(144), MHz(148), TS790_ALL_MODES, -1, -1, TS790_VFO}, {MHz(430), MHz(450), TS790_ALL_MODES, -1, -1, TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, -1, -1, TS790_VFO}, #endif RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TS790_LO_MODES, W(5), W(35), TS790_VFO}, {MHz(144), MHz(148), TS790_HI_MODES, W(5), W(45), TS790_VFO}, {MHz(430), MHz(450), TS790_LO_MODES, W(5), W(30), TS790_VFO}, {MHz(430), MHz(450), TS790_HI_MODES, W(5), W(40), TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, W(5), W(10), TS790_VFO}, #endif RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS790_ALL_MODES, 50}, {TS790_ALL_MODES, 100}, {TS790_ALL_MODES, kHz(1)}, {TS790_ALL_MODES, kHz(5)}, {TS790_ALL_MODES, kHz(9)}, {TS790_ALL_MODES, kHz(10)}, {TS790_ALL_MODES, 12500}, {TS790_ALL_MODES, kHz(20)}, {TS790_ALL_MODES, kHz(25)}, {TS790_ALL_MODES, kHz(100)}, {TS790_ALL_MODES, MHz(1)}, {TS790_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.1)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts790_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_channel = kenwood_set_channel, .get_channel = kenwood_get_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .get_info = kenwood_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts850.c0000664000175000017500000003564415056640443012131 /* * Hamlib Kenwood backend - TS850 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include "kenwood.h" #define TS850_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS850_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS850_AM_TX_MODES (RIG_MODE_AM) #define TS850_FUNC_ALL (RIG_FUNC_AIP|RIG_FUNC_LOCK) #define TS850_LEVEL_GET (RIG_LEVEL_SWR|RIG_LEVEL_COMP|RIG_LEVEL_ALC|RIG_LEVEL_CWPITCH|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH) #define TS850_LEVEL_SET (RIG_LEVEL_CWPITCH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH) #define TS850_VFO (RIG_VFO_A|RIG_VFO_B) #define TS850_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS850_CHANNEL_CAPS \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP, \ .ctcss_tone=1 #define TS850_STR_CAL { 4, \ { \ { 0, -54 }, \ { 15, 0 }, \ { 22,30 }, \ { 30, 66}, \ } } static struct kenwood_priv_caps ts850_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* forward definitions */ static int ts850_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ts850_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ts850_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts850_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static const struct confparams ts850_ext_parms[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /* * ts850 rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ts850_caps = { RIG_MODEL(RIG_MODEL_TS850), .model_name = "TS-850", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 500, .retry = 10, .has_get_func = TS850_FUNC_ALL, .has_set_func = TS850_FUNC_ALL, .has_get_level = TS850_LEVEL_GET, .has_set_level = TS850_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #include "level_gran_kenwood.h" #undef NO_LVL_CWPITCH [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 1000 }, .step = { .i = 50 } }, }, .parm_gran = {}, .extparms = ts850_ext_parms, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(1.27), .max_xit = kHz(1.27), .max_ifshift = Hz(0), .vfo_ops = TS850_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 3, .chan_list = { { 0, 89, RIG_MTYPE_MEM, {TS850_CHANNEL_CAPS}}, { 90, 99, RIG_MTYPE_EDGE, {TS850_CHANNEL_CAPS}}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), TS850_ALL_MODES, -1, -1, TS850_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, /* 40W class */ {kHz(3500), kHz(3800), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(3500), kHz(3800), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(7), kHz(7100), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(7), kHz(7100), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(10100), kHz(10150), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(10100), kHz(10150), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(14), kHz(14350), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(14), kHz(14350), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(18068), kHz(18168), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(18068), kHz(18168), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(21), kHz(21450), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(21), kHz(21450), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(24890), kHz(24990), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(24890), kHz(24990), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(28), kHz(29700), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(28), kHz(29700), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS850_ALL_MODES, -1, -1, TS850_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, /* 40W class */ {kHz(3500), MHz(4) - 1, TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(3500), MHz(4) - 1, TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(7), kHz(7300), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(7), kHz(7300), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(10100), kHz(10150), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(10100), kHz(10150), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(14), kHz(14350), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(14), kHz(14350), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(18068), kHz(18168), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(18068), kHz(18168), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(21), kHz(21450), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(21), kHz(21450), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(24890), kHz(24990), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(24890), kHz(24990), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(28), kHz(29700), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(28), kHz(29700), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS850_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {TS850_ALL_MODES, kHz(12)}, {TS850_ALL_MODES, kHz(6)}, {TS850_ALL_MODES, kHz(2.7)}, {TS850_ALL_MODES, Hz(500)}, {TS850_ALL_MODES, Hz(250)}, RIG_FLT_END, }, .str_cal = TS850_STR_CAL, .priv = (void *)& ts850_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts850_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts850_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt_safe, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts850_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .get_channel = kenwood_get_channel, .set_channel = ts850_set_channel, .set_trn = kenwood_set_trn, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ int ts850_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "RT0", NULL, 0); if (retval != RIG_OK) { return retval; } } else { retval = kenwood_transaction(rig, "RT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 20)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int ts850_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { char buf[50]; unsigned char c; int retval, i; if (xit == 0) { retval = kenwood_transaction(rig, "XT0", NULL, 0); if (retval != RIG_OK) { return retval; } } else { retval = kenwood_transaction(rig, "XT1", NULL, 0); if (retval != RIG_OK) { return retval; } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } if (xit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); for (i = 0; i < labs(lrint(xit / 20)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } static char mode_to_char(rmode_t mode) { switch (mode) { case RIG_MODE_CW: return (MD_CW); case RIG_MODE_CWR: return (MD_CWR); case RIG_MODE_USB: return (MD_USB); case RIG_MODE_LSB: return (MD_LSB); case RIG_MODE_FM: return (MD_FM); case RIG_MODE_AM: return (MD_AM); case RIG_MODE_RTTY: return (MD_FSK); case RIG_MODE_RTTYR: return (MD_FSKR); default: rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); } return (RIG_MODE_NONE); } int ts850_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; int i, retval; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RAWSTR: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); //val->i = (val->i * 4) - 54; Old approximate way of doing it. val->i = (int)rig_raw2val(val->i, &rig->caps->str_cal); break; case RIG_LEVEL_SWR: retval = kenwood_transaction(rig, "RM1", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } i = atoi(&lvlbuf[3]); if (i == 30) { val->f = 150.0; /* infinity :-) */ } else { val->f = 60.0 / (30.0 - (float)i) - 1.0; } break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "RM2", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ALC: retval = kenwood_transaction(rig, "RM3", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; default: return kenwood_get_level(rig, vfo, level, val); } return retval; // Never gets here. } int ts850_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[30]; int retval; int num, freq, tx_freq, tone; char mode, tx_mode, tones; num = chan->channel_num; freq = (int)chan->freq; mode = mode_to_char(chan->mode); if (chan->split == RIG_SPLIT_ON) { tx_freq = (int)chan->tx_freq; tx_mode = mode_to_char(chan->tx_mode); } else { tx_freq = 0; tx_mode = '\0'; } for (tone = 1; rig->caps->ctcss_list[tone - 1] != 0 && tone < 39; tone++) { if (rig->caps->ctcss_list[tone - 1] == chan->ctcss_tone) { break; } } if (chan->ctcss_tone != 0) { tones = '1'; } else { tones = '0'; tone = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW0 %02d%011d%c0%c%02d ", num, freq, mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW1 %02d%011d%c0%c%02d ", num, tx_freq, tx_mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } hamlib-4.6.5/rigs/kenwood/thd74.c0000664000175000017500000011623415056640443012173 /* * Hamlib Kenwood TH-D74 backend * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2018 by Sebastian Denz, based on THD72 from Brian Lucas * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" #define THD74_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_FMN|RIG_MODE_WFM|RIG_MODE_CWR) #define THD74_MODES_TX (RIG_MODE_FM) #define THD74_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_TONE) #define THD74_LEVEL_ALL (RIG_LEVEL_RFPOWER|\ RIG_LEVEL_SQL|\ RIG_LEVEL_ATT|\ RIG_LEVEL_VOXGAIN|\ RIG_LEVEL_VOXDELAY) #define THD74_PARMS (RIG_PARM_TIME) #define THD74_VFO_OP (RIG_OP_NONE) #define THD74_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t thd74_mode_table[10] = { [0] = RIG_MODE_FM, /* normal, but narrow compared to broadcast */ // [1] = RIG_MODE_DV, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW, [6] = RIG_MODE_FMN, /* what kenwood calls narrow */ // [7] = RIG_MODE_DR, [8] = RIG_MODE_WFM, [9] = RIG_MODE_CWR, }; static pbwidth_t thd74_width_table[10] = { [0] = 10000, // +-5KHz [1] = 5000, // +-2.5KHz [2] = 10000, // FIXME: what should this be? [3] = 10000, // FIXME: what should this be? [4] = 10000, // FIXME: what should this be? [5] = 10000, // FIXME: what should this be? [6] = 10000, // FIXME: what should this be? [7] = 10000, // FIXME: what should this be? [8] = 10000, // FIXME: what should this be? [9] = 10000, // FIXME: what should this be? }; static rptr_shift_t thd74_rshf_table[3] = { [0] = RIG_RPT_SHIFT_NONE, [1] = RIG_RPT_SHIFT_PLUS, [2] = RIG_RPT_SHIFT_MINUS, }; static int thd74tuningstep_fine[4] = { [0] = 20, [1] = 100, [2] = 500, [3] = 1000, }; static int thd74tuningstep[11] = { [0] = 5000, [1] = 6250, [2] = 8330, [3] = 9000, [4] = 10000, [5] = 15000, [6] = 20000, [7] = 25000, [8] = 30000, [9] = 50000, [10] = 100000, }; static int thd74voxdelay[7] = { [0] = 2500, [1] = 5000, [2] = 7500, [3] = 10000, [4] = 15000, [5] = 20000, [6] = 30000 }; static float thd74sqlevel[6] = { [0] = 0.0, /* open */ [1] = 0.2, [2] = 0.4, [3] = 0.6, [4] = 0.8, [5] = 1.0 }; static tone_t thd74dcs_list[105] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; static struct kenwood_priv_caps thd74_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thd74_mode_table, }; int thd74_open(RIG *rig) { //int ret; //struct kenwood_priv_data *priv = STATE(rig)->priv; // this is already done in kenwood_init //strcpy(priv->verify_cmd, "ID\r"); //ret = kenwood_transaction(rig, "", NULL, 0); return RIG_OK; } static int thd74_set_vfo(RIG *rig, vfo_t vfo) { const char *cmd; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd = "BC 0"; break; case RIG_VFO_B: cmd = "BC 1"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return kenwood_simple_transaction(rig, cmd, 4); } static int thd74_get_vfo(RIG *rig, vfo_t *vfo) { int retval; char c, buf[10]; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length == 4) { c = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; } switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EVFO; } return RIG_OK; } static int thd74_vfoc(RIG *rig, vfo_t vfo, char *vfoc) { vfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (vfo) { case RIG_VFO_A: *vfoc = '0'; break; case RIG_VFO_B: *vfoc = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return RIG_OK; } static int thd74_get_freq_info(RIG *rig, vfo_t vfo, char *buf) { int retval; char c, cmd[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "FO %c", c); retval = kenwood_transaction(rig, cmd, buf, 73); return retval; } /* item is an offset into reply buf that is a single char */ static int thd74_get_freq_item(RIG *rig, vfo_t vfo, int item, int hi, int *val) { int retval, lval; char c, buf[128]; retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } c = buf[item]; rig_debug(RIG_DEBUG_TRACE, "%s: c:%c\n", __func__, c); if (c < '0' || c > '9') { return -RIG_EPROTO; } lval = c - '0'; if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd74_set_freq_item(RIG *rig, vfo_t vfo, int item, int val) { int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[item] = val + '0'; return kenwood_simple_transaction(rig, buf, 72); } static int thd74_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval, tsinx, fine, fine_ts; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_item(rig, vfo, 16, 9, &tsinx); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } retval = thd74_get_freq_item(rig, vfo, 33, 1, &fine); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } retval = thd74_get_freq_item(rig, vfo, 35, 3, &fine_ts); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: tsinx is %d\n", __func__, tsinx); rig_debug(RIG_DEBUG_TRACE, "%s: fine is %d\n", __func__, fine); rig_debug(RIG_DEBUG_TRACE, "%s: fine_ts is %d\n", __func__, fine_ts); if (fine > 0) { *ts = thd74tuningstep_fine[fine_ts]; } else { *ts = thd74tuningstep[tsinx]; } rig_debug(RIG_DEBUG_TRACE, "%s: stepsize is %d\n", __func__, (int)*ts); return RIG_OK; } // needs rig and vfo to get correct stepsize static int thd74_round_freq(RIG *rig, vfo_t vfo, freq_t freq) { int64_t f; long double r; shortfreq_t ts; // cppcheck-suppress * char *fmt = "%s: rounded %"PRIll" to %"PRIll" because stepsize:%d\n"; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); thd74_get_ts(rig, vfo, &ts); f = (int64_t)freq; r = round((double)f / (double)ts); r = ts * r; rig_debug(RIG_DEBUG_TRACE, fmt, __func__, f, (int64_t)r, (int)ts); return (freq_t)r; } static int thd74_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128], fbuf[12]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } freq = thd74_round_freq(rig, vfo, freq); SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)freq); memcpy(buf + 5, fbuf, 10); retval = kenwood_simple_transaction(rig, buf, 72); return retval; } static int thd74_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%"SCNfreq, freq); return RIG_OK; } // setting the mode via FO leads to response 'N.' from the handset int thd74_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char kmode, mdbuf[8], replybuf[8], v; int retval; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &v); if (retval != RIG_OK) { return retval; } if (priv->mode_table) { kmode = rmode2kenwood(mode, priv->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unsupported Mode value '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } kmode += '0'; } else { switch (mode) { case RIG_MODE_FM: kmode = '0'; break; case RIG_MODE_AM: kmode = '1'; break; // case RIG_MODE_DV: kmode = '2'; break; case RIG_MODE_LSB: kmode = '3'; break; case RIG_MODE_USB: kmode = '4'; break; case RIG_MODE_CW: kmode = '5'; break; case RIG_MODE_FMN: kmode = '6'; break; // case RIG_MODE_DR: kmode = '7'; break; case RIG_MODE_WFM: kmode = '8'; break; case RIG_MODE_CWR: kmode = '9'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } } SNPRINTF(mdbuf, sizeof(mdbuf), "MD %c,%c", v, kmode); rig_debug(RIG_DEBUG_ERR, "%s: mdbuf: %s\n", __func__, mdbuf); retval = kenwood_transaction(rig, mdbuf, replybuf, 7); rig_debug(RIG_DEBUG_ERR, "%s: retval: %d\n", __func__, retval); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int thd74_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char modec, buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } modec = buf[31]; if (modec >= '0' && modec <= '9') { *mode = thd74_mode_table[modec - '0']; *width = thd74_width_table[modec - '0']; } else { return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rsinx = 0; break; case RIG_RPT_SHIFT_PLUS: rsinx = 1; break; case RIG_RPT_SHIFT_MINUS: rsinx = 2; break; default: return -RIG_EINVAL; } return thd74_set_freq_item(rig, vfo, 47, rsinx); } static int thd74_get_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int retval, rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_item(rig, vfo, 47, 3, &rsinx); if (retval != RIG_OK) { return retval; } /* rsinx == 3 indicates split mode? */ *rptr_shift = (rsinx == 3) ? RIG_RPT_SHIFT_NONE : thd74_rshf_table[rsinx]; return RIG_OK; } static int thd74_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { int retval; char boff[11], buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } SNPRINTF(boff, sizeof(boff), "%010ld", offs); memcpy(buf + 16, boff, 10); retval = kenwood_simple_transaction(rig, buf, 72); return retval; } static int thd74_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 16, "%ld", offs); return RIG_OK; } static int thd74_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (tsinx = 0; tsinx < 4; tsinx++) { if (thd74tuningstep_fine[tsinx] >= ts) { thd74_set_freq_item(rig, vfo, 33, 1); // Turn fine mode on thd74_set_freq_item(rig, vfo, 35, tsinx); return RIG_OK; } } for (tsinx = 0; tsinx < 10; tsinx++) { if (thd74tuningstep[tsinx] >= ts) { thd74_set_freq_item(rig, vfo, 33, 0); //Turn fine mode off thd74_set_freq_item(rig, vfo, 27, tsinx); return RIG_OK; } } return -RIG_EINVAL; } static int thd74_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[22] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 30, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[22] == '0') /* no tone */ { *tone = 0; } else { sscanf(buf + 30, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd74_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int retval, cinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cinx = 0; /* default */ if (code != 0) { for (cinx = 0; cinx < 104; cinx++) { if (code == thd74dcs_list[cinx]) { break; } } if (cinx >= 104) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[26] = (code == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%03d", cinx); memcpy(buf + 36, tmp, 3); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int retval, cinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[26] == '0') /* no tone */ { *code = 0; } else { sscanf(buf + 36, "%d", &cinx); *code = thd74dcs_list[cinx]; } return RIG_OK; } static int thd74_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[24] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 33, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[24] == '0') /* no tsql */ { *tone = 0; } else { sscanf(buf + 33, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } int thd74_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; return kenwood_simple_transaction(rig, ptt_cmd, 4); break; case RIG_PTT_OFF: ptt_cmd = "RX"; return kenwood_simple_transaction(rig, ptt_cmd, 2); break; default: return -RIG_EINVAL; } } static int thd74_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, lvl; char c, lvlc, cmd[11]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: level: %s\n", __func__, rig_strlevel(level)); rig_debug(RIG_DEBUG_TRACE, "%s: value.i: %d\n", __func__, val.i); rig_debug(RIG_DEBUG_TRACE, "%s: value.f: %lf\n", __func__, val.f); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvlc = '3'; } else if (val.f <= 0.1) { lvlc = '2'; } else if (val.f <= 0.4) { lvlc = '1'; } else { lvlc = '0'; } SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_VOXGAIN: SNPRINTF(cmd, sizeof(cmd), "VG %d", (int)(val.f * 10.0 - 0.5)); return kenwood_simple_transaction(rig, cmd, 4); case RIG_LEVEL_VOXDELAY: if (val.i > 20000) { lvl = 6; } else if (val.i > 10000) { lvl = val.i / 10000 + 3; } else { lvl = val.i / 2500; } SNPRINTF(cmd, sizeof(cmd), "VD %d", lvl); return kenwood_simple_transaction(rig, cmd, 4); case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c,%d", c, (int)val.f); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_ATT: // no value provided to distinguish between on/off?? SNPRINTF(cmd, sizeof(cmd), "RA %c,%d", c, (int)val.f); return kenwood_simple_transaction(rig, cmd, 6); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } static int thd74_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, v, l; char c, cmd[10], buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmd, sizeof(cmd), "PC %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } switch (l) { case 0: val->f = 1.00; break; /* 5.0 W */ case 1: val->f = 0.40; break; /* 2.0 W */ case 2: val->f = 0.1; break; /* 500 mW */ case 3: val->f = 0.01; break; /* 50 mW */ } break; case RIG_LEVEL_VOXGAIN: SNPRINTF(cmd, sizeof(cmd), "VG"); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: VOXGAIN buf:%s\n", __func__, buf); /* FIXME - if VOX is off, what do we return */ val->f = (buf[0] - '0') / 9.0; break; case RIG_LEVEL_VOXDELAY: SNPRINTF(cmd, sizeof(cmd), "VD"); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ rig_debug(RIG_DEBUG_TRACE, "%s: VOXDELAY buf:%s\n", __func__, buf); val->i = thd74voxdelay[buf[0] - '0']; break; case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "SQ %d,%d", &v, &l); if (retval != 2 || l < 0 || l >= 6) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } val->f = thd74sqlevel[l]; break; case RIG_LEVEL_ATT: SNPRINTF(cmd, sizeof(cmd), "RA %c", c); retval = kenwood_transaction(rig, cmd, buf, 7); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%d", &val->i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_TONE: return thd74_set_freq_item(rig, vfo, 37, status); case RIG_FUNC_TSQL: return thd74_set_freq_item(rig, vfo, 39, status); default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval, f; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_TONE: retval = thd74_get_freq_item(rig, vfo, 37, 1, &f); break; case RIG_FUNC_TSQL: retval = thd74_get_freq_item(rig, vfo, 39, 1, &f); break; default: return -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } *status = f; return RIG_OK; } static int thd74_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_TIME: // FIXME check val, send formatted via RT default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, hh, mm, ss; char buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_TIME: retval = kenwood_transaction(rig, "RT", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 11, "%2d%2d%2d", &hh, &mm, &ss); val->i = ss + 60 * (mm + 60 * hh); break; default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char c, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c,%03d", c, ch); return kenwood_simple_transaction(rig, cmd, 8); } static int thd74_get_mem(RIG *rig, vfo_t vfo, int *ch) { int retval; char c, cmd[10], buf[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 3, "%d", ch); return RIG_OK; } static int thd74_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return -RIG_EINVAL; } static int thd74_parse_channel(int kind, const char *buf, channel_t *chan) { int tmp; char c; const char *data; if (kind == 0) { data = buf + 5; } else { data = buf + 7; } sscanf(data, "%"SCNfreq, &chan->freq); c = data[46]; // mode if (c >= '0' && c <= '2') { chan->mode = thd74_mode_table[c - '0']; chan->width = thd74_width_table[c - '0']; } c = data[11]; // tuning step if (c >= '0' && c <= '9') { chan->tuning_step = thd74tuningstep[c - '0']; } c = data[13]; // repeater shift if (c >= '0' && c <= '2') { chan->rptr_shift = thd74_rshf_table[c - '0']; } sscanf(data + 37, "%ld", &chan->rptr_offs); c = data[17]; // Tone status if (c != '0') { sscanf(data + 25, "%d", &tmp); if (tmp > 0 && tmp < 42) { chan->ctcss_tone = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_tone = 0; } c = data[19]; // TSQL status if (c != '0') { sscanf(data + 28, "%d", &tmp); if (tmp > 0 && tmp < 42) { chan->ctcss_sql = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_sql = 0; } c = data[21]; // DCS status if (c != '0') { sscanf(data + 31, "%d", &tmp); chan->dcs_code = tmp; } else { chan->dcs_code = 0; } return RIG_OK; } static int thd74_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; char buf[72]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (chan->vfo == RIG_VFO_MEM) /* memory channel */ { int len; char cmd[16]; SNPRINTF(cmd, sizeof(cmd), "ME %03d", chan->channel_num); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = thd74_parse_channel(1, buf, chan); if (retval != RIG_OK) { return retval; } cmd[1] = 'N'; /* change ME to MN */ retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } len = strlen(buf); memcpy(chan->channel_desc, buf + 7, len - 7); } else /* current channel */ { retval = thd74_get_freq_info(rig, chan->vfo, buf); if (retval != RIG_OK) { return retval; } return thd74_parse_channel(0, buf, chan); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int thd74_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (txvfo != RIG_VFO_A) { return -RIG_EINVAL; } priv->split = split; return RIG_OK; } int thd74_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { *txvfo = RIG_VFO_A; } else { return -RIG_EPROTO; } return RIG_OK; } /* if priv->split is RIG_SPLIT_ON set *tx_freq to freq of VFOA and return RIG_OK otherwise return -RIG_EPROTO */ int thd74_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_A; } else { return -RIG_EINVAL; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%"SCNfreq, tx_freq); return RIG_OK; } /* if priv->split is RIG_SPLIT_ON set freq of VFOA to txfreq and return RIG_OK otherwise return -RIG_EPROTO */ int thd74_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { char fbuf[12], buf[128]; int retval = thd74_get_freq_info(rig, RIG_VFO_A, buf); if (retval != RIG_OK) { return retval; } tx_freq = thd74_round_freq(rig, RIG_VFO_A, tx_freq); SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)tx_freq); memcpy(buf + 5, fbuf, 10); return kenwood_simple_transaction(rig, buf, 72); } return -RIG_EPROTO; } #ifdef false /* not working */ #define CMD_SZ 5 #define BLOCK_SZ 256 #define BLOCK_COUNT 256 #define CHAN_PER_BLOCK 4 static int thd74_get_block(RIG *rig, int block_num, char *block) { hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; /* fetching block i */ cmd[2] = block_num & 0xff; ret = write_block(rp, cmd, CMD_SZ); if (ret != RIG_OK) { return ret; } /* read response first */ ret = read_block(rp, resp, CMD_SZ); if (ret != CMD_SZ) { return ret; } if (resp[0] != 'W' || memcmp(cmd + 1, resp + 1, CMD_SZ - 1)) { return -RIG_EPROTO; } /* read block */ ret = read_block(rp, block, BLOCK_SZ); if (ret != BLOCK_SZ) { return ret; } ret = write_block(rp, "\006", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } return RIG_OK; } #ifdef XXREMOVEDXX int thd74_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = STATE(rig)->chan_list; int chan_next = chan_list[0].start; char block[BLOCK_SZ]; char resp[CMD_SZ]; ret = kenwood_transaction(rig, "0M PROGRAM", resp, CMD_SZ); if (ret != RIG_OK) { return ret; } if (strlen(resp) != 2 || memcmp(resp, "0M", 2)) { return -RIG_EPROTO; } rp->parm.serial.rate = 57600; serial_setup(rp); hl_usleep(100 * 1000); /* let the pcr settle */ rig_flush(rp); /* flush any remaining data */ ret = ser_set_rts(rp, 1); /* setRTS or Hardware flow control? */ if (ret != RIG_OK) { return ret; } /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; ret = chan_cb(rig, &chan, chan_next, chan_list, arg); if (ret != RIG_OK) { return ret; } if (chan == NULL) { return -RIG_ENOMEM; } for (i = 0; i < BLOCK_COUNT; i++) { ret = thd74_get_block(rig, i, block); if (ret != RIG_OK) { return ret; } /* * Most probably, there's 64 bytes per channel (256*256 / 1000+) */ for (j = 0; j < CHAN_PER_BLOCK; j++) { char *block_chan = block + j * (BLOCK_SZ / CHAN_PER_BLOCK); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; chan->channel_num = i * CHAN_PER_BLOCK + j; /* What are the extra 64 channels ? */ if (chan->channel_num >= 1000) { break; } /* non-empty channel ? */ // if (block_chan[0] != 0xff) { // since block_chan is *signed* char, this maps to -1 if (block_chan[0] != -1) { memcpy(chan->channel_desc, block_chan, 8); /* TODO: chop off trailing chars */ chan->channel_desc[8] = '\0'; /* TODO: parse block and fill in chan */ } /* notify the end? */ chan_next = chan_next < chan_list[i].end ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, &chan, chan_next, chan_list, arg); } } ret = write_block(rp, "E", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } /* setRTS?? getCTS needed? */ ret = ser_set_rts(rp, 1); if (ret != RIG_OK) { return ret; } return RIG_OK; } #endif #endif /* none working stuff */ /* * th-d74 rig capabilities. */ struct rig_caps thd74_caps = { RIG_MODEL(RIG_MODEL_THD74), .model_name = "TH-D74", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .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_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THD74_FUNC_ALL, .has_set_func = THD74_FUNC_ALL, .has_get_level = THD74_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD74_LEVEL_ALL), .has_get_parm = THD74_PARMS, .has_set_parm = THD74_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, }, .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 = THD74_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, /* TBC */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* TBC MEM */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THD74_MODES, -1, -1, THD74_VFO}, {MHz(320), MHz(524), THD74_MODES, -1, -1, THD74_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), THD74_MODES_TX, W(0.05), W(5), THD74_VFO}, {MHz(430), MHz(440), THD74_MODES_TX, W(0.05), W(5), THD74_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {THD74_MODES, kHz(5)}, {THD74_MODES, kHz(6.25)}, /* kHz(8.33) ?? */ {THD74_MODES, kHz(10)}, {THD74_MODES, kHz(12.5)}, {THD74_MODES, kHz(15)}, {THD74_MODES, kHz(20)}, {THD74_MODES, kHz(25)}, {THD74_MODES, kHz(30)}, {THD74_MODES, kHz(50)}, {THD74_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(14)}, {RIG_MODE_FMN, kHz(7)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd74_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .set_freq = thd74_set_freq, .get_freq = thd74_get_freq, .set_mode = thd74_set_mode, .get_mode = thd74_get_mode, .set_vfo = thd74_set_vfo, .get_vfo = thd74_get_vfo, .set_ptt = thd74_set_ptt, .set_rptr_shift = thd74_set_rptr_shft, .get_rptr_shift = thd74_get_rptr_shft, .set_rptr_offs = thd74_set_rptr_offs, .get_rptr_offs = thd74_get_rptr_offs, .set_ts = thd74_set_ts, .get_ts = thd74_get_ts, .set_ctcss_tone = thd74_set_ctcss_tone, .get_ctcss_tone = thd74_get_ctcss_tone, .set_dcs_code = thd74_set_dcs_code, .get_dcs_code = thd74_get_dcs_code, .set_ctcss_sql = thd74_set_ctcss_sql, .get_ctcss_sql = thd74_get_ctcss_sql, .set_level = thd74_set_level, .get_level = thd74_get_level, .set_func = thd74_set_func, .get_func = thd74_get_func, .set_parm = thd74_set_parm, .get_parm = thd74_get_parm, .set_mem = thd74_set_mem, .get_mem = thd74_get_mem, .set_channel = thd74_set_channel, .get_channel = thd74_get_channel, .set_split_vfo = thd74_set_split_vfo, .get_split_vfo = thd74_get_split_vfo, .set_split_freq = thd74_set_split_freq, .get_split_freq = thd74_get_split_freq, //.get_chan_all_cb = thd74_get_chan_all_cb, this doesn't work yet .get_info = th_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts890s.c0000664000175000017500000005560715056640443012321 /* * Hamlib Kenwood backend - TS-890S description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "cal.h" #include "misc.h" #define TS890_VFO (RIG_VFO_A|RIG_VFO_B) #define TS890_ALL_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_RTTY|RIG_MODE_CWR|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define TS890_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS890_AM_TX_MODES RIG_MODE_AM #define TS890_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH|RIG_LEVEL_ATT|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS890_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_KEYSPD|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_TEMP_METER|RIG_LEVEL_CWPITCH|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT|RIG_LEVEL_RFPOWER_METER_WATTS) #define TS890_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_SEND_MORSE|RIG_FUNC_TONE|RIG_FUNC_TSQL) #define TS890_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) static int kenwood_ts890_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16], *command_string; int kenwood_val, retval; gran_t *level_info; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = check_level_param(rig, level, val, &level_info); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_AGC: /* hamlib argument is int, possible values rig.h:enum agc_level_e */ /* possible values for TS890 0(=off), 1(=slow), 2(=mid), 3(=fast), 4(=off/Last) */ rig_debug(RIG_DEBUG_VERBOSE, "%s TS890S RIG_LEVEL_AGC\n", __func__); kenwood_val = -1; /* Flag invalid value */ for (int j = 0; j < rig->caps->agc_level_count; j++) { if (val.i == rig->caps->agc_levels[j]) { kenwood_val = j; break; } } if (kenwood_val < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value:%d\n", __func__, val.i); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GC%d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); /* Odd man out */ case RIG_LEVEL_RF: command_string = "RG%03d"; break; case RIG_LEVEL_SQL: command_string = "SQ%03d"; break; case RIG_LEVEL_USB_AF: command_string = "EX00708 %03d"; break; case RIG_LEVEL_USB_AF_INPUT: command_string = "EX00706 %03d"; break; default: return kenwood_set_level(rig, vfo, level, val); } //TODO: Add use of RIG_LEVEL_IS_FLOAT() if need to handle int level kenwood_val = val.f / level_info->step.f + 0.5; SNPRINTF(levelbuf, sizeof(levelbuf), command_string, kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); } static int kenwood_ts890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len, ack_len_expected, len; int levelint; int retval; char *command_string; gran_t *level_info; level_info = &rig->caps->level_gran[rig_setting2idx(level)]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { // TODO: This doesn't appear in TS890_LEVEL_GET - should it? case RIG_LEVEL_VOXDELAY: retval = kenwood_safe_transaction(rig, "VD0", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(ackbuf + 3, "%d", &levelint); val->i = levelint * 3 / 2; /* 150ms units converted to 100ms units */ return RIG_OK; case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = levelint / (float) 255; return RIG_OK; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint * level_info->step.f; return RIG_OK; case RIG_LEVEL_AGC: retval = kenwood_safe_transaction(rig, "GC", ackbuf, sizeof(ackbuf), 3); if (RIG_OK != retval) { return retval; } levelint = ackbuf[2] - '0'; /* atoi */ if (levelint < 0 || levelint >= rig->caps->agc_level_count) { rig_debug(RIG_DEBUG_ERR, "%s: unknown agc value: %s\n", __func__, ackbuf); return -RIG_EPROTO; } val->i = rig->caps->agc_levels[levelint]; return RIG_OK; case RIG_LEVEL_ALC: retval = get_kenwood_meter_reading(rig, '1', &levelint); if (retval != RIG_OK) { return retval; } val->f = (float)levelint / 35.0; /* Half scale [0,35] -> [0.0,1.0] */ return RIG_OK; case RIG_LEVEL_SWR: retval = get_kenwood_meter_reading(rig, '2', &levelint); if (retval != RIG_OK) { return retval; } if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(levelint, &rig->caps->swr_cal); } else { /* Linear approximations of a very non-linear function */ if (levelint < 12) { val->f = 1.0 + (float)levelint / 22.0; } else if (levelint < 24) { val->f = 1.5 + (float)(levelint - 11) / 24.0; } else if (levelint < 36) { val->f = 2.0 + (float)(levelint - 23) / 12.0; } else { val->f = 3.0 + (float)(levelint - 35) / 6.0; } } return RIG_OK; case RIG_LEVEL_COMP_METER: retval = get_kenwood_meter_reading(rig, '3', &levelint); if (retval != RIG_OK) { return retval; } if (levelint < 21) { val->f = (float)levelint / 2.0; } /* db */ else if (levelint < 51) { val->f = 10.0 + (float)(levelint - 20) / 3.0; } else { val->f = 20.0 + (float)(levelint - 50) / 4.0; } return RIG_OK; case RIG_LEVEL_ID_METER: retval = get_kenwood_meter_reading(rig, '4', &levelint); if (retval != RIG_OK) { return retval; } val->f = (20.0 * (float)levelint) / 70.0; /* amperes */ return RIG_OK; case RIG_LEVEL_VD_METER: retval = get_kenwood_meter_reading(rig, '5', &levelint); if (retval != RIG_OK) { return retval; } val->f = (15.0 * (float)levelint) / 65.0; /* volts */ return RIG_OK; case RIG_LEVEL_TEMP_METER: #if 0 retval = get_kenwood_meter_reading(rig, '6', &levelint); if (retval != RIG_OK) { return retval; } #endif return -RIG_ENIMPL; case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RFPOWER_METER_WATTS: { cal_table_float_t *table; ptt_t ptt = RIG_PTT_OFF; /* Values taken from the TS-890S In-Depth Manual (IDM), p. 8 * 0.03 - 21.5 MHz, Preamp 1 */ /* Meter Type 1 - Kenwood specific, factory default */ static cal_table_float_t meter_type1 = { 9, { { 0, -28.4f}, { 3, -26}, {11, -19.5f}, {19, -13}, {27, -6.5f}, {35, 0}, {48, 20}, {59, 40}, {70, 60} } }; /* Meter Type 2 - IARU recommended */ static cal_table_float_t meter_type2 = { 9, { { 0, -54}, { 3, -48}, {11, -36}, {19, -24}, {27, -12}, {35, 0}, {48, 20}, {59, 40}, {70, 60} } }; static cal_table_t power_meter = { 7, { { 0, 0}, { 5, 5}, { 10, 10}, {19, 25}, { 35, 50}, { 59, 100}, { 70, 150} } }; /* Make sure we're asking the right question */ kenwood_get_ptt(rig, vfo, &ptt); if ((ptt == RIG_PTT_OFF) != (level == RIG_LEVEL_STRENGTH)) { /* We're sorry, the number you have dialed is not in service */ if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = 0; } else { val->i = 0; } return RIG_OK; } /* Find out which meter type is in use */ retval = kenwood_safe_transaction(rig, "EX00011", ackbuf, sizeof(ackbuf), 11); if (retval != RIG_OK) { return retval; } if (strncmp(ackbuf + 8, "000", 3) == 0) { table = &meter_type1; } else if (strncmp(ackbuf + 8, "001", 3) == 0) { table = &meter_type2; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected meter type: %s\n", __func__, ackbuf); return -RIG_EPROTO; } retval = kenwood_safe_transaction(rig, "SM", ackbuf, 10, 6); if (retval != RIG_OK) { return retval; } sscanf(ackbuf + 2, "%d", &val->i); if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = roundf(rig_raw2val(val->i, &power_meter)); } else { /* Convert reading back to dB (rounded) */ val->i = (int)floorf(rig_raw2val_float(val->i, table) + 0.5f); } return RIG_OK; } case RIG_LEVEL_USB_AF: case RIG_LEVEL_USB_AF_INPUT: if (level == RIG_LEVEL_USB_AF) { command_string = "EX00708"; } else { command_string = "EX00706"; } len = strlen(command_string); retval = kenwood_safe_transaction(rig, command_string, ackbuf, sizeof(ackbuf), len + 4); if (retval != RIG_OK) { return retval; } sscanf(&ackbuf[len + 1], "%3d", &levelint); /* Skip the extra space */ val->f = levelint * level_info->step.f; return RIG_OK; default: return kenwood_get_level(rig, vfo, level, val); } return -RIG_EINTERNAL; } static int ts890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int mask, retval; char current[4]; switch (func) { case RIG_FUNC_TONE: mask = 1; break; case RIG_FUNC_TSQL: mask = 2; break; default: return (kenwood_set_func(rig, vfo, func, status)); } retval = kenwood_safe_transaction(rig, "TO", current, sizeof(current), 3); if (retval != RIG_OK) { return (retval); } current[2] &= ~mask; current[2] |= status == 0 ? 0 : mask; return kenwood_transaction(rig, current, NULL, 0); } static int ts890_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int mask, retval; char current[4]; switch (func) { case RIG_FUNC_TONE: mask = 1; break; case RIG_FUNC_TSQL: mask = 2; break; default: return (kenwood_get_func(rig, vfo, func, status)); } retval = kenwood_safe_transaction(rig, "TO", current, sizeof(current), 3); if (retval != RIG_OK) { return retval; } *status = current[2] & mask ? 1 : 0; return RIG_OK; } /* * Gets split VFO status * */ static int ts890s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { char buf[4]; int retval; vfo_t tvfo; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; if (RIG_OK == (retval = kenwood_safe_transaction(rig, "FT", buf, sizeof(buf), 3))) { if ('0' == buf[2]) { tvfo = RIG_VFO_A; } else if ('1' == buf[2]) { tvfo = RIG_VFO_B; } else if ('3' == buf[2]) { tvfo = RIG_VFO_MEM; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown VFO - %s\n", __func__, buf); return -RIG_EPROTO; } *txvfo = priv->tx_vfo = rs->tx_vfo = tvfo; // Now get split status retval = kenwood_safe_transaction(rig, "TB", buf, sizeof buf, 3); if (RIG_OK != retval) {return retval;} *split = priv->split = buf[2] == '1'; } return retval; } static struct kenwood_priv_caps ts890s_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 0, }; /* SWR meter calibration table */ /* The full scale value reads infinity, so arbitrary */ #define TS890_SWR_CAL { 5, \ { \ { 0, 1.0 }, \ { 11, 1.5 }, \ { 23, 2.0 }, \ { 35, 3.0 }, \ { 70, 15.0 } \ } } /* * TS-890S rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps ts890s_caps = { RIG_MODEL(RIG_MODEL_TS890S), .model_name = "TS-890S", .mfg_name = "Kenwood", .version = BACKEND_VER ".16", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 1, .preamp = {12, RIG_DBLST_END,}, .attenuator = {6, 12, 18, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_ON }, .chan_list = { { 1, 6, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS890_ALL_MODES, -1, -1, TS890_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(3500), kHz(3800), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(7), kHz(7200), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(7), kHz(7200), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(14), kHz(14350), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(14), kHz(14350), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(21), kHz(21450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(21), kHz(21450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(28), kHz(29700), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(28), kHz(29700), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(50), kHz(52000), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(50), kHz(52000), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS890_ALL_MODES, -1, -1, TS890_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(3500), MHz(4) - 1, TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(5250), kHz(5450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(5250), kHz(5450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(7), kHz(7300), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(7), kHz(7300), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(14), kHz(14350), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(14), kHz(14350), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(21), kHz(21450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(21), kHz(21450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(28), kHz(29700), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(28), kHz(29700), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(50), kHz(52000), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(50), kHz(52000), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS890_ALL_MODES, kHz(1)}, {TS890_ALL_MODES, Hz(2500)}, {TS890_ALL_MODES, kHz(5)}, {TS890_ALL_MODES, Hz(6250)}, {TS890_ALL_MODES, kHz(10)}, {TS890_ALL_MODES, Hz(12500)}, {TS890_ALL_MODES, kHz(15)}, {TS890_ALL_MODES, kHz(20)}, {TS890_ALL_MODES, kHz(25)}, {TS890_ALL_MODES, kHz(30)}, {TS890_ALL_MODES, kHz(100)}, {TS890_ALL_MODES, kHz(500)}, {TS890_ALL_MODES, MHz(1)}, {TS890_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .vfo_ops = TS890_VFO_OPS, .ctcss_list = kenwood51_ctcss_list, .swr_cal = TS890_SWR_CAL, .priv = (void *)& ts890s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit_new, .get_rit = kenwood_get_rit_new, .set_xit = kenwood_set_rit_new, // Same routines as for RIT .get_xit = kenwood_get_rit_new, // Same .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .vfo_op = kenwood_vfo_op, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = ts890s_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = NULL, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .wait_morse = rig_wait_morse, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS890_LEVEL_SET, .has_get_level = TS890_LEVEL_GET, .set_level = kenwood_ts890_set_level, .get_level = kenwood_ts890_get_level, .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_SQL #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_kenwood.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_SQL #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1100 }, .step = { .i = 5 } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 255.0 } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 100.0 } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 100.0 } }, }, .has_get_func = TS890_FUNC_ALL, .has_set_func = TS890_FUNC_ALL, .set_func = ts890_set_func, .get_func = ts890_get_func, .get_clock = kenwood_get_clock, .set_clock = kenwood_set_clock, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts940.c0000664000175000017500000001354215056640443012122 /* * Hamlib Kenwood backend - TS940 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "bandplan.h" #include "kenwood.h" #define TS940_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_SSB) #define TS940_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS940_AM_TX_MODES RIG_MODE_AM #define TS940_FUNC_ALL RIG_FUNC_LOCK #define TS940_LEVEL_ALL RIG_LEVEL_NONE #define TS940_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS940_ANTS (0) #define TS940_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS940_SCAN_OPS (RIG_SCAN_VFO) /* memory capabilities */ #define TS940_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ } static rmode_t ts940_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_NONE, [7] = RIG_MODE_NONE, [8] = RIG_MODE_NONE, [9] = RIG_MODE_NONE }; static struct kenwood_priv_caps ts940_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = ts940_mode_table, .tone_table_base = 1, }; /* * ts940 rig capabilities. * written from specs: * http://www.qsl.net/sm7vhs/radio/kenwood/ts940/specs.htm * * TODO: protocol to be check with manual! */ struct rig_caps ts940_caps = { RIG_MODEL(RIG_MODEL_TS940), .model_name = "TS-940S", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .timeout = 600, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = TS940_FUNC_ALL, .has_get_level = TS940_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS940_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { RIG_DBLST_END, }, /* TBC */ .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = TS940_VFO_OPS, .scan_ops = TS940_SCAN_OPS, .transceive = RIG_TRN_RIG, // Unknown AGC levels .bank_qty = 0, .chan_desc_sz = 0, /* four banks of 10 memories */ .chan_list = { { 0, 0, RIG_MTYPE_EDGE, TS940_MEM_CAP}, /* TBC */ { 1, 8, RIG_MTYPE_MEM, TS940_MEM_CAP}, /* TBC */ { 9, 9, RIG_MTYPE_EDGE, TS940_MEM_CAP}, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS940_ALL_MODES, -1, -1, TS940_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS940_OTHER_TX_MODES, W(5), W(250), TS940_VFO, TS940_ANTS), FRQ_RNG_HF(1, TS940_AM_TX_MODES, W(4), W(140), TS940_VFO, TS940_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS940_ALL_MODES, -1, -1, TS940_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS940_OTHER_TX_MODES, W(5), W(250), TS940_VFO, TS940_ANTS), FRQ_RNG_HF(2, TS940_AM_TX_MODES, W(4), W(140), TS940_VFO, TS940_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS940_ALL_MODES, 10}, {TS940_ALL_MODES, kHz(100)}, {TS940_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts940_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split, .get_split_vfo = kenwood_get_split_vfo_if, .set_ptt = kenwood_set_ptt, .get_ptt = kenwood_get_ptt, .set_func = kenwood_set_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .scan = kenwood_scan, .set_channel = kenwood_set_channel, .get_channel = kenwood_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/ts680.c0000664000175000017500000001433015056640443012117 /* * Hamlib Kenwood backend - TS680 description * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "kenwood.h" #define TS680_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_CWR) #define TS680_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_CWR) #define TS680_AM_TX_MODES RIG_MODE_AM #define TS680_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS680_ANTS (0) /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' static struct kenwood_priv_caps ts680_priv_caps = { .cmdtrm = EOM_KEN, }; static int ts680_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "ts680_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); /* The 680 and 140 need this to set the VFO on the radio */ return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts680 rig capabilities. * GW0VNR 09042006 */ struct rig_caps ts680s_caps = { RIG_MODEL(RIG_MODEL_TS680S), .model_name = "TS-680S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, /* Rig only capable of 4800 baud from factory and 9k6 with jumper change */ .serial_data_bits = 8, .serial_stop_bits = 2, /* TWO stop bits. This is correct. */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* No PARAMS controllable */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* Not controllable */ .attenuator = { RIG_DBLST_END, }, /* Not controllable */ .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = Hz(0), /* Not controllable */ .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 19, RIG_MTYPE_MEM }, { 20, 30, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), kHz(34999), TS680_ALL_MODES, -1, -1, TS680_VFO}, {MHz(45), kHz(59999), TS680_ALL_MODES, -1, -1, TS680_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS680_OTHER_TX_MODES, W(5), W(100), TS680_VFO, TS680_ANTS), FRQ_RNG_HF(1, TS680_AM_TX_MODES, W(2), W(40), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(1, TS680_OTHER_TX_MODES, W(1), W(10), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(1, TS680_AM_TX_MODES, W(1), W(4), TS680_VFO, TS680_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), kHz(34999), TS680_ALL_MODES, -1, -1, TS680_VFO}, {MHz(45), kHz(59999), TS680_ALL_MODES, -1, -1, TS680_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS680_OTHER_TX_MODES, W(5), W(100), TS680_VFO, TS680_ANTS), FRQ_RNG_HF(2, TS680_AM_TX_MODES, W(2), W(40), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(2, TS680_OTHER_TX_MODES, W(1), W(10), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(2, TS680_AM_TX_MODES, W(1), W(4), TS680_VFO, TS680_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: Done */ {TS680_ALL_MODES, 10}, {TS680_ALL_MODES, 100}, {TS680_ALL_MODES, kHz(1)}, {TS680_ALL_MODES, kHz(5)}, {TS680_ALL_MODES, kHz(9)}, {TS680_ALL_MODES, kHz(10)}, {TS680_ALL_MODES, 12500}, {TS680_ALL_MODES, kHz(20)}, {TS680_ALL_MODES, kHz(25)}, {TS680_ALL_MODES, kHz(100)}, {TS680_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_CWR, 600}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts680_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, // we don't know the ID for this rig .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts680_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/README.kenwood0000664000175000017500000000146715056640443013423 hamlib - Copyright (C) 2000 Frank Singleton libkenwood.so - Copyright (C) 2000 Stephane Fillod This shared library provides an API for communicating via serial interface to a Kenwood rig. Reference Documentation ----------------------- Kenwood CAT protocol (manual). Status ------ All primitives are written from spec. Some testing has been done with a TS-870S. At least reading and setting of frequency, mode, VFO, audio- and RF level should work. Patches and contributions are welcome! I'm also looking for a real maintainer :) --SF This lib should/will support other Kenwood models as well. Warnings -------- 1. This library should be tested with more kenwood rigs. 2. Error codes returned by the rig are not yet handled. Contributors ------------ Joop Stakenborg, PA4TU for TS-870S. hamlib-4.6.5/rigs/kenwood/ts570.c0000664000175000017500000010744015056640443012122 /* * Hamlib Kenwood backend - TS570 description * Copyright (c) 2001-2005 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include #include "kenwood.h" #define TS570_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS570_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS570_AM_TX_MODES RIG_MODE_AM #define TS570_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_TSQL|RIG_FUNC_TONE|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_LOCK|RIG_FUNC_BC|RIG_FUNC_TUNER) #define TS570_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_KEYSPD) #define TS570_VFO (RIG_VFO_A|RIG_VFO_B) #define TS570_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS570_SCAN_OPS (RIG_SCAN_VFO) #define TS570_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS570_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } static struct kenwood_priv_caps ts570_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; static int ts570_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[50]; size_t length; int retval; retval = kenwood_transaction(rig, "MD", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 3 || buf[1] != 'D') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected MD answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } switch (buf[2]) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FSK: *mode = RIG_MODE_RTTY; break; case MD_FSKR: *mode = RIG_MODE_RTTYR; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_get_mode: " "unsupported mode '%c'\n", buf[2]); return -RIG_EINVAL; } /* * Use FW (Filter Width) for CW and RTTY, * SL (dsp Slope Low cut-off) for all the other modes. * This is how it works on the TS870S, which does not have SL/SH commands. * TODO: combine SL and SH to set/read bandwidth.... */ switch (*mode) { case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: retval = kenwood_transaction(rig, "FW", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 6 || buf[1] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected FW answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } *width = atoi(&buf[2]); break; case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_FM: case RIG_MODE_AM: retval = kenwood_transaction(rig, "SL", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 4 || buf[1] != 'L') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected SL answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } *width = 50 * atoi(&buf[2]); break; default: return -RIG_EINVAL; } return RIG_OK; } static char mode_to_char(rmode_t mode) { switch (mode) { case RIG_MODE_CW: return (MD_CW); case RIG_MODE_CWR: return (MD_CWR); case RIG_MODE_USB: return (MD_USB); case RIG_MODE_LSB: return (MD_LSB); case RIG_MODE_FM: return (MD_FM); case RIG_MODE_AM: return (MD_AM); case RIG_MODE_RTTY: return (MD_FSK); case RIG_MODE_RTTYR: return (MD_FSKR); default: rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); } return (RIG_MODE_NONE); } static int ts570_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[16]; int kmode, retval; if ((kmode = mode_to_char(mode)) == RIG_MODE_NONE) { return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", kmode); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: SNPRINTF(buf, sizeof(buf), "FW%04d", (int)width); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } break; case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_FM: case RIG_MODE_AM: SNPRINTF(buf, sizeof(buf), "SL%02d", (int)width / 50); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } break; default: return -RIG_EINVAL; } return RIG_OK; } /* * extends kenwood_set_func * Assumes rig!=NULL, val!=NULL */ int ts570_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fctbuf[6]; /* Filter unimplemented RIG_FUNC_TUNER and allow settings 0..2 for * RIG_FUNC_NR. * Send all other requests to kenwood_set_func() */ switch (func) { case RIG_FUNC_NR: if ((status < 0) || (status > 2)) { return -RIG_EINVAL; } SNPRINTF(fctbuf, sizeof(fctbuf), "NR%01d", status); return kenwood_transaction(rig, fctbuf, NULL, 0); case RIG_FUNC_TUNER: SNPRINTF(fctbuf, sizeof(fctbuf), "AC %c0", (0 == status) ? '0' : '1'); return kenwood_transaction(rig, fctbuf, NULL, 0); default: return kenwood_set_func(rig, vfo, func, status); } return RIG_OK; } /* * extends kenwood_get_func * Assumes rig!=NULL, val!=NULL */ int ts570_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fctbuf[50]; size_t fct_len; int retval; fct_len = 50; /* filter unimplemented RIG_FUNC_TUNER * and send all other requests to kenwood_get_func() */ switch (func) { case RIG_FUNC_NR: retval = kenwood_transaction(rig, "NR", fctbuf, sizeof(fctbuf)); if (retval != RIG_OK) { return retval; } fct_len = strlen(fctbuf); if (fct_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)fct_len); return -RIG_ERJCTED; } *status = atoi(&fctbuf[2]); break; case RIG_FUNC_TUNER: retval = kenwood_transaction(rig, "AC", fctbuf, sizeof(fctbuf)); if (retval != RIG_OK) { return retval; } fct_len = strlen(fctbuf); if (fct_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)fct_len); return -RIG_ERJCTED; } *status = fctbuf[3] == '0' ? 0 : 1; break; default: return kenwood_get_func(rig, vfo, func, status); } return RIG_OK; } /* * ts570_set_level * Assumes rig!=NULL * * set levels of most functions */ int ts570_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; switch (level) { case RIG_LEVEL_PREAMP: kenwood_val = val.i; /* set the preamplifier if a correct value is entered */ if (kenwood_val == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int i; for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) if (kenwood_val == STATE(rig)->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); break; /* found - stop searching */ } else { return -RIG_EINVAL; } } return kenwood_transaction(rig, levelbuf, NULL, 0); case RIG_LEVEL_RFPOWER: /* level for TS570D is from 0.. 100W in SSB and CW */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); case RIG_LEVEL_MICGAIN: /* level is from 0..100 */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); default: return kenwood_set_level(rig, vfo, level, val); } return RIG_OK; /* never reached */ } /* * ts570_get_level * Assumes rig!=NULL, val!=NULL */ int ts570_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len; int levelint; int retval; switch (level) { case RIG_LEVEL_RFPOWER: /* ts570d returns 5..100 measured in watt */ retval = kenwood_transaction(rig, "PC", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_MICGAIN: /* reads from 0..100 */ retval = kenwood_transaction(rig, "MG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } ack_len = strlen(ackbuf); if (3 != ack_len) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)ack_len); return -RIG_ERJCTED; } sscanf(ackbuf + 2, "%d", &levelint); if (levelint == 0) { val->i = 0; } else { int i; for (i = 0; i < levelint && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected att level %d\n", __func__, (int)levelint); return -RIG_EPROTO; } } if (i != levelint) { return -RIG_EINTERNAL; } val->i = STATE(rig)->preamp[i - 1]; } break; default: return kenwood_get_level(rig, vfo, level, val); } return RIG_OK; /* never reached */ } /* * ts570_get_split_vfo */ int ts570_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char ack[10]; char ack2[10]; int retval; retval = kenwood_transaction(rig, "FR", ack, sizeof(ack)); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "FT", ack2, sizeof(ack2)); if (retval != RIG_OK) { return retval; } if (ack[2] != ack2[2]) { *split = RIG_SPLIT_ON; switch (ack2[2]) { case '0': *tx_vfo = RIG_VFO_A; break; case '1': *tx_vfo = RIG_VFO_B; break; case '2': *tx_vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_get_split_vfo: unknown tx vfo: %d\n", ack2[2]); return -RIG_EINVAL; } } else { *split = RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_CURR; } return RIG_OK; } #define cmd_trm(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv)->cmdtrm /* * ts570_set_split_vfo */ int ts570_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { char cmdbuf[16], ackbuf[20]; int retval; unsigned char vfo_function; if (vfo != RIG_VFO_CURR) { switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_set_split_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } /* set RX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } if (split == RIG_SPLIT_ON) { switch (txvfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_TX: if (vfo == RIG_VFO_A) { vfo_function = '0'; } else if (vfo == RIG_VFO_B) { vfo_function = '1'; } else if (vfo == RIG_VFO_MEM) { vfo_function = '2'; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported vfo/txvfo combination vfo=%s, txvfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(txvfo)); return -RIG_EINVAL; } break; default: rig_debug(RIG_DEBUG_ERR, "ts570_set_split_vfo: unsupported VFO %s\n", rig_strvfo(txvfo)); return -RIG_EINVAL; } /* set TX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } else /* RIG_SPLIT_OFF */ if (vfo == RIG_VFO_CURR) { /* switch to current RX VFO */ /* first ask for it */ retval = kenwood_transaction(rig, "FR", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } /* and then set it to both vfo's */ vfo_function = ackbuf[2]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* memory capabilities */ #define TS570_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .ctcss_tone=1 \ } int ts570_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[30]; int retval; int num, freq, tx_freq, tone; char mode, tx_mode, tones; num = chan->channel_num; freq = (int)chan->freq; mode = mode_to_char(chan->mode); if (chan->split == RIG_SPLIT_ON) { tx_freq = (int)chan->tx_freq; tx_mode = mode_to_char(chan->tx_mode); } else { tx_freq = 0; tx_mode = '\0'; } for (tone = 1; rig->caps->ctcss_list[tone - 1] != 0 && tone < 39; tone++) { if (rig->caps->ctcss_list[tone - 1] == chan->ctcss_tone) { break; } } if (chan->ctcss_tone != 0) { tones = '1'; } else { tones = '0'; tone = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW0 %02d%011d%c0%c%02d ", num, freq, mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW1 %02d%011d%c0%c%02d ", num, tx_freq, tx_mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ts570_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { char infobuf[50]; int retval; size_t info_len; retval = kenwood_transaction(rig, "IF", infobuf, sizeof(infobuf)); if (retval != RIG_OK) { return retval; } info_len = strlen(infobuf); if (info_len != 37 || infobuf[1] != 'F') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)info_len); return -RIG_ERJCTED; } if (infobuf[24] == '0') /* RIT off? */ { *rit = 0; } else { infobuf[23] = '\0'; *rit = atoi(&infobuf[18]); } return RIG_OK; } int ts570_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "RT0", NULL, 0); if (retval != RIG_OK) { return retval; } else { return RIG_OK; } } else { retval = kenwood_transaction(rig, "RT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int ts570_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "XT0", NULL, 0); if (retval != RIG_OK) { return retval; } else { return RIG_OK; } } else { retval = kenwood_transaction(rig, "XT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * ts570 rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range 9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts570s_caps = { RIG_MODEL(RIG_MODEL_TS570S), .model_name = "TS-570S", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 30, .timeout = 500, .retry = 10, .has_get_func = TS570_FUNC_ALL, .has_set_func = TS570_FUNC_ALL, .has_get_level = TS570_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS570_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = TS570_VFO_OP, .scan_ops = TS570_SCAN_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 2, .agc_levels = { RIG_AGC_FAST, RIG_AGC_SLOW }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS570_MEM_CAP }, { 90, 99, RIG_MTYPE_EDGE, TS570_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(60), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), kHz(3800) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(60), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), MHz(4) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS570_ALL_MODES, 50}, {TS570_ALL_MODES, 100}, {TS570_ALL_MODES, kHz(1)}, {TS570_ALL_MODES, kHz(5)}, {TS570_ALL_MODES, kHz(9)}, {TS570_ALL_MODES, kHz(10)}, {TS570_ALL_MODES, 12500}, {TS570_ALL_MODES, kHz(20)}, {TS570_ALL_MODES, kHz(25)}, {TS570_ALL_MODES, kHz(100)}, {TS570_ALL_MODES, MHz(1)}, {TS570_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& ts570_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts570_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts570_set_xit, .get_xit = ts570_get_xit, .set_mode = ts570_set_mode, .get_mode = ts570_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = ts570_set_split_vfo, .get_split_vfo = ts570_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts570_set_func, .get_func = ts570_get_func, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .set_level = ts570_set_level, .get_level = ts570_get_level, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .set_channel = ts570_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .scan = kenwood_scan, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ts570d rig capabilities, which is basically the ts570s without 6m. * Notice that some rigs share the same functions. * RIT: Variable Range 9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts570d_caps = { RIG_MODEL(RIG_MODEL_TS570D), .model_name = "TS-570D", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 30, .timeout = 500, .retry = 10, .has_get_func = TS570_FUNC_ALL, .has_set_func = TS570_FUNC_ALL, .has_get_level = TS570_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS570_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = TS570_VFO_OP, .scan_ops = TS570_SCAN_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS570_MEM_CAP }, { 90, 99, RIG_MTYPE_EDGE, TS570_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), kHz(3800) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), MHz(4) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS570_ALL_MODES, 50}, {TS570_ALL_MODES, 100}, {TS570_ALL_MODES, kHz(1)}, {TS570_ALL_MODES, kHz(5)}, {TS570_ALL_MODES, kHz(9)}, {TS570_ALL_MODES, kHz(10)}, {TS570_ALL_MODES, 12500}, {TS570_ALL_MODES, kHz(20)}, {TS570_ALL_MODES, kHz(25)}, {TS570_ALL_MODES, kHz(100)}, {TS570_ALL_MODES, MHz(1)}, {TS570_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_SSB, Hz(0)}, {RIG_MODE_SSB, kHz(1)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(1000)}, {RIG_MODE_RTTY, Hz(1000)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, Hz(500)}, {RIG_MODE_AM, Hz(0)}, {RIG_MODE_AM, kHz(1)}, {RIG_MODE_FM, Hz(500)}, {RIG_MODE_FM, Hz(0)}, {RIG_MODE_FM, kHz(1)}, RIG_FLT_END, }, .str_cal = TS570_STR_CAL, .priv = (void *)& ts570_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts570_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts570_set_xit, .get_xit = ts570_get_xit, .set_mode = ts570_set_mode, .get_mode = ts570_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = ts570_set_split_vfo, .get_split_vfo = ts570_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts570_set_func, .get_func = ts570_get_func, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .set_level = ts570_set_level, .get_level = ts570_get_level, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .set_channel = ts570_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .scan = kenwood_scan, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/level_gran_kenwood.h0000664000175000017500000001100315056640443015076 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, #if !defined(NO_LVL_ATT) [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, #endif [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, /* levels with WPM units */ #if !defined(NO_LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, #endif [LVL_IF] = { .min = { .i = -1000 }, .max = { .i = 1000 }, .step = { .i = 1 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, #if !defined(NO_LVL_SLOPE_LOW) [LVL_SLOPE_LOW] = { .min = { .i = 10}, .max = { .i = 1000 }, .step = { .i = 50 } }, #endif #if !defined(NO_LVL_SLOPE_HIGH) [LVL_SLOPE_HIGH] = { .min = { .i = 1000 }, .max = { .i = 5000 }, .step = { .i = 10 } }, #endif /* levels with time units */ #if !defined(NO_LVL_VOXDELAY) [LVL_VOXDELAY] = { .min = { .i = 3 }, .max = { .i = 300 }, .step = { .i = 1 } }, #endif [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, #if !defined(NO_LVL_BKIN_DLYMS) [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, #endif /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, /* levels with 0-1 values -- increment based on rig's range */ #if !defined(NO_LVL_NR) [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_NB) [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_AF) [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RF) [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, #endif [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #if !defined(NO_LVL_SQL) [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #if !defined(NO_LVL_COMP) [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ANTIVOX] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #if !defined(NO_LVL_USB_AF) [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_USB_AF_INPUT) [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif hamlib-4.6.5/rigs/kenwood/flex.c0000664000175000017500000001053315056640443012172 /* * Hamlib Flex 6K series support using supported Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2011 by Alexander Sack, Alexander Sack, pisymbol@gmail.com * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include "flex.h" #include "kenwood.h" /* Private helper functions */ int verify_flexradio_id(RIG *rig, char *id) { int err; char *idptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!id) { return -RIG_EINVAL; } /* Check for a Flex 6700 which returns "904" */ err = kenwood_get_id(rig, id); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cannot get identification\n", __func__); return err; } /* ID is 'ID904;' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown ID type (%s)\n", __func__, id); return -RIG_EPROTO; } /* check for any white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } if (strcmp("900", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (PowerSDR compatible)\n", __func__, id); } else if (strcmp("904", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6700)\n", __func__, id); } else if (strcmp("905", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6500)\n", __func__, id); } else if (strcmp("906", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6500R)\n", __func__, id); } else if (strcmp("907", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6300)\n", __func__, id); } else if (strcmp("908", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6400)\n", __func__, id); } else if (strcmp("909", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6600)\n", __func__, id); } else { rig_debug(RIG_DEBUG_WARN, "%s: Rig (%.5s) is not a Flex 6000 Series\n", __func__, id); } return RIG_OK; } /* Shared backend function definitions */ /* flexradio_open() * */ int flexradio_open(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; int err; char id[FLEXRADIO_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); //struct flexradio_priv_data *priv = STATE(rig)->priv; /* Use check for "ID017;" to verify rig is reachable */ err = verify_flexradio_id(rig, id); if (err != RIG_OK) { return err; } switch (rig->caps->rig_model) { case RIG_MODEL_F6K: break; case RIG_MODEL_POWERSDR: case RIG_MODEL_THETIS: break; default: rig_debug(RIG_DEBUG_WARN, "%s: unrecognized rig model %u\n", __func__, rig->caps->rig_model); return -RIG_EINVAL; } priv->has_rit2 = 1; /* get current AI state so it can be restored */ priv->trn_state = -1; kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } //stopped hamlib-4.6.5/rigs/kenwood/ts440.c0000664000175000017500000001427515056640443012121 /* * Hamlib Kenwood backend - TS440 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "ic10.h" #define TS440_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS440_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS440_AM_TX_MODES RIG_MODE_AM #define TS440_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) #define TS440_LEVEL_ALL RIG_LEVEL_NONE #define TS440_VFO (RIG_VFO_A|RIG_VFO_B) #define TS440_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS440_SCAN_OPS (RIG_SCAN_VFO) static struct kenwood_priv_caps ts440_priv_caps = { .cmdtrm = EOM_KEN, .if_len = 37, .tone_table_base = 1, }; /* * ts440 rig capabilities. * * part of infos comes from .http = //www.n7uic.net/radio/kenwood/ts440/specs.htm * .http = //public.srce.hr/9A1CDD/mods/kenwood/knwdif.mod * .http = //www.ifrance.fr/clucas/modposte/ts440/mod440.htm * */ struct rig_caps ts440_caps = { RIG_MODEL(RIG_MODEL_TS440), .model_name = "TS-440S", .mfg_name = "Kenwood", .version = IC10_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = TS440_FUNC_ALL, .has_get_level = TS440_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS440_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(1270), .max_xit = Hz(1270), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = TS440_VFO_OPS, .scan_ops = TS440_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, {IC10_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS440_ALL_MODES, -1, -1, TS440_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(1800), MHz(2) - 1, TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(3500), MHz(4) - 1, TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(3500), MHz(4) - 1, TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(7), kHz(7300), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(7), kHz(7300), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(10100), kHz(10150), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(10100), kHz(10150), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(14), kHz(14350), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(14), kHz(14350), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(18068), kHz(18168), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(18068), kHz(18168), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(21), kHz(21450), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(21), kHz(21450), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(24890), kHz(24990), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(24890), kHz(24990), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(28), kHz(29700), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(28), kHz(29700), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS440_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts440_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = ic10_set_mode, .get_mode = ic10_get_mode, .set_vfo = ic10_set_vfo, .get_vfo = ic10_get_vfo, .set_split_freq = ic10_set_split_freq, .get_split_freq = ic10_get_split_freq, .set_split_vfo = ic10_set_split_vfo, .get_split_vfo = ic10_get_split_vfo, .set_ptt = ic10_set_ptt, .get_ptt = ic10_get_ptt, .set_func = kenwood_set_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = ic10_get_mem, .set_trn = kenwood_set_trn, .scan = kenwood_scan, .set_channel = ic10_set_channel, .get_channel = ic10_get_channel, .decode_event = ic10_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/kenwood.c0000664000175000017500000050770315056640443012714 /* * Hamlib Kenwood backend - main file * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "cal.h" #include "cache.h" #include "misc.h" #include "kenwood.h" #include "ts990s.h" #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct kenwood_id { rig_model_t model; int id; }; struct kenwood_id_string { rig_model_t model; const char *id; }; #define UNKNOWN_ID -1 /* * Identification number as returned by "ID;" * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF * * TODO: sort this list with most frequent rigs first. */ static const struct kenwood_id kenwood_id_list[] = { { RIG_MODEL_TS940, 1 }, { RIG_MODEL_TS811, 2 }, { RIG_MODEL_TS711, 3 }, { RIG_MODEL_TS440, 4 }, { RIG_MODEL_R5000, 5 }, { RIG_MODEL_TS140S, 6 }, // { RIG_MODEL_TS680S, 6 }, // The TS680S is supposed #6 too but it will return as TS140S since it matches it { RIG_MODEL_TS790, 7 }, { RIG_MODEL_TS950S, 8 }, { RIG_MODEL_TS850, 9 }, { RIG_MODEL_TS450S, 10 }, { RIG_MODEL_TS690S, 11 }, { RIG_MODEL_TS950SDX, 12 }, { RIG_MODEL_TS50, 13 }, { RIG_MODEL_TS870S, 15 }, { RIG_MODEL_TRC80, 16 }, { RIG_MODEL_TS570D, 17 }, /* Elecraft K2|K3 also returns 17 */ { RIG_MODEL_TS570S, 18 }, { RIG_MODEL_TS2000, 19 }, { RIG_MODEL_TS480, 20 }, { RIG_MODEL_TS590S, 21 }, { RIG_MODEL_TS990S, 22 }, { RIG_MODEL_TS590SG, 23 }, { RIG_MODEL_TS890S, 24 }, { RIG_MODEL_NONE, UNKNOWN_ID }, /* end marker */ }; /* XXX numeric ids have been tested only with the TS-450 */ static const struct kenwood_id_string kenwood_id_string_list[] = { { RIG_MODEL_TS940, "001" }, { RIG_MODEL_TS811, "002" }, { RIG_MODEL_TS711, "003" }, { RIG_MODEL_TS440, "004" }, { RIG_MODEL_R5000, "005" }, { RIG_MODEL_TS140S, "006" }, { RIG_MODEL_TS790, "007" }, { RIG_MODEL_TS950S, "008" }, { RIG_MODEL_TS850, "009" }, { RIG_MODEL_TS450S, "010" }, { RIG_MODEL_TS690S, "011" }, { RIG_MODEL_TS950SDX, "012" }, { RIG_MODEL_TS50, "013" }, { RIG_MODEL_TS870S, "015" }, { RIG_MODEL_TS570D, "017" }, /* Elecraft K2|K3|KX3 also returns 17 */ { RIG_MODEL_TS570S, "018" }, { RIG_MODEL_TS2000, "019" }, { RIG_MODEL_TS480, "020" }, { RIG_MODEL_PT8000A, "020" }, // TS480 ID but behaves differently { RIG_MODEL_SDRUNO, "020" }, // TS480 ID but behaves differently { RIG_MODEL_TS590S, "021" }, { RIG_MODEL_TS990S, "022" }, { RIG_MODEL_TS590SG, "023" }, { RIG_MODEL_TS890S, "024" }, { RIG_MODEL_THD7A, "TH-D7" }, { RIG_MODEL_THD7AG, "TH-D7G" }, { RIG_MODEL_TMD700, "TM-D700" }, { RIG_MODEL_TMD710, "TM-D710" }, { RIG_MODEL_THD72A, "TH-D72" }, { RIG_MODEL_THD74, "TH-D74" }, { RIG_MODEL_TMV7, "TM-V7" }, { RIG_MODEL_TMV71, "TM-V71" }, { RIG_MODEL_THF6A, "TH-F6" }, { RIG_MODEL_THF7E, "TH-F7" }, { RIG_MODEL_THG71, "TH-G71" }, { RIG_MODEL_MALACHITE, "020" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; rmode_t kenwood_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, // FSK Mode [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode or PKTUSB for SDRUNO */ [9] = RIG_MODE_RTTYR, // FSKR Mode [10] = RIG_MODE_PSK, [11] = RIG_MODE_PSKR, [12] = RIG_MODE_PKTLSB, [13] = RIG_MODE_PKTUSB, [14] = RIG_MODE_PKTFM, // FM-D1 not supported yet [15] = RIG_MODE_PKTAM, // AM-D1 not supported yet [16] = RIG_MODE_LSBD2, [17] = RIG_MODE_USBD2, [18] = RIG_MODE_NONE, // FM-D2 not supported yet [19] = RIG_MODE_NONE, // AM-D2 not supported yet [20] = RIG_MODE_LSBD3, [21] = RIG_MODE_USBD3, [22] = RIG_MODE_NONE, // FM-D3 not supported yet [23] = RIG_MODE_NONE, // AM-D3 not supported yet }; /* * 38 CTCSS sub-audible tones */ tone_t kenwood38_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; /* * 42 CTCSS sub-audible tones */ tone_t kenwood42_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* * 51 CTCSS sub-audible tones */ tone_t kenwood51_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, /* 0- 9 */ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, /* 10-19 */ 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, /* 20-29 */ 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, /* 30-39 */ 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, /* 40-49 */ 17500, 0 /* 50-99 */ }; /* Token definitions for .cfgparams in rig_caps * * See enum rig_conf_e and struct confparams in rig.h */ struct confparams kenwood_cfg_params[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_NO_ID, "no_id", "No ID", "If true do not send ID; with set commands", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; // This function removes non-printable characters from a buffer. This was // implemented to work around a problem reported with the uSDX transceiver // [1], which emulates the Kenwood TS-480 but apparently generates garbage // on the serial port in some situations. // // [1]: https://github.com/Hamlib/Hamlib/issues/1652 static int remove_nonprint(char *s) { int i, j = 0; if (s == NULL) return 0; for (i = 0; s[i] != '\0'; ++i) { if (isprint((unsigned char)s[i])) { s[j++] = s[i]; // Copy printable character } } s[j] = '\0'; // Null-terminate the string return j; // Return the new length of the string } /** * kenwood_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * Parameters: * cmdstr: Command to be sent to the rig. cmdstr can also be NULL, * indicating that only a reply is needed (nothing will be sent). * data: Buffer for reply string. Can be NULL, indicating that no reply * is needed and will return with RIG_OK after command was sent. * datasize: Size of buffer. It is the caller's responsibility to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize) { char buffer[KENWOOD_MAX_BUF_LEN]; /* use our own buffer since verification may need a longer buffer than the user supplied one */ char cmdtrm_str[2]; /* Default Command/Reply termination char */ int retval = -RIG_EINTERNAL; char *cmd; int len; int retry_read = 0; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct rig_state *rs; struct hamlib_port *rp; /* Pointer to rigport structure */ if (datasize > 0 && datasize < (cmdstr ? strlen(cmdstr) : 0)) { rig_debug(RIG_DEBUG_WARN, "%s called cmd=%.4095s datasize=%d, datasize < cmd length?\n", __func__, cmdstr ? cmdstr : "(NULL)", (int)datasize); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s called cmd=%s\n", __func__, cmdstr ? cmdstr : "(NULL)"); } if ((!cmdstr && !datasize) || (datasize && !data)) { RETURNFUNC2(-RIG_EINVAL); } rs = STATE(rig); rp = RIGPORT(rig); rs->transaction_active = 1; /* Emulators don't need any post_write_delay */ if (priv->is_emulation) { rp->post_write_delay = 0; } // if this is an IF cmdstr and not the first time through check cache if (cmdstr && strcmp(cmdstr, "IF") == 0 && priv->cache_start.tv_sec != 0) { int cache_age_ms; cache_age_ms = elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_GET); if (cache_age_ms < 500) // 500ms cache time { rig_debug(RIG_DEBUG_TRACE, "%s(%d): cache hit, age=%dms\n", __func__, __LINE__, cache_age_ms); if (data) { strncpy(data, priv->last_if_response, datasize); } RETURNFUNC2(RIG_OK); } // else we drop through and do the real IF command } if (cmdstr && (strlen(cmdstr) > 2 || strcmp(cmdstr, "RX") == 0 || strncmp(cmdstr, "TX", 2) == 0 || strncmp(cmdstr, "ZZTX", 4)) == 0) { // then we must be setting something so we'll invalidate the cache rig_debug(RIG_DEBUG_TRACE, "%s: cache invalidated\n", __func__); priv->cache_start.tv_sec = 0; } cmdtrm_str[0] = caps->cmdtrm; cmdtrm_str[1] = '\0'; transaction_write: if (cmdstr) { rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); len = strlen(cmdstr); cmd = calloc(1, len + 2); if (cmd == NULL) { retval = -RIG_ENOMEM; goto transaction_quit; } memcpy(cmd, cmdstr, len); /* XXX the if is temporary, until all invocations are fixed */ if (cmdstr[len - 1] != ';' && cmdstr[len - 1] != '\r') { cmd[len] = caps->cmdtrm; len++; } /* flush anything in the read buffer before command is sent */ rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, len); free(cmd); if (retval != RIG_OK) { goto transaction_quit; } } // we're not going to do the verify on RX cmd // Seems some rigs (like TS-480) return "?" when RX is done while PTT=OFF // So we'll skip the checks just on this one command for now // The TS-480 PC Control says RX; should return RX0; but it doesn't // We may eventually want to verify PTT with rig_get_ptt instead // The TS-2000 doesn't like doing an ID right after RU or RD if (retval == RIG_OK) { int skip = strncmp(cmdstr, "RX", 2) == 0; skip |= strncmp(cmdstr, "RU", 2) == 0; skip |= strncmp(cmdstr, "RD", 2) == 0; skip |= strncmp(cmdstr, "KYW", 3) == 0; skip |= strncmp(cmdstr, "KY ", 3) == 0; skip |= strncmp(cmdstr, "KY0", 3) == 0; skip |= strncmp(cmdstr, "KY2", 3) == 0; skip |= strncmp(cmdstr, "PS1", 3) == 0; skip |= strncmp(cmdstr, "PS0", 3) == 0; skip |= strncmp(cmdstr, "K22", 3) == 0; if (skip) { // most command we give them a little time -- but not KY if (strncmp(cmdstr, "KY", 2) != 0 || (cmdstr[2] != ' ' && cmdstr[2] != '0' && cmdstr[2] != '2')) { hl_usleep(200 * 1000); // give little settle time for these commands } goto transaction_quit; } } // Malachite SDR cannot send ID after FA if (!datasize && priv->no_id) { RETURNFUNC2(RIG_OK); } if (!datasize && strncmp(cmdstr, "KY", 2) != 0) { rs->transaction_active = 0; // there are some commands that have problems with immediate follow-up // so we'll just ignore them /* no reply expected so we need to write a command that always gives a reply so we can read any error replies from the actual command being sent without blocking */ if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { goto transaction_quit; } } transaction_read: /* allow room for most any response */ // this len/expected stuff is confusing -- logic in some places includes the semicolon // so we add 1 to our read_string length to cover these cases // eventually we should be able to get rid of this but requires testing all Kenwood rigs len = min(datasize ? datasize + 1 : strlen(priv->verify_cmd) + 48, KENWOOD_MAX_BUF_LEN); retval = read_string(rp, (unsigned char *) buffer, len, cmdtrm_str, strlen(cmdtrm_str), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string len=%d '%s'\n", __func__, (int)strlen(buffer), buffer); // This fixes the case when some corrupt data is returned; it lets us be a // little more robust about funky serial data. If the terminator is // printable(usually ';'), then there should be no nonprintables in the // message; if it isn't (usually '\r') then don't touch the message. if (isprint(caps->cmdtrm)) { remove_nonprint(buffer); } if (retval < 0) { rig_debug(RIG_DEBUG_WARN, "%s: read_string retval < 0, retval = %d, retry_read=%d, rp->retry=%d\n", __func__, retval, retry_read, rp->retry); // only retry if we expect a response from the command if (retry_read++ < rp->retry) { goto transaction_write; // we use to not re-do the write // but now we use ID; to verify commands are working // so in order to retry commands need to re-write them // https://github.com/Hamlib/Hamlib/issues/983 #if 0 if (datasize) { goto transaction_write; } else if (-RIG_ETIMEOUT == retval) { goto transaction_read; } #endif } goto transaction_quit; } /* Check that command termination is correct */ if (strchr(cmdtrm_str, buffer[strlen(buffer) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, buffer); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strlen(buffer) == 2) { switch (buffer[0]) { case 'N': /* Command recognised by rig but invalid data entered. */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, cmdstr); } retval = -RIG_ENAVAIL; goto transaction_quit; case 'O': /* Too many characters sent without a carriage return */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; case 'E': /* Communication error */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EIO; goto transaction_quit; case '?': /* The ? response is an ambiguous response, but for get commands it seems to * indicate that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue, * as the error is caused by the an invalid combination of rig state. * * For example, the following cases have been observed: * - NL (NB level) and RL (NR level) commands fail if NB / NR are not enabled on TS-590SG * - SH and SL (filter width) fail in CW mode on TS-590SG * - GT (AGC) fails in FM mode on TS-590SG * * There are more cases like these and they vary by rig model. */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (get): '%s'\n", __func__, cmdstr); RETURNFUNC2(-RIG_ERJCTED); } /* Command not understood by rig or rig busy */ if (cmdstr) { rig_debug(RIG_DEBUG_ERR, "%s: Unknown command or rig busy '%s'\n", __func__, cmdstr); // sometimes IF; command after TX; will return ? but still return IF response if (retry_read++ <= 1) { hl_usleep(100 * 1000); goto transaction_read; } } if (retry_read++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: Retrying shortly %d of %d\n", __func__, retry_read, rp->retry); hl_usleep(rig->caps->timeout * 1000); goto transaction_write; } retval = -RIG_ERJCTED; goto transaction_quit; } } /* * Check that we received the correct reply. The first two characters * should be the same as command. Because the Elecraft XG3 uses * single character commands we only check the first character in * that case. */ if (datasize) { // we ignore the special PS command if (cmdstr && strcmp(cmdstr, "PS") != 0 && (buffer[0] != cmdstr[0] || (cmdstr[1] && buffer[1] != cmdstr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %c%c for command %c%c\n", __func__, buffer[0], buffer[1], cmdstr[0], cmdstr[1]); rig_debug(RIG_DEBUG_ERR, "%s: retry_read=%d, rp->retry=%d\n", __func__, retry_read, rp->retry); if (retry_read++ < rp->retry) { if (strlen(buffer) == 0) { goto transaction_write; // didn't get an answer so send again } else { // should be able to handle transceive mode here goto transaction_read; // might be an async or corrupt reply so we'll read until timeout } } retval = -RIG_EPROTO; goto transaction_quit; } if (retval > 0) { /* move the result excluding the command terminator into the caller buffer */ len = min(datasize, retval) - 1; strncpy(data, buffer, len); data[len] = '\0'; } } else { rig_debug(RIG_DEBUG_TRACE, "%s: No data expected, checking %s in %s\n", __func__, priv->verify_cmd, buffer); // seems some rigs will send back an IF response to RX/TX when it changes the status // normally RX/TX returns nothing when it's a null effect // TS-950SDX is known to behave this way if (strncmp(cmdstr, "RX", 2) == 0 || strncmp(cmdstr, "TX", 2) == 0) { if (strncmp(priv->verify_cmd, "IF", 2) == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: RX/TX got IF response so we're good\n", __func__); goto transaction_quit; } } if (priv->verify_cmd[0] != buffer[0] || (priv->verify_cmd[1] && priv->verify_cmd[1] != buffer[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ // if we got FA or FB unexpectedly then perhaps RIG_TRN is enabled and we just need to handle it if (strncmp(buffer, "FA", 2) == 0) { freq_t freq; sscanf(buffer, "FA%lg", &freq); rig_set_cache_freq(rig, RIG_VFO_A, freq); goto transaction_read; } else if (strncmp(buffer, "FB", 2) == 0) { freq_t freq; sscanf(buffer, "FB%lg", &freq); rig_set_cache_freq(rig, RIG_VFO_B, freq); goto transaction_read; } rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %c%c for command verification %c%c\n", __func__, buffer[0], buffer[1] , priv->verify_cmd[0], priv->verify_cmd[1]); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } } retval = RIG_OK; rig_debug(RIG_DEBUG_TRACE, "%s: returning RIG_OK, retval=%d\n", __func__, retval); transaction_quit: // update the cache if (retval == RIG_OK && cmdstr && strcmp(cmdstr, "IF") == 0) { elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_SET); strncpy(priv->last_if_response, buffer, caps->if_len); } rs->transaction_active = 0; RETURNFUNC2(retval); } /** * kenwood_safe_transaction * A wrapper for kenwood_transaction to check returned data against * expected length, * * Parameters: * cmd Same as kenwood_transaction() cmdstr * buf Same as kenwwod_transaction() data * buf_size Same as kenwood_transaction() datasize * expected Value of expected string length * * Returns: * RIG_OK - if no error occurred. * RIG_EPROTO if returned string and expected are not equal * Error from kenwood_transaction() if any * */ int kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected) { int err; int retry = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s, expected=%d\n", __func__, cmd, (int)expected); if (!cmd) { RETURNFUNC2(-RIG_EINVAL); } memset(buf, 0, buf_size); if (expected == 0) { buf_size = 0; } do { size_t length; // some PowerSDR commands have variable len int checklen = !RIG_IS_POWERSDR && !RIG_IS_THETIS; err = kenwood_transaction(rig, cmd, buf, buf_size); if (err != RIG_OK) /* return immediately on error as any retries handled at lower level */ { RETURNFUNC2(err); } length = strlen(buf); if (checklen && length != expected) /* worth retrying as some rigs occasionally send short results */ { // QRPLABS can't seem to decide if they give 37 or 38 bytes for IF command if (strncmp(cmd, "IF", 2) == 0 && rig->caps->rig_model == RIG_MODEL_QRPLABS) { break; } struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_ERR, "%s: wrong answer; len for cmd %s: expected = %d, got %d\n", __func__, cmd, (int)expected, (int)length); err = -RIG_EPROTO; elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_INVALIDATE); hl_usleep(50 * 1000); // let's do a short wait } } while (err != RIG_OK && ++retry < RIGPORT(rig)->retry); RETURNFUNC2(err); } rmode_t kenwood2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode >= KENWOOD_MODE_TABLE_MAX) { return (RIG_MODE_NONE); } return (mode_table[mode]); } char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); if (mode != RIG_MODE_NONE) { int i; for (i = 0; i < KENWOOD_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: returning %d\n", __func__, i); return (i); } } } return (-1); } int kenwood_init(RIG *rig) { struct kenwood_priv_data *priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s/%s\n", __func__, BACKEND_VER, rig->caps->version); STATE(rig)->priv = calloc(1, sizeof(struct kenwood_priv_data)); if (STATE(rig)->priv == NULL) { RETURNFUNC2(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct kenwood_priv_data)); if (RIG_IS_XG3) { priv->verify_cmd[0] = caps->cmdtrm; priv->verify_cmd[1] = '\0'; } else { priv->verify_cmd[0] = 'I'; priv->verify_cmd[1] = 'D'; priv->verify_cmd[2] = caps->cmdtrm; priv->verify_cmd[3] = '\0'; } priv->split = RIG_SPLIT_OFF; priv->trn_state = -1; priv->curr_mode = 0; priv->micgain_min = -1; priv->micgain_max = -1; priv->has_ps = 1; // until proven otherwise if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS50 || rig->caps->rig_model == RIG_MODEL_TS140S || rig->caps->rig_model == RIG_MODEL_TS2000 || rig->caps->rig_model == RIG_MODEL_TS440 || rig->caps->rig_model == RIG_MODEL_QRPLABS) { priv->has_ps = 0; } /* default mode_table */ if (caps->mode_table == NULL) { caps->mode_table = kenwood_mode_table; } /* default if_len */ if (caps->if_len == 0) { caps->if_len = 37; } priv->ag_format = -1; // force determination of AG format rig_debug(RIG_DEBUG_TRACE, "%s: if_len = %d\n", __func__, caps->if_len); // SDRUno uses mode 8 for DIG if (rig->caps->rig_model == RIG_MODEL_SDRUNO) { kenwood_mode_table[8] = RIG_MODE_PKTUSB; } RETURNFUNC2(RIG_OK); } int kenwood_cleanup(RIG *rig) { ENTERFUNC; free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } int kenwood_open(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); int err, i; char *idptr; char id[KENWOOD_MAX_BUF_LEN]; int retry_save = RIGPORT(rig)->retry; ENTERFUNC; id[0] = 0; RIGPORT(rig)->retry = 0; priv->question_mark_response_means_rejected = 0; if (STATE(rig)->auto_power_on) { // Ensure rig is on rig_set_powerstat(rig, 1); sleep(1); } err = kenwood_get_id(rig, id); if (err != RIG_OK) { // TS450S is flaky on the 1st ID call so we'll try again hl_usleep(200 * 1000); err = kenwood_get_id(rig, id); } if (err == RIG_OK && priv->has_ps) // some rigs give ID while in standby { powerstat_t powerstat = 0; rig_debug(RIG_DEBUG_TRACE, "%s: got ID so try PS\n", __func__); err = rig_get_powerstat(rig, &powerstat); if (err == RIG_OK && powerstat == 0 && priv->poweron == 0 && STATE(rig)->auto_power_on) { priv->has_ps = 1; rig_debug(RIG_DEBUG_TRACE, "%s: got PS0 so powerup\n", __func__); rig_set_powerstat(rig, 1); } else if (err == -RIG_ETIMEOUT) // Some rigs like TS-450 don't have PS cmd { priv->has_ps = 0; } priv->poweron = 1; err = RIG_OK; // reset our err back to OK for later checks } if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response to get_id from rig...continuing anyway\n", __func__); } if (RIG_IS_TS2000 || RIG_IS_TS480 || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS890S || RIG_IS_TS990S) { // rig has Set 2 RIT/XIT function rig_debug(RIG_DEBUG_TRACE, "%s: rig has_rit2\n", __func__); priv->has_rit2 = 1; } if (RIG_IS_TS590S || RIG_IS_TS990S) { /* we need the firmware version for these rigs to deal with f/w defects */ static char fw_version[7]; err = kenwood_transaction(rig, "FV", fw_version, sizeof(fw_version)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version, defaulting to 1.0\n", __func__); RIGPORT(rig)->retry = retry_save; priv->fw_rev_uint = 100; } else { char *dot_pos; /* store the data after the "FV" which should be a f/w version string of the form n.n e.g. 1.07 */ priv->fw_rev = &fw_version[2]; dot_pos = strchr(fw_version, '.'); if (dot_pos) { priv->fw_rev_uint = atoi(&fw_version[2]) * 100 + atoi(dot_pos + 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(-RIG_EPROTO); } } rig_debug(RIG_DEBUG_TRACE, "%s: found f/w version %.2f\n", __func__, priv->fw_rev_uint / 100.0); } if (!RIG_IS_XG3 && -RIG_ETIMEOUT == err) { char buffer[KENWOOD_MAX_BUF_LEN]; /* Some Kenwood emulations have no ID command response :( * Try an FA command to see if anyone is listening */ err = kenwood_transaction(rig, "FA", buffer, sizeof(buffer)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response from rig\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } /* here we know there is something that responds to FA but not to ID so use FA as the command verification command */ priv->verify_cmd[0] = 'F'; priv->verify_cmd[1] = 'A'; priv->verify_cmd[2] = caps->cmdtrm; priv->verify_cmd[3] = '\0'; strcpy(id, "ID019"); /* fake a TS-2000 */ } else { if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } } /* id is something like 'IDXXX' or 'ID XXX' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unknown id type (%s)...continuing\n", __func__, id); // Malachite SDR gives no response to ID and is supposed to be TS480 compatible if (RIG_IS_MALACHITE) { strcpy(id, "ID020"); } } if (!strcmp("IDID900", id) /* DDUtil in TS-2000 mode */ || !strcmp("ID900", id) /* PowerSDR after ZZID; command */ || !strcmp("ID904", id) /* SmartSDR Flex-6700 */ || !strcmp("ID905", id) /* PowerSDR Flex-6500 */ || !strcmp("ID906", id) /* PowerSDR Flex-6700R */ || !strcmp("ID907", id) /* PowerSDR Flex-6300 */ || !strcmp("ID908", id) /* PowerSDR Flex-6400 */ || !strcmp("ID909", id) /* PowerSDR Flex-6600 */ ) { priv->is_emulation = 1; /* Emulations don't have SAT mode */ strcpy(id, "ID019"); /* fake it */ } /* check for a white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } /* compare id string */ for (i = 0; kenwood_id_string_list[i].model != RIG_MODEL_NONE; i++) { //rig_debug(RIG_DEBUG_ERR, "%s: comparing '%s'=='%s'\n", __func__, kenwood_id_string_list[i].id, idptr); if (strcmp(kenwood_id_string_list[i].id, idptr) != 0) { continue; } /* found matching id, verify driver */ rig_debug(RIG_DEBUG_TRACE, "%s: found match %s\n", __func__, kenwood_id_string_list[i].id); // current vfo is rx_vfo rig_get_vfo(rig, &STATE(rig)->rx_vfo); if (kenwood_id_string_list[i].model == rig->caps->rig_model) { vfo_t tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: found the right driver for %s(%u)\n", __func__, rig->caps->model_name, rig->caps->rig_model); /* get current AI state so it can be restored */ if (rig->caps->rig_model != RIG_MODEL_PT8000A) // doesn't know AI command { kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ } /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ if (priv->trn_state != RIG_TRN_OFF) { kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ } if (!RIG_IS_THD74 && !RIG_IS_THD7A && !RIG_IS_TMD700) { int retval; // call get_split to fill in current split and tx_vfo status split_t split; retval = kenwood_get_split_vfo_if(rig, RIG_VFO_A, &split, &tx_vfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); } priv->tx_vfo = tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); } RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } /* driver mismatch */ // SDRCONSOLE identifies as TS-2000 -- even though it's a sub/superset if (rig->caps->rig_model == RIG_MODEL_SDRCONSOLE && kenwood_id_string_list[i].model != 2014) { rig_debug(RIG_DEBUG_VERBOSE, "%s: not the right driver apparently (found %u, asked for %d, checked %s)\n", __func__, rig->caps->rig_model, kenwood_id_string_list[i].model, rig->caps->model_name); } // we continue to search for other matching IDs/models } rig_debug(RIG_DEBUG_VERBOSE, "%s: your rig (%s) did not match but we will continue anyways\n", __func__, id); // we're making this non fatal // mismatched IDs can still be tested RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } int kenwood_close(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (priv->poweron == 0) { RETURNFUNC(RIG_OK); } // nothing to do if (!no_restore_ai && priv->trn_state >= 0) { /* restore AI state */ kenwood_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } if (STATE(rig)->auto_power_off) { rig_debug(RIG_DEBUG_TRACE, "%s: got PS1 so powerdown\n", __func__); rig_set_powerstat(rig, 0); } RETURNFUNC(RIG_OK); } /* ID * Reads transceiver ID number * * caller must give a buffer of KENWOOD_MAX_BUF_LEN size * */ int kenwood_get_id(RIG *rig, char *buf) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_K4) { kenwood_transaction(rig, "K40", NULL, 0); } RETURNFUNC(kenwood_transaction(rig, "ID", buf, KENWOOD_MAX_BUF_LEN)); } /* IF * Retrieves the transceiver status * */ int kenwood_get_if(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); int retval; int post_write_delay_save = 0; ENTERFUNC; // Malachite has a 400ms delay but some get commands can work with no delay if (RIG_IS_MALACHITE) { post_write_delay_save = STATE(rig)->post_write_delay; STATE(rig)->post_write_delay = 0; } retval = kenwood_safe_transaction(rig, "IF", priv->info, KENWOOD_MAX_BUF_LEN, caps->if_len); if (RIG_IS_MALACHITE) { STATE(rig)->post_write_delay = post_write_delay_save; } RETURNFUNC(retval); } /* FN FR FT * Sets the RX/TX VFO or M.CH mode of the transceiver, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int kenwood_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[12]; int retval; char vfo_function; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, is_emulation=%d, curr_mode=%s\n", __func__, rig_strvfo(vfo), priv->is_emulation, rig_strrmode(priv->curr_mode)); /* Emulations do not need to set VFO since VFOB is a copy of VFOA * except for frequency. And we can change freq without changing VFOS * This prevents a 1.8 second delay in PowerSDR when switching VFOs * We'll do this once if curr_mode has not been set yet */ if (vfo == RIG_VFO_B && priv->is_emulation && priv->curr_mode > 0) { HAMLIB_TRACE; RETURNFUNC(RIG_OK); } #if 0 if (STATE(rig)->current_vfo == vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo already is %s...skipping\n", __func__, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } #endif switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_TX: vfo_function = STATE(rig)->tx_vfo == RIG_VFO_B ? '1' : '0'; break; #if 0 // VFO_RX really should NOT be VFO_CURR as VFO_CURR could be either VFO case RIG_VFO_RX: vfo_function = STATE(rig)->rx_vfo == RIG_VFO_B ? '1' : '0'; break; #endif case RIG_VFO_CURR: HAMLIB_TRACE; STATE(rig)->current_vfo = RIG_VFO_CURR; RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } //if rig=ts2000 then check Satellite mode status if (RIG_IS_TS2000 && !priv->is_emulation) { char retbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s: checking satellite mode status\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "SA"); retval = kenwood_transaction(rig, cmdbuf, retbuf, 18); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: satellite mode status %s\n", __func__, retbuf); //Satellite mode ON if (retbuf[2] == '1') { //SAT mode doesn't allow FR command (cannot select VFO) //selecting VFO is useless in SAT MODE RETURNFUNC(RIG_OK); } } HAMLIB_TRACE; SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); // as we change VFO we will change split to the other VFO // some rigs turn split off with FR command if (priv->split) { if (vfo_function == '0') { strcat(cmdbuf, ";FT1"); } else { strcat(cmdbuf, ";FT0"); } } if (RIG_IS_TS50 || RIG_IS_TS940) { cmdbuf[1] = 'N'; } /* set RX VFO */ retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } HAMLIB_TRACE; STATE(rig)->current_vfo = vfo; /* if FN command then there's no FT or FR */ /* If split mode on, the don't change TxVFO */ if ('N' == cmdbuf[1] || priv->split != RIG_SPLIT_OFF) { RETURNFUNC(RIG_OK); } HAMLIB_TRACE; // some rigs need split turned on after VFOA is set if (priv->split == RIG_SPLIT_ON) { // so let's figure out who the rx_vfo is based on the tx_vfo HAMLIB_TRACE; vfo_t rx_vfo = RIG_VFO_A; switch (priv->tx_vfo) { case RIG_VFO_A: rx_vfo = RIG_VFO_B; break; case RIG_VFO_MAIN: rx_vfo = RIG_VFO_SUB; break; case RIG_VFO_MAIN_A: rx_vfo = RIG_VFO_MAIN_B; break; case RIG_VFO_B: rx_vfo = RIG_VFO_A; break; case RIG_VFO_SUB: rx_vfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB_B: rx_vfo = RIG_VFO_MAIN_A; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unhandled VFO=%s, defaulting to VFOA\n", __func__, rig_strvfo(priv->tx_vfo)); } retval = rig_set_split_vfo(rig, rx_vfo, 1, priv->tx_vfo); } #if 0 /* set TX VFO */ cmdbuf[1] = 'T'; RETURNFUNC(kenwood_transaction(rig, cmdbuf, NULL, 0)); #else RETURNFUNC(retval); #endif } /* CB * Sets the operating VFO, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int kenwood_set_vfo_main_sub(RIG *rig, vfo_t vfo) { char cmdbuf[6]; char vfo_function; ENTERFUNC; switch (vfo) { case RIG_VFO_MAIN: vfo_function = '0'; break; case RIG_VFO_SUB: vfo_function = '1'; break; case RIG_VFO_CURR: RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "CB%c", vfo_function); RETURNFUNC(kenwood_transaction(rig, cmdbuf, NULL, 0)); } /* CB * Gets the operating VFO * */ int kenwood_get_vfo_main_sub(RIG *rig, vfo_t *vfo) { char buf[4]; int rc; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } if (RIG_OK == (rc = kenwood_safe_transaction(rig, "CB", buf, sizeof(buf), 3))) { *vfo = buf[2] == '1' ? RIG_VFO_SUB : RIG_VFO_MAIN; } RETURNFUNC(rc); } /* FR FT TB * Sets the split RX/TX VFO or M.CH mode of the transceiver. * */ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char cmdbuf[12]; int retval; unsigned char vfo_function; split_t tsplit = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s,%d,%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(txvfo)); if (RIG_IS_TS990S) { if (split) { // Rx MAIN/Tx SUB is the only split method retval = kenwood_set_vfo_main_sub(rig, RIG_VFO_MAIN); if (retval != RIG_OK) { RETURNFUNC2(retval); } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "TB%c", RIG_SPLIT_ON == split ? '1' : '0'); RETURNFUNC2(kenwood_transaction(rig, cmdbuf, NULL, 0)); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_TX || vfo == RIG_VFO_RX) { vfo = vfo_fixup(rig, vfo, split); } switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } vfo_t tx_vfo; rig_get_split_vfo(rig, vfo, &tsplit, &tx_vfo); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): tsplit=%d, split=%d\n", __func__, __LINE__, tsplit, split); if (tsplit == split) { rig_debug(RIG_DEBUG_TRACE, "%s: split already set\n", __func__); RETURNFUNC2(RIG_OK); } /* set RX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); // FR can turn off split on some Kenwood rigs // So we'll turn it back on just in case HAMLIB_TRACE; if (split) { if (vfo_function == '0') { HAMLIB_TRACE; strcat(cmdbuf, ";FT1"); } else { HAMLIB_TRACE; strcat(cmdbuf, ";FT0"); } } else { HAMLIB_TRACE; strcat(cmdbuf, ";FT0"); } retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC2(retval); } /* Split off means Rx and Tx are the same */ if (split == RIG_SPLIT_OFF) { txvfo = vfo; if (txvfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &txvfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } if (txvfo == RIG_VFO_CURR && vfo == RIG_VFO_A) { if (vfo == RIG_VFO_A) { txvfo = RIG_VFO_B; } else if (vfo == RIG_VFO_B) { txvfo = RIG_VFO_A; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported split VFO=%s\n", __func__, rig_strvfo(txvfo)); RETURNFUNC2(-RIG_EINVAL); } } txvfo = vfo_fixup(rig, txvfo, RIG_SPLIT_ON); priv->tx_vfo = txvfo; /* do not attempt redundant split change commands on Elecraft as they impact output power when transmitting and all other rigs don't need to set it if it's already set correctly */ tsplit = RIG_SPLIT_OFF; // default in case rig does not set split status retval = rig_get_split_vfo(rig, vfo, &tsplit, &tx_vfo); priv->split = CACHE(rig)->split = split; CACHE(rig)->split_vfo = txvfo; elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); // and it should be OK to do a SPLIT_OFF at any time so we won's skip that if (retval == RIG_OK && split == RIG_SPLIT_ON && tsplit == RIG_SPLIT_ON) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already set split=%d\n", __func__, tsplit); RETURNFUNC2(RIG_OK); } rig_debug(RIG_DEBUG_VERBOSE, "%s: split is=%d, split wants=%d\n", __func__, tsplit, split); /* set TX VFO */ // if turning on split need to do some VFOB setup on Elecraft rigs to avoid SPLIT N/A and ER59 messages if (rig->caps->rig_model == RIG_MODEL_K4 // Elecraft needs VFOB to be same band as VFOA || rig->caps->rig_model == RIG_MODEL_K3 || rig->caps->rig_model == RIG_MODEL_KX2 || rig->caps->rig_model == RIG_MODEL_KX3) { rig_set_freq(rig, RIG_VFO_B, CACHE(rig)->freqMainA); } if (retval != RIG_OK) { RETURNFUNC2(retval); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = CACHE(rig)->split = split; elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); RETURNFUNC2(RIG_OK); } /* SP * Sets the split mode of the transceivers that have the FN command. * */ int kenwood_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '1' : '0'); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = split; priv->tx_vfo = txvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); RETURNFUNC(RIG_OK); } /* IF * Gets split VFO status from kenwood_get_if() * */ int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { int transmitting; int retval; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; ENTERFUNC; if (!split || !txvfo) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (priv->info[32]) { case '0': *split = RIG_SPLIT_OFF; break; case '1': *split = RIG_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %c\n", __func__, priv->info[32]); RETURNFUNC(-RIG_EPROTO); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = *split; /* find where is the txvfo.. */ /* Elecraft info[30] does not track split VFO when transmitting */ transmitting = '1' == priv->info[28] && !RIG_IS_K2 && !RIG_IS_K3; switch (priv->info[30]) { case '0': rs->rx_vfo = STATE(rig)->current_vfo; if (rs->rx_vfo == RIG_VFO_A) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else if (rs->rx_vfo == RIG_VFO_B) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else if (rs->rx_vfo == RIG_VFO_CURR) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown rx_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->rx_vfo)); *txvfo = RIG_VFO_A; // pick a default rs->rx_vfo = priv->tx_vfo = RIG_VFO_A; } break; case '1': if (rs->rx_vfo == RIG_VFO_A) { HAMLIB_TRACE; *txvfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_A : RIG_VFO_B; } else if (rs->rx_vfo == RIG_VFO_B) { HAMLIB_TRACE; *txvfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown rx_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->rx_vfo)); *txvfo = RIG_VFO_A; // pick a default rs->rx_vfo = RIG_VFO_A; } break; case '2': *txvfo = priv->tx_vfo = RIG_VFO_MEM; /* SPLIT MEM operation doesn't involve VFO A or VFO B */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); RETURNFUNC(-RIG_EPROTO); } priv->tx_vfo = *txvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s, split=%d\n", __func__, rig_strvfo(priv->tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * kenwood_get_vfo_if using byte 31 of the IF information field * * Specifically this needs to return the RX VFO, the IF command tells * us the TX VFO in split TX mode when transmitting so we need to swap * results sometimes. */ int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo) { int retval; int split_and_transmitting; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Elecraft info[30] does not track split VFO when transmitting */ split_and_transmitting = '1' == priv->info[28] /* transmitting */ && '1' == priv->info[32] /* split */ && !RIG_IS_K2 && !RIG_IS_K3; switch (priv->info[30]) { case '0': *vfo = rs->rx_vfo = rs->tx_vfo = priv->tx_vfo = split_and_transmitting ? RIG_VFO_B : RIG_VFO_A; if (priv->info[32] == '1') { priv->tx_vfo = rs->tx_vfo = RIG_VFO_B; } break; case '1': *vfo = split_and_transmitting ? RIG_VFO_A : RIG_VFO_B; priv->tx_vfo = RIG_VFO_B; break; case '2': *vfo = priv->tx_vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); RETURNFUNC(RIG_OK); } /* * kenwood_set_freq */ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16]; unsigned char vfo_letter = '\0'; vfo_t tvfo; freq_t tfreq = 0; int err; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tvfo=%s\n", __func__, rig_strvfo(tvfo)); if (tvfo == RIG_VFO_CURR || tvfo == RIG_VFO_NONE) { /* fetch from rig */ err = rig_get_vfo(rig, &tvfo); if (RIG_OK != err) { RETURNFUNC2(err); } } // Malchite is so slow we don't do the get_freq // And when we have detected Doppler operations we just set the freq all the time // This should provide stable timing for set_ptt operation so relay delays are consistent if (!RIG_IS_MALACHITE && STATE(rig)->doppler == 0) { rig_get_freq(rig, tvfo, &tfreq); if (tfreq == freq) { rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__); RETURNFUNC2(RIG_OK); } } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; case RIG_VFO_TX: if (priv->tx_vfo == RIG_VFO_A) { vfo_letter = 'A'; } else if (priv->tx_vfo == RIG_VFO_B) { vfo_letter = 'B'; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx_vfo, tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll, vfo_letter, (int64_t)freq); // we need to modify priv->verify_cmd if ID is not being used // if FB command than we change to FB and back again to avoid VFO blinking if (priv->verify_cmd[1] == 'A' && vfo_letter == 'B') { priv->verify_cmd[1] = 'A'; } err = kenwood_transaction(rig, freqbuf, NULL, 0); hl_usleep(50 * 1000); // TS480 is slow to change freq so give it some time as well as others just in case if (priv->verify_cmd[1] == 'B' && vfo_letter == 'B') { priv->verify_cmd[1] = 'A'; } if (RIG_OK == err && RIG_IS_TS590S && priv->fw_rev_uint <= 107 && ('A' == vfo_letter || 'B' == vfo_letter)) { /* TS590s f/w rev 1.07 or earlier has a defect that means frequency set on TX VFO in split mode may not be set correctly. The symptom of the defect is either TX on the wrong frequency (i.e. TX on a frequency different from that showing on the TX VFO) or no output. We use an IF command to find out if we have just set the "back" VFO when the rig is in split mode. If we have; we then read the other VFO and set it to what we read - a null transaction that fixes the defect. */ err = kenwood_get_if(rig); if (RIG_OK != err) { RETURNFUNC2(err); } if ('1' == priv->info[32] && priv->info[30] != ('A' == vfo_letter ? '0' : '1')) { /* split mode and setting "back" VFO */ /* set other VFO to whatever it is at currently */ err = kenwood_safe_transaction(rig, 'A' == vfo_letter ? "FB" : "FA", freqbuf, 16, 13); if (RIG_OK != err) { RETURNFUNC2(err); } err = kenwood_transaction(rig, freqbuf, NULL, 0); } } RETURNFUNC2(err); } int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; char freqbuf[50]; int retval; ENTERFUNC; if (!freq) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(freqbuf, priv->info, 15); freqbuf[14] = '\0'; sscanf(freqbuf + 2, "%"SCNfreq, freq); RETURNFUNC(RIG_OK); } /* * kenwood_get_freq */ int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[50]; char cmdbuf[4]; int retval; unsigned char vfo_letter = '\0'; vfo_t tvfo; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!freq) { RETURNFUNC(-RIG_EINVAL); } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ retval = rig_get_vfo(rig, &tvfo); if (RIG_OK != retval) { RETURNFUNC(retval); } } /* memory frequency cannot be read with an Fx command, use IF */ if (tvfo == RIG_VFO_MEM) { RETURNFUNC(kenwood_get_freq_if(rig, vfo, freq)); } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; case RIG_VFO_TX: if (priv->split) { vfo_letter = 'B'; } // always assume B is the TX VFO else { vfo_letter = 'A'; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_MALACHITE && vfo == RIG_VFO_B) { // Malachite does not have VFOB so we'll just return VFOA *freq = 0; RETURNFUNC(RIG_OK); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "F%c", vfo_letter); retval = kenwood_safe_transaction(rig, cmdbuf, freqbuf, 50, 13); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(freqbuf + 2, "%"SCNfreq, freq); RETURNFUNC(RIG_OK); } int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } // TODO: Fix for different rigs memcpy(buf, &priv->info[17], 6); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } /* RF * kenwood_get_rit_new (also usable as kenwood_get_xit_new) * Gets the RIT or XIT value using dedicated command * and without using IF. */ int kenwood_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval, tempf; char rfbuf[10]; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, "RF", rfbuf, sizeof rfbuf, 7); if (retval != RIG_OK) {RETURNFUNC(retval); } tempf = atoi(rfbuf + 3); if (rfbuf[2] == '1') { tempf = -tempf; } *rit = tempf; RETURNFUNC(RIG_OK); } /* * rit can only move up/down by 10 Hz, so we use a loop... */ int kenwood_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[32]; int retval, i; int diff; int rit_enabled; int xit_enabled; shortfreq_t curr_rit; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: vfo=%s, rit=%ld\n", __func__, rig_strvfo(vfo), rit); // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC2(retval); } } // by getting current rit we can determine how to handle change // we just use curr_rit - rit to determine how far we need to move // No need to zero out rit retval = kenwood_get_rit(rig, RIG_VFO_CURR, &curr_rit); if (retval != RIG_OK) { RETURNFUNC2(retval); } #if 0 // no longer needed if diff can be done retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC2(retval); } #endif if (rit == 0 && curr_rit == 0) { RETURNFUNC2(RIG_OK); } if (priv->has_rit2) { diff = rit - curr_rit; rig_debug(RIG_DEBUG_TRACE, "%s: rit=%ld, curr_rit=%ld, diff=%d\n", __func__, rit, curr_rit, diff); SNPRINTF(buf, sizeof(buf), "R%c%05d", (diff > 0) ? 'U' : 'D', abs((int) diff)); retval = kenwood_transaction(rig, buf, NULL, 0); } else { SNPRINTF(buf, sizeof(buf), "R%c", (rit > 0) ? 'U' : 'D'); diff = labs(((curr_rit - rit) + (curr_rit - rit) >= 0 ? 5 : -5) / 10); // round to nearest 10Hz rig_debug(RIG_DEBUG_TRACE, "%s: rit=%ld, curr_rit=%ld, diff=%d\n", __func__, rit, curr_rit, diff); rig_debug(RIG_DEBUG_TRACE, "%s: rit change loop=%d\n", __func__, diff); for (i = 0; i < diff; i++) { retval = kenwood_transaction(rig, buf, NULL, 0); } } RETURNFUNC2(retval); } /* RU/RD * Set the RIT/XIT frequency offset * using dedicated commands (not IF) */ int kenwood_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t rit) { int retval, diff; shortfreq_t oldrit; char rdbuf[10]; ENTERFUNC; if (abs(rit) > 9999) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_rit_new(rig, vfo, &oldrit); if (retval != RIG_OK) { RETURNFUNC(retval); } if (rit == oldrit) // if the new value is the same { RETURNFUNC(RIG_OK); // Nothing to do } diff = rit - oldrit; SNPRINTF(rdbuf, sizeof rdbuf, "R%c%05d;", diff < 0 ? 'D' : 'U', abs(diff)); retval = kenwood_transaction(rig, rdbuf, NULL, 0); RETURNFUNC(retval); } /* * rit and xit are the same */ int kenwood_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { ENTERFUNC; RETURNFUNC(kenwood_get_rit(rig, vfo, rit)); } int kenwood_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; RETURNFUNC(kenwood_set_rit(rig, vfo, rit)); } int kenwood_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { ENTERFUNC; if (RIG_IS_TS990S) { RETURNFUNC(kenwood_transaction(rig, scan == RIG_SCAN_STOP ? "SC00" : "SC01", NULL, 0)); } else { RETURNFUNC(kenwood_transaction(rig, scan == RIG_SCAN_STOP ? "SC0" : "SC1", NULL, 0)); } } /* * 000 No select * 002 FM Wide * 003 FM Narrow * 005 AM * 007 SSB * 009 CW * 010 CW NARROW */ /* XXX revise */ static int kenwood_set_filter(RIG *rig, pbwidth_t width) { char *cmd; ENTERFUNC; if (width <= Hz(250)) { cmd = "FL010009"; } else if (width <= Hz(500)) { cmd = "FL009009"; } else if (width <= kHz(2.7)) { cmd = "FL007007"; } else if (width <= kHz(6)) { cmd = "FL005005"; } else { cmd = "FL002002"; } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } static int kenwood_set_filter_width(RIG *rig, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_filter_width *selected_filter_width = NULL; char cmd[20]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called, width=%ld\n", __func__, width); if (caps->filter_width == NULL) { RETURNFUNC2(-RIG_ENAVAIL); } for (i = 0; caps->filter_width[i].value >= 0; i++) { if (caps->filter_width[i].modes & mode) { selected_filter_width = &caps->filter_width[i]; if (caps->filter_width[i].width_hz >= width) { break; } } } if (selected_filter_width == NULL) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "FW%04d", selected_filter_width->value); RETURNFUNC2(kenwood_transaction(rig, cmd, NULL, 0)); } /* * kenwood_set_mode */ int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char c; char kmode; char buf[6]; char data_mode = '0'; char *data_cmd = "DA"; int err; int datamode = 0; int needdata; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s, mode=%s, width=%d, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width, rig_strvfo(STATE(rig)->current_vfo)); // we won't set opposite VFO if the mode is the same as requested // setting VFOB mode requires split modifications which cause VFO flashing // this should generally work unless the user changes mode on VFOB // in which case VFOB won't get mode changed until restart if (priv->split && (priv->tx_vfo & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_A))) { if (priv->modeB == mode) { rig_debug(RIG_DEBUG_TRACE, "%s: VFOB mode already %s so ignoring request\n", __func__, rig_strrmode(mode)); return (RIG_OK); } } if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX) { /* supports DATA sub modes */ switch (mode) { case RIG_MODE_PKTUSB: data_mode = '1'; mode = RIG_MODE_USB; break; case RIG_MODE_PKTLSB: data_mode = '1'; mode = RIG_MODE_LSB; break; case RIG_MODE_PKTFM: data_mode = '1'; mode = RIG_MODE_FM; break; default: break; } } if (priv->is_emulation || RIG_IS_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ rig_debug(RIG_DEBUG_VERBOSE, "%s: emulate=%d, HPSDR=%d, changing PKT mode to RTTY\n", __func__, priv->is_emulation, RIG_IS_HPSDR); if (RIG_MODE_PKTLSB == mode) { mode = RIG_MODE_RTTY; } if (RIG_MODE_PKTUSB == mode) { mode = RIG_MODE_RTTYR; } } if (RIG_IS_TS990S) { if (mode == RIG_MODE_PKTUSB) { mode = RIG_MODE_USBD1; } if (mode == RIG_MODE_PKTLSB) { mode = RIG_MODE_LSBD1; } } kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC2(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: kmode=%d, cmode=%c, datamode=%c\n", __func__, kmode, c, data_mode); if (RIG_IS_TS890S) { char sf[20]; char sfcmd[] = "SF0;"; // TS890 has SF command -- unique so far if (vfo != RIG_VFO_A) { sfcmd[2] = '1'; } err = kenwood_transaction(rig, sfcmd, sf, sizeof(sf)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, sfcmd, rigerror(err)); return err; } sf[14] = c; err = kenwood_transaction(rig, sf, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, sf, rigerror(err)); } return err; } else if (RIG_IS_TS990S) { /* The TS990s has targetable read mode but can only set the mode of the current VFO :( So we need to toggle the operating VFO to set the "back" VFO mode. This is done here rather than not setting caps.targetable_vfo to not include RIG_TARGETABLE_MODE since the toggle is not required for reading the mode. */ vfo_t curr_vfo; err = kenwood_get_vfo_main_sub(rig, &curr_vfo); if (err != RIG_OK) { RETURNFUNC2(err); } if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { err = kenwood_set_vfo_main_sub(rig, vfo); if (err != RIG_OK) { RETURNFUNC2(err); } } SNPRINTF(buf, sizeof(buf), "OM0%c", c); /* target vfo is ignored */ err = kenwood_transaction(rig, buf, NULL, 0); if (err == RIG_OK && vfo != RIG_VFO_CURR && vfo != curr_vfo) { int err2; err2 = kenwood_set_vfo_main_sub(rig, curr_vfo); if (err2 != RIG_OK) { RETURNFUNC2(err2); } } return RIG_OK; } else { pbwidth_t twidth; err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); } if (err != RIG_OK) { RETURNFUNC2(err); } if (data_mode == '1' && (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX)) { if (RIG_IS_TS950S || RIG_IS_TS950SDX) { data_cmd = "DT"; } datamode = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, curr_mode=%s, new_mode=%s, datamode=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(priv->curr_mode), rig_strrmode(mode), datamode); // only change mode if needed if (priv->curr_mode != mode) { SNPRINTF(buf, sizeof(buf), "MD%c", c); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: MD cmd failed: %s\n", __func__, rigerror(err)); RETURNFUNC2(err); } } // determine if we need to set datamode on A or B needdata = 0; if (vfo == RIG_VFO_CURR) { HAMLIB_TRACE; vfo = STATE(rig)->current_vfo; } if ((vfo & (RIG_VFO_A | RIG_VFO_MAIN)) && ((priv->datamodeA == 0 && datamode) || (priv->datamodeA == 1 && !datamode))) { needdata = 1; } if ((vfo & (RIG_VFO_B | RIG_VFO_SUB)) && ((priv->datamodeB == 0 && datamode) || (priv->datamodeB == 1 && !datamode))) { needdata = 1; } if (needdata) { /* supports DATA sub modes - see above */ SNPRINTF(buf, sizeof(buf), "%s%c", data_cmd, data_mode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC2(err); } } else if (datamode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): datamode set on %s not needed\n", __func__, __LINE__, rig_strvfo(vfo)); } if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC2(RIG_OK); } if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX) { if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } kenwood_set_filter(rig, width); /* non fatal */ } else if (RIG_IS_TS480) { err = kenwood_set_filter_width(rig, mode, width); if (err != RIG_OK) { // Ignore errors as non-fatal rig_debug(RIG_DEBUG_ERR, "%s: error setting filter width, error: %d\n", __func__, err); } } RETURNFUNC2(RIG_OK); } static int kenwood_get_filter(RIG *rig, pbwidth_t *width) { int err, f, f1, f2; char buf[10]; ENTERFUNC; if (!width) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_safe_transaction(rig, "FL", buf, sizeof(buf), 8); if (err != RIG_OK) { RETURNFUNC(err); } f2 = atoi(&buf[5]); buf[5] = '\0'; f1 = atoi(&buf[2]); if (f2 > f1) { f = f2; } else { f = f1; } switch (f) { case 2: *width = kHz(12); break; case 3: case 5: *width = kHz(6); break; case 7: *width = kHz(2.7); break; case 9: *width = Hz(500); break; case 10: *width = Hz(250); break; } RETURNFUNC(RIG_OK); } static int kenwood_get_filter_width(RIG *rig, rmode_t mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char ackbuf[20]; int i; int retval; int filter_value; ENTERFUNC; if (caps->filter_width == NULL) { RETURNFUNC(-RIG_ENAVAIL); } retval = kenwood_safe_transaction(rig, "FW", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "FW%d", &filter_value); for (i = 0; caps->filter_width[i].value >= 0; i++) { if (caps->filter_width[i].modes & mode) { if (caps->filter_width[i].value == filter_value) { *width = caps->filter_width[i].width_hz; RETURNFUNC(RIG_OK); } } } if (filter_value >= 50) // then it's probably a custom filter width { *width = filter_value; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_get_mode */ int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char cmd[5]; char modebuf[20]; int offs; int len = 6; int retval; int kmode; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, curr_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); if (!mode || !width) { RETURNFUNC2(-RIG_EINVAL); } /* for emulation do not read mode from VFOB as it is copy of VFOA */ /* we avoid the VFO swapping most of the time this way */ /* only need to get it if it has to be initialized */ if (priv->curr_mode > 0 && priv->is_emulation && vfo == RIG_VFO_B) { STATE(rig)->current_vfo = RIG_VFO_A; RETURNFUNC2(RIG_OK); } if (RIG_IS_TS890S) { len = 16; // TS890 has SF command -- unique so far if (vfo == RIG_VFO_A) { strcpy(cmd, "SF0;"); offs = 14; } else { strcpy(cmd, "SF1;"); offs = 14; } } else if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC2(retval); } } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "OM%c", c); offs = 3; } else { if ((priv->is_k3 || priv->is_k3s || priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { SNPRINTF(cmd, sizeof(cmd), "MD$"); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "MD"); offs = 2; } } retval = kenwood_safe_transaction(rig, cmd, modebuf, len, offs + 1); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (modebuf[offs] <= '9') { kmode = modebuf[offs] - '0'; } else { kmode = modebuf[offs] - 'A' + 10; } *mode = kenwood2rmode(kmode, caps->mode_table); if (priv->is_emulation || RIG_IS_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ rig_debug(RIG_DEBUG_VERBOSE, "%s: emulate=%d, HPSDR=%d, changing RTTY mode to PKT\n", __func__, priv->is_emulation, RIG_IS_HPSDR); if (RIG_MODE_RTTY == *mode) { *mode = RIG_MODE_PKTLSB; } if (RIG_MODE_RTTYR == *mode) { *mode = RIG_MODE_PKTUSB; } } if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX) { /* supports DATA sub-modes */ retval = kenwood_safe_transaction(rig, "DA", modebuf, 6, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ('1' == modebuf[2]) { if (vfo == RIG_VFO_A) { priv->datamodeA = 1; } else { priv->datamodeB = 1; } switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; case RIG_MODE_AM: *mode = RIG_MODE_PKTAM; break; default: break; } } else { if (vfo == RIG_VFO_A) { priv->datamodeA = 0; } else { priv->datamodeB = 0; } } } if (RIG_IS_TS480) { retval = kenwood_get_filter_width(rig, *mode, width); if (retval != RIG_OK) { // Ignore errors as non-fatal rig_debug(RIG_DEBUG_ERR, "%s: error getting filter width, error: %d\n", __func__, retval); *width = rig_passband_normal(rig, *mode); } } else { *width = rig_passband_normal(rig, *mode); } if (vfo == RIG_VFO_A) { priv->modeA = *mode; } else { priv->modeB = *mode; } RETURNFUNC2(RIG_OK); } /* This is used when the radio does not support MD; for mode reading */ int kenwood_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!mode || !width) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } *mode = kenwood2rmode(priv->info[29] - '0', caps->mode_table); *width = rig_passband_normal(rig, *mode); if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX) { kenwood_get_filter(rig, width); /* non fatal */ } RETURNFUNC(RIG_OK); } /* kenwood_get_micgain_minmax * Kenwood rigs have different micgain levels * This routine relies on the idea that setting the micgain * to 0 and 255 will result in the minimum and maximum values being set * If a rig doesn't behave this way then customize inside that rig's backend */ static int kenwood_get_micgain_minmax(RIG *rig, int *micgain_now, int *micgain_min, int *micgain_max, int restore) { int expected_length = 18; int retval; char levelbuf[expected_length + 1]; // read micgain_now, set 0, read micgain_min, set 255, read_micgain_max; set 0 // we set back to 0 for safety and if restore is true we restore micgain_min // otherwise we expect calling routine to be setting new micgain level // we batch these commands together for speed char *cmd = "MG;MG000;MG;MG255;MG;MG000;"; int n; struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } retval = read_string(rp, (unsigned char *) levelbuf, sizeof(levelbuf), NULL, 0, 1, 1); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); if (retval != 18) { rig_debug(RIG_DEBUG_ERR, "%s: expected 19, got %d in '%s'\n", __func__, retval, levelbuf); RETURNFUNC(-RIG_EPROTO); } n = sscanf(levelbuf, "MG%d;MG%d;MG%d", micgain_now, micgain_min, micgain_max); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 3 values from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (restore) { SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d;", *micgain_now); retval = kenwood_transaction(rig, levelbuf, NULL, 0); RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: returning now=%d, min=%d, max=%d\n", __func__, *micgain_now, *micgain_min, *micgain_max); RETURNFUNC(RIG_OK); } /* kenwood_get_power_minmax * Kenwood rigs have different power levels by mode and by rig * This routine relies on the idea that setting the power * to 0 and 255 will result in the minimum and maximum values being set * If a rig doesn't behave this way then customize inside that rig's backend */ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, int *power_max, int restore) { int max_length = 18; int expected_length; int retval; int simple_PC = 0; // flag to do just a simple PC command char levelbuf[max_length + 1]; // read power_now, set 0, read power_min, set 255, read_power_max; set 0 // we set back to 0 for safety and if restore is true we restore power_min // otherwise we expect calling routine to be setting new power level // we batch these commands together for speed char *cmd; int n; struct rig_state *rs = STATE(rig); struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; if (power_now == NULL || power_min == NULL) { simple_PC = 1; } switch (rig->caps->rig_model) { // TS480 can't handle the long command string // We can treat it like the TS890S case RIG_MODEL_TS480: // TS890S can't take power levels outside 5-100 and 5-25 // So all we'll do is read power_now case RIG_MODEL_TS890S: rs->power_min = 5; rs->power_max = 100; if (power_min) { *power_min = 5; } if (power_max) { *power_max = 100; } if (rs->current_mode == RIG_MODE_AM) { *power_max = 25; } if (rs->current_freq >= 70000000) { rs->power_max = 50; if (rs->current_mode == RIG_MODE_AM) { *power_max = 13; } } cmd = "PC;"; break; default: if (simple_PC) { cmd = "PC;"; } else { cmd = "PC;PC000;PC;PC255;PC;PC000;"; } } // Don't do this if PTT is on...don't want to max out power!! if (CACHE(rig)->ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_TRACE, "%s: ptt on so not checking min/max power levels\n", __func__); // return the last values we got *power_now = rs->power_now; if (power_min) { *power_min = rs->power_min; } if (power_max) { *power_max = rs->power_max; } RETURNFUNC(RIG_OK); } retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_IS_TS890S || RIG_IS_TS480 || simple_PC) { expected_length = 6; } else { expected_length = 18; } retval = read_string(rp, (unsigned char *) levelbuf, expected_length + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); if (retval != expected_length) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d, got %d in '%s'\n", __func__, expected_length, retval, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS890S || RIG_IS_TS480 || simple_PC) { n = sscanf(levelbuf, "PC%d;", power_now); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 1 value from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } } else { n = sscanf(levelbuf, "PC%d;PC%d;PC%d", power_now, power_min, power_max); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 3 values from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (restore) // only need to restore if 3-value cmd is done { SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d;", *power_now); retval = kenwood_transaction(rig, levelbuf, NULL, 0); RETURNFUNC(retval); } } rs->power_now = *power_now; if (!simple_PC) { rs->power_min = *power_min; rs->power_max = *power_max; } RETURNFUNC(RIG_OK); } static int kenwood_find_slope_filter_for_frequency(RIG *rig, vfo_t vfo, struct kenwood_slope_filter *filter, int frequency_hz, int *value) { int retval; int i; struct kenwood_slope_filter *last_filter = NULL; freq_t freq; int cache_ms_freq; rmode_t mode; int cache_ms_mode; pbwidth_t width; int cache_ms_width; int data_mode_filter_active; if (filter == NULL) { return -RIG_ENAVAIL; } retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { return -RIG_EINVAL; } retval = rig_get_ext_func(rig, vfo, TOK_FUNC_FILTER_WIDTH_DATA, &data_mode_filter_active); if (retval != RIG_OK) { // Ignore errors, e.g. if the command is not supported data_mode_filter_active = 0; } for (i = 0; filter[i].value >= 0; i++) { if (filter[i].modes & mode && filter[i].data_mode_filter == data_mode_filter_active) { if (filter[i].frequency_hz >= frequency_hz) { *value = filter[i].value; return RIG_OK; } last_filter = &filter[i]; } } if (last_filter != NULL) { *value = last_filter->value; return RIG_OK; } return -RIG_EINVAL; } static int kenwood_find_slope_filter_for_value(RIG *rig, vfo_t vfo, struct kenwood_slope_filter *filter, int value, int *frequency_hz) { int retval; int i; freq_t freq; int cache_ms_freq; rmode_t mode; int cache_ms_mode; pbwidth_t width; int cache_ms_width; int data_mode_filter_active; if (filter == NULL) { return -RIG_ENAVAIL; } retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { return -RIG_EINVAL; } retval = rig_get_ext_func(rig, vfo, TOK_FUNC_FILTER_WIDTH_DATA, &data_mode_filter_active); if (retval != RIG_OK) { // Ignore errors, e.g. if the command is not supported data_mode_filter_active = 0; } for (i = 0; filter[i].value >= 0; i++) { if (filter[i].modes & mode && filter[i].data_mode_filter == data_mode_filter_active) { if (filter[i].value == value) { *frequency_hz = filter[i].frequency_hz; return RIG_OK; } } } return -RIG_EINVAL; } int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, kenwood_val, len, result; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); gran_t *level_info; ENTERFUNC; /* Check input parameter against level_gran limits */ result = check_level_param(rig, level, val, &level_info); if (result != RIG_OK) { RETURNFUNC(result); } if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { int retval; case RIG_LEVEL_RFPOWER: { retval = RIG_OK; pbwidth_t twidth; int err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); // https://github.com/Hamlib/Hamlib/issues/1595 if (!err && priv->last_mode_pc != priv->curr_mode) // only need to check when mode changes { priv->last_mode_pc = priv->curr_mode; // Power min/max can vary so we query to find them out every time retval = kenwood_get_power_minmax(rig, &priv->power_now, &priv->power_min, &priv->power_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } // https://github.com/Hamlib/Hamlib/issues/465 kenwood_val = val.f * priv->power_max; if (kenwood_val < priv->power_min) { kenwood_val = priv->power_min; } if (kenwood_val > priv->power_max) { kenwood_val = priv->power_max; } SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); break; } case RIG_LEVEL_AF: { int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B) ? 1 : 0; } else { vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; } // some rigs only recognize 0 for vfo_set // https://github.com/Hamlib/Hamlib/issues/304 // This is now fixed for all rigs // https://github.com/Hamlib/Hamlib/issues/380 // ag_format is determined in kenwood_get_level switch (priv->ag_format) { case 1: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", kenwood_val); break; case 2: SNPRINTF(levelbuf, sizeof(levelbuf), "AG0%03d", kenwood_val); break; case 3: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%d%03d", vfo_num, kenwood_val); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown ag_format=%d\n", __func__, priv->ag_format); } } break; case RIG_LEVEL_MICGAIN: { int micgain_now; if (priv->micgain_min == -1) // then we need to know our min/max { retval = kenwood_get_micgain_minmax(rig, &micgain_now, &priv->micgain_min, &priv->micgain_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } // is micgain_min ever > 0 ?? kenwood_val = val.f * (priv->micgain_max - priv->micgain_min) + priv->micgain_min; SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", kenwood_val); break; } case RIG_LEVEL_RF: /* XXX check level range */ // KX2 and KX3 have range -190 to 250 if (val.f > 1.0 || val.f < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.f * 255.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_SQL: { int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { /* Default to RX#0 */ vfo_num = 0; } SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%d%03d", vfo_num, kenwood_val); break; } case RIG_LEVEL_AGC: SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", 84 * kenwood_val); break; case RIG_LEVEL_ATT: len = RIG_IS_TS890S ? 1 : 2; /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%0*d", len, 0); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i]; i++) { if (val.i == rs->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%0*d", len, i + 1); foundit = 1; break; } } if (!foundit) { RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i]; i++) { if (val.i == rs->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_SLOPE_HIGH: retval = kenwood_find_slope_filter_for_frequency(rig, vfo, caps->slope_filter_high, val.i, &kenwood_val); if (retval != RIG_OK) { // Fall back to using raw values if (val.i > 20 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.i; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", kenwood_val); priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_SLOPE_LOW: retval = kenwood_find_slope_filter_for_frequency(rig, vfo, caps->slope_filter_low, val.i, &kenwood_val); if (retval != RIG_OK) { // Fall back to using raw values if (val.i > 20 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.i; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", kenwood_val); priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_CWPITCH: { /* Newer rigs have an extra digit of pitch factor */ len = (RIG_IS_TS890S || RIG_IS_TS990S) ? 3 : 2; /* Round input freq to nearest multiple of step */ kenwood_val = (val.i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i; SNPRINTF(levelbuf, sizeof(levelbuf), "PT%0*d", len, kenwood_val); break; } case RIG_LEVEL_KEYSPD: SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; case RIG_LEVEL_COMP: kenwood_val = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(levelbuf, sizeof(levelbuf), "PL%03d%03d", kenwood_val, kenwood_val); break; case RIG_LEVEL_VOXDELAY: if (val.i > 30 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } // Raw value is in milliseconds SNPRINTF(levelbuf, sizeof(levelbuf), "VD%04d", val.i * 100); break; case RIG_LEVEL_VOXGAIN: kenwood_val = val.f * 9.0f; SNPRINTF(levelbuf, sizeof(levelbuf), "VG%03d", kenwood_val); break; case RIG_LEVEL_BKIN_DLYMS: if (val.i > 1000 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "SD%04d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level (0x%08llx) %s", __func__, (unsigned long long)level, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } result = kenwood_transaction(rig, levelbuf, NULL, 0); priv->question_mark_response_means_rejected = 0; RETURNFUNC(result); } int get_kenwood_level(RIG *rig, const char *cmd, float *fval, int *ival) { char lvlbuf[10]; int retval; int lvl; int len = strlen(cmd); ENTERFUNC; if (!fval && !ival) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 3); if (retval != RIG_OK) { RETURNFUNC(retval); } /* 000..255 */ sscanf(lvlbuf + len, "%d", &lvl); if (ival) { *ival = lvl; } // raw value if (fval) { *fval = lvl / 255.0; } // our default scaling of 0-255 RETURNFUNC(RIG_OK); } /* Helper to get and parse meter values using RM * Note that we turn readings on, but nothing off. * 'pips' is the number of LED bars lit in the digital meter, max=70 */ int get_kenwood_meter_reading(RIG *rig, char meter, int *pips) { char reading[9]; /* 8 char + '\0' */ int retval; char target[] = "RMx1"; /* Turn on reading this meter */ target[2] = meter; retval = kenwood_transaction(rig, target, NULL, 0); if (retval != RIG_OK) { return retval; } /* Read the first value */ retval = kenwood_transaction(rig, "RM", reading, sizeof(reading)); if (retval != RIG_OK) { return retval; } /* Find the one we want */ while (strncmp(reading, target, 3) != 0) { /* That wasn't it, get the next one */ retval = kenwood_transaction(rig, NULL, reading, sizeof(reading)); if (retval != RIG_OK) { return retval; } if (reading[0] != target[0] || reading[1] != target[1]) { /* Somebody else's data, bail */ return -RIG_EPROTO; } } sscanf(reading + 3, "%4d", pips); return RIG_OK; } /* * kenwood_get_level */ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[8]; char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int lvl; int i, ret, agclevel, len, value; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); gran_t *level_info; ENTERFUNC; if (!val) { RETURNFUNC(-RIG_EINVAL); } level_info = &rig->caps->level_gran[rig_setting2idx(level)]; switch (level) { case RIG_LEVEL_RAWSTR: if (RIG_IS_TS590S || RIG_IS_TS590SG) { cmd = "SM0"; len = 3; } else if (RIG_IS_TS2000) { len = 3; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; } else { cmd = "SM0"; } } else { cmd = "SM"; len = 2; } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + len, "%d", &val->i); break; case RIG_LEVEL_STRENGTH: { int multiplier = 1; if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS480) { cmd = "SM0"; len = 3; } else if (RIG_IS_TS2000) { len = 3; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; // TS-2000 sub-transceiver S-meter range is half of the main one multiplier = 2; } else { cmd = "SM0"; } } else { cmd = "SM"; len = 2; } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + len, "%d", &val->i); val->i *= multiplier; if (rig->caps->str_cal.size) { val->i = (int) rig_raw2val(val->i, &rig->caps->str_cal); } else { val->i = (val->i * 4) - 54; } break; } case RIG_LEVEL_SQL: { int ack_len; int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { /* Default to RX#0 */ vfo_num = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SQ%c", vfo_num); retval = kenwood_transaction(rig, cmdbuf, lvlbuf, sizeof(lvlbuf)); len = 6; if (retval != RIG_OK) { RETURNFUNC(retval); } ack_len = strlen(lvlbuf); if (ack_len != len) { RETURNFUNC(-RIG_EPROTO); } if (sscanf(&lvlbuf[len - 3], "%d", &lvl) != 1) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) lvl / 255.f; RETURNFUNC(RIG_OK); } case RIG_LEVEL_ATT: len = RIG_IS_TS890S ? 3 : 6; retval = kenwood_safe_transaction(rig, "RA", lvlbuf, 50, len); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected att level %d\n", __func__, lvl); RETURNFUNC(-RIG_EPROTO); } } if (i != lvl) { RETURNFUNC(-RIG_EINTERNAL); } val->i = rs->attenuator[i - 1]; } break; case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", lvlbuf, 50, 3); if (retval != RIG_OK) { RETURNFUNC(retval); } if (lvlbuf[2] == '0') { val->i = 0; } else if (isdigit((int)lvlbuf[2])) { lvl = lvlbuf[2] - '0'; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp level %d\n", __func__, lvl); RETURNFUNC(-RIG_EPROTO); } } if (i != lvl) { RETURNFUNC(-RIG_EINTERNAL); } val->i = rs->preamp[i - 1]; } else { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp char '%c'\n", __func__, lvlbuf[2]); RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_RFPOWER: { pbwidth_t twidth; int err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); // https://github.com/Hamlib/Hamlib/issues/1595 if (!err && priv->last_mode_pc != priv->curr_mode) // only need to check when mode changes { priv->last_mode_pc = priv->curr_mode; // Power min/max can vary so we query to find them out every time retval = kenwood_get_power_minmax(rig, &priv->power_now, &priv->power_min, &priv->power_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } else { retval = kenwood_get_power_minmax(rig, &priv->power_now, NULL, NULL, 0); } priv->power_min = 0; // our return scale is 0-max to match the input scale val->f = (priv->power_now - priv->power_min) / (float)(priv->power_max - priv->power_min); RETURNFUNC(RIG_OK); } case RIG_LEVEL_AF: { int vfo_num; // first time through we'll determine the AG format // Can be "AG" "AG0" or "AG0/1" // This could be done by rig but easy enough to make it automagic if (priv->ag_format < 0) { int retry_save = RIGPORT(rig)->retry; RIGPORT(rig)->retry = 0; // speed up this check so no retries rig_debug(RIG_DEBUG_TRACE, "%s: AF format check determination...\n", __func__); // Determine AG format // =-1 == Undetermine // 0 == Unknown // 1 == AG // 2 == AG0 (fixed VFO) // 3 == AG0/1 (with VFO arg) char buffer[KENWOOD_MAX_BUF_LEN]; ret = kenwood_transaction(rig, "AG", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 1; } else { ret = kenwood_transaction(rig, "AG1", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 3; } else { ret = kenwood_transaction(rig, "AG0", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 2; } else { priv->ag_format = 0; // rats....can't figure it out } } } RIGPORT(rig)->retry = retry_save; } rig_debug(RIG_DEBUG_TRACE, "%s: ag_format=%d\n", __func__, priv->ag_format); if (priv->ag_format == 0) { priv->ag_format = -1; // we'll keep trying next time rig_debug(RIG_DEBUG_WARN, "%s: Unable to set AG format?\n", __func__); RETURNFUNC(RIG_OK); // this is non-fatal for no))w } if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; } switch (priv->ag_format) { case 0: priv->ag_format = -1; // reset to try again RETURNFUNC(RIG_OK); break; case 1: retval = get_kenwood_level(rig, "AG", &val->f, NULL); break; case 2: retval = get_kenwood_level(rig, "AG0", &val->f, NULL); break; case 3: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AG%d", vfo_num); retval = get_kenwood_level(rig, cmdbuf, &val->f, NULL); break; default: rig_debug(RIG_DEBUG_WARN, "%s: Invalid ag_format=%d?\n", __func__, priv->ag_format); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(retval); } case RIG_LEVEL_RF: RETURNFUNC(get_kenwood_level(rig, "RG", &val->f, NULL)); case RIG_LEVEL_MICGAIN: { int micgain_now; float vali = 0; if (priv->micgain_min == -1) // then we need to know our min/max { retval = kenwood_get_micgain_minmax(rig, &micgain_now, &priv->micgain_min, &priv->micgain_max, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } rig_debug(RIG_DEBUG_TRACE, "%s: micgain_min=%d, micgain_max=%d\n", __func__, priv->micgain_min, priv->micgain_max); ret = get_kenwood_level(rig, "MG", NULL, &val->i); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Error getting MICGAIN\n", __func__); RETURNFUNC(ret); } vali = val->i; val->f = (vali - priv->micgain_min) / (float)(priv->micgain_max - priv->micgain_min); RETURNFUNC(RIG_OK); } case RIG_LEVEL_AGC: ret = get_kenwood_level(rig, "GT", NULL, &val->i); agclevel = val->i; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } RETURNFUNC(ret); case RIG_LEVEL_SLOPE_LOW: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "SL", lvlbuf, sizeof(lvlbuf)); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } value = atoi(&lvlbuf[2]); retval = kenwood_find_slope_filter_for_value(rig, vfo, caps->slope_filter_low, value, &val->i); if (retval != RIG_OK) { if (retval == -RIG_ENAVAIL) { // Fall back to using raw values val->i = value; } else { RETURNFUNC(retval); } } break; case RIG_LEVEL_SLOPE_HIGH: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "SH", lvlbuf, sizeof(lvlbuf)); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } value = atoi(&lvlbuf[2]); retval = kenwood_find_slope_filter_for_value(rig, vfo, caps->slope_filter_high, value, &val->i); if (retval != RIG_OK) { if (retval == -RIG_ENAVAIL) { // Fall back to using raw values val->i = value; } else { RETURNFUNC(retval); } } break; case RIG_LEVEL_CWPITCH: /* Newer rigs have an extra digit of pitch factor */ len = (RIG_IS_TS890S || RIG_IS_TS990S) ? 3 : 2; retval = kenwood_safe_transaction(rig, "PT", lvlbuf, 50, len + 2); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * level_info->step.i) + level_info->min.i; break; case RIG_LEVEL_KEYSPD: retval = kenwood_safe_transaction(rig, "KS", lvlbuf, 50, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &val->i); break; case RIG_LEVEL_COMP: { int raw_value; retval = kenwood_safe_transaction(rig, "PL", lvlbuf, 50, 8); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%3d", &raw_value); val->f = (float) raw_value * level_info->step.f; break; } case RIG_LEVEL_VOXDELAY: { int raw_value; retval = kenwood_safe_transaction(rig, "VD", lvlbuf, 50, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); // Value is in milliseconds val->i = raw_value / 100; break; } case RIG_LEVEL_VOXGAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "VG", lvlbuf, 50, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_BKIN_DLYMS: { int raw_value; retval = kenwood_safe_transaction(rig, "SD", lvlbuf, 50, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); val->i = raw_value; break; } case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: RETURNFUNC(-RIG_ENIMPL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[10]; /* longest cmd is GTxxx */ ENTERFUNC; switch (func) { case RIG_FUNC_NB: case RIG_FUNC_NB2: /* newer Kenwoods have a second noise blanker */ if (RIG_IS_TS890S) { switch (func) { case RIG_FUNC_NB: SNPRINTF(buf, sizeof(buf), "NB1%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_NB2: SNPRINTF(buf, sizeof(buf), "NB2%c", (status == 0) ? '0' : '1'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: expected 0,1, or 2 and got %d\n", __func__, status); RETURNFUNC(-RIG_EINVAL); } } else { SNPRINTF(buf, sizeof(buf), "NB%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_ABM: SNPRINTF(buf, sizeof(buf), "AM%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_COMP: if (RIG_IS_TS890S) { SNPRINTF(buf, sizeof(buf), "PR0%c", (status == 0) ? '0' : '1'); } else { SNPRINTF(buf, sizeof(buf), "PR%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TONE: SNPRINTF(buf, sizeof(buf), "TO%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TSQL: SNPRINTF(buf, sizeof(buf), "CT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_VOX: SNPRINTF(buf, sizeof(buf), "VX%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_FAGC: SNPRINTF(buf, sizeof(buf), "GT00%c", (status == 0) ? '4' : '2'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_NR: if (RIG_IS_TS890S || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS480 || RIG_IS_TS2000 || RIG_IS_QRPLABS) { char c = '1'; if (status == 2) { c = '2'; } SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : c); } else { SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_BC: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_BC2: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '2'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_ANF: SNPRINTF(buf, sizeof(buf), "NT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_AIP: SNPRINTF(buf, sizeof(buf), "MX%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TUNER: SNPRINTF(buf, sizeof(buf), "AC1%c0", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_FBKIN: SNPRINTF(buf, sizeof(buf), "SD%04d", (status == 1) ? 0 : 50); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s", rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * works for any 'format 1' command or newer command like the TS890 has * as long as the return is a number 0-9 * answer is always 4 bytes or 5 bytes: two or three byte command id, status and terminator */ int get_kenwood_func(RIG *rig, const char *cmd, int *status) { int retval; char buf[10]; int offset = 2; ENTERFUNC; if (!cmd || !status) { RETURNFUNC(-RIG_EINVAL); } if (strlen(cmd) == 3) { offset = 3; } // some commands are 3 letters retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), offset + 1); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[offset] - '0'; // just return whatever the rig returns RETURNFUNC(RIG_OK); } /* * kenwood_get_func */ int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char *cmd; char respbuf[20]; int retval; int raw_value; ENTERFUNC; if (!status) { RETURNFUNC(-RIG_EINVAL); } switch (func) { case RIG_FUNC_FAGC: retval = kenwood_safe_transaction(rig, "GT", respbuf, 20, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = respbuf[4] != '4' ? 1 : 0; RETURNFUNC(RIG_OK); case RIG_FUNC_NB: cmd = "NB"; if (RIG_IS_TS890S) { cmd = "NB1"; } RETURNFUNC(get_kenwood_func(rig, cmd, status)); case RIG_FUNC_NB2: RETURNFUNC(get_kenwood_func(rig, "NB2", status)); case RIG_FUNC_ABM: RETURNFUNC(get_kenwood_func(rig, "AM", status)); case RIG_FUNC_COMP: RETURNFUNC(get_kenwood_func(rig, "PR", status)); case RIG_FUNC_TONE: RETURNFUNC(get_kenwood_func(rig, "TO", status)); case RIG_FUNC_TSQL: RETURNFUNC(get_kenwood_func(rig, "CT", status)); case RIG_FUNC_VOX: RETURNFUNC(get_kenwood_func(rig, "VX", status)); case RIG_FUNC_NR: RETURNFUNC(get_kenwood_func(rig, "NR", status)); /* FIXME on TS2000 */ // Check for BC #1 case RIG_FUNC_BC: // Most will return BC1 or BC0, if BC2 then BC1 is off retval = get_kenwood_func(rig, "BC", &raw_value); if (retval == RIG_OK) { *status = raw_value == 1 ? 1 : 0; } RETURNFUNC(retval); case RIG_FUNC_BC2: // TS-890 check Beat Cancel 2 we return boolean true/false retval = get_kenwood_func(rig, "BC", &raw_value); if (retval == RIG_OK) { *status = raw_value == 2 ? 1 : 0; } RETURNFUNC(retval); case RIG_FUNC_ANF: RETURNFUNC(get_kenwood_func(rig, "NT", status)); case RIG_FUNC_LOCK: RETURNFUNC(get_kenwood_func(rig, "LK", status)); case RIG_FUNC_AIP: RETURNFUNC(get_kenwood_func(rig, "MX", status)); case RIG_FUNC_RIT: RETURNFUNC(get_kenwood_func(rig, "RT", status)); case RIG_FUNC_XIT: RETURNFUNC(get_kenwood_func(rig, "XT", status)); case RIG_FUNC_TUNER: retval = kenwood_safe_transaction(rig, "AC", respbuf, 20, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = respbuf[3] != '0' ? 1 : 0; RETURNFUNC(RIG_OK); case RIG_FUNC_FBKIN: { retval = kenwood_safe_transaction(rig, "SD", respbuf, 20, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(respbuf + 2, "%d", &raw_value); *status = (raw_value == 0) ? 1 : 0; RETURNFUNC(RIG_OK); } default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %s", rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_set_ctcss_tone * Assumes rig->caps->ctcss_list != NULL * * Warning! This is untested stuff! May work at least on TS-870S * Please owners report to me , thanks. --SF */ int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } /* TODO: replace menu no 57 by a define */ SNPRINTF(tonebuf, sizeof(tonebuf), "EX%03d%04d", 57, i + kenwood_caps(rig)->tone_table_base); RETURNFUNC(kenwood_transaction(rig, tonebuf, NULL, 0)); } int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; ENTERFUNC; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "TN%c%02d", c, i + kenwood_caps(rig)->tone_table_base); } else { SNPRINTF(buf, sizeof(buf), "TN%02d", i + kenwood_caps(rig)->tone_table_base); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * kenwood_get_ctcss_tone * Assumes STATE(rig)->priv != NULL */ int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct rig_caps *caps; char tonebuf[3]; int i, retval; unsigned int tone_idx; ENTERFUNC; if (!tone) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (RIG_IS_TS890S) { char buf[5]; retval = kenwood_safe_transaction(rig, "TN", buf, sizeof(buf), 4); memcpy(tonebuf, buf + 2, 2); } else if (RIG_IS_TS990S) { char cmd[4]; char buf[6]; char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "TN%c", c); retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 5); memcpy(tonebuf, &buf[3], 2); } else { retval = kenwood_get_if(rig); memcpy(tonebuf, &priv->info[34], 2); } if (retval != RIG_OK) { RETURNFUNC(retval); } tonebuf[2] = '\0'; tone_idx = atoi(tonebuf); if (tone_idx < kenwood_caps(rig)->tone_table_base) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS tone is zero (%s)\n", __func__, tonebuf); RETURNFUNC(-RIG_EPROTO); } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); RETURNFUNC(-RIG_EPROTO); } } *tone = caps->ctcss_list[tone_idx - kenwood_caps(rig)->tone_table_base]; RETURNFUNC(RIG_OK); } int kenwood_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; ENTERFUNC; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "CN%c%02d", c, i + kenwood_caps(rig)->tone_table_base); } else { SNPRINTF(buf, sizeof(buf), "CN%02d", i + kenwood_caps(rig)->tone_table_base); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } int kenwood_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char cmd[4]; char tonebuf[6]; int offs; int i, retval; unsigned int tone_idx; ENTERFUNC; if (!tone) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "CN%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "CN"); offs = 2; } retval = kenwood_safe_transaction(rig, cmd, tonebuf, 6, offs + 2); if (retval != RIG_OK) { RETURNFUNC(retval); } tone_idx = atoi(tonebuf + offs); if (tone_idx < kenwood_caps(rig)->tone_table_base) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS is zero (%s)\n", __func__, tonebuf); RETURNFUNC(-RIG_EPROTO); } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); RETURNFUNC(-RIG_EPROTO); } } *tone = caps->ctcss_list[tone_idx - kenwood_caps(rig)->tone_table_base]; RETURNFUNC(RIG_OK); } /* * set the aerial/antenna to use */ int kenwood_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[8]; char a; ENTERFUNC; switch (ant) { case RIG_ANT_1: a = '1'; break; case RIG_ANT_2: a = '2'; break; case RIG_ANT_3: a = '3'; break; case RIG_ANT_4: a = '4'; break; default: RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "AN0%c%c99", c, a); } else if (RIG_IS_TS890S) { SNPRINTF(cmd, sizeof(cmd), "AN%c999", a); } else if (RIG_IS_TS590S || RIG_IS_TS590SG) { SNPRINTF(cmd, sizeof(cmd), "AN%c99", a); } else { SNPRINTF(cmd, sizeof(cmd), "AN%c", a); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } int kenwood_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { const char *cmd; ENTERFUNC; switch (ant) { case RIG_ANT_1: cmd = "AN1"; break; case RIG_ANT_2: cmd = "AN2"; break; case RIG_ANT_3: cmd = "AN3"; break; case RIG_ANT_4: cmd = "AN4"; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } /* * get the aerial/antenna in use */ int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char ackbuf[8]; int offs; int retval; char antenna; ENTERFUNC; if (!ant_curr) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { retval = kenwood_safe_transaction(rig, "AN0", ackbuf, sizeof(ackbuf), 7); offs = 4; } else if (RIG_IS_TS890S) { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 6); offs = 2; } else if (RIG_IS_TS590S || RIG_IS_TS590SG) { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 5); offs = 2; } else { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 3); offs = 2; } if (retval != RIG_OK) { RETURNFUNC(retval); } antenna = ackbuf[offs]; if (antenna < '0' || antenna > '9') { RETURNFUNC(-RIG_EPROTO); } if (antenna == '0') { // At least TS-2000 return AN0 on VHF/UHF bands *ant_curr = RIG_ANT_1; } else { *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); } /* XXX check that the returned antenna is valid for the current rig */ RETURNFUNC(RIG_OK); } /* * kenwood_get_ptt */ int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; ENTERFUNC; if (!ptt) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } *ptt = priv->info[28] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; RETURNFUNC(RIG_OK); } int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); if (RIG_IS_TS2000) { switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: case RIG_PTT_ON_DATA: ptt_cmd = "VX0;TX"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: RETURNFUNC(-RIG_EINVAL); } } else { switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; break; case RIG_PTT_ON_MIC: ptt_cmd = "TX0"; break; case RIG_PTT_ON_DATA: ptt_cmd = "TX1"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: RETURNFUNC(-RIG_EINVAL); } } int retval = kenwood_transaction(rig, ptt_cmd, NULL, 0); if (ptt == RIG_PTT_OFF) { hl_usleep(100 * 1000); } // a little time for PTT to turn off RETURNFUNC(retval); } int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) { int err; ptt_t current_ptt; ENTERFUNC; err = kenwood_get_ptt(rig, vfo, ¤t_ptt); if (err != RIG_OK) { RETURNFUNC(err); } if (current_ptt == ptt) { RETURNFUNC(RIG_OK); } RETURNFUNC(kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", NULL, 0)); } /* * kenwood_get_dcd */ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char busybuf[10]; int retval; int expected; int offs; ENTERFUNC; if (!dcd) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS480 || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS990S || RIG_IS_TS2000) { expected = 4; } else { expected = 3; } retval = kenwood_safe_transaction(rig, "BY", busybuf, 10, expected); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((RIG_IS_TS990S && RIG_VFO_SUB == vfo) || (RIG_IS_TS2000 && (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo))) { offs = 3; } else { offs = 2; } *dcd = (busybuf[offs] == '1') ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } /* * kenwood_set_trn */ int kenwood_set_trn(RIG *rig, int trn) { ENTERFUNC; switch (rig->caps->rig_model) { char buf[5]; case RIG_MODEL_POWERSDR: // powersdr doesn't have AI command case RIG_MODEL_THETIS: // powersdr doesn't have AI command case RIG_MODEL_PT8000A: // powersdr doesn't have AI command RETURNFUNC(-RIG_ENAVAIL); case RIG_MODEL_TS990S: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI2" : "AI0", NULL, 0)); case RIG_MODEL_THD7A: case RIG_MODEL_THD74: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI 1" : "AI 0", buf, sizeof buf)); default: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI1" : "AI0", NULL, 0)); } } /* * kenwood_get_trn */ int kenwood_get_trn(RIG *rig, int *trn) { char trnbuf[6]; int retval; ENTERFUNC; if (!trn) { RETURNFUNC(-RIG_EINVAL); } /* these rigs only have AI[0|1] set commands and no AI query */ if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS790 || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX || RIG_IS_POWERSDR || RIG_IS_THETIS) { RETURNFUNC(-RIG_ENAVAIL); } if (RIG_IS_THD74 || RIG_IS_THD7A || RIG_IS_TMD700) { retval = kenwood_safe_transaction(rig, "AI", trnbuf, 6, 4); } else { retval = kenwood_safe_transaction(rig, "AI", trnbuf, 6, 3); } if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_IS_THD74 || RIG_IS_THD7A || RIG_IS_TMD700) { *trn = trnbuf[3] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; } else { *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; } RETURNFUNC(RIG_OK); } /* * kenwood_set_powerstat */ int kenwood_set_powerstat(RIG *rig, powerstat_t status) { int retval; struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; if ((priv->is_k3 || priv->is_k3s) && status == RIG_POWER_ON) { rig_debug(RIG_DEBUG_ERR, "%s: K3/K3S must use aux I/O jack pulled low to power on\n", __func__); return -RIG_EPOWER; } int i = 0; int retry_save = rp->retry; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, status); if (status == RIG_POWER_ON) { // When powering on a Kenwood rig needs dummy bytes to wake it up, // then wait at least 200ms and within 2 seconds issue the power-on command again write_block(rp, (unsigned char *) "PS1;", 4); hl_usleep(500000); } rp->retry = 0; retval = kenwood_transaction(rig, (status == RIG_POWER_ON) ? "PS1;" : "PS0;", NULL, 0); if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < 8; ++i) // up to ~10 seconds including the timeouts { freq_t freq; sleep(1); retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval == RIG_OK) { rp->retry = retry_save; RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait #%d for power up\n", __func__, i + 1); } } rp->retry = retry_save; if (i == 9) { rig_debug(RIG_DEBUG_TRACE, "%s: timeout waiting for powerup, try %d\n", __func__, i + 1); retval = -RIG_ETIMEOUT; } RETURNFUNC2(retval); } /* * kenwood_get_powerstat */ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[6]; int result; struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!priv->has_ps) { *status = RIG_POWER_ON; RETURNFUNC(RIG_OK); // fake the OK return for these rigs } if (!status) { RETURNFUNC(-RIG_EINVAL); } // The first PS command has two purposes: // 1. to detect that the rig is turned on/off when it responds with PS1/PS0 immediately // 2. to act as dummy wake-up data for a rig that is turned off // Timeout needs to be set temporarily to a low value, // so that the second command can be sent in 2 seconds, which is what Kenwood rigs expect. short retry_save; short timeout_retry_save; int timeout_save; retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; timeout_save = rp->timeout; rp->retry = 0; rp->timeout_retry = 0; rp->timeout = 500; result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; rp->timeout = timeout_save; // Rig may respond here already if (result == RIG_OK) { char ps = pwrbuf[2]; switch (ps) { case '1': *status = RIG_POWER_ON; RETURNFUNC(RIG_OK); case '0': *status = RIG_POWER_OFF; RETURNFUNC(RIG_OK); default: // fall through to retry command break; } } // Kenwood rigs in powered-off state require the PS command to be sent // after waiting for at least 200ms and within 2 seconds after dummy data hl_usleep(500000); // Discard any unsolicited data rig_flush(rp); result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); if (result != RIG_OK) { RETURNFUNC(result); } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; RETURNFUNC(RIG_OK); } /* * kenwood_reset */ int kenwood_reset(RIG *rig, reset_t reset) { char rstbuf[6]; char rst; ENTERFUNC; if (RIG_IS_TS990S) { switch (reset) { case RIG_RESET_SOFT: rst = '4'; break; case RIG_RESET_VFO: rst = '3'; break; case RIG_RESET_MCALL: rst = '2'; break; case RIG_RESET_MASTER: rst = '5'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); RETURNFUNC(-RIG_EINVAL); } } else { switch (reset) { case RIG_RESET_VFO: rst = '1'; break; case RIG_RESET_MASTER: rst = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); RETURNFUNC(-RIG_EINVAL); } } SNPRINTF(rstbuf, sizeof(rstbuf), "SR%c", rst); /* this command has no answer */ RETURNFUNC(kenwood_transaction(rig, rstbuf, NULL, 0)); } /* * kenwood_send_morse */ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) { char morsebuf[40], m2[30]; int msg_len, retval; const char *p; struct kenwood_priv_data *priv; ENTERFUNC; if (!msg) { RETURNFUNC(-RIG_EINVAL); } p = msg; msg_len = strlen(msg); while (msg_len > 0) { int buff_len; /* * Check with "KY" if char buffer is available. * if not, sleep. */ for (;;) { retval = kenwood_transaction(rig, "KY;", m2, 4); if (retval != RIG_OK) { RETURNFUNC(retval); } // If answer is "KY0;", there is space in buffer and we can proceed. // If answer is "KY1;", we have to wait a while // If answer is "KY2;", there is space in buffer and we aren't sending so we can proceed. // If answer is something else, return with error to prevent infinite loops if (!strncmp(m2, "KY0", 3)) { break; } if (!strncmp(m2, "KY2", 3)) { break; } if (!strncmp(m2, "KY1", 3)) { hl_usleep(50 * 1000); } else { RETURNFUNC(-RIG_EINVAL); } } buff_len = msg_len > 24 ? 24 : msg_len; strncpy(m2, p, 24); m2[24] = '\0'; /* * Make the total message segments 28 characters * in length because some Kenwoods demand it. * 0x20 fills in the message end. * Some rigs don't need the fill */ switch (rig->caps->rig_model) { case RIG_MODEL_K3: // probably a lot more rigs need to go here case RIG_MODEL_K3S: case RIG_MODEL_KX2: case RIG_MODEL_KX3: case RIG_MODEL_QRPLABS: SNPRINTF(morsebuf, sizeof(morsebuf), "KY %s", m2); break; case RIG_MODEL_TS590S: //??case RIG_MODEL_TS590SG: /* The command must consist of 28 bytes right aligned. * See https://github.com/Hamlib/Hamlib/issues/1634 */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %24s", m2); break; case RIG_MODEL_TS890S: SNPRINTF(morsebuf, sizeof morsebuf, "KY2%s", m2); break; case RIG_MODEL_TS990S: // Variable message length only on newer firmware priv = STATE(rig)->priv; if (priv->fw_rev_uint >= 110) { SNPRINTF(morsebuf, sizeof morsebuf, "KY2%s", m2); break; } /* FALL THROUGH */ default: /* the command must consist of 28 bytes 0x20 padded */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %-24s", m2); } retval = kenwood_transaction(rig, morsebuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } msg_len -= buff_len; p += buff_len; } RETURNFUNC(RIG_OK); } /* * kenwood_stop_morse / */ int kenwood_stop_morse(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(kenwood_transaction(rig, "KY0", NULL, 0)); } /* * kenwood_send_voice */ int kenwood_send_voice_mem(RIG *rig, vfo_t vfo, int bank) { char cmd[16]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; #if 0 // don't really need to turn on the list SNPRINTF(cmd, sizeof(cmd), "PB01"); kenwood_transaction(rig, cmd, NULL, 0); #endif if ((bank < 1 || bank > 3) && (rig->caps->rig_model == RIG_MODEL_TS2000 || rig->caps->rig_model == RIG_MODEL_TS480)) { rig_debug(RIG_DEBUG_ERR, "%s: TS2000/TS480 channel is from 1 to 3\n", __func__); RETURNFUNC(-RIG_EINVAL); } // some rigs have 5 channels -- newew ones have 10 channels if ((bank < 1 || bank > 5) && (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S)) { rig_debug(RIG_DEBUG_ERR, "%s: TS590S/SG channel is from 1 to 5\n", __func__); RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS2000 || (rig->caps->rig_model == RIG_MODEL_TS480 || (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S))) { SNPRINTF(cmd, sizeof(cmd), "PB%d", bank); } else { SNPRINTF(cmd, sizeof(cmd), "PB1%d1", bank); } priv->voice_bank = bank; RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } int kenwood_stop_voice_mem(RIG *rig, vfo_t vfo) { char cmd[16]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_TS2000 || (rig->caps->rig_model == RIG_MODEL_TS480 || (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S))) { SNPRINTF(cmd, sizeof(cmd), "PB0"); } else { SNPRINTF(cmd, sizeof(cmd), "PB1%d0", priv->voice_bank); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } /* * kenwood_vfo_op */ int kenwood_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { ENTERFUNC; switch (op) { case RIG_OP_UP: RETURNFUNC(kenwood_transaction(rig, "UP", NULL, 0)); case RIG_OP_DOWN: RETURNFUNC(kenwood_transaction(rig, "DN", NULL, 0)); case RIG_OP_BAND_UP: RETURNFUNC(kenwood_transaction(rig, "BU", NULL, 0)); case RIG_OP_BAND_DOWN: RETURNFUNC(kenwood_transaction(rig, "BD", NULL, 0)); case RIG_OP_TUNE: RETURNFUNC(kenwood_transaction(rig, "AC111", NULL, 0)); case RIG_OP_CPY: RETURNFUNC(kenwood_transaction(rig, "VV", NULL, 0)); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); RETURNFUNC(-RIG_EINVAL); } } /* * kenwood_set_mem */ int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[7]; ENTERFUNC; if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "MN%c%03d", c, ch); } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(buf, sizeof(buf), "MC %02d", ch); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * kenwood_get_mem */ int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[4]; char membuf[10]; int offs; int retval; ENTERFUNC; if (!ch) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "MN%c", c); offs = 3; } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(cmd, sizeof(cmd), "MC"); offs = 2; } retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 3 + offs); if (retval != RIG_OK) { RETURNFUNC(retval); } *ch = atoi(membuf + offs); RETURNFUNC(RIG_OK); } int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch) { int err; char buf[4]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!ch) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } memcpy(buf, &priv->info[26], 2); buf[2] = '\0'; *ch = atoi(buf); RETURNFUNC(RIG_OK); } int kenwood_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; char buf[26]; char cmd[8]; char bank = ' '; struct kenwood_priv_caps *caps = kenwood_caps(rig); ENTERFUNC; if (!chan) { RETURNFUNC(-RIG_EINVAL); } /* put channel num in the command string */ if (RIG_IS_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(cmd, sizeof(cmd), "MR0%c%02d", bank, chan->channel_num); err = kenwood_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { RETURNFUNC(err); } memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_VFO; /* MR0 1700005890000510 ; * MRsbccfffffffffffMLTtt ; */ /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ if (buf[19] == '0' || buf[19] == ' ') { chan->ctcss_tone = 0; } else { buf[22] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[atoi(&buf[20])]; } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { RETURNFUNC(-RIG_ENAVAIL); } buf[6] = '\0'; chan->channel_num = atoi(&buf[4]); if (buf[3] >= '0' && buf[3] <= '9') { chan->bank_num = buf[3] - '0'; } /* split freq */ cmd[2] = '1'; err = kenwood_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { RETURNFUNC(err); } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } int kenwood_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char buf[128]; char mode, tx_mode = 0; char bank = ' '; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); ENTERFUNC; if (!chan) { RETURNFUNC(-RIG_EINVAL); } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); RETURNFUNC(-RIG_EINVAL); } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); RETURNFUNC(-RIG_EINVAL); } } /* find tone */ if (chan->ctcss_tone) { for (tone = 0; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = 0; } } if (RIG_IS_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(buf, sizeof(buf), "MW0%c%02d%011"PRIll"%c%c%c%02d ", /* note the space at the end */ bank, chan->channel_num, (int64_t)chan->freq, '0' + mode, (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } SNPRINTF(buf, sizeof(buf), "MW1%c%02d%011"PRIll"%c%c%c%02d ", bank, chan->channel_num, (int64_t)(chan->split == RIG_SPLIT_ON ? chan->tx_freq : 0), (chan->split == RIG_SPLIT_ON) ? ('0' + tx_mode) : '0', (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } int kenwood_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[4]; ENTERFUNC; switch (token) { case TOK_VOICE: RETURNFUNC(kenwood_transaction(rig, "VR", NULL, 0)); case TOK_FINE: SNPRINTF(buf, sizeof(buf), "FS%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_NO_ID: priv->no_id = val.i; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_set_clock */ int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { char cmd[20]; int retval, kenwood_val; /* Do the offset first. Then if the clock is synced to NTP, * the set failure still should allow correct display * * utc_offset = hours * 100 + minutes * Kenwood value = 15 minute intervals normalized to 56 ( = UTC+00) */ // Convert utc_offset to minutes kenwood_val = ((utc_offset / 100) * 60) + (utc_offset % 100); // Now convert to 15 minute intervals, centered on 56 kenwood_val = kenwood_val / 15 + 56; SNPRINTF(cmd, sizeof(cmd), "CK2%03d", kenwood_val); retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) {return retval;} // Offset is set, now check if clock is settable retval = kenwood_transaction(rig, "CK6", cmd, sizeof(cmd)); if (retval != RIG_OK) {return retval;} if (cmd[3] == '1') { // OK, autoset by NTP is on so we can't set it // What should we tell the user? // Until I hear otherwise, pretend everything worked, and // the local clock should display the correct time in whatever // zone the app thought it was trying to set. return RIG_OK; } // Local clock should be settable; build the command SNPRINTF(cmd, sizeof(cmd), "CK0%02d%02d%02d%02d%02d%02d", year % 100, month, day, hour, min, sec); if (RIG_IS_TS990S) { // TS-990S does not have seconds cmd[13] = '\0'; } retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } /* * kenwood_get_clock */ int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval; int fields, diff; char ans[20]; // Make sure the clock has been set at least once retval = kenwood_transaction(rig, "CK1", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} if (ans[3] != '1') { return -RIG_ENAVAIL; } // Get the local clock retval = kenwood_transaction(rig, "CK0", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} fields = sscanf(ans, "CK0%2d%2d%2d%2d%2d%2d", year, month, day, hour, min, sec); // TS-890S doesn't define what P6 is, but it sure looks like seconds to me. // TS-990S doesn't have a P6, so set it to 0 if (fields < 6) { *sec = 0; } // Add the century if (*year <= 20) //TODO: Update this every decade or so { *year += 100; } *year += 2000; //TODO: Update this every century or so // Now figure out the time zone retval = kenwood_transaction(rig, "CK2", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} diff = (atoi(&ans[3]) - 56) * 15; // UTC offset in minutes // Pack as hours * 100 + minutes *utc_offset = (diff / 60) * 100 + diff % 60; // No msec available *msec = 0; return RIG_OK; } int kenwood_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { int err; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!val) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FINE: RETURNFUNC(get_kenwood_func(rig, "FS", &val->i)); case TOK_XIT: err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } val->i = (priv->info[24] == '1') ? 1 : 0; RETURNFUNC(RIG_OK); case TOK_RIT: err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } val->i = (priv->info[23] == '1') ? 1 : 0; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_ENIMPL); } /* * kenwood_get_info * supposed to work only for TS2000... */ const char *kenwood_get_info(RIG *rig) { char firmbuf[10]; int retval; ENTERFUNC2; if (!rig) { return ("*rig == NULL"); } retval = kenwood_safe_transaction(rig, "TY", firmbuf, 10, 5); if (retval != RIG_OK) { return (NULL); } switch (firmbuf[4]) { case '0': return ("Firmware: Overseas type"); case '1': return ("Firmware: Japanese 100W type"); case '2': return ("Firmware: Japanese 20W type"); default: return ("Firmware: unknown"); } } #define IDBUFSZ 16 /* * proberigs_kenwood * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_kenwood(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(kenwood) { char idbuf[IDBUFSZ] = ""; int id_len = -1, i, k_id; int retval = -1; int rates[] = { 115200, 57600, 38400, 19200, 9600, 4800, 1200, 0 }; /* possible baud rates */ int rates_idx; int write_delay = port->write_delay; short retry = port->retry; if (port->type.rig != RIG_PORT_SERIAL) { return (RIG_MODEL_NONE); } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 2; port->retry = 0; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } retval = write_block(port, (unsigned char *) "ID;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || !strcmp(idbuf, "ID;")) { port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } /* * reply should be something like 'IDxxx;' */ if (id_len != 5 && id_len != 6) { idbuf[7] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: protocol error, " " expected %d, received %d: %s\n", 6, id_len, idbuf); port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } /* first, try ID string */ for (i = 0; kenwood_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!strncmp(kenwood_id_string_list[i].id, idbuf + 2, 16)) { rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: " "found %s\n", idbuf + 2); if (cfunc) { (*cfunc)(port, kenwood_id_string_list[i].model, data); } port->write_delay = write_delay; port->retry = retry; return (kenwood_id_string_list[i].model); } } /* then, try ID numbers */ k_id = atoi(idbuf + 2); /* * Elecraft K2 returns same ID as TS570 */ if (k_id == 17) { retval = serial_open(port); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } retval = write_block(port, (unsigned char *) "K2;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } /* * reply should be something like 'K2n;' */ if (id_len == 4 || !strcmp(idbuf, "K2")) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found K2\n", __func__); if (cfunc) { (*cfunc)(port, RIG_MODEL_K2, data); } return (RIG_MODEL_K2); } } for (i = 0; kenwood_id_list[i].model != RIG_MODEL_NONE; i++) { if (kenwood_id_list[i].id == k_id) { rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: " "found %03d\n", k_id); if (cfunc) { (*cfunc)(port, kenwood_id_list[i].model, data); } return (kenwood_id_list[i].model); } } /* * not found in known table.... * update kenwood_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_kenwood: found unknown device " "with ID %03d, please report to Hamlib " "developers.\n", k_id); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay=%d\n", __func__, port->post_write_delay); return (RIG_MODEL_NONE); } /* * initrigs_kenwood is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kenwood) { rig_register(&ts950s_caps); rig_register(&ts950sdx_caps); rig_register(&ts50s_caps); rig_register(&ts140_caps); rig_register(&ts450s_caps); rig_register(&ts570d_caps); rig_register(&ts570s_caps); rig_register(&ts680s_caps); rig_register(&ts690s_caps); rig_register(&ts790_caps); rig_register(&ts850_caps); rig_register(&ts870s_caps); rig_register(&ts930_caps); rig_register(&ts2000_caps); rig_register(&trc80_caps); rig_register(&k2_caps); rig_register(&k3_caps); rig_register(&k3s_caps); rig_register(&kx2_caps); rig_register(&kx3_caps); rig_register(&k4_caps); rig_register(&xg3_caps); rig_register(&sdrconsole_caps); rig_register(&ts440_caps); rig_register(&ts940_caps); rig_register(&ts711_caps); rig_register(&ts811_caps); rig_register(&r5000_caps); rig_register(&tmd700_caps); rig_register(&thd7a_caps); rig_register(&thd72a_caps); rig_register(&thd74_caps); rig_register(&thf7e_caps); rig_register(&thg71_caps); rig_register(&tmv7_caps); rig_register(&tmv71_caps); rig_register(&tmd710_caps); rig_register(&ts590_caps); rig_register(&ts990s_caps); rig_register(&ts590sg_caps); rig_register(&ts480_caps); rig_register(&thf6a_caps); rig_register(&transfox_caps); rig_register(&f6k_caps); rig_register(&powersdr_caps); rig_register(&pihpsdr_caps); rig_register(&ts890s_caps); rig_register(&pt8000a_caps); rig_register(&malachite_caps); rig_register(&tx500_caps); rig_register(&sdruno_caps); rig_register(&qrplabs_caps); rig_register(&qrplabs_qmx_caps); rig_register(&fx4_caps); rig_register(&thetis_caps); rig_register(&trudx_caps); return (RIG_OK); } hamlib-4.6.5/rigs/kenwood/ts50s.c0000664000175000017500000002016315056640443012212 /* * Hamlib Kenwood backend - TS50 description * Copyright (c) 2002-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS50_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS50_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS50_AM_TX_MODES RIG_MODE_AM #define TS50_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_TSQL|RIG_FUNC_TONE|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_LOCK|RIG_FUNC_BC) #define TS50_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN) #define TS50_VFO (RIG_VFO_A|RIG_VFO_B) #define TS50_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) static struct kenwood_priv_caps ts50_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * ts50 rig capabilities. * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts50s_caps = { RIG_MODEL(RIG_MODEL_TS50), .model_name = "TS-50S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS50_FUNC_ALL, .has_set_func = TS50_FUNC_ALL, .has_get_level = TS50_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS50_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 18, RIG_DBLST_END, }, .max_rit = kHz(1.1), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TS50_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS50_ALL_MODES, -1, -1, TS50_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(3500), kHz(3800) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(7), kHz(7100), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(7), kHz(7100), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(14), kHz(14350), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(14), kHz(14350), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(21), kHz(21450), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(21), kHz(21450), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(28), kHz(29700), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(28), kHz(29700), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS50_ALL_MODES, -1, -1, TS50_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(3500), MHz(4) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(7), kHz(7300), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(7), kHz(7300), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(14), kHz(14350), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(14), kHz(14350), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(21), kHz(21450), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(21), kHz(21450), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(28), kHz(29700), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(28), kHz(29700), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS50_ALL_MODES, 50}, {TS50_ALL_MODES, 100}, {TS50_ALL_MODES, kHz(1)}, {TS50_ALL_MODES, kHz(5)}, {TS50_ALL_MODES, kHz(9)}, {TS50_ALL_MODES, kHz(10)}, {TS50_ALL_MODES, 12500}, {TS50_ALL_MODES, kHz(20)}, {TS50_ALL_MODES, kHz(25)}, {TS50_ALL_MODES, kHz(100)}, {TS50_ALL_MODES, MHz(1)}, {TS50_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_AM, kHz(5)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts50_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/k3.c0000664000175000017500000025134215056640443011556 /* * Hamlib Kenwood backend - Elecraft K3 description * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (C) 2010,2011,2012,2013 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include #include "idx_builtin.h" #include "kenwood.h" #include "misc.h" #include "bandplan.h" #include "elecraft.h" #include "cal.h" #define K3_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_PKTUSB|\ RIG_MODE_PKTLSB) #define K3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ RIG_FUNC_DUAL_WATCH|RIG_FUNC_DIVERSITY|\ RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SEND_MORSE) #define K4_FUNC_ALL (K3_FUNC_ALL|RIG_FUNC_MUTE) #define K3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS) #define K3_VFO (RIG_VFO_A|RIG_VFO_B) #define K3_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TUNE) #define K3_ANTS (RIG_ANT_1|RIG_ANT_2) #define K4_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define KX3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ RIG_FUNC_DUAL_WATCH|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) #define KX3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER|\ RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SWR) /* * Elecraft K3/K3S extra level definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams k3_ext_levels[] = { { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } }, { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RX_ANT, "rx_ant", "RX ANT", "RX antenna", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_LINK_VFOS, "link_vfos", "Link VFOs", "Link VFOs", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_TX_METER, "tx_meter", "TX meter", "Transmit meter mode", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "SWR", "ALC", NULL } } } }, { TOK_IF_NB, "if_nb", "IF NB", "IF noise blanker level", NULL, RIG_CONF_NUMERIC, { .n = { 0, 21, 1 } }, }, { RIG_CONF_END, NULL, } }; /* * Elecraft KX3/KX2 extra level definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams kx3_ext_levels[] = { { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { RIG_CONF_END, NULL, } }; /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps k3_priv_caps = { .cmdtrm = EOM_KEN, }; /* K3 specific function declarations */ int k3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); 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_get_vfo(RIG *rig, vfo_t *vfo); int k3_set_vfo(RIG *rig, vfo_t vfo); int k3_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int k3_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int k3_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); int k3_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit); int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int kx3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int k3_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int k3_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); /* Private helper functions */ int set_rit_xit(RIG *rig, shortfreq_t rit); int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb); int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb); int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx); int k4_get_bar_graph_level(RIG *rig, float *swr, float *pwr, float *alc, int *mode_tx); int kx3_get_bar_graph_level(RIG *rig, float *level); int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k3_stop_voice_mem(RIG *rig, vfo_t vfo); int k3_stop_morse(RIG *rig, vfo_t vfo); /* K4 functions */ int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k4_stop_voice_mem(RIG *rig, vfo_t vfo); int k4_stop_morse(RIG *rig, vfo_t vfo); /* * K3 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) 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 */ int kx3_get_bar_graph_level(RIG *rig, float *level); int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k3_stop_voice_mem(RIG *rig, vfo_t vfo); int k3_stop_morse(RIG *rig, vfo_t vfo); /* K4 functions */ int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k4_stop_voice_mem(RIG *rig, vfo_t vfo); int k4_stop_morse(RIG *rig, vfo_t vfo); /* * K3 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) 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 * */ struct rig_caps k3_caps = { RIG_MODEL(RIG_MODEL_K3), .model_name = "K3", .mfg_name = "Elecraft", .version = BACKEND_VER ".31", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K3_FUNC_ALL, .has_set_func = K3_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { // cppcheck-suppress * #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = k3_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps k3s_caps = { RIG_MODEL(RIG_MODEL_K3S), .model_name = "K3S", .mfg_name = "Elecraft", .version = BACKEND_VER ".25", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K3_FUNC_ALL, .has_set_func = K3_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_elecraft.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 15 }, .step = { .i = 5 } }, }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = k3_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; // How similar is this to the K3S? struct rig_caps k4_caps = { RIG_MODEL(RIG_MODEL_K4), .model_name = "K4", .mfg_name = "Elecraft", .version = BACKEND_VER ".32", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K4_FUNC_ALL, .has_set_func = K4_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_VOXDELAY #define NO_LVL_PREAMP #include "level_gran_elecraft.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_VOXDELAY #undef NO_LVL_PREAMP [LVL_CWPITCH] = { .min = { .i = 250 }, .max = { .i = 950 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 15 }, .step = { .i = 5 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 10 } }, [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 30}, .step = { .i = 10 } }, }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 10, 20, 30, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_FAST }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K4_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = elecraft_get_vfo_tq, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k4_stop_morse, .send_voice_mem = k4_send_voice_mem, .stop_voice_mem = k4_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps kx3_caps = { RIG_MODEL(RIG_MODEL_KX3), .model_name = "KX3", .mfg_name = "Elecraft", .version = BACKEND_VER ".22", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = KX3_FUNC_ALL, .has_set_func = KX3_FUNC_ALL, .has_get_level = KX3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = kx3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kx3_set_level, .get_level = kx3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps kx2_caps = { RIG_MODEL(RIG_MODEL_KX2), .model_name = "KX2", .mfg_name = "Elecraft", .version = BACKEND_VER ".21", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = KX3_FUNC_ALL, .has_set_func = KX3_FUNC_ALL, .has_get_level = KX3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = kx3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kx3_set_level, .get_level = kx3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .power2mW = k3_power2mW, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * 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) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rmode_t temp_m; pbwidth_t temp_w; char *cmd_data = "DT"; char *cmd_bw = "BW"; int cmd_bw_len = 6; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if ((priv->is_k3 || priv->is_k3s || priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { if (!(priv->is_k3 || priv->is_k3s)) { cmd_data = "DT$"; } cmd_bw = "BW$"; cmd_bw_len = 7; } if (!mode || !width) { return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } 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, cmd_data, buf, KENWOOD_MAX_BUF_LEN, strlen(cmd_data) + 1); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *mode = RIG_MODE_PKTLSB; break; default: *mode = temp_m; break; } } else if (temp_m == RIG_MODE_RTTYR) { err = kenwood_safe_transaction(rig, cmd_data, buf, KENWOOD_MAX_BUF_LEN, strlen(cmd_data) + 1); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *mode = RIG_MODE_PKTLSB; break; case K3_MODE_FSK_D: default: *mode = temp_m; break; } } 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, cmd_bw, buf, KENWOOD_MAX_BUF_LEN, cmd_bw_len); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 BW value\n", __func__); return err; } *width = atoi(&buf[cmd_bw_len - 4]) * 10; return RIG_OK; } /* k3_set_mode() * * As with k3_get_mode(), the K3 can also set the data sub-modes which * allows use of RIG_MODE_PKTUSB and RIG_MODE_PKTLSB. * * The K3 supports AFSK & FSK sub-modes and for the D versions it also * has an internal RTTY and PSK31 decoder. The decoder sub-modes are * reported as FSK (RTTY) and the AFSK sub-modes are reported as * PKT(USB & LSB). The Submode determines if MD6 starts off in USB * or LSB. To get the reverse of that, you send MD9 and the the submode. * On KX3 it's * * DT0 defaults MD6 to USB * DT1 defaults MD6 to LSB * DT2 defaults MD6 to LSB * DT3 defaults MD6 to USB * * So to inverse that DT0 for LSB, you'd send MD9 then DT0. * * For mode set the data sub-modes are set as follows: * * PKTUSB = sets the rig to DATA mode submode Data A (DT0) * PKTLSB = sets the rig to DATA REV mode submode Data A (DT0) * RTTY = sets the rig to AFSK A 45 bps rtty (DT1) * RTTYR = sets the rig to FSK D 45 bps rtty (DT2) * PSK = sets the rig to PSK D (DT3) * Not all data sub-mode combinations are possible but the above * mapping seems most likely to cover the user requirements. */ int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int err, err2; char cmd_m[5]; char buf[KENWOOD_MAX_BUF_LEN]; char *dtcmd; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } rmode_t tmodeA, tmodeB; pbwidth_t twidth; err = k3_get_mode(rig, RIG_VFO_A, &tmodeA, &twidth); err2 = k3_get_mode(rig, RIG_VFO_B, &tmodeB, &twidth); // we keep both vfos in the same mode -- any reason they should ever be different? If so, fix this // if we change mode on one VFO we'll also change the other if (err == RIG_OK && err2 == RIG_OK && tmodeA == mode && tmodeB == mode && width == RIG_PASSBAND_NOCHANGE) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): mode/width no change, skipping\n", __FILE__, __LINE__); RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s(%d): changing oldmode=A=%s B=%s, to mode=%s, oldwidth=%ld, to width=%ld\n", __FILE__, __LINE__, rig_strrmode(tmodeA), rig_strrmode(tmodeB), rig_strrmode(mode), twidth, width); } dtcmd = "DT"; if ((priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { dtcmd = "DT$"; } switch (mode) { case RIG_MODE_PKTLSB: mode = RIG_MODE_RTTYR; // in "DT0" Subband RIG_MODE_RTTYR = USB and RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "%s0", dtcmd); /* DATA A mode - DATA (REV) on LSB optimized for HF Packet, VFO dial is suppressed carrier QRG */ break; case RIG_MODE_PKTUSB: mode = RIG_MODE_RTTY; // in "DT0" Subband RIG_MODE_RTTYR = USB and RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "%s0", dtcmd); /* DATA A mode - DATA on USB general, VFO dial is suppressed carrier QRG */ break; case RIG_MODE_RTTY: mode = RIG_MODE_RTTY; // in "DT1" Subband RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "%s2", dtcmd); /* FSK D mode - direct FSK on LSB optimized for RTTY, VFO dial is MARK */ break; case RIG_MODE_RTTYR: mode = RIG_MODE_RTTYR; // in "DT2" Subband RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "%s1", dtcmd); /* FSK D mode - direct FSK keying, LSB is "normal", VFO dial is MARK */ break; case RIG_MODE_PSK: mode = RIG_MODE_PSK; // in "DT3" subband RIG_MODE_PSK = USB # kenwood.c mode but may need kenwwod.c mode table review. SNPRINTF(cmd_m, sizeof(cmd_m), "%s3", dtcmd); /* PSK D Mode - direct PSK keying, USB is "normal", VFO dial is MARK */ break; default: break; } int kmode; int c; kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: kmode=%d, cmode=%c\n", __func__, kmode, c); if (vfo == RIG_VFO_B) { SNPRINTF(buf, sizeof(buf), "MD$%c", c); } else { SNPRINTF(buf, sizeof(buf), "MD%c", c); } if (priv->split) { // then we keep both VFOS in the same mode SNPRINTF(buf, sizeof(buf), "MD%c;MD$%c", c, c); } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } if (width != RIG_PASSBAND_NOCHANGE) { char cmd_s[64]; /* 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. */ /* passband widths vary by mode so gather lower and upper limits */ //pbwidth_t pb_nar = rig_passband_narrow(rig, mode); //pbwidth_t pb_wid = rig_passband_wide(rig, mode); if (width < 0) { width = labs(width); } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } #if 0 else if (width < pb_nar) { width = pb_nar; } else if (width > pb_wid) { width = pb_wid; } #endif width += 9; // rounds to 10Hz if (width > 99999) { width = 99999; } if (vfo == RIG_VFO_B) { SNPRINTF(cmd_s, sizeof(cmd_s), "BW$%04ld", width / 10); } else { SNPRINTF(cmd_s, sizeof(cmd_s), "BW%04ld", width / 10); } err = kenwood_transaction(rig, cmd_s, NULL, 0); if (err != RIG_OK) { RETURNFUNC(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_transaction(rig, cmd_m, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } /* Elecraft rigs don't really know about swappings vfos. * We just emulate them so rigctl can work correctly. */ int k3_set_vfo(RIG *rig, vfo_t vfo) { ENTERFUNC; // we emulate vfo selection for Elecraft STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } int k3_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = STATE(rig)->current_vfo; RETURNFUNC(RIG_OK); } /* Support the RC command for clearing RIT/XIT, * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 * * See Private Elecraft extra levels definitions in elecraft.c and * private token #define in elecraft.h */ int k3_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_RIT_CLR: return kenwood_transaction(rig, "RC", NULL, 0); case TOK_ESSB: SNPRINTF(buf, sizeof(buf), "ES%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_RX_ANT: SNPRINTF(buf, sizeof(buf), "AR%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_LINK_VFOS: SNPRINTF(buf, sizeof(buf), "LN%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_TX_METER: SNPRINTF(buf, sizeof(buf), "TM%c", val.i + '0'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_IF_NB: return k3_set_nb_level(rig, -1, val.f / 21.0f); default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported set_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } } /* Support the FI command for reading the IF center frequency, * useful for panadapters and such that need to know the IF center. * TQ command is a quick transmit status query--K2/K3 only. * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ int k3_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (token) { case TOK_IF_FREQ: err = kenwood_safe_transaction(rig, "FI", buf, KENWOOD_MAX_BUF_LEN, 6); if (err != RIG_OK) { return err; } val->f = 8210000.0 + (float) atoi(&buf[2]); break; case TOK_TX_STAT: return get_kenwood_func(rig, "TQ", &val->i); case TOK_ESSB: return get_kenwood_func(rig, "ES", &val->i); case TOK_RX_ANT: return get_kenwood_func(rig, "AR", &val->i); case TOK_LINK_VFOS: return get_kenwood_func(rig, "LN", &val->i); case TOK_TX_METER: return get_kenwood_func(rig, "TM", &val->i); case TOK_IF_NB: { float if_nb; err = k3_get_nb_level(rig, NULL, &if_nb); if (err != RIG_OK) { return err; } val->f = (float)((int)(if_nb * 21.0f)); break; } default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* * k3_set_rit() -- Differs from from generic Kenwood function as K3 can set * RIT to an arbitrary offset. When rit == 0, the RIT offset is cleared. */ int k3_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = set_rit_xit(rig, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * k3_set_xit() -- Differs from from generic Kenwood function as K3 can set * XIT to an arbitrary offset. When rit == 0, the XIT offset is cleared. */ int k3_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = set_rit_xit(rig, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * The K3 *always* uses VFOB for TX. */ int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[32]; char kmode; int err; char cmd_m[16]; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (tx_mode) { case RIG_MODE_PKTLSB: tx_mode = RIG_MODE_RTTYR; // "DT0" RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "DT0;"); /* DATA A mode - DATA-R LSB, suppressed carrier */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$0;"); } break; case RIG_MODE_PKTUSB: tx_mode = RIG_MODE_RTTY; // "DT0" RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT0;"); /* DATA A mode - DATA on USB, suppressed carrier */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$0;"); } break; case RIG_MODE_RTTY: tx_mode = RIG_MODE_RTTY; // DT1" RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT2;"); /* FSK D mode - direct FSK on LSB optimized for RTTY, VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$2;"); } break; case RIG_MODE_RTTYR: tx_mode = RIG_MODE_RTTYR; // "DT2" RIG_MODE_RTTY = USB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT1;"); /* FSK D mode - direct FSK on USB optimized for RTTY, VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$1;"); } break; case RIG_MODE_PSK: tx_mode = RIG_MODE_PSK; SNPRINTF(cmd_m, sizeof(cmd_m), "DT3;FT1;"); /* PSK D Mode - direct PSK keying, USB is "normal", VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$3;"); } break; default: break; } // Enabling this clause for just the K4 for now #if 1 if (priv->is_k4d || priv->is_k4hd) { // split can get turned off when modes are changing // so if the rig did this independently of us we turn it back on // even if the rig changes the split status should be the last thing we did if (priv->split) { strcat(cmd_m, "FT1;"); } /* Set data sub-mode. K3 needs to be in a DATA mode before setting * the sub-mode or switching to VFOB so we do this before the MD$ command. */ if (tx_mode == RIG_MODE_PKTLSB || tx_mode == RIG_MODE_PKTUSB || tx_mode == RIG_MODE_RTTY || tx_mode == RIG_MODE_RTTYR) { err = kenwood_transaction(rig, cmd_m, NULL, 0); if (err != RIG_OK) { return err; } } } #endif kmode = rmode2kenwood(tx_mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(tx_mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD$%c", '0' + kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (tx_width != RIG_PASSBAND_NOCHANGE) { char cmd_s[32]; /* 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. * * tx_width string value must be padded with leading '0' to equal four * characters. */ /* passband widths vary by mode so gather lower and upper limits */ //pbwidth_t pb_nar = rig_passband_narrow(rig, tx_mode); //pbwidth_t pb_wid = rig_passband_wide(rig, tx_mode); if (tx_width < 0) { tx_width = labs(tx_width); } if (tx_width == RIG_PASSBAND_NORMAL) { tx_width = rig_passband_normal(rig, tx_mode); } #if 0 else if (tx_width < pb_nar) { tx_width = pb_nar; } else if (tx_width > pb_wid) { tx_width = pb_wid; } #endif SNPRINTF(cmd_s, sizeof(cmd_s), "BW$%04ld", tx_width / 10); err = kenwood_transaction(rig, cmd_s, NULL, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* The K3 *always* uses VFOB for TX. */ int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rmode_t temp_m; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!tx_mode || !tx_width) { return -RIG_EINVAL; } err = kenwood_safe_transaction(rig, "MD$", buf, KENWOOD_MAX_BUF_LEN, 4); if (err != RIG_OK) { return err; } temp_m = kenwood2rmode(buf[3] - '0', caps->mode_table); if (temp_m == RIG_MODE_RTTY) { err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *tx_mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *tx_mode = RIG_MODE_PKTLSB; break; default: *tx_mode = temp_m; break; } } else if (temp_m == RIG_MODE_RTTYR) { err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *tx_mode = RIG_MODE_PKTLSB; break; case K3_MODE_AFSK_A: *tx_mode = RIG_MODE_PKTUSB; break; case K3_MODE_FSK_D: break; default: *tx_mode = temp_m; break; } } else { *tx_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_VERBOSE, "%s: Cannot read K3 BW$ value\n", __func__); return err; } *tx_width = atoi(&buf[3]) * 10; return RIG_OK; } static int k3_get_maxpower(RIG *rig) { //int retval; int maxpower = 15; // K3 default power level //char levelbuf[KENWOOD_MAX_BUF_LEN]; const struct kenwood_priv_data *priv = STATE(rig)->priv; // default range is 0-15 if there is no KPA3 installed if (priv->has_kpa3 || priv->has_kpa100) { maxpower = 110; } else if (RIG_IS_KX2 || RIG_IS_KX3) { int bandnum = -1; char levelbuf[KENWOOD_MAX_BUF_LEN]; int retval = kenwood_safe_transaction(rig, "BN", levelbuf, KENWOOD_MAX_BUF_LEN, 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf, "BN%d", &bandnum); switch (bandnum) { case 1: case 2: case 3: case 4: case 5: maxpower = 15; break; case 0: // 160M case 6: // 17M case 7: // 15M case 8: // 12M case 9: // 10M maxpower = 12; break; case 10: // 6M maxpower = 10; break; default: // are transverters all limited to 3W?? maxpower = 3; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: maxpower=%d\n", __func__, maxpower); return maxpower; } int k3_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char buf[32]; snprintf(buf, sizeof(buf), "%.0f", power * k3_get_maxpower(rig) * 1000); *mwpower = atoi(buf); return RIG_OK; } int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; float pwr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: case RIG_AGC_FAST: kenwood_val = 2; break; case RIG_AGC_MEDIUM: case RIG_AGC_SLOW: kenwood_val = 4; break; case RIG_AGC_USER: case RIG_AGC_AUTO: return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_ATT: if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else if (val.i == 10) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA01"); } else { int i; int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->attenuator[i]; i++) { if (val.i == STATE(rig)->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_MICGAIN: SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", (int)(val.f * 60.0f)); break; case RIG_LEVEL_COMP: SNPRINTF(levelbuf, sizeof(levelbuf), "CP%03d", (int)(val.f * 40.0f)); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", (int)(val.f * 29.0f)); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", (int)(val.f * 250.0f)); break; case RIG_LEVEL_RF: SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", (int)(val.f * 250.0f)); break; case RIG_LEVEL_NR: return k3_set_nb_level(rig, val.f, -1); case RIG_LEVEL_MONITOR_GAIN: SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", (int)(val.f * 60.0f)); break; case RIG_LEVEL_RFPOWER: pwr = val.f * k3_get_maxpower(rig); SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03.f%c", pwr > 15.0 ? pwr : 10.0 * pwr, pwr > 15.0 ? '1' : '0'); break; default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * Handle S-meter (SM, SMH) level locally and pass rest to kenwood_get_level() */ int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char levelbuf[16]; int retval; int lvl; size_t len; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { float firmware_have; float firmware_need; case RIG_LEVEL_STRENGTH: /* As of FW rev 4.37 the K3 supports an 'SMH' command that * offers a higher resolution, 0-100 (mine went to 106), * rawstr value for more precise S-meter reporting. */ firmware_have = 0; if (priv->fw_rev != NULL) { sscanf(priv->fw_rev, "%f", &firmware_have); } sscanf("4.37", "%f", &firmware_need); if (firmware_have < firmware_need) { cal_table_t str_cal = K3_SM_CAL; retval = kenwood_safe_transaction(rig, "SM", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &val->i); /* rawstr */ val->i = (int) rig_raw2val(val->i, &str_cal); } else { cal_table_t str_cal = K3_SMH_CAL; retval = kenwood_safe_transaction(rig, "SMH", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 3, "%d", &val->i); /* rawstr */ val->i = (int) rig_raw2val(val->i, &str_cal); } break; case RIG_LEVEL_ALC: { int tx_mode; float alc; if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, NULL, NULL, &alc, &tx_mode); tx_mode = 1; // Assume ALC is zero when in Tx so we don't care about ptt status } else { retval = k3_get_bar_graph_level(rig, NULL, NULL, &alc, &tx_mode); } if (retval != RIG_OK) { return retval; } if (!tx_mode) { val->f = 0.0f; return RIG_OK; } if (alc < 0) { return -RIG_EINVAL; } val->f = alc; break; } case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { int tx_mode; float pwr; if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, NULL, &pwr, NULL, &tx_mode); tx_mode = 1; // Does K4 return pwr=0 when in Rx? Hope so. } else { retval = k3_get_bar_graph_level(rig, NULL, &pwr, NULL, &tx_mode); } if (retval != RIG_OK) { return retval; } if (!tx_mode) { val->f = 0.0f; return RIG_OK; } if (pwr < 0) { return -RIG_EINVAL; } val->f = pwr; if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f *= 100; } break; } case RIG_LEVEL_AGC: retval = kenwood_safe_transaction(rig, "GT", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = RIG_AGC_OFF; } else if (lvl == 2) { val->i = RIG_AGC_FAST; } else if (lvl == 4) { val->i = RIG_AGC_SLOW; } else { return -RIG_EPROTO; } break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", levelbuf, sizeof(levelbuf), 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else if (lvl == 1) { val->i = 10; } else { int i; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected att level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_MICGAIN: retval = kenwood_safe_transaction(rig, "MG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 60.0f; break; case RIG_LEVEL_COMP: retval = kenwood_safe_transaction(rig, "CP", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 40.0f; break; case RIG_LEVEL_SQL: retval = kenwood_safe_transaction(rig, "SQ", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 29.0f; break; case RIG_LEVEL_RF: retval = kenwood_safe_transaction(rig, "RG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 250.0f; break; case RIG_LEVEL_AF: retval = kenwood_safe_transaction(rig, "AG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 250.0f; break; case RIG_LEVEL_NR: return k3_get_nb_level(rig, &val->f, NULL); case RIG_LEVEL_MONITOR_GAIN: retval = kenwood_safe_transaction(rig, "ML", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 60.0f; break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", levelbuf, sizeof(levelbuf)); if (retval != RIG_OK) { return retval; } len = strlen(levelbuf); if (len == 5 || len == 6) { sscanf(levelbuf + 2, "%3d", &lvl); } else { return RIG_EPROTO; } // extended K22 format PCnnnx where 0=.1W units and 1=1W units if (len == 6 && levelbuf[5] == '0') { val->f = (float) lvl / 10.0 / k3_get_maxpower(rig); } else { val->f = (float) lvl / k3_get_maxpower(rig); } break; case RIG_LEVEL_SWR: if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, &val->f, NULL, NULL, NULL); return RIG_OK; } else { retval = kenwood_safe_transaction(rig, "SW", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &val->i); } val->f = (float) val->i / 10.0f; break; default: return kenwood_get_level(rig, vfo, level, val); } return RIG_OK; } int kx3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ival; char cmdbuf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (val.f > 1.0 || val.f < 0) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RF: ival = val.f * (250.0 - 190.0) + 190.0; SNPRINTF(cmdbuf, sizeof(cmdbuf) - 1, "RG%03d", ival); return kenwood_transaction(rig, cmdbuf, NULL, 0); case RIG_LEVEL_AF: // manual says 0-255 as of Rev G5 but experiment says 0-60 SNPRINTF(cmdbuf, sizeof(cmdbuf), "AG%03d", (int)(val.f * 60.0f)); return kenwood_transaction(rig, cmdbuf, NULL, 0); case RIG_LEVEL_MICGAIN: // manual says 0-255 as of Rev G5 but experiment says 0-80 SNPRINTF(cmdbuf, sizeof(cmdbuf), "MG%03d", (int)(val.f * 80.0f)); return kenwood_transaction(rig, cmdbuf, NULL, 0); } return k3_set_level(rig, vfo, level, val); } int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; float f; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_AF: retval = get_kenwood_level(rig, "AG", NULL, &val->i); if (retval != RIG_OK) { return retval; } // manual says 0-255 as of Rev G5 but experiment says 0-60 f = val->i / 60.0; val->f = f; return retval; case RIG_LEVEL_RF: retval = get_kenwood_level(rig, "RG", NULL, &val->i); if (retval != RIG_OK) { return retval; } f = (val->i - 190.0) / (250.0 - 190.0); val->f = f; return retval; case RIG_LEVEL_MICGAIN: retval = get_kenwood_level(rig, "MG", NULL, &val->i); if (retval != RIG_OK) { return retval; } f = val->i / 80.0; val->f = f; return retval; case RIG_LEVEL_RFPOWER_METER: { int tx_status = 0; float pwr; // Return zero RF power when not in TX mode retval = get_kenwood_func(rig, "TQ", &tx_status); if (retval != RIG_OK) { return retval; } if (!tx_status) { val->f = 0.0f; return RIG_OK; } retval = kx3_get_bar_graph_level(rig, &pwr); if (retval != RIG_OK) { return retval; } val->f = pwr; return retval; } case RIG_LEVEL_RFPOWER_METER_WATTS: { struct kenwood_priv_data *priv = STATE(rig)->priv; char levelbuf[KENWOOD_MAX_BUF_LEN]; int pwr; retval = kenwood_safe_transaction(rig, "PO", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &pwr); val->f = priv->has_kpa100 ? pwr : pwr / 10.0; return retval; } } return k3_get_level(rig, vfo, level, val); } int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_APF: SNPRINTF(buf, sizeof(buf), "AP%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_DUAL_WATCH: SNPRINTF(buf, sizeof(buf), "SB%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_DIVERSITY: SNPRINTF(buf, sizeof(buf), "DV%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_SEND_MORSE: // Transmit a CW character - K3 does not return any response snprintf(buf, sizeof(buf), "KYW%c", status); break; case RIG_FUNC_MUTE: // K4 Only that we know of SNPRINTF(buf, sizeof(buf), "AG%c", (status == 0) ? '/' : '0'); break; case RIG_FUNC_TUNER: // K2 KX2 K3 K3S KX3 K4 SNPRINTF(buf, sizeof(buf), "SWT16"); break; default: return kenwood_set_func(rig, vfo, func, status); } return kenwood_transaction(rig, buf, NULL, 0); } int k3_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[32]; ENTERFUNC; switch (op) { case RIG_OP_TUNE: // KX2 K3 K3S KX3 K4 -- K2 needs SWH20 to it's in k2.c switch (rig->caps->rig_model) { case RIG_MODEL_KX2: SNPRINTF(buf, sizeof(buf), "SWT20"); break; case RIG_MODEL_K3S: case RIG_MODEL_K3: SNPRINTF(buf, sizeof(buf), "SWT19"); break; case RIG_MODEL_KX3: SNPRINTF(buf, sizeof(buf), "SWT44"); break; case RIG_MODEL_K4: SNPRINTF(buf, sizeof(buf), "SW40"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig=%d\n", __func__, rig->caps->rig_model); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(kenwood_vfo_op(rig, vfo, op)); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * Some functions, notably RIT and XIT On/Off status, can be queried * on the K3. Those functions are handled here and others are passed * through to kenwood_get_func(). */ int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_RIT: return get_kenwood_func(rig, "RT", status); case RIG_FUNC_XIT: return get_kenwood_func(rig, "XT", status); case RIG_FUNC_APF: return get_kenwood_func(rig, "AP", status); case RIG_FUNC_DUAL_WATCH: return get_kenwood_func(rig, "SB", status); case RIG_FUNC_DIVERSITY: return get_kenwood_func(rig, "DV", status); default: return kenwood_get_func(rig, vfo, func, status); } } /* Private K3 helper functions */ /* * set_rit_xit() -- Differs from from generic Kenwood function as K3 can set * RIT/XIT to an arbitrary offset. When rit == 0, the RIT/XIT offset is * cleared. */ int set_rit_xit(RIG *rig, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rit == 0) { /* Clear offset and return */ err = kenwood_transaction(rig, "RC", NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* Set offset */ if (rit <= 9999 && rit >= -9999) { char cmd[16]; char offs; offs = (rit < 0) ? '-' : '+'; SNPRINTF(cmd, 8, "RO%c%04d", offs, abs((int)rit)); err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { return err; } } else { return -RIG_EINVAL; } return RIG_OK; } int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb) { char levelbuf[16]; int dsp_nb_raw = 0; int if_nb_raw = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (dsp_nb >= 0) { dsp_nb_raw = (int)(dsp_nb * 21.0f); } if (if_nb >= 0) { if_nb_raw = (int)(if_nb * 21.0f); } if (dsp_nb < 0 || if_nb < 0) { int current_dsp_nb_raw; int current_if_nb_raw; int retval = kenwood_safe_transaction(rig, "NL", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%02d", ¤t_dsp_nb_raw, ¤t_if_nb_raw); if (dsp_nb < 0) { dsp_nb_raw = current_dsp_nb_raw; } if (if_nb < 0) { if_nb_raw = current_if_nb_raw; } } SNPRINTF(levelbuf, sizeof(levelbuf), "NL%02d%02d", dsp_nb_raw, if_nb_raw); return kenwood_transaction(rig, levelbuf, NULL, 0); } int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb) { char levelbuf[16]; int retval; int dsp_nb_raw; int if_nb_raw; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "NL", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%02d", &dsp_nb_raw, &if_nb_raw); if (dsp_nb != NULL) { *dsp_nb = (float) dsp_nb_raw / 21.0f; } if (if_nb != NULL) { *if_nb = (float) if_nb_raw / 21.0f; } return RIG_OK; } int k4_get_bar_graph_level(RIG *rig, float *swr, float *pwr, float *alc, int *mode_tx) { int retval; int ialc, icmp, ifwd, iswr; char levelbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "TM", levelbuf, sizeof(levelbuf), 14); if (retval != RIG_OK) { return retval; } sscanf(levelbuf, "TM%03d%03d%03d%03d", &ialc, &icmp, &ifwd, &iswr); if (swr) { *swr = iswr / 10.0; } if (pwr) { *pwr = ifwd / 100.0; } // pwr is returned in 0-1 sscale if (alc) { *alc = ialc; } return RIG_OK; } int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx) { char levelbuf[16]; int retval; int tm_raw; int bg_raw; char mode; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Determine transmit metering mode: 0 = RF POWER, 1 = ALC retval = get_kenwood_func(rig, "TM", &tm_raw); if (retval != RIG_OK) { return retval; } retval = kenwood_safe_transaction(rig, "BG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%c", &bg_raw, &mode); if (mode == 'R') { // S-meter: nn is 00 - 21 (CWT off) or 00 - 09 (CWT on) if (smeter != NULL) { *smeter = (float) bg_raw / 21.0f; } if (pwr != NULL) { *pwr = -1; } if (alc != NULL) { *alc = -1; } } else if (mode == 'T') { if (tm_raw) { // ALC: nn is 00 - 07 if (alc != NULL) { *alc = (float) bg_raw / 7.0f; } if (pwr != NULL) { *pwr = -1; } if (smeter != NULL) { *smeter = -1; } } else { // PWR: nn is 00 - 12 if (pwr != NULL) { *pwr = (float) bg_raw / 12.0f; } if (alc != NULL) { *alc = -1; } if (smeter != NULL) { *smeter = -1; } } } else { return -RIG_EPROTO; } if (mode_tx != NULL) { *mode_tx = (mode == 'T'); } return RIG_OK; } int kx3_get_bar_graph_level(RIG *rig, float *level) { char levelbuf[16]; int retval; int bg_raw; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "BG", levelbuf, sizeof(levelbuf), 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d", &bg_raw); if (bg_raw >= 0 && bg_raw <= 10) { if (level != NULL) { *level = (float) bg_raw / 10.0f; } } else if (bg_raw >= 12 && bg_raw <= 22) { if (level != NULL) { *level = (float)(bg_raw - 12) / 10.0f; } } else { return -RIG_EPROTO; } return RIG_OK; } int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "TQ", pttbuf, 6, 3); if (retval != RIG_OK) { return retval; } *ptt = pttbuf[2] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; // we're not caching this for now return RIG_OK; } // The K4 has a problem in Fake It mode where the FA command is ignored // We will use its special TQ command to try and ensure PTT is really off int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char pttbuf[6]; int i; int retval; ptt_t ptt2 = -1; char cmd[4]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "RX"); if (ptt) { cmd[0] = 'T'; } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5 && ptt2 != ptt; ++i) { retval = kenwood_safe_transaction(rig, "TQ", pttbuf, 6, 3); if (retval != RIG_OK) { return retval; } ptt2 = pttbuf[2] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; if (ptt2 != ptt) { hl_usleep(100 * 1000); rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d, expected=%d\n", __func__, ptt2, ptt); } } // had one report of Fake It not returning to RX freq after TX -- so a little more time for the K4 if (ptt == RIG_PTT_OFF) { hl_usleep(100 * 1000); } return RIG_OK; } // K3S band memory needs some time to do its thing after freq change // K3 probably does too // But what about the K4? int k3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; freq_t tfreq; retval = kenwood_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { return retval; } retval = kenwood_set_freq(rig, vfo, freq); // if more than 1MHz probably a band change so give it some time // before continuing if (fabs(tfreq - freq) > 1e6) { hl_usleep(200 * 1000); // give 200ms for rig to do band switch if needed } return retval; } int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { char *cmd; int retval; if (ch < 1 || ch > 4) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1<=ch<=4, got %d\n", __func__, ch); return (-RIG_EINVAL); } switch (ch) { case 1: cmd = "SWT21;"; break; case 2: cmd = "SWT31;"; break; case 3: cmd = "SWT35;"; break; case 4: cmd = "SWT39;"; break; } retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } int k3_stop_voice_mem(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "SWT37;", NULL, 0); return retval; } int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char cmd[32]; if (ch < 1 || ch > 8) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1<=ch<=8, got %d\n", __func__, ch); return (-RIG_EINVAL); } sprintf(cmd, "DAMP%d00000;", ch); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } int k4_stop_voice_mem(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "DA0;", NULL, 0); return retval; } int k4_stop_morse(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "KY @;", NULL, 0); return retval; } int k3_stop_morse(RIG *rig, vfo_t vfo) { int retval; char cmd[32]; SNPRINTF(cmd, sizeof(cmd), "KY %c;", 0x04); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } hamlib-4.6.5/rigs/kenwood/thd72.c0000664000175000017500000011417615056640443012174 /* * Hamlib Kenwood TH-D72 backend * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2018 by Brian Lucas * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" // Some commands are very slow to process so we put a DELAY in those places #define DELAY hl_usleep(300*1000) #define THD72_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) #define THD72_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) #define THD72_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_TONE| \ RIG_FUNC_ARO) #define THD72_LEVEL_ALL (RIG_LEVEL_RFPOWER| \ RIG_LEVEL_SQL| \ RIG_LEVEL_BALANCE| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY) #define THD72_PARMS (RIG_PARM_APO| \ RIG_PARM_TIME) #define THD72_VFO_OP (RIG_OP_NONE) #define THD72_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t thd72_mode_table[3] = { [0] = RIG_MODE_FM, /* normal, but narrow compared to broadcast */ [1] = RIG_MODE_FMN, /* what kenwood calls narrow */ [2] = RIG_MODE_AM, }; static pbwidth_t thd72_width_table[3] = { [0] = 10000, // +-5KHz [1] = 5000, // +-2.5KHz [2] = 10000, // what should this be? }; static rptr_shift_t thd72_rshf_table[3] = { [0] = RIG_RPT_SHIFT_NONE, [1] = RIG_RPT_SHIFT_PLUS, [2] = RIG_RPT_SHIFT_MINUS, }; static int thd72tuningstep[11] = { [0] = 5000, [1] = 6250, [2] = 0, // not used in thd72 [3] = 10000, [4] = 12500, [5] = 15000, [6] = 20000, [7] = 25000, [8] = 30000, [9] = 50000, [10] = 100000 }; static int thd72voxdelay[7] = { [0] = 2500, [1] = 5000, [2] = 7500, [3] = 10000, [4] = 15000, [5] = 20000, [6] = 30000 }; static float thd72sqlevel[6] = { [0] = 0.0, /* open */ [1] = 0.2, [2] = 0.4, [3] = 0.6, [4] = 0.8, [5] = 1.0 }; static int thd72apo[4] = { [0] = 0, [1] = 15, [2] = 30, [3] = 60 }; static tone_t thd72dcs_list[105] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; static struct kenwood_priv_caps thd72_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thd72_mode_table, }; int thd72_open(RIG *rig) { int ret; struct kenwood_priv_data *priv = STATE(rig)->priv; strcpy(priv->verify_cmd, "ID\r"); //ret = kenwood_transaction(rig, "", NULL, 0); //DELAY; ret = rig_set_vfo(rig, RIG_VFO_A); return ret; } static int thd72_set_vfo(RIG *rig, vfo_t vfo) { const char *cmd; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd = "BC 0"; STATE(rig)->current_vfo = RIG_VFO_A; break; case RIG_VFO_B: case RIG_VFO_SUB: STATE(rig)->current_vfo = RIG_VFO_B; cmd = "BC 1"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return kenwood_simple_transaction(rig, cmd, 4); } static int thd72_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char vfobuf[16]; const struct kenwood_priv_data *priv = STATE(rig)->priv; char vfonum = '0'; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo == RIG_VFO_B || priv->split) { vfonum = '1'; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC %c", vfonum); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", NULL, 0); } static int thd72_get_vfo(RIG *rig, vfo_t *vfo) { int retval; char c, buf[10]; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length == 4) { c = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; } switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %c\n", __func__, c); return -RIG_EVFO; } return RIG_OK; } static int thd72_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char vfobuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (txvfo != RIG_VFO_B) // Only split with RIG_VFO_B as tx { return -RIG_EINVAL; } /* Set VFO mode */ SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 1,0"); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC 1"); // leave VFOB as selected VFO retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for thd72_set_vfo */ priv->split = split; return RIG_OK; } static int thd72_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 4); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } *split = (buf[3] == buf[5]) ? RIG_SPLIT_OFF : RIG_SPLIT_ON; /* Remember whether split is on, for th_set_vfo */ priv->split = *split; return RIG_OK; } static int thd72_vfoc(RIG *rig, vfo_t vfo, char *vfoc) { rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s\n", __func__, rig_strvfo(vfo)); vfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: *vfoc = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: *vfoc = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return RIG_OK; } static int thd72_get_freq_info(RIG *rig, vfo_t vfo, char *buf) { int retval; char c, cmd[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s\n", __func__, rig_strvfo(vfo)); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "FO %c", c); retval = kenwood_transaction(rig, cmd, buf, 53); return retval; } /* item is an offset into reply buf that is a single char */ static int thd72_get_freq_item(RIG *rig, vfo_t vfo, int item, int hi, int *val) { int retval, lval; char c, buf[64]; retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } c = buf[item]; if (c < '0' || c > '9') { return -RIG_EPROTO; } lval = c - '0'; if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd72_set_freq_item(RIG *rig, vfo_t vfo, int item, int val) { int retval; char buf[64]; retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[item] = val + '0'; return kenwood_simple_transaction(rig, buf, 52); } static int thd72_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; int tsindex; shortfreq_t ts; char buf[64], fbuf[11]; rig_debug(RIG_DEBUG_TRACE, "%s: called, vfo=%s, freq=%f\n", __func__, rig_strvfo(vfo), freq); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } tsindex = buf[16] - '0'; if (buf[16] >= 'A') { tsindex = buf[16] - 'A' + 10; } ts = thd72tuningstep[tsindex]; rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex, (int)ts); freq = roundl(freq / ts) * ts; SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)freq); memcpy(buf + 5, fbuf, 10); retval = kenwood_simple_transaction(rig, buf, 52); return retval; } static int thd72_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; int tsindex; shortfreq_t ts; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } tsindex = buf[16] - '0'; ts = thd72tuningstep[tsindex]; rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex, (int)ts); sscanf(buf + 5, "%"SCNfreq, freq); return RIG_OK; } static int thd72_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int val; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (mode) { case RIG_MODE_FM: val = 0; break; case RIG_MODE_FMN: val = 1; break; case RIG_MODE_AM: val = 2; break; default: return -RIG_EINVAL; } return thd72_set_freq_item(rig, vfo, 51, val); } static int thd72_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval, modeinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 51, 2, &modeinx); if (retval != RIG_OK) { return retval; } *mode = thd72_mode_table[modeinx]; *width = thd72_width_table[modeinx]; return RIG_OK; } static int thd72_set_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rsinx = 0; break; case RIG_RPT_SHIFT_PLUS: rsinx = 1; break; case RIG_RPT_SHIFT_MINUS: rsinx = 2; break; default: return -RIG_EINVAL; } return thd72_set_freq_item(rig, vfo, 18, rsinx); } static int thd72_get_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int retval, rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 18, 3, &rsinx); if (retval != RIG_OK) { return retval; } /* rsinx == 3 indicates split mode? */ *rptr_shift = (rsinx == 3) ? RIG_RPT_SHIFT_NONE : thd72_rshf_table[rsinx]; return RIG_OK; } static int thd72_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { int retval; char boff[9], buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } SNPRINTF(boff, sizeof(boff), "%08ld", offs); memcpy(buf + 42, boff, 8); retval = kenwood_simple_transaction(rig, buf, 52); return retval; } static int thd72_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { int retval; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 42, "%ld", offs); return RIG_OK; } static int thd72_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (tsinx = 0; tsinx < 10; tsinx++) { if (thd72tuningstep[tsinx] >= ts) { thd72_set_freq_item(rig, vfo, 16, tsinx); return RIG_OK; } } return -RIG_EINVAL; } static int thd72_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval, tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 16, 9, &tsinx); if (retval != RIG_OK) { return retval; } *ts = thd72tuningstep[tsinx]; return RIG_OK; } static int thd72_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[22] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 30, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[22] == '0') /* no tone */ { *tone = 0; } else { sscanf(buf + 30, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd72_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int retval, cinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cinx = 0; /* default */ if (code != 0) { for (cinx = 0; cinx < 104; cinx++) { if (code == thd72dcs_list[cinx]) { break; } } if (cinx >= 104) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[26] = (code == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%03d", cinx); memcpy(buf + 36, tmp, 3); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int retval, cinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[26] == '0') /* no tone */ { *code = 0; } else { sscanf(buf + 36, "%d", &cinx); *code = thd72dcs_list[cinx]; } return RIG_OK; } static int thd72_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[24] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 33, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[24] == '0') /* no tsql */ { *tone = 0; } else { sscanf(buf + 33, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd72_get_menu_info(RIG *rig, char *buf) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "MU", buf, 41); if (retval != RIG_OK) { return retval; } if (strlen(buf) != 40) { return -RIG_ERJCTED; } return RIG_OK; } /* each menu item is a single hex digit */ static int thd72_get_menu_item(RIG *rig, int item, int hi, int *val) { int retval, lval; char c, buf[48]; retval = thd72_get_menu_info(rig, buf); if (retval != RIG_OK) { return retval; } c = buf[3 + 2 * item]; /* "MU 0,1,2 ... */ if (c >= '0' && c <= '9') { lval = c - '0'; } else if (c >= 'A' && c <= 'F') { lval = c - 'A' + 10; } else { return -RIG_EPROTO; } if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd72_set_menu_item(RIG *rig, int item, int val) { int retval; char c, buf[48]; retval = thd72_get_menu_info(rig, buf); if (retval != RIG_OK) { return retval; } if (val < 10) { c = val + '0'; } else { c = val - 10 + 'A'; } buf[3 + 2 * item] = c; return kenwood_simple_transaction(rig, buf, 40); } static int thd72_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, lvl; char c, lvlc, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s, level=%s, val=%g\n", __func__, rig_strvfo(vfo), rig_strlevel(level), val.f); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvlc = '2'; } else if (val.f <= 0.10) { lvlc = '1'; } else { lvlc = '0'; } SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_VOXGAIN: return thd72_set_menu_item(rig, 8, (int)(val.f * 10.0 - 0.5)); case RIG_LEVEL_VOXDELAY: if (val.i > 20000) { lvl = 6; } else if (val.i > 10000) { lvl = val.i / 10000 + 3; } else { lvl = val.i / 2500; } return thd72_set_menu_item(rig, 9, lvl); case RIG_LEVEL_SQL: lvlc = '0' + (int)(val.f * 5); SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_BALANCE: /* FIXME - is balance 0.0 .. 1.0 or -1.0 .. 1.0? */ lvl = (int)(val.f * 4.0); return thd72_set_menu_item(rig, 13, lvl); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } static int thd72_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, v, l; char c, cmd[10], buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmd, sizeof(cmd), "PC %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } switch (l) { case 0: val->f = 1.00; break; /* 5.0 W */ case 1: val->f = 0.10; break; /* 500 mW */ case 2: val->f = 0.01; break; /* 50 mW */ } break; case RIG_LEVEL_VOXGAIN: retval = thd72_get_menu_item(rig, 8, 9, &l); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ val->f = l / 9.0; break; case RIG_LEVEL_VOXDELAY: retval = thd72_get_menu_item(rig, 9, 7, &l); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ val->i = thd72voxdelay[l]; break; case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "SQ %d,%d", &v, &l); if (retval != 2 || l < 0 || l >= 6) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } val->f = thd72sqlevel[l]; break; case RIG_LEVEL_BALANCE: retval = thd72_get_menu_item(rig, 13, 4, &l); if (retval != RIG_OK) { return retval; } /* FIXME - is balance 0.0 .. 1.0 or -1.0 .. 1.0? */ val->f = (float)(l) / 4.0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int thd72_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; char c; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_AIP: retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } return thd72_set_menu_item(rig, c == '0' ? 5 : 6, status); case RIG_FUNC_ARO: return thd72_set_menu_item(rig, 18, status); case RIG_FUNC_TONE: return thd72_set_freq_item(rig, vfo, 22, status); case RIG_FUNC_TSQL: return thd72_set_freq_item(rig, vfo, 24, status); default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval, f = -1; char c; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_AIP: retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } retval = thd72_get_menu_item(rig, c == '0' ? 5 : 6, 1, &f); break; case RIG_FUNC_ARO: retval = thd72_get_menu_item(rig, 18, 1, &f); break; case RIG_FUNC_TONE: retval = thd72_get_freq_item(rig, vfo, 22, 1, &f); break; case RIG_FUNC_TSQL: retval = thd72_get_freq_item(rig, vfo, 24, 1, &f); break; default: retval = -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } *status = f; return RIG_OK; } static int thd72_set_parm(RIG *rig, setting_t parm, value_t val) { int l; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_APO: if (val.i == 0) { l = 0; } else if (val.i <= 15) { l = 1; } else if (val.i <= 30) { l = 2; } else { l = 3; } return thd72_set_menu_item(rig, 3, l); case RIG_PARM_TIME: default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, l, hh, mm, ss; char buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_APO: retval = thd72_get_menu_item(rig, 3, 3, &l); if (retval != RIG_OK) { return retval; } val->i = thd72apo[l]; break; case RIG_PARM_TIME: retval = kenwood_transaction(rig, "RT", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 11, "%2d%2d%2d", &hh, &mm, &ss); val->i = ss + 60 * (mm + 60 * hh); break; default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_set_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char c, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c,%03d", c, ch); return kenwood_simple_transaction(rig, cmd, 10); } static int thd72_get_mem(RIG *rig, vfo_t vfo, int *ch) { int retval; char c, cmd[10], buf[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%d", ch); return RIG_OK; } static int thd72_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return -RIG_EINVAL; } static int thd72_parse_channel(int kind, const char *buf, channel_t *chan) { int tmp; int n; char c; const char *data; if (kind == 0) { data = buf + 5; } else { data = buf + 7; } n = sscanf(data, "%"SCNfreq, &chan->freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning %s\n", __func__, data); return -RIG_EPROTO; } c = data[46]; // mode if (c >= '0' && c <= '2') { chan->mode = thd72_mode_table[c - '0']; chan->width = thd72_width_table[c - '0']; } c = data[11]; // tuning step if (c >= '0' && c <= '9') { chan->tuning_step = thd72tuningstep[c - '0']; } c = data[13]; // repeater shift if (c >= '0' && c <= '2') { chan->rptr_shift = thd72_rshf_table[c - '0']; } n = sscanf(data + 37, "%ld", &chan->rptr_offs); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[37]%s\n", __func__, data); return -RIG_EPROTO; } c = data[17]; // Tone status if (c != '0') { n = sscanf(data + 25, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[25]%s\n", __func__, data); return -RIG_EPROTO; } if (tmp > 0 && tmp < 42) { chan->ctcss_tone = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_tone = 0; } c = data[19]; // TSQL status if (c != '0') { n = sscanf(data + 28, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[28]%s\n", __func__, data); return -RIG_EPROTO; } if (tmp > 0 && tmp < 42) { chan->ctcss_sql = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_sql = 0; } c = data[21]; // DCS status if (c != '0') { n = sscanf(data + 31, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[31]%s\n", __func__, data); return -RIG_EPROTO; } chan->dcs_code = tmp; } else { chan->dcs_code = 0; } return RIG_OK; } static int thd72_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; char buf[72]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (chan->vfo == RIG_VFO_MEM) /* memory channel */ { int len; char cmd[16]; SNPRINTF(cmd, sizeof(cmd), "ME %03d", chan->channel_num); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = thd72_parse_channel(1, buf, chan); if (retval != RIG_OK) { return retval; } cmd[1] = 'N'; /* change ME to MN */ retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } len = strlen(buf); memcpy(chan->channel_desc, buf + 7, len - 7); } else /* current channel */ { retval = thd72_get_freq_info(rig, chan->vfo, buf); if (retval != RIG_OK) { return retval; } return thd72_parse_channel(0, buf, chan); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } #ifdef false /* not working */ #define CMD_SZ 5 #define BLOCK_SZ 256 #define BLOCK_COUNT 256 #define CHAN_PER_BLOCK 4 static int thd72_get_block(RIG *rig, int block_num, char *block) { hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; /* fetching block i */ cmd[2] = block_num & 0xff; ret = write_block(rp, cmd, CMD_SZ); if (ret != RIG_OK) { return ret; } /* read response first */ ret = read_block(rp, resp, CMD_SZ); if (ret != CMD_SZ) { return ret; } if (resp[0] != 'W' || memcmp(cmd + 1, resp + 1, CMD_SZ - 1)) { return -RIG_EPROTO; } /* read block */ ret = read_block(rp, block, BLOCK_SZ); if (ret != BLOCK_SZ) { return ret; } ret = write_block(rp, "\006", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } return RIG_OK; } #ifdef XXREMOVEDXX int thd72_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = STATE(rig)->chan_list; int chan_next = chan_list[0].start; char block[BLOCK_SZ]; char resp[CMD_SZ]; ret = kenwood_transaction(rig, "0M PROGRAM", resp, CMD_SZ); if (ret != RIG_OK) { return ret; } if (strlen(resp) != 2 || memcmp(resp, "0M", 2)) { return -RIG_EPROTO; } rp->parm.serial.rate = 57600; serial_setup(rp); hl_usleep(100 * 1000); /* let the pcr settle */ rig_flush(rp); /* flush any remaining data */ ret = ser_set_rts(rp, 1); /* setRTS or Hardware flow control? */ if (ret != RIG_OK) { return ret; } /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; ret = chan_cb(rig, &chan, chan_next, chan_list, arg); if (ret != RIG_OK) { return ret; } if (chan == NULL) { return -RIG_ENOMEM; } for (i = 0; i < BLOCK_COUNT; i++) { ret = thd72_get_block(rig, i, block); if (ret != RIG_OK) { return ret; } /* * Most probably, there's 64 bytes per channel (256*256 / 1000+) */ for (j = 0; j < CHAN_PER_BLOCK; j++) { const char *block_chan = block + j * (BLOCK_SZ / CHAN_PER_BLOCK); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; chan->channel_num = i * CHAN_PER_BLOCK + j; /* What are the extra 64 channels ? */ if (chan->channel_num >= 1000) { break; } /* non-empty channel ? */ // if (block_chan[0] != 0xff) { // since block_chan is *signed* char, this maps to -1 if (block_chan[0] != -1) { memcpy(chan->channel_desc, block_chan, 8); /* TODO: chop off trailing chars */ chan->channel_desc[8] = '\0'; /* TODO: parse block and fill in chan */ } /* notify the end? */ chan_next = chan_next < chan_list[i].end ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, &chan, chan_next, chan_list, arg); } } ret = write_block(rp, "E", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } /* setRTS?? getCTS needed? */ ret = ser_set_rts(rp, 1); if (ret != RIG_OK) { return ret; } return RIG_OK; } #endif #endif /* none working stuff */ /* * th-d72a rig capabilities. */ struct rig_caps thd72a_caps = { RIG_MODEL(RIG_MODEL_THD72A), .model_name = "TH-D72A", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .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_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THD72_FUNC_ALL, .has_set_func = THD72_FUNC_ALL, .has_get_level = THD72_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD72_LEVEL_ALL), .has_get_parm = THD72_PARMS, .has_set_parm = THD72_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = kenwood42_ctcss_list, .dcs_list = thd72dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THD72_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, /* TBC */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* TBC MEM */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THD72_MODES, -1, -1, THD72_VFO}, {MHz(320), MHz(524), THD72_MODES, -1, -1, THD72_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), THD72_MODES_TX, W(0.05), W(5), THD72_VFO}, {MHz(430), MHz(440), THD72_MODES_TX, W(0.05), W(5), THD72_VFO}, RIG_FRNG_END, }, .tuning_steps = { {THD72_MODES, kHz(5)}, {THD72_MODES, kHz(6.25)}, {THD72_MODES, kHz(8.33)}, {THD72_MODES, kHz(10)}, {THD72_MODES, kHz(12.5)}, {THD72_MODES, kHz(15)}, {THD72_MODES, kHz(20)}, {THD72_MODES, kHz(25)}, {THD72_MODES, kHz(30)}, {THD72_MODES, kHz(50)}, RIG_TS_END, }, .filters = { /* mode/filter list, remember: order matters! */ {RIG_MODE_FM, kHz(14)}, {RIG_MODE_FMN, kHz(7)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd72_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = thd72_open, .set_freq = thd72_set_freq, .get_freq = thd72_get_freq, .set_mode = thd72_set_mode, .get_mode = thd72_get_mode, .set_vfo = thd72_set_vfo, .get_vfo = thd72_get_vfo, .set_ptt = thd72_set_ptt, .set_split_vfo = thd72_set_split_vfo, .get_split_vfo = thd72_get_split_vfo, .set_rptr_shift = thd72_set_rptr_shft, .get_rptr_shift = thd72_get_rptr_shft, .set_rptr_offs = thd72_set_rptr_offs, .get_rptr_offs = thd72_get_rptr_offs, .set_ts = thd72_set_ts, .get_ts = thd72_get_ts, .set_ctcss_tone = thd72_set_ctcss_tone, .get_ctcss_tone = thd72_get_ctcss_tone, .set_dcs_code = thd72_set_dcs_code, .get_dcs_code = thd72_get_dcs_code, .set_ctcss_sql = thd72_set_ctcss_sql, .get_ctcss_sql = thd72_get_ctcss_sql, .set_level = thd72_set_level, .get_level = thd72_get_level, .set_func = thd72_set_func, .get_func = thd72_get_func, .set_parm = thd72_set_parm, .get_parm = thd72_get_parm, .set_mem = thd72_set_mem, .get_mem = thd72_get_mem, .set_channel = thd72_set_channel, .get_channel = thd72_get_channel, //.get_chan_all_cb = thd72_get_chan_all_cb, this doesn't work yet .get_info = th_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts450s.c0000664000175000017500000002163415056640443012302 /* * Hamlib Kenwood backend - TS450S description * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "bandplan.h" #define TS450S_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS450S_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS450S_AM_TX_MODES RIG_MODE_AM #define TS450S_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_AIP|RIG_FUNC_TONE) #define TS450S_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_CWPITCH|RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define TS450S_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS450S_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS450S_SCAN_OPS (RIG_SCAN_VFO) #define TS450S_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps ts450_priv_caps = { .cmdtrm = EOM_KEN, }; static const struct confparams ts450_ext_parms[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; int ts450_open(RIG *rig) { int err; int maxtries; err = kenwood_open(rig); if (err != RIG_OK) { return err; } maxtries = RIGPORT(rig)->retry; /* no retry for this command that may be missing */ RIGPORT(rig)->retry = 0; err = kenwood_simple_transaction(rig, "TO", 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tone unit not detected\n", __func__); STATE(rig)->has_set_func &= ~RIG_FUNC_TONE; STATE(rig)->has_get_func &= ~RIG_FUNC_TONE; } RIGPORT(rig)->retry = maxtries; return RIG_OK; } /* * ts450s rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range 9.99 kHz * * TODO: protocol to be checked with manual (identical to TS690) * - get_channel/set_channel: MR/MW * - how to set_split in vfo mode? * - ... * * specs: http://www.qsl.net/sm7vhs/radio/kenwood/ts450/specs.htm * infos comes from http://www.cnham.com/ts450/ts_450_ex_control.pdf */ struct rig_caps ts450s_caps = { RIG_MODEL(RIG_MODEL_TS450S), .model_name = "TS-450S", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 10, .timeout = 1000, .retry = 10, .has_get_func = TS450S_FUNC_ALL, .has_set_func = TS450S_FUNC_ALL, .has_get_level = TS450S_LEVEL_ALL | RIG_LEVEL_RFPOWER, .has_set_level = RIG_LEVEL_SET(TS450S_LEVEL_ALL), .has_get_parm = 0, .has_set_parm = 0, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .extparms = ts450_ext_parms, .ctcss_list = NULL, /* hw dip-switch */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* can't be controlled */ .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TS450S_VFO_OPS, .scan_ops = TS450S_SCAN_OPS, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS450S_CHANNEL_CAPS }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE, TS450S_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(500), MHz(30), TS450S_ALL_MODES, -1, -1, TS450S_VFO }, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS450S_OTHER_TX_MODES, W(5), W(100), TS450S_VFO, 0), FRQ_RNG_HF(1, TS450S_AM_TX_MODES, W(2), W(40), TS450S_VFO, 0), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS450S_ALL_MODES, -1, -1, TS450S_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, /* 40W class */ {kHz(3500), MHz(4) - 1, TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(3500), MHz(4) - 1, TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(7), kHz(7300), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(7), kHz(7300), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(10100), kHz(10150), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(10100), kHz(10150), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(14), kHz(14350), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(14), kHz(14350), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(18068), kHz(18168), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(18068), kHz(18168), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(21), kHz(21450), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(21), kHz(21450), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(24890), kHz(24990), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(24890), kHz(24990), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(28), kHz(29700), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(28), kHz(29700), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { { TS450S_ALL_MODES, 1 }, { TS450S_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12) }, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, Hz(500)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(6)}, RIG_FLT_END, }, .priv = (void *)& ts450_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = ts450_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .scan = kenwood_scan, .get_channel = kenwood_get_channel, .set_channel = kenwood_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts711.c0000664000175000017500000001360615056640443012117 /* * Hamlib Kenwood backend - TS-711 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS711_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* func and levels to be checked */ #define TS711_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define TS711_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS711_VFO (RIG_VFO_A|RIG_VFO_B) #define TS711_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS711_SCAN_OP (RIG_SCAN_VFO) /* * There are some platform differences: * * + Tone on/off isn't applicable to "kenwood" versions of the E rigs * + Tone frequency is only A/B rigs * + Offset is only TS-811A, TS-811B, TS-811E, TS-711A, TS-711E. * * So maybe this should have a separate set of backends for each * rig variation because of the frequency range differences, capability * differences, etc, etc. */ static struct kenwood_priv_caps ts711_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' /* Note: The 140/680/711/811 need this to set the VFO on the radio */ static int ts711_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts711 rig capabilities. */ struct rig_caps ts711_caps = { RIG_MODEL(RIG_MODEL_TS711), .model_name = "TS-711", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = TS711_FUNC_ALL, .has_set_func = TS711_FUNC_ALL, .has_get_level = TS711_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS711_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .vfo_ops = TS711_VFO_OP, .scan_ops = TS711_SCAN_OP, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(9.9), .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* FIXME: split memories, call channel, etc. */ .chan_list = { { 1, 59, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), TS711_ALL_MODES, -1, -1, TS711_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TS711_ALL_MODES, W(5), W(25), TS711_VFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(144), MHz(148), TS711_ALL_MODES, -1, -1, TS711_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TS711_ALL_MODES, W(5), W(25), TS711_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS711_ALL_MODES, 50}, {TS711_ALL_MODES, 100}, {TS711_ALL_MODES, kHz(1)}, {TS711_ALL_MODES, kHz(5)}, {TS711_ALL_MODES, kHz(9)}, {TS711_ALL_MODES, kHz(10)}, {TS711_ALL_MODES, 12500}, {TS711_ALL_MODES, kHz(20)}, {TS711_ALL_MODES, kHz(25)}, {TS711_ALL_MODES, kHz(100)}, {TS711_ALL_MODES, MHz(1)}, {TS711_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts711_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts711_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/tmd710.c0000664000175000017500000022214515056640443012254 /* * Hamlib Kenwood backend - TM-D710(G) description * Copyright (c) 2011 by Charles Suprin * Copyright (c) 2018 Mikael Nousiainen * * Command set specification available in: * - https://github.com/LA3QMA/TM-V71_TM-D710-Kenwood * - http://kd7dvd.us/equipment/tm-d710a/manuals/control_commands.pdf * * Limitations: * - It is possible to set frequency only inside the selected frequency band of the current VFO, * since there is no command to change the frequency band of a VFO * * Features not yet implemented: * - DTMF send * - Tone burst frequency setting * - Call channel settings * - Change between dual-band/single-band mode * - Several miscellaneous settings available via the MU menu command, which could be exposed via extparms/extlevels * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "tones.h" #include "num_stdio.h" static int tmd710_open(RIG *rig); static int tmd710_do_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_do_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_set_vfo(RIG *rig, vfo_t vfo); static int tmd710_get_vfo(RIG *rig, vfo_t *vfo); static int tmd710_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); static int tmd710_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); static int tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift); static int tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offset); static int tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offset); static int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch); static int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch); static int tmd710_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int tmd710_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); static int tmd710_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int tmd710_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val); static int tmd710_set_parm(RIG *rig, setting_t parm, value_t val); static int tmd710_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); static int tmd710_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); #define TMD710_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) #define TMD710_MODES_FM (RIG_MODE_FM|RIG_MODE_FMN) #define TMD710_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) #define TMD710_FUNC_GET (RIG_FUNC_TSQL| \ RIG_FUNC_TONE| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO| \ RIG_FUNC_AIP| \ RIG_FUNC_RESUME) #define TMD710_FUNC_SET (RIG_FUNC_TSQL| \ RIG_FUNC_TONE| \ RIG_FUNC_TBURST| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO| \ RIG_FUNC_AIP| \ RIG_FUNC_RESUME) #define TMD710_LEVEL_ALL (RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER) #define TMD710_PARMS (RIG_PARM_BACKLIGHT|\ RIG_PARM_BEEP|\ RIG_PARM_APO) #define TMD710_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TMD710_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define TMD710_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, #define TOKEN_BACKEND(t) (t) #define TOK_LEVEL_EXT_DATA_BAND TOKEN_BACKEND(100) // TM-D710 protocol definitions #define TMD710_BAND_A 0 #define TMD710_BAND_B 1 #define TMD710_BAND_MODE_VFO 0 #define TMD710_BAND_MODE_MEMORY 1 #define TMD710_BAND_MODE_CALL 2 #define TMD710_BAND_MODE_WX 3 #define TMD710_RF_POWER_MIN 0 #define TMD710_RF_POWER_MAX 2 #define TMD710_SQL_MIN 0 #define TMD710_SQL_MAX 0x1F // TM-D710 MU command value tables #define TMD710_ANNOUNCE_OFF 0 #define TMD710_ANNOUNCE_AUTO 1 #define TMD710_ANNOUNCE_MANUAL 2 #define TMD710_LANGUAGE_ENGLISH 0 #define TMD710_LANGUAGE_JAPANESE 1 #define TMD710_SMETER_HANG_UP_TIME_OFF 0 #define TMD710_SMETER_HANG_UP_TIME_125 1 #define TMD710_SMETER_HANG_UP_TIME_250 2 #define TMD710_SMETER_HANG_UP_TIME_500 3 #define TMD710_MUTE_HANG_UP_TIME_OFF 0 #define TMD710_MUTE_HANG_UP_TIME_125 1 #define TMD710_MUTE_HANG_UP_TIME_250 2 #define TMD710_MUTE_HANG_UP_TIME_500 3 #define TMD710_MUTE_HANG_UP_TIME_750 4 #define TMD710_MUTE_HANG_UP_TIME_1000 5 #define TMD710_TIMEOUT_TIMER_3MIN 0 #define TMD710_TIMEOUT_TIMER_5MIN 1 #define TMD710_TIMEOUT_TIMER_10MIN 2 #define TMD710_RECALL_METHOD_ALL 0 #define TMD710_RECALL_METHOD_CURRENT 1 #define TMD710_ECHOLINK_SPEED_FAST 0 #define TMD710_ECHOLINK_SPEED_SLOW 1 #define TMD710_DTMF_SPEED_FAST 0 #define TMD710_DTMF_SPEED_SLOW 1 #define TMD710_DTMF_PAUSE_100 0 #define TMD710_DTMF_PAUSE_250 1 #define TMD710_DTMF_PAUSE_500 2 #define TMD710_DTMF_PAUSE_750 3 #define TMD710_DTMF_PAUSE_1000 4 #define TMD710_DTMF_PAUSE_1500 5 #define TMD710_DTMF_PAUSE_2000 6 #define TMD710_BACKLIGHT_COLOR_AMBER 0 #define TMD710_BACKLIGHT_COLOR_GREEN 1 #define TMD710_SCAN_RESUME_TIME 0 #define TMD710_SCAN_RESUME_CARRIER 1 #define TMD710_SCAN_RESUME_SEEK 2 #define TMD710_AUTO_POWER_OFF_OFF 0 #define TMD710_AUTO_POWER_OFF_30MIN 1 #define TMD710_AUTO_POWER_OFF_60MIN 2 #define TMD710_AUTO_POWER_OFF_90MIN 3 #define TMD710_AUTO_POWER_OFF_120MIN 4 #define TMD710_AUTO_POWER_OFF_180MIN 5 #define TMD710_EXT_DATA_BAND_A 0 #define TMD710_EXT_DATA_BAND_B 1 #define TMD710_EXT_DATA_BAND_TXA_RXB 2 #define TMD710_EXT_DATA_BAND_TXB_RXA 3 #define TMD710_EXT_DATA_SPEED_1200 0 #define TMD710_EXT_DATA_SPEED_9600 1 #define TMD710_SQC_SOURCE_OFF 0 #define TMD710_SQC_SOURCE_BUSY 1 #define TMD710_SQC_SOURCE_SQL 2 #define TMD710_SQC_SOURCE_TX 3 #define TMD710_SQC_SOURCE_BUSY_OR_TX 4 #define TMD710_SQC_SOURCE_SQL_OR_TX 5 static rmode_t tmd710_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_FMN, [2] = RIG_MODE_AM, }; static struct kenwood_priv_caps tmd710_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = tmd710_mode_table, }; /* Private TM-D710 extra levels definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams tmd710_ext_levels[] = { { TOK_LEVEL_EXT_DATA_BAND, "EXTDATABAND", "External data band", "External data band", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "A", "B", "TXA-RXB", "TXB-RXA", NULL } } } }, { RIG_CONF_END, NULL, } }; struct rig_caps tmd710_caps = { RIG_MODEL(RIG_MODEL_TMD710), .model_name = "TM-D710(G)", .mfg_name = "Kenwood", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = TMD710_FUNC_GET, .has_set_func = TMD710_FUNC_SET, .has_get_level = TMD710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), .has_get_parm = TMD710_PARMS, .has_set_parm = TMD710_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood42_ctcss_list, .dcs_list = common_dcs_list, .preamp = {RIG_DBLST_END,}, .attenuator = {RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD710_VFO_OP, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { {0, 199, RIG_MTYPE_MEM, {TMD710_CHANNEL_CAPS}}, /* normal MEM */ {200, 219, RIG_MTYPE_EDGE, {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ {221, 222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(440), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(450), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD710_MODES, kHz(5)}, {TMD710_MODES, kHz(6.25)}, {TMD710_MODES, kHz(8.33)}, {TMD710_MODES, kHz(10)}, {TMD710_MODES, kHz(12.5)}, {TMD710_MODES, kHz(15)}, {TMD710_MODES, kHz(20)}, {TMD710_MODES, kHz(25)}, {TMD710_MODES, kHz(30)}, {TMD710_MODES, kHz(50)}, {TMD710_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FMN, kHz(5)}, {RIG_MODE_AM, kHz(4)}, RIG_FLT_END, }, .priv = (void *)& tmd710_priv_caps, .rig_init = kenwood_init, .rig_open = tmd710_open, .rig_cleanup = kenwood_cleanup, .set_freq = tmd710_set_freq, .get_freq = tmd710_get_freq, .set_split_freq = tmd710_set_split_freq, .get_split_freq = tmd710_get_split_freq, .set_mode = tmd710_set_mode, .get_mode = tmd710_get_mode, .set_vfo = tmd710_set_vfo, .get_vfo = tmd710_get_vfo, .set_ts = tmd710_set_ts, .get_ts = tmd710_get_ts, .set_ctcss_tone = tmd710_set_ctcss_tone, .get_ctcss_tone = tmd710_get_ctcss_tone, .set_ctcss_sql = tmd710_set_ctcss_sql, .get_ctcss_sql = tmd710_get_ctcss_sql, .set_split_vfo = tmd710_set_split_vfo, .get_split_vfo = tmd710_get_split_vfo, .set_dcs_sql = tmd710_set_dcs_sql, .get_dcs_sql = tmd710_get_dcs_sql, .set_mem = tmd710_set_mem, .get_mem = tmd710_get_mem, .set_channel = tmd710_set_channel, .get_channel = tmd710_get_channel, //.set_trn = th_set_trn, //.get_trn = th_get_trn, .set_func = tmd710_set_func, .get_func = tmd710_get_func, .set_level = tmd710_set_level, .get_level = tmd710_get_level, .set_parm = tmd710_set_parm, .get_parm = tmd710_get_parm, //.get_info = th_get_info, .get_dcd = tmd710_get_dcd, .set_ptt = tmd710_set_ptt, .vfo_op = tmd710_vfo_op, //.scan = th_scan, .set_ext_level = tmd710_set_ext_level, .get_ext_level = tmd710_get_ext_level, .extlevels = tmd710_ext_levels, .set_rptr_shift = tmd710_set_rptr_shift, .get_rptr_shift = tmd710_get_rptr_shift, .set_rptr_offs = tmd710_set_rptr_offs, .get_rptr_offs = tmd710_get_rptr_offs, .decode_event = th_decode_event, }; struct rig_caps tmv71_caps = { RIG_MODEL(RIG_MODEL_TMV71), .model_name = "TM-V71(A)", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = TMD710_FUNC_GET, .has_set_func = TMD710_FUNC_SET, .has_get_level = TMD710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), .has_get_parm = TMD710_PARMS, .has_set_parm = TMD710_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood42_ctcss_list, .dcs_list = common_dcs_list, .preamp = {RIG_DBLST_END,}, .attenuator = {RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD710_VFO_OP, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { {0, 199, RIG_MTYPE_MEM, {TMD710_CHANNEL_CAPS}}, /* normal MEM */ {200, 219, RIG_MTYPE_EDGE, {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ {221, 222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(440), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(450), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD710_MODES, kHz(5)}, {TMD710_MODES, kHz(6.25)}, {TMD710_MODES, kHz(8.33)}, {TMD710_MODES, kHz(10)}, {TMD710_MODES, kHz(12.5)}, {TMD710_MODES, kHz(15)}, {TMD710_MODES, kHz(20)}, {TMD710_MODES, kHz(25)}, {TMD710_MODES, kHz(30)}, {TMD710_MODES, kHz(50)}, {TMD710_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FMN, kHz(5)}, {RIG_MODE_AM, kHz(4)}, RIG_FLT_END, }, .priv = (void *)& tmd710_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = tmd710_set_freq, .get_freq = tmd710_get_freq, .set_mode = tmd710_set_mode, .get_mode = tmd710_get_mode, .set_vfo = tmd710_set_vfo, .get_vfo = tmd710_get_vfo, .set_ts = tmd710_set_ts, .get_ts = tmd710_get_ts, .set_ctcss_tone = tmd710_set_ctcss_tone, .get_ctcss_tone = tmd710_get_ctcss_tone, .set_ctcss_sql = tmd710_set_ctcss_sql, .get_ctcss_sql = tmd710_get_ctcss_sql, //.set_split_vfo = th_set_split_vfo, //.get_split_vfo = th_get_split_vfo, .set_dcs_sql = tmd710_set_dcs_sql, .get_dcs_sql = tmd710_get_dcs_sql, .set_mem = tmd710_set_mem, .get_mem = tmd710_get_mem, .set_channel = tmd710_set_channel, .get_channel = tmd710_get_channel, //.set_trn = th_set_trn, //.get_trn = th_get_trn, .set_func = tmd710_set_func, .get_func = tmd710_get_func, .set_level = tmd710_set_level, .get_level = tmd710_get_level, .set_parm = tmd710_set_parm, .get_parm = tmd710_get_parm, //.get_info = th_get_info, .get_dcd = tmd710_get_dcd, .set_ptt = tmd710_set_ptt, .vfo_op = tmd710_vfo_op, //.scan = th_scan, .set_ext_level = tmd710_set_ext_level, .get_ext_level = tmd710_get_ext_level, .extlevels = tmd710_ext_levels, .set_rptr_shift = tmd710_set_rptr_shift, .get_rptr_shift = tmd710_get_rptr_shift, .set_rptr_offs = tmd710_set_rptr_offs, .get_rptr_offs = tmd710_get_rptr_offs, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* structure for handling FO radio command */ typedef struct { int vfo; // P1 freq_t freq; // P2 int step; // P3 int shift; // P4 int reverse; // P5 int tone; // P6 int ct; // P7 int dcs; // P8 int tone_freq; // P9 int ct_freq; // P10 int dcs_val; // P11 int offset; // P12 int mode; // P13 } tmd710_fo; /* structure for handling ME radio command */ typedef struct { int channel; // P1 freq_t freq; // P2 int step; // P3 int shift; // P4 int reverse; // P5 int tone; // P6 int ct; // P7 int dcs; // P8 int tone_freq; // P9 int ct_freq; // P10 int dcs_val; // P11 int offset; // P12 int mode; // P13 freq_t tx_freq; // P14 int p15_unknown; // P15 int lockout; // P16 } tmd710_me; /* structure for handling MU (menu) radio command */ typedef struct { int beep; // P1 0/1 int beep_volume; // P2 (1-7) int ext_speaker_mode; // P3 int announce; // P4 int language; // P5 int voice_volume; // P6 (0-7) int voice_speed; // P7 (0-4) int playback_repeat; // P8 0/1 int playback_repeat_interval; // P9 (00-60) int continuous_recording; // P10 0/1 int vhf_aip; // P11 0/1 int uhf_aip; // P12 0/1 int smeter_sql_hang_up_time; // P13 int mute_hang_up_time; // P14 int beat_shift; // P15 0/1 int timeout_timer; // P16 int recall_method; // P17 int echolink_speed; // P18 int dtmf_hold; // P19 0/1 int dtmf_speed; // P20 int dtmf_pause; // P21 int dtmf_key_lock; // P22 0/1 int auto_repeater_offset; // P23 0/1 int tone_1750_tx_hold; // P24 0/1 int p25_unknown; // TODO int brightness_level; // P26 (0-8) int auto_brightness; // P27 0/1 int backlight_color; // P28 int pf1_key; // P29 int pf2_key; // P30 int mic_pf1_key; // P31 int mic_pf2_key; // P32 int mic_pf3_key; // P33 int mic_pf4_key; // P34 int mic_key_lock; // P35 0/1 int scan_resume; // P36 int auto_power_off; // P37 int ext_data_band; // P38 int ext_data_speed; // P39 int sqc_source; // P40 int auto_pm_store; // P41 0/1 int display_partition_bar; // P42 0/1 } tmd710_mu; static int tmd710_open(RIG *rig) { split_t split; vfo_t vfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); STATE(rig)->tx_vfo = RIG_VFO_A; // Get current RX and TX VFO state, do not care if we succeed or not tmd710_get_vfo(rig, &vfo); tmd710_get_split_vfo(rig, RIG_VFO_CURR, &split, &vfo); rig_debug(RIG_DEBUG_TRACE, "STATE(rig)->tx_vfo: %s\n", rig_strvfo(STATE(rig)->tx_vfo)); return 0; } static int tmd710_get_vfo_num(RIG *rig, int *vfonum, vfo_t *vfo) { char buf[10]; int retval, ctrlnum, pttnum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "BC %d,%d", &ctrlnum, &pttnum); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'BC c,p'\n", buf); return -RIG_EPROTO; } switch (ctrlnum) { case TMD710_BAND_A: if (vfo != NULL) { *vfo = RIG_VFO_A; } break; case TMD710_BAND_B: if (vfo != NULL) { *vfo = RIG_VFO_B; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); return -RIG_EVFO; } if (vfonum != NULL) { *vfonum = ctrlnum; } return RIG_OK; } static int tmd710_get_vfo_and_mode(RIG *rig, vfo_t *vfo, int *vfomode) { char cmdbuf[10], buf[10]; int retval, vfonum, vfomodenum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = tmd710_get_vfo_num(rig, &vfonum, vfo); if (retval != RIG_OK) { return retval; } /* Get mode of the VFO band */ snprintf(cmdbuf, sizeof(cmdbuf), "VM %d", vfonum); retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 6); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "VM %d,%d", &vfonum, &vfomodenum); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'VM c,m'\n", buf); return -RIG_EPROTO; } if (vfomode != NULL) { *vfomode = vfomodenum; } return RIG_OK; } static int tmd710_resolve_vfo(RIG *rig, vfo_t vfo, vfo_t *resolved_vfo, int *resolved_vfonum) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_MEM: return tmd710_get_vfo_num(rig, resolved_vfonum, resolved_vfo); case RIG_VFO_A: if (resolved_vfo != NULL) { *resolved_vfo = RIG_VFO_A; } if (resolved_vfonum != NULL) { *resolved_vfonum = TMD710_BAND_A; } break; case RIG_VFO_B: if (resolved_vfo != NULL) { *resolved_vfo = RIG_VFO_B; } if (resolved_vfonum != NULL) { *resolved_vfonum = TMD710_BAND_B; } break; default: return -RIG_ENTARGET; } return RIG_OK; } static int tmd710_scan_me(char *buf, tmd710_me *me_struct) { int retval; retval = num_sscanf(buf, "ME %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d", (unsigned int *)&me_struct->channel, &me_struct->freq, (unsigned int *)&me_struct->step, (unsigned int *)&me_struct->shift, (unsigned int *)&me_struct->reverse, (unsigned int *)&me_struct->tone, (unsigned int *)&me_struct->ct, (unsigned int *)&me_struct->dcs, &me_struct->tone_freq, &me_struct->ct_freq, &me_struct->dcs_val, &me_struct->offset, &me_struct->mode, &me_struct->tx_freq, &me_struct->p15_unknown, &me_struct->lockout); if (retval != 16) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } /* * The TM-D710(G) has a single command ME that queries and sets many values. * This function pulls that string from the radio given a memory channel. * Push/pull naming is used inside the backend rather than get/set. * There is one unknown field. */ int tmd710_pull_me(RIG *rig, int ch, tmd710_me *me_struct) { char cmdbuf[8]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d", ch); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_me(buf, me_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tmd710_push_me(RIG *rig, const tmd710_me *me_struct) { char cmdbuf[80]; char buf[80]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d,%010.0f,%1d,%1d", me_struct->channel, me_struct->freq, me_struct->step, me_struct->shift, me_struct->reverse, me_struct->tone, me_struct->ct, me_struct->dcs, me_struct->tone_freq, me_struct->ct_freq, me_struct->dcs_val, me_struct->offset, me_struct->mode, me_struct->tx_freq, me_struct->p15_unknown, me_struct->lockout); return kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); } int tmd710_get_memory_name(RIG *rig, int ch, char *name) { char cmdbuf[8]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d\n", __func__, ch); snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d", ch); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "MN %d,%30s", &ch, name); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_set_memory_name(RIG *rig, int ch, char *name) { char cmdbuf[32]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d with name %s\n", __func__, ch, name); snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d,%s", ch, name); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * The TM-D710(G) has a single command FO that queries and sets many values. * This function pulls that string from the radio given a VFO. * Push/pull language is used inside the backend rather than get/set. */ int tmd710_pull_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) { char cmdbuf[8]; char buf[80]; int vfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called with VFO %08X\n", __func__, vfo); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d", vfonum); retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", (unsigned int *)&fo_struct->vfo, &fo_struct->freq, (unsigned int *)&fo_struct->step, (unsigned int *)&fo_struct->shift, (unsigned int *)&fo_struct->reverse, (unsigned int *)&fo_struct->tone, (unsigned int *)&fo_struct->ct, (unsigned int *)&fo_struct->dcs, &fo_struct->tone_freq, &fo_struct->ct_freq, &fo_struct->dcs_val, &fo_struct->offset, &fo_struct->mode); if (retval != 13) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_push_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) { char cmdbuf[80]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d", fo_struct->vfo, fo_struct->freq, fo_struct->step, fo_struct->shift, fo_struct->reverse, fo_struct->tone, fo_struct->ct, fo_struct->dcs, fo_struct->tone_freq, fo_struct->ct_freq, fo_struct->dcs_val, fo_struct->offset, fo_struct->mode); retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", (unsigned int *)&fo_struct->vfo, &fo_struct->freq, (unsigned int *)&fo_struct->step, (unsigned int *)&fo_struct->shift, (unsigned int *)&fo_struct->reverse, (unsigned int *)&fo_struct->tone, (unsigned int *)&fo_struct->ct, (unsigned int *)&fo_struct->dcs, &fo_struct->tone_freq, &fo_struct->ct_freq, &fo_struct->dcs_val, &fo_struct->offset, &fo_struct->mode); if (retval != 13) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_scan_mu(char *buf, tmd710_mu *mu_struct) { int retval; retval = num_sscanf(buf, "MU %d,%d,%d,%d,%d,%d,%d,%d,%d,%d," "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," "%d,%d,%d,%d,%d,%d,%d,%d,%X,%X," "%X,%X,%X,%X,%d,%d,%d,%d,%d,%d," "%d,%d", &mu_struct->beep, &mu_struct->beep_volume, &mu_struct->ext_speaker_mode, &mu_struct->announce, &mu_struct->language, &mu_struct->voice_volume, &mu_struct->voice_speed, &mu_struct->playback_repeat, &mu_struct->playback_repeat_interval, &mu_struct->continuous_recording, &mu_struct->vhf_aip, &mu_struct->uhf_aip, &mu_struct->smeter_sql_hang_up_time, &mu_struct->mute_hang_up_time, &mu_struct->beat_shift, &mu_struct->timeout_timer, &mu_struct->recall_method, &mu_struct->echolink_speed, &mu_struct->dtmf_hold, &mu_struct->dtmf_speed, &mu_struct->dtmf_pause, &mu_struct->dtmf_key_lock, &mu_struct->auto_repeater_offset, &mu_struct->tone_1750_tx_hold, &mu_struct->p25_unknown, &mu_struct->brightness_level, &mu_struct->auto_brightness, &mu_struct->backlight_color, (unsigned int *)&mu_struct->pf1_key, (unsigned int *)&mu_struct->pf2_key, (unsigned int *)&mu_struct->mic_pf1_key, (unsigned int *)&mu_struct->mic_pf2_key, (unsigned int *)&mu_struct->mic_pf3_key, (unsigned int *)&mu_struct->mic_pf4_key, &mu_struct->mic_key_lock, &mu_struct->scan_resume, &mu_struct->auto_power_off, &mu_struct->ext_data_band, &mu_struct->ext_data_speed, &mu_struct->sqc_source, &mu_struct->auto_pm_store, &mu_struct->display_partition_bar ); if (retval != 42) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_pull_mu(RIG *rig, tmd710_mu *mu_struct) { char buf[128]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "MU", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_mu(buf, mu_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tmd710_push_mu(RIG *rig, tmd710_mu *mu_struct) { char cmdbuf[128]; char buf[128]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // we reuse fo_struct->vfo for the channel# snprintf(cmdbuf, sizeof(cmdbuf), "MU %1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%1d," "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d," "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02X,%02X," "%02X,%02X,%02X,%02X,%1d,%1d,%1d,%1d,%1d,%1d," "%1d,%1d", mu_struct->beep, mu_struct->beep_volume, mu_struct->ext_speaker_mode, mu_struct->announce, mu_struct->language, mu_struct->voice_volume, mu_struct->voice_speed, mu_struct->playback_repeat, mu_struct->playback_repeat_interval, mu_struct->continuous_recording, mu_struct->vhf_aip, mu_struct->uhf_aip, mu_struct->smeter_sql_hang_up_time, mu_struct->mute_hang_up_time, mu_struct->beat_shift, mu_struct->timeout_timer, mu_struct->recall_method, mu_struct->echolink_speed, mu_struct->dtmf_hold, mu_struct->dtmf_speed, mu_struct->dtmf_pause, mu_struct->dtmf_key_lock, mu_struct->auto_repeater_offset, mu_struct->tone_1750_tx_hold, mu_struct->p25_unknown, mu_struct->brightness_level, mu_struct->auto_brightness, mu_struct->backlight_color, mu_struct->pf1_key, mu_struct->pf2_key, mu_struct->mic_pf1_key, mu_struct->mic_pf2_key, mu_struct->mic_pf3_key, mu_struct->mic_pf4_key, mu_struct->mic_key_lock, mu_struct->scan_resume, mu_struct->auto_power_off, mu_struct->ext_data_band, mu_struct->ext_data_speed, mu_struct->sqc_source, mu_struct->auto_pm_store, mu_struct->display_partition_bar ); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_mu(buf, mu_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_freq * Assumes rig!=NULL * Common function for getting the main and split frequency. */ int tmd710_do_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; tmd710_fo fo_struct; long freq5, freq625, freq_sent; int step; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (fabs(freq5 - freq) < fabs(freq625 - freq)) { step = 0; freq_sent = freq5; } else { step = 1; freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ fo_struct.step = freq_sent >= MHz(470) ? 4 : step; fo_struct.freq = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; //return tmd710_push_fo(rig, vfo, &fo_struct); return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_do_get_freq * Assumes rig!=NULL, freq!=NULL * Common function for getting the main and split frequency. */ int tmd710_do_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called for vfo: %s(%u)\n", __func__, rig_strvfo(vfo), vfo); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *freq = fo_struct.freq; } return retval; } /* * tmd710_set_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called for vfo: %s(%u)\n", __func__, rig_strvfo(vfo), vfo); return tmd710_do_set_freq(rig, vfo, freq); } /* * tmd710_get_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return tmd710_do_get_freq(rig, vfo, freq); } /* * tmd710_set_split_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // Use the TX VFO for split return tmd710_do_set_freq(rig, STATE(rig)->tx_vfo, freq); } /* * tmd710_get_split_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // Use the TX VFO for split return tmd710_do_get_freq(rig, STATE(rig)->tx_vfo, freq); } static int tmd710_find_ctcss_index(RIG *rig, tone_t tone, int *ctcss_index) { int k, stepind = -1; for (k = 0; k < 42; k++) { if (rig->caps->ctcss_list[k] == tone) { stepind = k; break; } } if (stepind == -1) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tone value '%u'\n", __func__, tone); return -RIG_EINVAL; } *ctcss_index = stepind; return RIG_OK; } /* * tmd710_set_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_ctcss_index(rig, tone, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.tone_freq = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; struct rig_caps *caps; caps = rig->caps; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *tone = caps->ctcss_list[fo_struct.tone_freq]; } return retval; } /* * tmd710_set_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_ctcss_index(rig, tone, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.ct_freq = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; struct rig_caps *caps; caps = rig->caps; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *tone = caps->ctcss_list[fo_struct.ct_freq]; } return retval; } /* * status: ok, no vfo checks */ int tmd710_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { int retval; tmd710_fo fo_struct; if (!rig || !code) { return -RIG_EINVAL; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } if (fo_struct.dcs) { const tone_t *dcs_list = common_dcs_list; *code = dcs_list[fo_struct.dcs_val]; } else { *code = 0; } return RIG_OK; } static int tmd710_find_dcs_index(tone_t code, int *dcs_index) { int i = 0; // we only allow exact matches here const tone_t *dcs_list = common_dcs_list; while (code != dcs_list[i]) { if (dcs_list[i] == 0) { return -RIG_EINVAL; } i++; } *dcs_index = i; return RIG_OK; } /* * status: ok, no vfo checks */ int tmd710_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { int retval, dcs_index, dcs_enable; tmd710_fo fo_struct; if (code == 0) { dcs_index = 0; dcs_enable = 0; } else { retval = tmd710_find_dcs_index(code, &dcs_index); if (retval != RIG_OK) { return retval; } dcs_enable = 1; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.dcs = dcs_enable; fo_struct.dcs_val = dcs_index; return tmd710_push_fo(rig, vfo, &fo_struct); } static int tmd710_get_mode_hamlib_values(int tmd710_mode, rmode_t *mode, pbwidth_t *width) { switch (tmd710_mode) { case 0: *mode = RIG_MODE_FM; *width = 15000; break; case 1: *mode = RIG_MODE_FMN; *width = 5000; break; case 2: *mode = RIG_MODE_AM; *width = 4000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, (long)tmd710_mode); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_get_mode * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_mode_hamlib_values(fo_struct.mode, mode, width); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int tmd710_get_mode_tmd710_value(rmode_t mode, int *tmd710_mode) { if (mode == RIG_MODE_FM) { *tmd710_mode = 0; } else if (mode == RIG_MODE_FMN) { *tmd710_mode = 1; } else if (mode == RIG_MODE_AM) { *tmd710_mode = 2; } else { rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, (long)mode); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_mode * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval, tmd710_mode = RIG_MODE_NONE; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_get_mode_tmd710_value(mode, &tmd710_mode); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.mode = tmd710_mode; return tmd710_push_fo(rig, vfo, &fo_struct); } static int tmd710_find_tuning_step_index(RIG *rig, shortfreq_t ts, int *step_index) { int k, stepind = -1; for (k = 0; STATE(rig)->tuning_steps[k].ts != 0; ++k) { if ((rig->caps->tuning_steps[k].modes == RIG_MODE_NONE) && (rig->caps->tuning_steps[k].ts == 0)) { break; } else if (rig->caps->tuning_steps[k].ts == ts) { stepind = k; break; } } if (stepind == -1) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tuning step value '%ld'\n", __func__, ts); return -RIG_EINVAL; } *step_index = stepind; return RIG_OK; } /* * tmd710_set_ts * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_tuning_step_index(rig, ts, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.step = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ts * Assumes rig!=NULL, freq!=NULL */ static int tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *ts = rig->caps->tuning_steps[fo_struct.step].ts; } return retval; } int tmd710_get_rptr_shift_tmd710_value(rptr_shift_t shift, int *tmd710_shift) { switch (shift) { case RIG_RPT_SHIFT_NONE: *tmd710_shift = 0; break; case RIG_RPT_SHIFT_PLUS: *tmd710_shift = 1; break; case RIG_RPT_SHIFT_MINUS: *tmd710_shift = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, shift); return -RIG_EPROTO; } return RIG_OK; } /* * tmd710_set_rptr_shift * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_tmd710_value(shift, &fo_struct.shift); if (retval != RIG_OK) { return retval; } return tmd710_push_fo(rig, vfo, &fo_struct); } int tmd710_get_rptr_shift_hamlib_value(int tmd710_shift, rptr_shift_t *shift) { switch (tmd710_shift) { case 0: *shift = RIG_RPT_SHIFT_NONE; break; case 1: *shift = RIG_RPT_SHIFT_PLUS; break; case 2: *shift = RIG_RPT_SHIFT_MINUS; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, tmd710_shift); return -RIG_EPROTO; } return RIG_OK; } /* * tmd710_get_rptr_shft * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_hamlib_value(fo_struct.shift, shift); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_rptr_offs * Assumes rig!=NULL */ int tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t freq) { int retval; tmd710_fo fo_struct; long freq5, freq625, freq_sent; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (abs((int)(freq5 - freq)) < abs((int)(freq625 - freq))) { freq_sent = freq5; } else { freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ fo_struct.offset = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_rptr_offs * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *rptr_offs = fo_struct.offset; } return retval; } /* * tmd710_get_vfo * Assumes rig!=NULL */ int tmd710_get_vfo(RIG *rig, vfo_t *vfo) { int vfomode; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_get_vfo_and_mode(rig, vfo, &vfomode); if (retval != RIG_OK) { return retval; } switch (vfomode) { case TMD710_BAND_MODE_VFO: break; case TMD710_BAND_MODE_MEMORY: case TMD710_BAND_MODE_CALL: *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO mode value '%c'\n", __func__, vfomode); return -RIG_EVFO; } return RIG_OK; } /* * tmd710_set_vfo * * Assumes rig!=NULL */ int tmd710_set_vfo(RIG *rig, vfo_t vfo) { char vfobuf[16], ackbuf[16]; int vfonum, vfomode; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = TMD710_BAND_A; vfomode = TMD710_BAND_MODE_VFO; break; case RIG_VFO_B: vfonum = TMD710_BAND_B; vfomode = TMD710_BAND_MODE_VFO; break; case RIG_VFO_MEM: /* get current band */ retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } vfomode = TMD710_BAND_MODE_MEMORY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %u\n", __func__, vfo); return -RIG_EVFO; } snprintf(vfobuf, sizeof(vfobuf), "VM %1d,%1d", vfonum, vfomode); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } if (vfo == RIG_VFO_MEM) { return RIG_OK; } snprintf(vfobuf, sizeof(vfobuf), "BC %1d,%1d", vfonum, vfonum); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_split_vfo * * This radio has two VFOs, and either one can be the TX/RX. As such, this function does the following: * - Keeps VFO control (CTRL) on the currently active VFO. * - Sets PTT control on the specified VFO. * - Sets the tx_vfo for use in set_split_freq(). * - The value of split is ignored, as the radio is always in "split" mode. * */ int tmd710_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { char vfobuf[16], ackbuf[16]; int retval; int ctrl_vfo_index; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo: %s, txvfo: %s\n", __func__, rig_strvfo(vfo), rig_strvfo(txvfo)); retval = tmd710_get_vfo_num(rig, &ctrl_vfo_index, NULL); if (retval != RIG_OK) { return retval; } int ptt_vfo_index = txvfo == RIG_VFO_A ? 0 : 1; // Keep CTRL VFO as it is and only set the PTT VFO as TX VFO sprintf(vfobuf, "BC %d,%d", ctrl_vfo_index, ptt_vfo_index); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } STATE(rig)->tx_vfo = txvfo; return RIG_OK; } int tmd710_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } STATE(rig)->tx_vfo = *txvfo; // Rig is always in "split mode" and VFOs are targetable, so simply check current and TX VFOs *split = STATE(rig)->current_vfo == STATE(rig)->tx_vfo ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[16]; char membuf[16]; int retval; int vfonum; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !ch) { return -RIG_EINVAL; } if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } } else { vfonum = STATE(rig)->current_vfo == RIG_VFO_A ? 0 : 1; } snprintf(cmd, sizeof(cmd), "MR %d", vfonum); retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); if (retval != RIG_OK) { return retval; } n = sscanf(membuf, "MR %*d,%d", ch); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'MR v,ccc'\n", membuf); return -RIG_EPROTO; } return RIG_OK; } int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch) { int vfonum; char cmd[16]; char membuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } } else { vfonum = STATE(rig)->current_vfo == RIG_VFO_A ? 0 : 1; } snprintf(cmd, sizeof(cmd), "MR %d,%03d", vfonum, ch); return kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); } int tmd710_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; tmd710_me me_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !chan) { return -RIG_EINVAL; } retval = tmd710_pull_me(rig, chan->channel_num, &me_struct); if (retval != RIG_OK) { return retval; } chan->freq = me_struct.freq; chan->vfo = RIG_VFO_CURR; retval = tmd710_get_mode_hamlib_values(me_struct.mode, &chan->mode, &chan->width); if (retval != RIG_OK) { return retval; } chan->tuning_step = rig->caps->tuning_steps[me_struct.step].ts; chan->funcs = 0; if (me_struct.tone != 0) { chan->funcs |= RIG_FUNC_TONE; } if (me_struct.ct != 0) { chan->funcs |= RIG_FUNC_TSQL; } if (me_struct.reverse != 0) { chan->funcs |= RIG_FUNC_REV; } chan->ctcss_tone = rig->caps->ctcss_list[me_struct.tone_freq]; chan->ctcss_sql = rig->caps->ctcss_list[me_struct.ct_freq]; chan->dcs_code = 0; if (me_struct.dcs) { const tone_t *dcs_list = common_dcs_list; chan->dcs_sql = dcs_list[me_struct.dcs_val]; } else { chan->dcs_sql = 0; } retval = tmd710_get_rptr_shift_hamlib_value(me_struct.shift, &chan->rptr_shift); if (retval != RIG_OK) { return retval; } chan->rptr_offs = me_struct.offset; retval = tmd710_get_memory_name(rig, chan->channel_num, chan->channel_desc); if (retval != RIG_OK) { return retval; } chan->flags = RIG_CHFLAG_NONE; if (me_struct.lockout) { chan->flags |= RIG_CHFLAG_SKIP; } chan->tx_freq = me_struct.tx_freq; // Unsupported features chan->bank_num = 0; chan->ant = 0; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = 0; chan->rit = 0; chan->xit = 0; chan->scan_group = 0; // TODO: chan->levels chan->ext_levels = NULL; return RIG_OK; } int tmd710_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { int retval; tmd710_me me_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !chan) { return -RIG_EINVAL; } me_struct.channel = chan->channel_num; me_struct.freq = chan->freq; me_struct.tx_freq = chan->tx_freq; retval = tmd710_find_tuning_step_index(rig, chan->tuning_step, &me_struct.step); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_tmd710_value(chan->rptr_shift, &me_struct.shift); if (retval != RIG_OK) { return retval; } me_struct.offset = chan->rptr_offs; me_struct.reverse = (chan->funcs & RIG_FUNC_REV) ? 1 : 0; me_struct.tone = (chan->funcs & RIG_FUNC_TONE) ? 1 : 0; me_struct.ct = (chan->funcs & RIG_FUNC_TSQL) ? 1 : 0; if (!me_struct.tone && chan->ctcss_tone == 0) { me_struct.tone_freq = 0; } else { retval = tmd710_find_ctcss_index(rig, chan->ctcss_tone, &me_struct.tone_freq); if (retval != RIG_OK) { return retval; } } if (!me_struct.ct && chan->ctcss_sql == 0) { me_struct.ct_freq = 0; } else { retval = tmd710_find_ctcss_index(rig, chan->ctcss_sql, &me_struct.ct_freq); if (retval != RIG_OK) { return retval; } } if (chan->dcs_sql == 0) { me_struct.dcs = 0; me_struct.dcs_val = 0; } else { retval = tmd710_find_dcs_index(chan->dcs_sql, &me_struct.dcs_val); if (retval != RIG_OK) { return retval; } me_struct.dcs = 1; } me_struct.lockout = (chan->flags & RIG_CHFLAG_SKIP) ? 1 : 0; retval = tmd710_get_mode_tmd710_value(chan->mode, &me_struct.mode); if (retval != RIG_OK) { return retval; } me_struct.p15_unknown = 0; retval = tmd710_push_me(rig, &me_struct); if (retval != RIG_OK) { return retval; } return tmd710_set_memory_name(rig, me_struct.channel, (char *) chan->channel_desc); } int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char ackbuf[32]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", ackbuf, sizeof(ackbuf)); } int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char cmd[8], buf[8]; int retval; int vfonum, dcd_val; retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } snprintf(cmd, sizeof(cmd), "BY %d", vfonum); retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 6); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "BY %d,%d", &vfonum, &dcd_val); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%ld\n", __func__, buf, (long)strlen(buf)); return -RIG_EPROTO; } switch (dcd_val) { case 0: *dcd = RIG_DCD_OFF; break; case 1: *dcd = RIG_DCD_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%ld\n", __func__, buf, (long)strlen(buf)); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char ackbuf[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", ackbuf, sizeof(ackbuf)); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", ackbuf, sizeof(ackbuf)); default: return -RIG_EINVAL; } } /* * tmd710_get_level * Assumes rig!=NULL, val!=NULL */ int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[10], ackbuf[20]; int retval, v, l; int vfonum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: snprintf(buf, sizeof(buf), "PC %d", vfonum); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - TMD710_RF_POWER_MIN) / (float)(TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN); // RF power needs to be inverted val->f = 1.0f - val->f; break; case RIG_LEVEL_SQL: snprintf(buf, sizeof(buf), "SQ %d", vfonum); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SQ %X", (unsigned int *)&l); if (retval != 1 || l < TMD710_SQL_MIN || l > TMD710_SQL_MAX) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - TMD710_SQL_MIN) / (float)(TMD710_SQL_MAX - TMD710_SQL_MIN); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %ld\n", __func__, (long)level); return -RIG_EINVAL; } return RIG_OK; } int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[12], ackbuf[12]; int vfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: // RF power needs to be inverted snprintf(buf, sizeof(buf), "PC %d,%d", vfonum, (int)((1.0f - val.f) * (TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN) + TMD710_RF_POWER_MIN)); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); case RIG_LEVEL_SQL: snprintf(buf, sizeof(buf), "SQ %d,%02X", vfonum, (int)(val.f * (TMD710_SQL_MAX - TMD710_SQL_MIN) + TMD710_SQL_MIN)); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %ld\n", __func__, (long)level); return -RIG_EINVAL; } } static int tmd710_tburst(RIG *rig, int status) { char ackbuf[8]; return kenwood_transaction(rig, (status == 1) ? "TT" : "RX", ackbuf, sizeof(ackbuf)); } /* * tmd710_get_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int tmd710_get_kenwood_func(RIG *rig, const char *cmd, int *status) { char buf[8]; int retval, len, expected; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); len = strlen(cmd); expected = len + 2; retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), expected); if (retval != RIG_OK) { return retval; } if (status) { *status = (buf[len + 1] == '0') ? 0 : 1; } return RIG_OK; }; /* * tmd710_set_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int tmd710_set_kenwood_func(RIG *rig, const char *cmd, int status) { char buf[16], ackbuf[16]; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, status = %d\n", __func__, cmd, status); strncpy(buf, cmd, sizeof(buf) - 2); buf[sizeof(buf) - 1] = '\0'; strncat(buf, status ? " 1" : " 0", sizeof(buf) - 1); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); } /* * tmd710_get_func * Assumes rig!=NULL, status!=NULL */ int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int use_fo = 0, use_mu = 0; tmd710_fo fo_struct; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)func); switch (func) { case RIG_FUNC_TONE: case RIG_FUNC_TSQL: case RIG_FUNC_REV: use_fo = 1; break; case RIG_FUNC_ARO: case RIG_FUNC_AIP: case RIG_FUNC_RESUME: use_mu = 1; break; } if (use_fo) { retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } } if (use_mu) { retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } } switch (func) { case RIG_FUNC_TONE: *status = (fo_struct.tone != 0) ? 1 : 0; break; case RIG_FUNC_TSQL: *status = (fo_struct.ct != 0) ? 1 : 0; break; case RIG_FUNC_REV: *status = (fo_struct.reverse != 0) ? 1 : 0; break; case RIG_FUNC_LOCK: return tmd710_get_kenwood_func(rig, "LK", status); case RIG_FUNC_ARO: *status = (mu_struct.auto_repeater_offset != 0) ? 1 : 0; break; case RIG_FUNC_AIP: *status = ((mu_struct.vhf_aip != 0) || (mu_struct.uhf_aip != 0)) ? 1 : 0; break; case RIG_FUNC_RESUME: *status = (mu_struct.scan_resume == TMD710_SCAN_RESUME_TIME) ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#lx\n", __func__, (long)func); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_func * Assumes rig!=NULL, status!=NULL */ int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; int use_fo = 0, use_mu = 0; tmd710_fo fo_struct; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)func); switch (func) { case RIG_FUNC_TONE: case RIG_FUNC_TSQL: case RIG_FUNC_REV: use_fo = 1; break; case RIG_FUNC_ARO: case RIG_FUNC_AIP: case RIG_FUNC_RESUME: use_mu = 1; break; } if (use_fo) { retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } } if (use_mu) { retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } } switch (func) { case RIG_FUNC_TONE: fo_struct.tone = status ? 1 : 0; break; case RIG_FUNC_TSQL: fo_struct.ct = status ? 1 : 0; break; case RIG_FUNC_REV: fo_struct.reverse = status ? 1 : 0; break; case RIG_FUNC_ARO: mu_struct.auto_repeater_offset = status ? 1 : 0; break; case RIG_FUNC_AIP: mu_struct.vhf_aip = status ? 1 : 0; mu_struct.uhf_aip = status ? 1 : 0; break; case RIG_FUNC_RESUME: mu_struct.scan_resume = status ? TMD710_SCAN_RESUME_TIME : TMD710_SCAN_RESUME_CARRIER; break; case RIG_FUNC_LOCK: return tmd710_set_kenwood_func(rig, "LK", status); case RIG_FUNC_TBURST: return tmd710_tburst(rig, status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#lx\n", __func__, (long)func); return -RIG_EINVAL; } if (use_fo) { return tmd710_push_fo(rig, vfo, &fo_struct); } if (use_mu) { return tmd710_push_mu(rig, &mu_struct); } return -RIG_EINVAL; } /* * tmd710_get_parm * Assumes rig!=NULL, status!=NULL */ int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)parm); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (parm) { case RIG_PARM_BEEP: val->i = mu_struct.beep ? 1 : 0; break; case RIG_PARM_APO: if (mu_struct.auto_power_off == TMD710_AUTO_POWER_OFF_180MIN) { val->i = 180; } else { val->i = mu_struct.auto_power_off * 30; } break; case RIG_PARM_BACKLIGHT: val->f = ((float) mu_struct.brightness_level) / 8.0f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#lx\n", __func__, (long)parm); return -RIG_EINVAL; } return RIG_OK; } int tmd710_set_parm(RIG *rig, setting_t parm, value_t val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (parm) { case RIG_PARM_BEEP: mu_struct.beep = val.i ? 1 : 0; break; case RIG_PARM_BACKLIGHT: if (val.f < 0 || val.f > 1) { return -RIG_EINVAL; } mu_struct.brightness_level = (int)(val.f * 8); break; case RIG_PARM_APO: { int value = 0; if (val.i > 120) { value = TMD710_AUTO_POWER_OFF_180MIN; } else if (val.i > 90) { value = TMD710_AUTO_POWER_OFF_120MIN; } else if (val.i > 60) { value = TMD710_AUTO_POWER_OFF_90MIN; } else if (val.i > 30) { value = TMD710_AUTO_POWER_OFF_60MIN; } else if (val.i > 0) { value = TMD710_AUTO_POWER_OFF_30MIN; } mu_struct.auto_power_off = value; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#lx\n", __func__, (long)parm); return -RIG_EINVAL; } return tmd710_push_mu(rig, &mu_struct); } /* * tmd710_get_ext_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL * */ int tmd710_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_LEVEL_EXT_DATA_BAND: val->i = mu_struct.ext_data_band; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %ld\n", __func__, (long)token); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_ext_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL * */ int tmd710_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_LEVEL_EXT_DATA_BAND: { int v = val.i; if (v != TMD710_EXT_DATA_BAND_A && v != TMD710_EXT_DATA_BAND_B && v != TMD710_EXT_DATA_BAND_TXA_RXB && v != TMD710_EXT_DATA_BAND_TXB_RXA) { return -RIG_EINVAL; } mu_struct.ext_data_band = v; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %ld\n", __func__, (long)token); return -RIG_EINVAL; } return tmd710_push_mu(rig, &mu_struct); } hamlib-4.6.5/rigs/kenwood/ts480.c0000664000175000017500000024115415056640443012123 /* * Hamlib Kenwood backend - TS-480 description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * Copyright (c) 2021 by Mikael Nousiainen * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "cal.h" #include "idx_builtin.h" #include "iofunc.h" #include "misc.h" #include "token.h" #include "kenwood.h" #include "cache.h" #define TS480_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define SDRUNO_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB) #define PS8000A_ALL_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define QMX_ALL_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define TS480_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS480_AM_TX_MODES RIG_MODE_AM #define TS480_VFO (RIG_VFO_A|RIG_VFO_B) #define TS480_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define PT8000A_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS480_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define PT8000A_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS480_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK) #define TS480_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) // TS-480 S-meter calibration table based on LCD display bars #define TS480_STR_CAL { 9, \ { \ { 0, -60 }, \ { 3, -48 }, \ { 5, -36 }, \ { 7, -24 }, \ { 9, -12 }, \ { 11, 0 }, \ { 14, 20 }, \ { 17, 40 }, \ { 20, 60 } \ } } // TS-480 SWR calibration table based approximately on LCD display bars #define TS480_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 4, 1.5f }, \ { 8, 2.0f }, \ { 12, 3.0f }, \ { 20, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT TOKEN_BACKEND(103) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_DSP_TX_BANDWIDTH TOKEN_BACKEND(106) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) #define TOK_LEVEL_AF_INPUT_LEVEL TOKEN_BACKEND(109) #define TOK_LEVEL_AF_OUTPUT_LEVEL TOKEN_BACKEND(110) #define TOK_LEVEL_DIGITAL_NOISE_LIMITER TOKEN_BACKEND(111) #define TOK_FUNC_CW_IF_FOR_SSB_RX TOKEN_BACKEND(112) int ts480_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_FUNC_FILTER_WIDTH_DATA, TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_DSP_TX_BANDWIDTH, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_LEVEL_AF_INPUT_LEVEL, TOK_LEVEL_AF_OUTPUT_LEVEL, TOK_LEVEL_DIGITAL_NOISE_LIMITER, TOK_FUNC_CW_IF_FOR_SSB_RX, TOK_BACKEND_NONE, }; const struct confparams ts480_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_CW_IF_FOR_SSB_RX, "CW_IF_FOR_SSB_RX", "CW IF filter for SSB", "Use CW IF filter for SSB reception", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_FILTER_WIDTH_DATA, "FILTER_WIDTH_DATA", "Filter bandwidth for data", "Filter bandwidth for data communications", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT, "TX_AUDIO_FROM_DATA_INPUT", "TX audio from data input", "Transmit with audio input from the data terminal", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts480_ext_levels[] = { { TOK_LEVEL_DIGITAL_NOISE_LIMITER, "DIGITAL_NOISE_LIMITER", "Digital Noise Limiter", "Digital Noise Limiter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "DNL Level 1", "DNL Level 2", "DNL Level 3", NULL } } } }, { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_BANDWIDTH, "DSP_TX_BANDWIDTH", "DSP TX bandwidth", "DSP TX bandwidth for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2.0 kHz", "2.4 kHz", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_AF_INPUT_LEVEL, "AF_INPUT_LEVEL", "AF input level", "AF input level for data communications", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_AF_OUTPUT_LEVEL, "AF_OUTPUT_LEVEL", "AF output level", "AF output level for data communications", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { RIG_CONF_END, NULL, } }; /* * kenwood_ts480_get_info * Assumes rig!=NULL */ const char * kenwood_ts480_get_info(RIG *rig) { char firmbuf[50]; int retval; size_t firm_len; retval = kenwood_transaction(rig, "TY", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)firm_len); return NULL; } switch (firmbuf[4]) { case '0': return "TS-480HX (200W)"; case '1': return "TS-480SAT (100W + AT)"; case '2': return "Japanese 50W type"; case '3': return "Japanese 20W type"; default: return "Firmware: unknown"; } } static int ts480_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts480_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts480_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c%c", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); default: return kenwood_set_func(rig, vfo, func, status); } } static int ts480_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0' || buf[3] != '0'; break; default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } /* * WARNING: The commands differ slightly from the general versions in kenwood.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ int kenwood_ts480_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RF: kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: return kenwood_set_level(rig, vfo, level, val); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", kenwood_val); break; case RIG_LEVEL_AGC: /* hamlib argument is int, possible values rig.h:enum agc_level_e */ /* possible values for TS480 000(=off), 001(=fast), 002(=slow) */ rig_debug(RIG_DEBUG_VERBOSE, "%s TS480 RIG_LEVEL_AGC\n", __func__); switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_FAST: kenwood_val = 1; break; case RIG_AGC_SLOW: kenwood_val = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_METER: switch (val.i) { case RIG_METER_SWR: kenwood_val = 1; break; case RIG_METER_COMP: kenwood_val = 2; break; case RIG_METER_ALC: kenwood_val = 3; break; default: RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RM%d", kenwood_val); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(ts480_set_ex_menu(rig, 34, 2, (val.i - 400) / 50)); default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } static int ts480_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-480 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM1%d;RM2%d;RM3%d;", swr, comp, alc); if (retval != 3) { rig_debug(RIG_DEBUG_ERR, "%s: expected 3 meter values to parse, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * kenwood_ts480_get_level * Assumes rig!=NULL, val!=NULL */ int kenwood_ts480_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint; int retval; ENTERFUNC; switch (level) { case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 100; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } switch (ackbuf[ack_len_expected - 1]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_SLOW; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_NB: { int raw_value; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int swr; int comp; int alc; retval = ts480_read_meters(rig, &swr, &comp, &alc); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 20dB break; case RIG_LEVEL_ALC: // Maximum value is 20, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 4.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: { int raw_value; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } retval = kenwood_safe_transaction(rig, "SM0", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM0%d", &raw_value); val->f = (float) raw_value / 20.0f; break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts480_get_ex_menu(rig, 34, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 400 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts480_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -9999 || rit > 9999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts480_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts480_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; case TOK_FUNC_CW_IF_FOR_SSB_RX: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 17, 1, status); break; case TOK_FUNC_FILTER_WIDTH_DATA: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 45, 1, status); break; case TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 60, 1, status); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } case TOK_FUNC_CW_IF_FOR_SSB_RX: retval = ts480_get_ex_menu(rig, 17, 1, status); break; case TOK_FUNC_FILTER_WIDTH_DATA: retval = ts480_get_ex_menu(rig, 45, 1, status); break; case TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT: retval = ts480_get_ex_menu(rig, 60, 1, status); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; char cmdbuf[20]; ENTERFUNC; switch (token) { case TOK_LEVEL_DIGITAL_NOISE_LIMITER: if (val.i < 0 || val.i > 3) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "DL%d%02d", val.i != 0 ? 1 : 0, val.i > 0 ? val.i - 1 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 18, 1, val.i); break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 19, 1, val.i); break; case TOK_LEVEL_DSP_TX_BANDWIDTH: if (val.i < 0 || val.i > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 20, 1, val.i); break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 12, 1, (int) val.f); break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 13, 1, (int) val.f); break; case TOK_LEVEL_AF_INPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 46, 1, (int) val.f); break; case TOK_LEVEL_AF_OUTPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 47, 1, (int) val.f); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DIGITAL_NOISE_LIMITER: { int enabled; int level; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "DL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "DL%1d%2d", &enabled, &level); val->i = enabled ? level + 1 : 0; break; } case TOK_LEVEL_DSP_RX_EQUALIZER: retval = ts480_get_ex_menu(rig, 18, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: retval = ts480_get_ex_menu(rig, 19, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_BANDWIDTH: retval = ts480_get_ex_menu(rig, 20, 1, &value); val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: retval = ts480_get_ex_menu(rig, 12, 1, &value); val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: retval = ts480_get_ex_menu(rig, 13, 1, &value); val->f = value; break; case TOK_LEVEL_AF_INPUT_LEVEL: retval = ts480_get_ex_menu(rig, 46, 1, &value); val->f = value; break; case TOK_LEVEL_AF_OUTPUT_LEVEL: retval = ts480_get_ex_menu(rig, 47, 1, &value); val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static struct kenwood_filter_width ts480_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_SSB, 1, 500 }, // NAR1 optional filter { RIG_MODE_SSB, 2, 270 }, // NAR2 optional filter { RIG_MODE_FM, 0, 12000 }, { RIG_MODE_AM, 0, 6000 }, { RIG_MODE_AM, 1, 2400 }, // NAR1 optional filter (?) { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts480_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 1600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 1800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 2600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 2800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 3000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 3400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 12, 4000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 13, 5000 }, { RIG_MODE_AM, 0, 0, 2500 }, { RIG_MODE_AM, 0, 1, 3000 }, { RIG_MODE_AM, 0, 2, 4000 }, { RIG_MODE_AM, 0, 3, 5000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 2210 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts480_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 1000 }, { RIG_MODE_AM, 0, 0, 0 }, { RIG_MODE_AM, 0, 1, 100 }, { RIG_MODE_AM, 0, 2, 200 }, { RIG_MODE_AM, 0, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 50 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 100 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 250 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 4, 1000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 5, 1500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 6, 2400 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts480_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts480_filter_width, .slope_filter_high = ts480_slope_filter_high, .slope_filter_low = ts480_slope_filter_low, }; int ts480_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv = (struct kenwood_priv_data *) STATE(rig)->priv; priv->ag_format = 2; priv->micgain_min = 0; priv->micgain_max = 100; RETURNFUNC(RIG_OK); } int qrplabs_open(RIG *rig) { int retval; char buf[64]; struct kenwood_priv_data *priv = (struct kenwood_priv_data *) STATE(rig)->priv; ENTERFUNC; retval = kenwood_open(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } retval = kenwood_transaction(rig, "VN", buf, sizeof(buf)); if (retval == RIG_OK) { strtok(buf, ";"); rig_debug(RIG_DEBUG_VERBOSE, "%s: firmware version %s\n", __func__, &buf[2]); } priv->is_emulation = 1; RETURNFUNC(retval); } int qdx_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TQ1"; break; case RIG_PTT_OFF: ptt_cmd = "TQ0"; break; default: RETURNFUNC(-RIG_EINVAL); } int retval = kenwood_transaction(rig, ptt_cmd, NULL, 0); hl_usleep(100 * 1000); // a little time for PTT to return whatever it returns which we ignore rig_flush(rp); RETURNFUNC(retval); } int qrplabs_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { char tm_cmd[32]; char tm_buf[32]; *year = *month = *day = *hour = *min = *sec = *msec = *utc_offset = 0; *month = 0; *day = 0; sprintf(tm_cmd, "TM;"); int retval = kenwood_transaction(rig, tm_cmd, tm_buf, sizeof(tm_buf)); if (retval == RIG_OK && strlen(tm_buf) >= 8) { sscanf(tm_buf, "TM%02d%02d%02d", hour, min, sec); } return retval; } int qrplabs_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { char tm_cmd[32]; sprintf(tm_cmd, "TM%02d%02d%02d;", hour, min, sec); int retval = kenwood_transaction(rig, tm_cmd, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting time: %s\n", __func__, rigerror(retval)); } return retval; } /* * TS-480 rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps ts480_caps = { RIG_MODEL(RIG_MODEL_TS480), .model_name = "TS-480", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * truSDC rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps trudx_caps = { RIG_MODEL(RIG_MODEL_TRUSDX), .model_name = "(tr)uSDX", .mfg_name = "DL2MAN", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 38400, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * QRPLabs TS-480 emulation rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps qrplabs_caps = { RIG_MODEL(RIG_MODEL_QRPLABS), .model_name = "QCX/QDX", .mfg_name = "QRPLabs", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = qrplabs_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .has_set_level = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .get_clock = qrplabs_get_clock, .set_clock = qrplabs_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps qrplabs_qmx_caps = { RIG_MODEL(RIG_MODEL_QRPLABS_QMX), .model_name = "QMX", .mfg_name = "QRPLabs", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 256000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {MHz(4), MHz(14), QMX_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {MHz(4), MHz(14), QMX_ALL_MODES, 5000, 100000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, RIG_FLT_END, }, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = qrplabs_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_info = kenwood_ts480_get_info, .get_clock = qrplabs_get_clock, .set_clock = qrplabs_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Hilberling PT8000A TS480 emulation * Notice that some rigs share the same functions. */ struct rig_caps pt8000a_caps = { RIG_MODEL(RIG_MODEL_PT8000A), .model_name = "PT-8000A", .mfg_name = "Hilberling", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 500, .retry = 10, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .rx_range_list1 = { // not region specific {kHz(9), MHz(30), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, {MHz(50), MHz(54), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(69.9), MHz(70.5), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(110), MHz(143.99), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(144), MHz(148), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {MHz(1.8), MHz(30), TS480_OTHER_TX_MODES, 1000, 200000, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, /* 200W class */ {MHz(1.8), MHz(30), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 50000, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, /* 50W class */ {MHz(50), MHz(54), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(50), MHz(54), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ {MHz(69.9), MHz(70.5), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(69.9), MHz(70.5), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ {MHz(144), MHz(148), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(144), MHz(148), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ RIG_FRNG_END, }, .tuning_steps = { {PS8000A_ALL_MODES, Hz(1)}, {PS8000A_ALL_MODES, Hz(10)}, {PS8000A_ALL_MODES, Hz(100)}, {PS8000A_ALL_MODES, Hz(1000)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(6.0)}, {RIG_MODE_SSB, kHz(1.0)}, {RIG_MODE_SSB, kHz(1.2)}, {RIG_MODE_SSB, kHz(1.4)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.9)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(2.1)}, {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(2.3)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.5)}, {RIG_MODE_SSB, kHz(2.6)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(2.9)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, kHz(3.1)}, {RIG_MODE_SSB, kHz(3.2)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(3.4)}, {RIG_MODE_SSB, kHz(3.5)}, {RIG_MODE_SSB, kHz(4.6)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(2.5)}, {RIG_MODE_AM, kHz(2.6)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, kHz(2.8)}, {RIG_MODE_AM, kHz(2.9)}, {RIG_MODE_AM, kHz(3.0)}, {RIG_MODE_AM, kHz(3.1)}, {RIG_MODE_AM, kHz(3.2)}, {RIG_MODE_AM, kHz(3.3)}, {RIG_MODE_AM, kHz(3.4)}, {RIG_MODE_AM, kHz(3.5)}, {RIG_MODE_AM, kHz(3.5)}, {RIG_MODE_AM, kHz(4.6)}, {RIG_MODE_AM, kHz(6.0)}, {RIG_MODE_FM, kHz(2.4)}, {RIG_MODE_FM, kHz(2.5)}, {RIG_MODE_FM, kHz(2.6)}, {RIG_MODE_FM, kHz(2.7)}, {RIG_MODE_FM, kHz(2.8)}, {RIG_MODE_FM, kHz(2.9)}, {RIG_MODE_FM, kHz(3.0)}, {RIG_MODE_FM, kHz(3.1)}, {RIG_MODE_FM, kHz(3.2)}, {RIG_MODE_FM, kHz(3.3)}, {RIG_MODE_FM, kHz(3.4)}, {RIG_MODE_FM, kHz(3.5)}, {RIG_MODE_FM, kHz(3.5)}, {RIG_MODE_FM, kHz(4.6)}, {RIG_MODE_FM, kHz(6.0)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .priv = (void *)& ts480_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, // .set_powerstat = kenwood_set_powerstat, // .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = PT8000A_LEVEL_SET, .has_get_level = PT8000A_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * SDRPlay SDRUno rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps sdruno_caps = { RIG_MODEL(RIG_MODEL_SDRUNO), .model_name = "SDRUno", .mfg_name = "SDRPlay", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {kHz(100), Hz(59999999), SDRUNO_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_PKTUSB, kHz(4)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; const struct confparams malachite_cfg_parms[] = { { // the Malachite SDR cannot handle sending ID; after FA; commands TOK_NO_ID, "no_id", "No ID", "If true do not send ID; with set commands", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; int malachite_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); priv = STATE(rig)->priv; priv->no_id = 1; // the Malchite doesn't like the ID; verify cmd if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int malachite_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int post_write_delay_save = STATE(rig)->post_write_delay; STATE(rig)->post_write_delay = 0; int retval = kenwood_get_mode(rig, vfo, mode, width); STATE(rig)->post_write_delay = post_write_delay_save; return retval; } int malachite_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int post_write_delay_save = STATE(rig)->post_write_delay; ENTERFUNC; STATE(rig)->post_write_delay = 0; int retval = kenwood_get_freq(rig, vfo, freq); STATE(rig)->post_write_delay = post_write_delay_save; RETURNFUNC(retval); } int malachite_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: freqMainA=%g, freq=%g\n", __func__, cachep->freqMainA, freq); if ((cachep->freqMainA < 400000000 && freq >= 400000000) || (cachep->freqMainA >= 400000000 && freq < 400000000) || cachep->freqMainA == 0) { // Malachite has a bug where it takes two freq set to make it work // under band changes -- so we just do this all the time retval = kenwood_set_freq(rig, vfo, freq + 1); STATE(rig)->post_write_delay = 250; // need a bit more time on band change if (retval != RIG_OK) { RETURNFUNC(retval); } } else { STATE(rig)->post_write_delay = 125; } retval = kenwood_set_freq(rig, vfo, freq); RETURNFUNC(retval); } /* * Malachite SDR rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps malachite_caps = { RIG_MODEL(RIG_MODEL_MALACHITE), .model_name = "DSP", .mfg_name = "Malachite", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, // Malchite needs 125ms unless going from low to high band -- see malachite_set_freq // Do not change this without checking the 300ms delay in malachite_set_freq .post_write_delay = 250, .timeout = 3000, .retry = 3, .preamp = {0, RIG_DBLST_END,}, .attenuator = {0, RIG_DBLST_END,}, .max_ifshift = Hz(0), // .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_POLL, .rx_range_list1 = { {kHz(50), MHz(250), TS480_ALL_MODES, -1, -1, RIG_VFO_A, RIG_ANT_CURR, "Generic" }, {MHz(400), GHz(2), TS480_ALL_MODES, -1, -1, RIG_VFO_A, RIG_ANT_CURR, "Generic" }, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, Hz(1)}, RIG_TS_END }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = (void *)& ts480_priv_caps, .rig_init = malachite_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = malachite_set_freq, .get_freq = malachite_get_freq, .set_mode = kenwood_set_mode, .get_mode = malachite_get_mode, .set_vfo = kenwood_set_vfo, // Malachite only supports VFOA .get_vfo = kenwood_get_vfo_if, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts811.c0000664000175000017500000001254415056640443012120 /* * Hamlib Kenwood backend - TS-811 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS811_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS811_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS811_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS811_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS811_SCAN_OP (RIG_SCAN_VFO) static struct kenwood_priv_caps ts811_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' /* Note: The 140/680/711/811 need this to set the VFO on the radio */ static int ts811_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts811 rig capabilities. */ struct rig_caps ts811_caps = { RIG_MODEL(RIG_MODEL_TS811), .model_name = "TS-811", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = TS811_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS811_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(9.9), .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* FIXME: split memories, call channel, etc. */ .chan_list = { { 1, 59, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(440), TS811_ALL_MODES, -1, -1, TS811_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(430), MHz(440), TS811_ALL_MODES, W(5), W(25), TS811_VFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(430), MHz(450), TS811_ALL_MODES, -1, -1, TS811_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(430), MHz(450), TS811_ALL_MODES, W(5), W(25), TS811_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS811_ALL_MODES, 50}, {TS811_ALL_MODES, 100}, {TS811_ALL_MODES, kHz(1)}, {TS811_ALL_MODES, kHz(5)}, {TS811_ALL_MODES, kHz(9)}, {TS811_ALL_MODES, kHz(10)}, {TS811_ALL_MODES, 12500}, {TS811_ALL_MODES, kHz(20)}, {TS811_ALL_MODES, kHz(25)}, {TS811_ALL_MODES, kHz(100)}, {TS811_ALL_MODES, MHz(1)}, {TS811_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts811_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts811_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/ts990s.h0000664000175000017500000000172115056640443012313 /* * Hamlib Kenwood backend - main header * Copyright (c) 2015 by Bill Somerville G4WJS * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef TS990S_H__ #define TS990S_H__ #include "hamlib/rig.h" extern struct rig_caps ts990s_caps; #endif hamlib-4.6.5/rigs/kenwood/trc80.c0000664000175000017500000001261615056640443012200 /* * Hamlib Kenwood backend - TRC-80 description * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "kenwood.h" #define TRC80_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_RTTY) #define TRC80_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRC80_AM_TX_MODES RIG_MODE_AM /* TODO: make sure they are implemented by kenwood generic backend, and compatible */ #define TRC80_FUNC_ALL (RIG_FUNC_TUNER|RIG_FUNC_AIP|\ RIG_FUNC_TONE|RIG_FUNC_AIP|RIG_FUNC_NB|RIG_FUNC_VOX) #define TRC80_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_MICGAIN|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_CWPITCH|RIG_LEVEL_BKIN_DLYMS|\ RIG_LEVEL_SQL|RIG_LEVEL_VOXDELAY) #define TRC80_PARMS (RIG_PARM_NONE) #define TRC80_VFO_OPS (RIG_OP_NONE) #define TRC80_SCAN_OPS (RIG_SCAN_VFO) #define TRC80_VFO (RIG_VFO_MEM) #define TRC80_ANTS (0) #define TRC80_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps trc80_priv_caps = { .cmdtrm = EOM_KEN, }; /* * TRC-80/TK-80 rig capabilities. */ struct rig_caps trc80_caps = { RIG_MODEL(RIG_MODEL_TRC80), .model_name = "TRC-80", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .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_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 1000, .retry = 3, .has_get_func = TRC80_FUNC_ALL, .has_set_func = TRC80_FUNC_ALL, .has_get_level = TRC80_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TRC80_LEVEL_ALL), .has_get_parm = TRC80_PARMS, .has_set_parm = RIG_LEVEL_SET(TRC80_PARMS), /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(1.1), .max_xit = 0, .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TRC80_VFO_OPS, .scan_ops = TRC80_SCAN_OPS, .chan_list = { { 1, 80, RIG_MTYPE_MEM, TRC80_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TRC80_ALL_MODES, -1, -1, TRC80_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(1.8), MHz(30), TRC80_OTHER_TX_MODES, W(15), W(100), TRC80_VFO, TRC80_ANTS}, {MHz(1.8), MHz(30), TRC80_AM_TX_MODES, W(5), W(25), TRC80_VFO, TRC80_ANTS}, /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRC80_ALL_MODES, -1, -1, TRC80_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(1.8), MHz(30), TRC80_OTHER_TX_MODES, W(15), W(100), TRC80_VFO, TRC80_ANTS}, {MHz(1.8), MHz(30), TRC80_AM_TX_MODES, W(5), W(25), TRC80_VFO, TRC80_ANTS}, /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TRC80_ALL_MODES, 1}, {TRC80_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_AM, kHz(5)}, RIG_FLT_END, }, .priv = (void *)& trc80_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, #ifdef XXREMOVEDXX .set_freq = kenwood_set_freq, #endif .get_freq = kenwood_get_freq_if, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .scan = kenwood_scan, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/Android.mk0000664000175000017500000000113615056640443013000 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c \ ts440.c ts940.c ts711.c ts811.c r5000.c \ thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c \ kenwood.c th.c ic10.c elecraft.c transfox.c flex6xxx.c ts990s.c \ xg3.c thd74.c flex.c pihpsdr.c ts890s.c LOCAL_MODULE := kenwood LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/kenwood/th.h0000664000175000017500000000727315056640443011663 /* * Hamlib Kenwood backend - TH handheld header * Copyright (c) 2001-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef __TH_H__ #define __TH_H__ 1 #include #include "rig.h" #define TH_VER "20231001" extern int th_transaction (RIG *rig, const char *cmdstr, char *data, size_t datasize); extern int th_get_vfo_char(RIG *rig, vfo_t *vfo, char *vfoch); extern int th_decode_event (RIG *rig); extern int th_set_freq (RIG *rig, vfo_t vfo, freq_t freq); extern int th_get_freq (RIG *rig, vfo_t vfo, freq_t *freq); extern int th_set_mode (RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int th_get_mode (RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int th_set_vfo(RIG *rig, vfo_t vfo); extern int th_get_vfo(RIG *rig, vfo_t *vfo); extern int tm_set_vfo_bc2 (RIG *rig, vfo_t vfo); extern int th_set_split_vfo (RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); extern int th_get_split_vfo (RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); extern int th_set_trn(RIG *rig, int trn); extern int th_get_trn (RIG *rig, int *trn); extern int th_set_powerstat (RIG *rig, powerstat_t status); extern int th_get_powerstat (RIG *rig, powerstat_t *status); extern int th_set_func (RIG *rig, vfo_t vfo, setting_t func, int status); extern int th_get_func (RIG *rig, vfo_t vfo, setting_t func, int *status); extern int th_set_parm (RIG *rig, setting_t parm, value_t val); extern int th_get_parm (RIG *rig, setting_t parm, value_t *val); extern int th_get_level (RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern int th_set_level (RIG *rig, vfo_t vfo, setting_t level, value_t val); extern int th_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); extern int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); extern int th_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); extern int th_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); extern int th_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); extern int th_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); extern const char *th_get_info(RIG *rig); extern int th_set_mem(RIG *rig, vfo_t vfo, int ch); extern int th_get_mem(RIG *rig, vfo_t vfo, int *ch); extern int th_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); extern int th_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); extern int th_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); extern int th_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); extern int th_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); extern int th_set_ant (RIG * rig, vfo_t vfo, ant_t ant, value_t option); extern int th_get_ant (RIG * rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t * ant_curr, ant_t *ant_tx, ant_t *ant_rx); extern int th_reset(RIG *rig, reset_t reset); extern int th_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); #define TH_CHANNEL_CAPS \ .freq=1,\ .tx_freq=1,\ .split=1,\ .mode=1,\ .width=1,\ .tuning_step=1,\ .rptr_shift=1,\ .rptr_offs=1,\ .funcs=RIG_FUNC_REV,\ .ctcss_tone=1,\ .ctcss_sql=1,\ .channel_desc=1 #endif /* __TH_H__ */ /* end of file */ hamlib-4.6.5/rigs/kenwood/ts2000.c0000664000175000017500000020463215056640443012171 /* * Hamlib Kenwood backend - TS2000 description * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2023 by Mikael Nousiainen * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "token.h" #include "misc.h" #include "iofunc.h" #include "cal.h" #define TS2000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS2000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS2000_AM_TX_MODES RIG_MODE_AM #define TS2000_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS2000_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define SDRCONSOLE_LEVEL_GET (|RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH|RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define SDRCONSOLE_LEVEL_SET (RIG_LEVEL_NONE) #define TS2000_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_ANF) #define TS2000_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define TS2000_SUBVFO (RIG_VFO_C) #define TS2000_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) #define TS2000_SCAN_OP (RIG_SCAN_VFO) #define TS2000_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS2000_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } #define TS2000_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 4, 1.5f }, \ { 8, 2.0f }, \ { 12, 3.0f }, \ { 20, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_DSP_TX_BANDWIDTH TOKEN_BACKEND(106) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) /* * 38 CTCSS sub-audible tones + 1750 tone */ tone_t ts2000_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 17500, 0, }; /* * 103 available DCS codes */ tone_t ts2000_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; int ts2000_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_FUNC_FILTER_WIDTH_DATA, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_DSP_TX_BANDWIDTH, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_BACKEND_NONE, }; const struct confparams ts2000_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts2000_ext_levels[] = { { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } }, { TOK_LEVEL_DSP_TX_BANDWIDTH, "DSP_TX_BANDWIDTH", "DSP TX bandwidth", "DSP TX bandwidth for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2.0 kHz", "2.2 kHz", "2.4 kHz", "2.6 kHz", "2.8 kHz", "3.0 kHz", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { RIG_CONF_END, NULL, } }; static struct kenwood_filter_width ts2000_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_SSB, 1, 500 }, // NAR1 optional filter { RIG_MODE_SSB, 2, 270 }, // NAR2 optional filter { RIG_MODE_FM, 0, 6000 }, { RIG_MODE_FM, 1, 12000 }, { RIG_MODE_AM, 0, 2400 }, { RIG_MODE_AM, 1, 6000 }, // NAR1 optional filter (?) { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts2000_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 2000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 2200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 3000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 3400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 4000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 5000 }, { RIG_MODE_AM, 0, 0, 2500 }, { RIG_MODE_AM, 0, 1, 3000 }, { RIG_MODE_AM, 0, 2, 4000 }, { RIG_MODE_AM, 0, 3, 5000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 170 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1930 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 2160 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts2000_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 10, 1, 1000 }, { RIG_MODE_AM, 0, 0, 0 }, { RIG_MODE_AM, 0, 1, 100 }, { RIG_MODE_AM, 0, 2, 200 }, { RIG_MODE_AM, 0, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 2500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1000 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts2000_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts2000_filter_width, .slope_filter_high = ts2000_slope_filter_high, .slope_filter_low = ts2000_slope_filter_low, .tone_table_base = 1, }; /* memory capabilities */ #define TS2000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * Function definitions below */ int ts2000_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv = (struct kenwood_priv_data *) STATE(rig)->priv; priv->ag_format = 3; priv->micgain_min = 0; priv->micgain_max = 100; RETURNFUNC(RIG_OK); } static int ts2000_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts2000_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c%c", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); default: return kenwood_set_func(rig, vfo, func, status); } } static int ts2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0' || buf[3] != '0'; break; default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } /* * WARNING: The commands differ slightly from the general versions in kenwood.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ static int ts2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; char vfo_num = (vfo == RIG_VFO_C) ? '1' : '0'; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RF: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: return kenwood_set_level(rig, vfo, level, val); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%c%03d", vfo_num, kenwood_val); break; case RIG_LEVEL_AGC: /* Possible values for TS-2000 are 0(=off)-020(=slow) */ switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: kenwood_val = 1; break; case RIG_AGC_FAST: kenwood_val = 5; break; case RIG_AGC_MEDIUM: kenwood_val = 10; break; case RIG_AGC_SLOW: kenwood_val = 20; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_METER: switch (val.i) { case RIG_METER_SWR: kenwood_val = 1; break; case RIG_METER_COMP: kenwood_val = 2; break; case RIG_METER_ALC: kenwood_val = 3; break; default: RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RM%d", kenwood_val); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(ts2000_set_ex_menu(rig, 31, 2, (val.i - 400) / 50)); default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } // TS-2000 can only read one meter at a time and the user must select // the meter using RIG_LEVEL_METER. This function returns the meter value if // the selected meter matches the expected meter. static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) { int retval; char cmdbuf[8]; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 8; int read_meter; int read_value; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "RM;"); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-2000 returns values for a single meter at the same time, for example: RM10000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM%1d%d;", &read_meter, &read_value); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: expected 2 values to parse for meters, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } if (read_meter == expected_meter) { *value = read_value; } else { *value = 0; } RETURNFUNC(RIG_OK); } static int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[8]; char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint; int retval; char vfo_num = (vfo == RIG_VFO_C) ? '1' : '0'; ENTERFUNC; switch (level) { case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 255; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "SQ%c", vfo_num); retval = kenwood_transaction(rig, cmdbuf, ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (retval != RIG_OK) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint) != 1) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.f; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } if (levelint == 0) { val->i = RIG_AGC_OFF; } else if (levelint <= 1) { val->i = RIG_AGC_SUPERFAST; } else if (levelint <= 5) { val->i = RIG_AGC_FAST; } else if (levelint <= 10) { val->i = RIG_AGC_MEDIUM; } else { val->i = RIG_AGC_SLOW; } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_NB: { int raw_value; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_METER: { int raw_value; // TODO: Read all meters at the same time: RM10000;RM20000;RM30000; retval = kenwood_safe_transaction(rig, "RM", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RM%1d", &raw_value); switch (raw_value) { case 1: val->i = RIG_METER_SWR; break; case 2: val->i = RIG_METER_COMP; break; case 3: val->i = RIG_METER_ALC; break; default: val->i = RIG_METER_NONE; } break; } case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int meter; int swr; int comp; int *value; int alc; switch (level) { case RIG_LEVEL_SWR: meter = 1; value = &swr; break; case RIG_LEVEL_COMP_METER: meter = 2; value = ∁ break; case RIG_LEVEL_ALC: meter = 3; value = &alc; break; default: RETURNFUNC(-RIG_EINVAL); } retval = ts2000_read_meter(rig, meter, value); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 20dB break; case RIG_LEVEL_ALC: // Maximum value is 20, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 4.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: { int raw_value; char read_vfo_num; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SM%c", vfo_num); retval = kenwood_safe_transaction(rig, cmdbuf, ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM%c%d", &read_vfo_num, &raw_value); if (vfo_num == '1') { val->f = (float) raw_value / 15.0f; } else { val->f = (float) raw_value / 30.0f; } break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts2000_get_ex_menu(rig, 31, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 400 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts2000_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -19999 || rit > 19999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts2000_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts2000_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 20, 1, val.i); break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 21, 1, val.i); break; case TOK_LEVEL_DSP_TX_BANDWIDTH: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 22, 1, val.i); break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 12, 1, (int) val.f); break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 13, 1, (int) val.f); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: retval = ts2000_get_ex_menu(rig, 20, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: retval = ts2000_get_ex_menu(rig, 21, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_BANDWIDTH: retval = ts2000_get_ex_menu(rig, 22, 1, &value); val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: retval = ts2000_get_ex_menu(rig, 12, 1, &value); val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: retval = ts2000_get_ex_menu(rig, 13, 1, &value); val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } /* * ts2000_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; size_t length; char buf[52]; char cmd[8]; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype = '0'; char buf[128]; char mode, tx_mode = 0; char shift = '0'; short dcscode = 0; short code = 0; int tstep = 0; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } /* * TS-2000 rig capabilities */ struct rig_caps ts2000_caps = { RIG_MODEL(RIG_MODEL_TS2000), .model_name = "TS-2000", .mfg_name = "Kenwood", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, /* ms */ .timeout = 200, .retry = 3, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_GET, .has_set_level = TS2000_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .parm_gran = {}, .vfo_ops = TS2000_VFO_OPS, .scan_ops = TS2000_SCAN_OP, .ctcss_list = ts2000_ctcss_list, .dcs_list = ts2000_dcs_list, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS2000_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1830), kHz(1850), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(142), MHz(152), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(420), MHz(450), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(118), MHz(174), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(220), MHz(512), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1800), MHz(2), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(148), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(148), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TS2000_ALL_MODES, 10}, {TS2000_ALL_MODES, 100}, {TS2000_ALL_MODES, kHz(1)}, {TS2000_ALL_MODES, kHz(2.5)}, {TS2000_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TS2000_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TS2000_ALL_MODES, MHz(1)}, {TS2000_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = TS2000_STR_CAL, .swr_cal = TS2000_SWR_CAL, .ext_tokens = ts2000_ext_tokens, .extfuncs = ts2000_ext_funcs, .extlevels = ts2000_ext_levels, .priv = (void *)& ts2000_priv_caps, .rig_init = ts2000_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts2000_set_rit, .get_rit = ts2000_get_rit, .set_xit = ts2000_set_rit, .get_xit = ts2000_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts2000_set_func, .get_func = ts2000_get_func, .set_level = ts2000_set_level, .get_level = ts2000_get_level, .set_ext_func = ts2000_set_ext_func, .get_ext_func = ts2000_get_ext_func, .set_ext_level = ts2000_set_ext_level, .get_ext_level = ts2000_get_ext_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = ts2000_get_channel, .set_channel = ts2000_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * SDRConsole TS-2000 rig capabilities * SDRConsole does not use hardware flow control for example */ struct rig_caps sdrconsole_caps = { RIG_MODEL(RIG_MODEL_SDRCONSOLE), .model_name = "SDRConsole", .mfg_name = "SDR Radio", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, /* ms */ .timeout = 200, .retry = 3, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_GET, .has_set_level = TS2000_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .parm_gran = {}, .vfo_ops = TS2000_VFO_OPS, .scan_ops = TS2000_SCAN_OP, .ctcss_list = ts2000_ctcss_list, .dcs_list = ts2000_dcs_list, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS2000_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1830), kHz(1850), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(142), MHz(152), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(420), MHz(450), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(118), MHz(174), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(220), MHz(512), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1800), MHz(2), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(148), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(148), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TS2000_ALL_MODES, 10}, {TS2000_ALL_MODES, 100}, {TS2000_ALL_MODES, kHz(1)}, {TS2000_ALL_MODES, kHz(2.5)}, {TS2000_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TS2000_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TS2000_ALL_MODES, MHz(1)}, {TS2000_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = TS2000_STR_CAL, .swr_cal = TS2000_SWR_CAL, .ext_tokens = ts2000_ext_tokens, .extfuncs = ts2000_ext_funcs, .extlevels = ts2000_ext_levels, .priv = (void *)& ts2000_priv_caps, .rig_init = ts2000_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, //.set_rit = ts2000_set_rit, //.get_rit = ts2000_get_rit, //.set_xit = ts2000_set_rit, //.get_xit = ts2000_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, //.set_ctcss_tone = kenwood_set_ctcss_tone_tn, //.get_ctcss_tone = kenwood_get_ctcss_tone, //.set_ctcss_sql = kenwood_set_ctcss_sql, //.get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, //.get_dcd = kenwood_get_dcd, //.set_func = ts2000_set_func, //.get_func = ts2000_get_func, .set_level = ts2000_set_level, .get_level = ts2000_get_level, //.set_ext_func = ts2000_set_ext_func, //.get_ext_func = ts2000_get_ext_func, //.set_ext_level = ts2000_set_ext_level, //.get_ext_level = ts2000_get_ext_level, //.set_ant = kenwood_set_ant, //.get_ant = kenwood_get_ant, //.send_morse = kenwood_send_morse, //.wait_morse = rig_wait_morse, //.send_voice_mem = kenwood_send_voice_mem, //.stop_voice_mem = kenwood_stop_voice_mem, //.vfo_op = kenwood_vfo_op, //.scan = kenwood_scan, //.set_mem = kenwood_set_mem, //.get_mem = kenwood_get_mem, //.get_channel = ts2000_get_channel, //.set_channel = ts2000_set_channel, //.set_trn = kenwood_set_trn, //.get_trn = kenwood_get_trn, //.set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/tmd700.c0000664000175000017500000001624715056640443012257 /* * Hamlib Kenwood backend - TM-D700 description * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "tones.h" #define TMD700_MODES (RIG_MODE_FM|RIG_MODE_AM) #define TMD700_MODES_TX (RIG_MODE_FM) /* TBC */ #define TMD700_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_MON| \ RIG_FUNC_MUTE| \ RIG_FUNC_SQL| \ RIG_FUNC_TONE| \ RIG_FUNC_TBURST| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO) #define TMD700_LEVEL_ALL (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_AF| \ RIG_LEVEL_RF|\ RIG_LEVEL_MICGAIN) #define TMD700_PARMS (RIG_PARM_BACKLIGHT|\ RIG_PARM_BEEP|\ RIG_PARM_APO) #define TMD700_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TMD700_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define TMD700_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* * TODO: Band A & B */ #define TMD700_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t tmd700_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps tmd700_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = tmd700_mode_table, }; /* * TM-D700 rig capabilities. * * specs: http://www.geocities.jp/hkwatarin/TM-D700/English/spec.htm * protocol: http://www.qsl.net/k/k7jar//pages/D700Cmds.html */ struct rig_caps tmd700_caps = { RIG_MODEL(RIG_MODEL_TMD700), .model_name = "TM-D700", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = TMD700_FUNC_ALL, .has_set_func = TMD700_FUNC_ALL, .has_get_level = TMD700_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD700_LEVEL_ALL), .has_get_parm = TMD700_PARMS, .has_set_parm = TMD700_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD700_VFO_OP, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 1, 199, RIG_MTYPE_MEM, {TMD700_CHANNEL_CAPS}}, /* normal MEM */ { 200, 219, RIG_MTYPE_EDGE, {TMD700_CHANNEL_CAPS}}, /* U/L MEM */ { 221, 222, RIG_MTYPE_CALL, {TMD700_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD700_MODES, -1, -1, RIG_VFO_A}, {MHz(136), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(300), MHz(524), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(800), MHz(1300), RIG_MODE_FM, -1, -1, RIG_VFO_B}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD700_MODES_TX, W(5), W(50), RIG_VFO_A}, {MHz(430), MHz(440), TMD700_MODES_TX, W(5), W(35), RIG_VFO_A}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD700_MODES, -1, -1, RIG_VFO_A}, {MHz(136), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(300), MHz(524), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(800), MHz(1300), RIG_MODE_FM, -1, -1, RIG_VFO_B}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD700_MODES_TX, W(5), W(50), RIG_VFO_A}, {MHz(430), MHz(450), TMD700_MODES_TX, W(5), W(35), RIG_VFO_A}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD700_MODES, kHz(5)}, {TMD700_MODES, kHz(6.25)}, {TMD700_MODES, kHz(10)}, {TMD700_MODES, kHz(12.5)}, {TMD700_MODES, kHz(15)}, {TMD700_MODES, kHz(20)}, {TMD700_MODES, kHz(25)}, {TMD700_MODES, kHz(30)}, {TMD700_MODES, kHz(50)}, {TMD700_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(9)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& tmd700_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = th_set_freq, .get_freq = th_get_freq, .set_mode = th_set_mode, .get_mode = th_get_mode, .set_vfo = tm_set_vfo_bc2, .get_vfo = th_get_vfo, .set_split_vfo = th_set_split_vfo, .get_split_vfo = th_get_split_vfo, .set_ctcss_tone = th_set_ctcss_tone, .get_ctcss_tone = th_get_ctcss_tone, .set_ctcss_sql = th_set_ctcss_sql, .get_ctcss_sql = th_get_ctcss_sql, .set_dcs_sql = th_set_dcs_sql, .get_dcs_sql = th_get_dcs_sql, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .set_parm = th_set_parm, .get_parm = th_get_parm, .get_info = th_get_info, .get_dcd = th_get_dcd, .set_ptt = th_set_ptt, .vfo_op = th_vfo_op, .scan = th_scan, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* end of file */ hamlib-4.6.5/rigs/kenwood/ts950.c0000664000175000017500000003042015056640443012115 /* * Hamlib Kenwood backend - TS950 description * Copyright (c) 2002-2012 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Edited by Martin Ewing AA6E, March, 2012 * The '950 has a relatively small command set. */ #include #include #include "kenwood.h" #define TS950_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS950_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS950_AM_TX_MODES RIG_MODE_AM #define TS950_VFO (RIG_VFO_A|RIG_VFO_B) #define TS950_GET_LEVEL (RIG_LEVEL_RAWSTR) // STR_CAL borrowed from TS850 #define TS950_STR_CAL { 4, \ { \ { 0, -54 }, \ { 15, 0 }, \ { 22,30 }, \ { 30, 66}, \ } } #define cmd_trm(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv)->cmdtrm static struct kenwood_priv_caps ts950_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * This backend should work with all models in the TS-950 series (TS-950S, SDX, etc.) * There are minor differences between the SDX and other models, but they are * in commands not implemented here. * * Reference: TS-950 series External Control Instruction Manual (1992) */ struct rig_caps ts950s_caps = { RIG_MODEL(RIG_MODEL_TS950S), .model_name = "TS-950S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 600, // this rig takes over 250ms to respond an IF command .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TS950_GET_LEVEL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* atten settings are not available in CAT interface */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS950_ALL_MODES, -1, -1, TS950_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(3500), MHz(4) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(7), kHz(7300), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(7), kHz(7300), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(10100), kHz(10150), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(10100), kHz(10150), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(14), kHz(14350), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(14), kHz(14350), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(18068), kHz(18168), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(18068), kHz(18168), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(21), kHz(21450), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(21), kHz(21450), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(24890), kHz(24990), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(24890), kHz(24990), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(28), kHz(29700), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(28), kHz(29700), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS950_ALL_MODES, 50}, {TS950_ALL_MODES, 100}, {TS950_ALL_MODES, kHz(1)}, {TS950_ALL_MODES, kHz(5)}, {TS950_ALL_MODES, kHz(9)}, {TS950_ALL_MODES, kHz(10)}, {TS950_ALL_MODES, 12500}, {TS950_ALL_MODES, kHz(20)}, {TS950_ALL_MODES, kHz(25)}, {TS950_ALL_MODES, kHz(100)}, {TS950_ALL_MODES, MHz(1)}, {TS950_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .str_cal = TS950_STR_CAL, .priv = (void *)& ts950_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, /* Things that the '950 doesn't do ... * .set_func = kenwood_set_func, * .get_func = kenwood_get_func, * .set_level = kenwood_set_level, */ .get_level = kenwood_get_level, /* * .send_morse = kenwood_send_morse, */ .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ts950sdx_caps = { RIG_MODEL(RIG_MODEL_TS950SDX), .model_name = "TS-950SDX", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 600, // this rig takes over 250ms to respond an IF command .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TS950_GET_LEVEL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* atten settings are not available in CAT interface */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS950_ALL_MODES, -1, -1, TS950_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(3500), MHz(4) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(7), kHz(7300), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(7), kHz(7300), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(10100), kHz(10150), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(10100), kHz(10150), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(14), kHz(14350), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(14), kHz(14350), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(18068), kHz(18168), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(18068), kHz(18168), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(21), kHz(21450), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(21), kHz(21450), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(24890), kHz(24990), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(24890), kHz(24990), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(28), kHz(29700), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(28), kHz(29700), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS950_ALL_MODES, 50}, {TS950_ALL_MODES, 100}, {TS950_ALL_MODES, kHz(1)}, {TS950_ALL_MODES, kHz(5)}, {TS950_ALL_MODES, kHz(9)}, {TS950_ALL_MODES, kHz(10)}, {TS950_ALL_MODES, 12500}, {TS950_ALL_MODES, kHz(20)}, {TS950_ALL_MODES, kHz(25)}, {TS950_ALL_MODES, kHz(100)}, {TS950_ALL_MODES, MHz(1)}, {TS950_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .str_cal = TS950_STR_CAL, .priv = (void *)& ts950_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, /* Things that the '950 doesn't do ... * .set_func = kenwood_set_func, * .get_func = kenwood_get_func, * .set_level = kenwood_set_level, */ .get_level = kenwood_get_level, /* * .send_morse = kenwood_send_morse, */ .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/tmv7.c0000664000175000017500000005305415056640443012136 /* * 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #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, vfo_t vfo, channel_t *chan, int read_only); static int tmv7_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); /* * tm-v7 rig capabilities. */ struct rig_caps tmv7_caps = { RIG_MODEL(RIG_MODEL_TMV7), .model_name = "TM-V7", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .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 = { #include "level_gran_kenwood.h" }, .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_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .str_cal = { 4, { {0, -60 }, {1, -30,}, {5, 0}, {7, 20}}}, /* rough guess */ .priv = (void *)& tmv7_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .rig_close = kenwood_close, .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, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* --------------------------------------------------------------------- */ int tmv7_decode_event(RIG *rig) { char asyncbuf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); 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)\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,%u", &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 - %u\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; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); break; case RIG_VFO_B: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 1,0"); break; case RIG_VFO_MEM: SNPRINTF(vfobuf, sizeof(vfobuf), "BC"); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "VMC %c,2", ackbuf[3]); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad return \n", __func__); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: next %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "BC 0,0"); break; case RIG_VFO_B: SNPRINTF(vfobuf, sizeof(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__); retval = kenwood_transaction(rig, vfobuf, NULL, 0); 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; 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 %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } /* try to guess from frequency */ retval = kenwood_transaction(rig, "FQ", ackbuf, sizeof(ackbuf)); 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, vfo_t vfo, channel_t *chan, int read_only) { char membuf[64], ackbuf[ACKBUF_LEN]; int retval; freq_t freq; char req[32], scf[128]; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; if (chan->channel_num < 100) { SNPRINTF(req, sizeof(req), "MR 0,0,%03d", chan->channel_num); } else if (chan->channel_num < 200) { SNPRINTF(req, sizeof(req), "MR 1,0,%03d", chan->channel_num - 100); } else if (chan->channel_num < 204) { SNPRINTF(req, sizeof(req), "MR 0,0,L%01d", chan->channel_num - 200); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d/V", chan->channel_num - 200); } else if (chan->channel_num < 211) { SNPRINTF(req, sizeof(req), "MR 1,0,L%01d", chan->channel_num - 203); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d/U", chan->channel_num - 203); } else if (chan->channel_num < 214) { SNPRINTF(req, sizeof(req), "MR 0,0,U%01d", chan->channel_num - 210); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d/V", chan->channel_num - 210); } else if (chan->channel_num < 220) { SNPRINTF(req, sizeof(req), "MR 1,0,U%01d", chan->channel_num - 213); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d/U", chan->channel_num - 213); } else if (chan->channel_num < 223) { if (chan->channel_num == 221) { SNPRINTF(req, sizeof(req), "CR 0,0"); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call V"); } if (chan->channel_num == 222) { SNPRINTF(req, sizeof(req), "CR 1,0"); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call U"); } } else { return -RIG_EINVAL; } SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); 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 = STATE(rig)->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'; SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval == RIG_OK) { strcpy(scf, req); strcat(scf, ",%"SCNfreq",%d"); num_sscanf(ackbuf, scf, &freq, &step); chan->tx_freq = freq; } } if (chan->channel_num < 200) { if (chan->channel_num < 100) { SNPRINTF(membuf, sizeof(membuf), "MNA 0,%03d", chan->channel_num); } else { SNPRINTF(membuf, sizeof(membuf), "MNA 1,%03d", chan->channel_num - 100); } retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } memcpy(chan->channel_desc, &ackbuf[10], 7); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* --------------------------------------------------------------------- */ int tmv7_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[ACKBUF_LEN]; int retval; char req[64]; long freq; int step, shift, tone, ctcss, tonefq, ctcssfq; freq = (long)chan->freq; for (step = 0; STATE(rig)->tuning_steps[step].ts != 0; step++) if (chan->tuning_step == STATE(rig)->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++) { 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++) { if (rig->caps->ctcss_list[ctcssfq] == chan->ctcss_sql) { break; } } ctcssfq = ctcssfq == 0 ? 1 : ctcssfq + 2; } if (chan->channel_num < 100) { SNPRINTF(req, sizeof(req), "MW 0,0,%03d", chan->channel_num); } else if (chan->channel_num < 200) { SNPRINTF(req, sizeof(req), "MW 1,0,%03d", chan->channel_num - 100); } else if (chan->channel_num < 204) { SNPRINTF(req, sizeof(req), "MW 0,0,L%01d", chan->channel_num - 200); } else if (chan->channel_num < 211) { SNPRINTF(req, sizeof(req), "MW 1,0,L%01d", chan->channel_num - 203); } else if (chan->channel_num < 214) { SNPRINTF(req, sizeof(req), "MW 0,0,U%01d", chan->channel_num - 210); } else if (chan->channel_num < 220) { SNPRINTF(req, sizeof(req), "MW 1,0,U%01d", chan->channel_num - 213); } else if (chan->channel_num < 223) { if (chan->channel_num == 221) { SNPRINTF(req, sizeof(req), "CW 0,0"); } if (chan->channel_num == 222) { SNPRINTF(req, sizeof(req), "CW 1,0"); } } else { return -RIG_EINVAL; } if (chan->channel_num < 221) { SNPRINTF(membuf, sizeof(membuf), "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,0,0", req, (long)freq, step, shift, tone, ctcss, tonefq, ctcssfq); } else { SNPRINTF(membuf, sizeof(membuf), "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,", req, (long)freq, step, shift, tone, ctcss, tonefq, ctcssfq); } retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } if (chan->tx_freq != RIG_FREQ_NONE) { req[5] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%01d", req, (int64_t)chan->tx_freq, step); retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } } if (chan->channel_num < 200) { if (chan->channel_num < 100) { SNPRINTF(membuf, sizeof(membuf), "MNA 0,%03d,%s", chan->channel_num, chan->channel_desc); } else { SNPRINTF(membuf, sizeof(membuf), "MNA 1,%03d,%s", chan->channel_num - 100, chan->channel_desc); } retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } hamlib-4.6.5/rigs/kenwood/Makefile.in0000664000175000017500000007272215056640452013145 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/kenwood ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_kenwood_la_LIBADD = am__objects_1 = ts850.lo ts870s.lo ts570.lo ts450s.lo ts950.lo \ ts50s.lo ts790.lo ts2000.lo k2.lo k3.lo xg3.lo ts930.lo \ ts680.lo ts690.lo ts140.lo ts480.lo trc80.lo ts590.lo \ ts890s.lo ts990s.lo flex6xxx.lo pihpsdr.lo tx500.lo am__objects_2 = thd7.lo thf7.lo thg71.lo tmd700.lo tmv7.lo thf6a.lo \ thd72.lo tmd710.lo thd74.lo am__objects_3 = ts440.lo ts940.lo ts711.lo ts811.lo r5000.lo am__objects_4 = kenwood.lo th.lo ic10.lo elecraft.lo transfox.lo \ flex.lo am_libhamlib_kenwood_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libhamlib_kenwood_la_OBJECTS = $(am_libhamlib_kenwood_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/elecraft.Plo ./$(DEPDIR)/flex.Plo \ ./$(DEPDIR)/flex6xxx.Plo ./$(DEPDIR)/ic10.Plo \ ./$(DEPDIR)/k2.Plo ./$(DEPDIR)/k3.Plo ./$(DEPDIR)/kenwood.Plo \ ./$(DEPDIR)/pihpsdr.Plo ./$(DEPDIR)/r5000.Plo \ ./$(DEPDIR)/th.Plo ./$(DEPDIR)/thd7.Plo ./$(DEPDIR)/thd72.Plo \ ./$(DEPDIR)/thd74.Plo ./$(DEPDIR)/thf6a.Plo \ ./$(DEPDIR)/thf7.Plo ./$(DEPDIR)/thg71.Plo \ ./$(DEPDIR)/tmd700.Plo ./$(DEPDIR)/tmd710.Plo \ ./$(DEPDIR)/tmv7.Plo ./$(DEPDIR)/transfox.Plo \ ./$(DEPDIR)/trc80.Plo ./$(DEPDIR)/ts140.Plo \ ./$(DEPDIR)/ts2000.Plo ./$(DEPDIR)/ts440.Plo \ ./$(DEPDIR)/ts450s.Plo ./$(DEPDIR)/ts480.Plo \ ./$(DEPDIR)/ts50s.Plo ./$(DEPDIR)/ts570.Plo \ ./$(DEPDIR)/ts590.Plo ./$(DEPDIR)/ts680.Plo \ ./$(DEPDIR)/ts690.Plo ./$(DEPDIR)/ts711.Plo \ ./$(DEPDIR)/ts790.Plo ./$(DEPDIR)/ts811.Plo \ ./$(DEPDIR)/ts850.Plo ./$(DEPDIR)/ts870s.Plo \ ./$(DEPDIR)/ts890s.Plo ./$(DEPDIR)/ts930.Plo \ ./$(DEPDIR)/ts940.Plo ./$(DEPDIR)/ts950.Plo \ ./$(DEPDIR)/ts990s.Plo ./$(DEPDIR)/tx500.Plo \ ./$(DEPDIR)/xg3.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_kenwood_la_SOURCES) DIST_SOURCES = $(libhamlib_kenwood_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TSSRC = ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c xg3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c ts890s.c \ ts990s.c ts990s.h flex6xxx.c pihpsdr.c tx500.c IC10SRC = ts440.c ts940.c ts711.c ts811.c r5000.c THSRC = thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c thd74.c KENWOODSRC = kenwood.c kenwood.h th.c th.h ic10.c ic10.h elecraft.c elecraft.h \ transfox.c flex.c flex.h level_gran_kenwood.h level_gran_elecraft.h noinst_LTLIBRARIES = libhamlib-kenwood.la libhamlib_kenwood_la_SOURCES = $(TSSRC) $(THSRC) $(IC10SRC) $(KENWOODSRC) EXTRA_DIST = README.kenwood README.k2 README.k3 README.flex Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kenwood/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kenwood/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-kenwood.la: $(libhamlib_kenwood_la_OBJECTS) $(libhamlib_kenwood_la_DEPENDENCIES) $(EXTRA_libhamlib_kenwood_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_kenwood_la_OBJECTS) $(libhamlib_kenwood_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elecraft.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flex6xxx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/k2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/k3.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kenwood.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pihpsdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd72.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd74.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thf6a.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thf7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thg71.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmd700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmd710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmv7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfox.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trc80.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts140.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts440.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts450s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts480.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts50s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts570.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts590.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts680.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts690.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts711.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts790.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts811.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts850.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts870s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts890s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts930.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts940.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts990s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xg3.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/elecraft.Plo -rm -f ./$(DEPDIR)/flex.Plo -rm -f ./$(DEPDIR)/flex6xxx.Plo -rm -f ./$(DEPDIR)/ic10.Plo -rm -f ./$(DEPDIR)/k2.Plo -rm -f ./$(DEPDIR)/k3.Plo -rm -f ./$(DEPDIR)/kenwood.Plo -rm -f ./$(DEPDIR)/pihpsdr.Plo -rm -f ./$(DEPDIR)/r5000.Plo -rm -f ./$(DEPDIR)/th.Plo -rm -f ./$(DEPDIR)/thd7.Plo -rm -f ./$(DEPDIR)/thd72.Plo -rm -f ./$(DEPDIR)/thd74.Plo -rm -f ./$(DEPDIR)/thf6a.Plo -rm -f ./$(DEPDIR)/thf7.Plo -rm -f ./$(DEPDIR)/thg71.Plo -rm -f ./$(DEPDIR)/tmd700.Plo -rm -f ./$(DEPDIR)/tmd710.Plo -rm -f ./$(DEPDIR)/tmv7.Plo -rm -f ./$(DEPDIR)/transfox.Plo -rm -f ./$(DEPDIR)/trc80.Plo -rm -f ./$(DEPDIR)/ts140.Plo -rm -f ./$(DEPDIR)/ts2000.Plo -rm -f ./$(DEPDIR)/ts440.Plo -rm -f ./$(DEPDIR)/ts450s.Plo -rm -f ./$(DEPDIR)/ts480.Plo -rm -f ./$(DEPDIR)/ts50s.Plo -rm -f ./$(DEPDIR)/ts570.Plo -rm -f ./$(DEPDIR)/ts590.Plo -rm -f ./$(DEPDIR)/ts680.Plo -rm -f ./$(DEPDIR)/ts690.Plo -rm -f ./$(DEPDIR)/ts711.Plo -rm -f ./$(DEPDIR)/ts790.Plo -rm -f ./$(DEPDIR)/ts811.Plo -rm -f ./$(DEPDIR)/ts850.Plo -rm -f ./$(DEPDIR)/ts870s.Plo -rm -f ./$(DEPDIR)/ts890s.Plo -rm -f ./$(DEPDIR)/ts930.Plo -rm -f ./$(DEPDIR)/ts940.Plo -rm -f ./$(DEPDIR)/ts950.Plo -rm -f ./$(DEPDIR)/ts990s.Plo -rm -f ./$(DEPDIR)/tx500.Plo -rm -f ./$(DEPDIR)/xg3.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/elecraft.Plo -rm -f ./$(DEPDIR)/flex.Plo -rm -f ./$(DEPDIR)/flex6xxx.Plo -rm -f ./$(DEPDIR)/ic10.Plo -rm -f ./$(DEPDIR)/k2.Plo -rm -f ./$(DEPDIR)/k3.Plo -rm -f ./$(DEPDIR)/kenwood.Plo -rm -f ./$(DEPDIR)/pihpsdr.Plo -rm -f ./$(DEPDIR)/r5000.Plo -rm -f ./$(DEPDIR)/th.Plo -rm -f ./$(DEPDIR)/thd7.Plo -rm -f ./$(DEPDIR)/thd72.Plo -rm -f ./$(DEPDIR)/thd74.Plo -rm -f ./$(DEPDIR)/thf6a.Plo -rm -f ./$(DEPDIR)/thf7.Plo -rm -f ./$(DEPDIR)/thg71.Plo -rm -f ./$(DEPDIR)/tmd700.Plo -rm -f ./$(DEPDIR)/tmd710.Plo -rm -f ./$(DEPDIR)/tmv7.Plo -rm -f ./$(DEPDIR)/transfox.Plo -rm -f ./$(DEPDIR)/trc80.Plo -rm -f ./$(DEPDIR)/ts140.Plo -rm -f ./$(DEPDIR)/ts2000.Plo -rm -f ./$(DEPDIR)/ts440.Plo -rm -f ./$(DEPDIR)/ts450s.Plo -rm -f ./$(DEPDIR)/ts480.Plo -rm -f ./$(DEPDIR)/ts50s.Plo -rm -f ./$(DEPDIR)/ts570.Plo -rm -f ./$(DEPDIR)/ts590.Plo -rm -f ./$(DEPDIR)/ts680.Plo -rm -f ./$(DEPDIR)/ts690.Plo -rm -f ./$(DEPDIR)/ts711.Plo -rm -f ./$(DEPDIR)/ts790.Plo -rm -f ./$(DEPDIR)/ts811.Plo -rm -f ./$(DEPDIR)/ts850.Plo -rm -f ./$(DEPDIR)/ts870s.Plo -rm -f ./$(DEPDIR)/ts890s.Plo -rm -f ./$(DEPDIR)/ts930.Plo -rm -f ./$(DEPDIR)/ts940.Plo -rm -f ./$(DEPDIR)/ts950.Plo -rm -f ./$(DEPDIR)/ts990s.Plo -rm -f ./$(DEPDIR)/tx500.Plo -rm -f ./$(DEPDIR)/xg3.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/kenwood/README.k30000664000175000017500000001262515056640443012270 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 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() ============ The K3's use of VFO A and VFO B differs from other rigs in that VFO A is *always* the main or upper display and VFO B is *always* the sub or lower display. The A/B panel button simply swaps the contents of the two displays. The K3 manual states that VFO A is always the receive frequency and VFO B is the transmit frequency in split mode. This is complicated somewhat when the second receiver is installed and VFO B serves as its display frequency *and* the transmit frequency in split mode. Got that? Good! As a result of the above, I found that using the kenwood_set_vfo function had the side effect of clearing the rig out of split mode when the VFO was set to RIG_VFO_B. The Kenwood command 'FT1;' is used to make VFO B the transmitting VFO while this command will cause the K3 to enter split mode. Likewise, the Kenwood command 'FR1;' is used to set VFO B as the receiving VFO while the K3 exits split mode when it receives *any* set value for 'FR'. My solution is to simply issue the 'SWT11;' command which emulates tapping the A/B button on the K3's front panel to swap the displays when the k3_set_vfo function is called with RIG_VFO_B. Any other vfo value leaves the display alone. Feedback on improving this function is welcome. k3_get_mode() k3_get_mode() =========================== As an extension to the common Kenwood mode definitions, the K3 implements the custom 'DT' command which can query and set its data sub-modes. These are as follows: DT0 DATA A DT1 AFSK A DT2 FSK D DT3 PSK D The main difference is that DT0 and DT1 are for soundcard audio modes from a computer such as PSK31, MFSK, Olivia, etc. with DT1 being "optimized for RTTY". Conversely, DT2 and DT3 utilize "direct FSK in" on the accessory jack as well as enable the K3's internal encoding/decoding of RTTY and PSK31 modes (outside the realm of Hamlib). As implemented the k3_get_mode function will query the data sub-mode when the kenwood_get_mode function returns RIG_MODE_RTTY or RIG_MODE_RTTYR. As of k3 backend version 20101027 the following will be returned: MD6 MD9 DT0 RIG_MODE_PKTUSB RIG_MODE_PKTLSB DT1 RIG_MODE_RTTY RIG_MODE_RTTYR DT2 N/A N/A DT3 N/A N/A Perhaps it would be preferable to return the RTTY modes when DT2 is detected. Feedback is requested. Mode setting is little different as the MD and DT values will be set as above for the Hamlib RIG_MODE values. Feedback is requested on whether RTTY/RTTYR should map to AFSK A (DT1) or FSK D (DT2). The K3 can set any bandwidth in any mode using its custom 'BW' command. Band- width values are sent to the K3 in 10 Hz increments and the K3 will round down to the nearest 100 Hz values from 10 to 40 Hz. It will round down to the nearest 50 Hz values from 50 to 90 Hz. As an example, sending 'BW0236' (2360 in rigctl) will set the bandwidth to 2350 Hz (rounded down by the K3). The k3_get_mode function will query and return the actual bandwidth in use in Hertz. k3_set_ext_level() ================== This function is used to set the K3 for some extra level functions (rigctl command examples shown). To clear the RIT and XIT offset, use the 'L' command with the token name 'ritclr' for 'Level' to set in rigctl[d]. The prompted value is not used and can be safely set to 0. Use this level to clear the RIT and XIT offsets when it is not desired to turn RIT|XIT off. k3_get_ext_level() ================== This function is used to query the K3 for some extra information (rigctl command examples shown). To query the IF center frequency, use the 'l' command with the token name 'ifctr' for 'Level' to read in rigctl[d]. Value returned is 8210000.0 + queried value from rig (see K3 Programmers Reference, FI command). Returned type is a floating point value. To query the TX status, use the 'l' command with the token name 'txst' for 'Level' to read in rigctl[d]. Value returned is 1 for K3 in transmit mode and 0 for receive mode. Returned type is an integer. kenwood_get/set_ext_parms() =========================== These functions are used to get and set RIT/XIT on and off. The special token names of 'rit' and 'xit' are used with the P/p commands of rigctl[d] for the 'parm'. Set/returned value is 0 or 1 for off or on. hamlib-4.6.5/rigs/kenwood/elecraft.c0000664000175000017500000004364615056640443013034 /* * Hamlib Elecraft backend--support Elecraft extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2011 by Alexander Sack, Alexander Sack, pisymbol@gmail.com * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include "serial.h" #include "elecraft.h" #include "kenwood.h" #include "misc.h" static const struct elec_ext_id_str elec_ext_id_str_lst[] = { { K20, "K20" }, { K21, "K21" }, { K22, "K22" }, { K23, "K23" }, { K30, "K30" }, { K31, "K31" }, { EXT_LEVEL_NONE, NULL }, /* end marker */ }; /* K3 firmware revision level, will be assigned to the fw_rev pointer in * kenwood_priv_data structure at runtime in electraft_open(). The array is * declared here so that the sizeof operator can be used in the call to * elecraft_get_firmware_revision_level() to calculate the exact size of the * array for the call to strncpy(). */ static char k3_fw_rev[KENWOOD_MAX_BUF_LEN]; /* Private Elecraft extra levels definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams elecraft_ext_levels[] = { { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } }, { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { RIG_CONF_END, NULL, } }; /* Private function declarations */ int verify_kenwood_id(RIG *rig, char *id); int elecraft_get_extension_level(RIG *rig, const char *cmd, int *ext_level); int elecraft_get_firmware_revision_level(RIG *rig, const char *cmd, char *fw_rev, size_t fw_rev_sz); /* Shared backend function definitions */ /* elecraft_open() * * First checks for ID of '017' then tests for an Elecraft radio/backend using * the K2; command. Here we also test for a K3 and if that fails, assume a K2. * Finally, save the value for later reading. * */ int elecraft_open(RIG *rig) { int err; char buf[KENWOOD_MAX_BUF_LEN]; char *model = "Unknown"; struct rig_state *rs = STATE(rig); struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, rig version=%s\n", __func__, rig->caps->version); if (rs->auto_power_on && priv->poweron == 0) { rig_set_powerstat(rig, 1); priv->poweron = 1; } /* Actual read extension levels from radio. * * The value stored in the k?_ext_lvl variables map to * elec_ext_id_str_lst.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! */ /* As k3_fw_rev is declared static, it is persistent so the structure * can point to it. This way was chosen to allow the compiler to * calculate the size of the array to resolve a bug found by gcc 4.8.x */ priv->fw_rev = k3_fw_rev; /* Use check for "ID017;" to verify rig is reachable */ rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%u,%d\n", __func__, rig->caps->rig_model, RIG_MODEL_XG3); if (rig->caps->rig_model == RIG_MODEL_XG3) // XG3 doesn't have ID { char *cmd = "V;"; char data[32]; strcpy(data, "EMPTY"); // Not going to get carried away with retries and such err = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: XG3 cannot request identification\n", __func__); return err; } err = read_string(rp, (unsigned char *) buf, sizeof(buf), ";", 1, 0, 1); if (err < 0) { rig_debug(RIG_DEBUG_TRACE, "%s: XG3 cannot get identification\n", __func__); return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: id=%s\n", __func__, buf); #if 0 if (err != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: cannot get identification\n", __func__); return err; } #endif } else // Standard Kenwood { err = verify_kenwood_id(rig, buf); if (err != RIG_OK) { return err; } } priv->save_k2_ext_lvl = -1; // so we don't restore if not neeede if (rig->caps->rig_model != RIG_MODEL_XG3) // XG3 doesn't have extended { err = elecraft_get_extension_level(rig, "K2", &priv->save_k2_ext_lvl); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting K2 ext_lvl: %s\n", __func__, rigerror(err)); return err; } // turn on k2 extended to get PC values in more resolution err = kenwood_transaction(rig, "K22;", NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting K22='%s'...continuing\n", __func__, rigerror(err)); } } switch (rig->caps->rig_model) { case RIG_MODEL_K2: err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K2 level is %d, %s\n", __func__, priv->k2_ext_lvl, elec_ext_id_str_lst[priv->k2_ext_lvl].id); priv->is_k2 = 1; break; case RIG_MODEL_K3: case RIG_MODEL_K3S: case RIG_MODEL_KX2: case RIG_MODEL_KX3: case RIG_MODEL_K4: // we need to know what's hooked up for PC command max levels err = kenwood_safe_transaction(rig, "OM", buf, KENWOOD_MAX_BUF_LEN, 15); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: OM=%s\n", __func__, buf); priv->has_kpa3 = 0; if (strstr(buf, "P")) { priv->has_kpa3 = 1; } // could also use K4; command priv->is_k3 = 1; // default to K3 if (rig->caps->rig_model == RIG_MODEL_K4) { priv->is_k3 = 0; priv->is_k4 = 1; } else if (strstr(buf, "R")) { priv->is_k3 = 0; priv->is_k3s = 1; } // combination of OM flags determines model if (strstr(buf, "S") && strstr(buf, "4") && strstr(buf, "H")) { // new firmware should recognize k4hd now priv->is_k4 = priv->is_k3 = 0; priv->is_k4hd = 1; } else if (strstr(buf, "S") && strstr(buf, "4")) { priv->is_k4 = priv->is_k3 = 0; priv->is_k4d = 1; } if (buf[13] == '0') // then we have a KX3 or KX2 { char modelnum; modelnum = buf[14]; switch (modelnum) { case '1': priv->is_k2 = 0; model = "KX2"; priv->is_kx2 = 1; break; case '2': model = "KX3"; priv->is_k3 = 0; priv->is_kx3 = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown Elecraft modelnum=%c, expected 1 or 2\n", __func__, modelnum); break; } if (strstr(buf, "P")) { priv->has_kpa100 = 1; } } else { model = "K3"; if (strstr(buf, "R")) { model = "K3S"; } } rig_debug(RIG_DEBUG_TRACE, "%s: model=%s, is_k2=%d, is_k3=%d, is_k3s=%d, is_kx3=%d, is_kx2=%d, is_k4=%d, is_k4d=%d, is_k4hd=%d, kpa3=%d\n", __func__, model, priv->is_k2, priv->is_k3, priv->is_k3s, priv->is_kx3, priv->is_kx2, priv->is_k4, priv->is_k4d, priv->is_k4hd, priv->has_kpa3); err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K2 level is %d, %s\n", __func__, priv->k2_ext_lvl, elec_ext_id_str_lst[priv->k2_ext_lvl].id); err = elecraft_get_extension_level(rig, "K3", &priv->k3_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K3 level is %d, %s\n", __func__, priv->k3_ext_lvl, elec_ext_id_str_lst[priv->k3_ext_lvl].id); err = elecraft_get_firmware_revision_level(rig, "RVM", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVM failed\n", __func__); return err; } err = elecraft_get_firmware_revision_level(rig, "RVD", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVD failed\n", __func__); } if (priv->is_k3) { err = elecraft_get_firmware_revision_level(rig, "RVA", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVA failed\n", __func__); } err = elecraft_get_firmware_revision_level(rig, "RVR", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVR failed\n", __func__); } err = elecraft_get_firmware_revision_level(rig, "RVF", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVF failed\n", __func__); } } break; case RIG_MODEL_XG3: rig_debug(RIG_DEBUG_VERBOSE, "%s: XG3 level is %d, %s\n", __func__, priv->k3_ext_lvl, elec_ext_id_str_lst[priv->k3_ext_lvl].id); break; default: rig_debug(RIG_DEBUG_WARN, "%s: unrecognized rig model %u\n", __func__, rig->caps->rig_model); return -RIG_EINVAL; } if (RIG_MODEL_XG3 != rig->caps->rig_model) { /* get current AI state so it can be restored */ priv->trn_state = -1; kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ } // For rigs like K3X vfo emulation need to set VFO_A to start vfo_t vfo; rig_get_vfo(rig, &vfo); if (vfo != RIG_VFO_A && vfo != RIG_VFO_B) { rig_set_vfo(rig, RIG_VFO_A); } return RIG_OK; } int elecraft_close(RIG *rig) { const struct kenwood_priv_data *priv = STATE(rig)->priv; if (priv->save_k2_ext_lvl >= 0) { int err; char cmd[32]; sprintf(cmd, "K2%d;", priv->save_k2_ext_lvl); err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error restoring %s='%s'...continuing\n", __func__, cmd, rigerror(err)); } } return kenwood_close(rig); } /* Private helper functions */ /* Tests for Kenwood ID string of "017" */ int verify_kenwood_id(RIG *rig, char *id) { int err; char *idptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!id) { return -RIG_EINVAL; } /* Check for an Elecraft K2|K3 which returns "017" */ err = kenwood_get_id(rig, id); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cannot get identification\n", __func__); return err; } /* ID is 'ID017;' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown ID type (%s)\n", __func__, id); return -RIG_EPROTO; } /* check for any white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } if (strcmp("017", idptr) != 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig (%.4095s) is not a K2 or K3\n", __func__, id); // return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.4095s\n", __func__, id); } return RIG_OK; } /* Determines K2 and K3 extension level */ int elecraft_get_extension_level(RIG *rig, const char *cmd, int *ext_level) { int err, i; char buf[KENWOOD_MAX_BUF_LEN]; char *bufptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ext_level) { return -RIG_EINVAL; } err = kenwood_safe_transaction(rig, cmd, buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot get K2|K3 ID\n", __func__); return err; } /* Get extension level string */ bufptr = &buf[0]; for (i = 0; elec_ext_id_str_lst[i].level != EXT_LEVEL_NONE; i++) { if (strcmp(elec_ext_id_str_lst[i].id, bufptr) == 0) { *ext_level = elec_ext_id_str_lst[i].level; rig_debug(RIG_DEBUG_VERBOSE, "%s: %s extension level is %d, %s\n", __func__, cmd, *ext_level, elec_ext_id_str_lst[i].id); } } return RIG_OK; } /* Determine firmware revision level */ int elecraft_get_firmware_revision_level(RIG *rig, const char *cmd, char *fw_rev, size_t fw_rev_sz) { int err; char *bufptr; char buf[KENWOOD_MAX_BUF_LEN]; char rvp = cmd[2]; char *rv = "UNK"; if (rig->caps->rig_model == RIG_MODEL_K4) { switch (rvp) { case 'F': case 'M': rv = "FPF"; break; case 'A': case 'D': rv = "DSP"; break; case 'R': rv = "DAP"; break; } } else { switch (rvp) { case 'M': rv = "MCU"; break; case 'D': rv = "DSP"; break; case 'A': rv = "AUX"; break; case 'R': rv = "DVR"; break; case 'F': rv = "FPF"; break; } } rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!fw_rev) { return -RIG_EINVAL; } /* Get the actual firmware revision number. */ err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot get firmware revision level\n", __func__); return err; } /* Now buf[] contains the string from the K3 which includes the command * and the firmware revision number as: "RVM04.67". */ bufptr = &buf[0]; /* Skip the command string */ bufptr += strlen(cmd); /* Skip leading zero(s) as the revision number has the format of: "04.67" */ while (*bufptr == '0') { bufptr++; } /* Copy out */ strncpy(fw_rev, bufptr, fw_rev_sz - 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: Elecraft %s firmware revision is %s\n", __func__, rv, fw_rev); return RIG_OK; } // FR;FT;TQ; is faster than IF; // Works on K4 int elecraft_get_vfo_tq(RIG *rig, vfo_t *vfo) { int retval; int fr, ft, tq; char cmdbuf[10]; char splitbuf[12]; ENTERFUNC2; memset(splitbuf, 0, sizeof(splitbuf)); SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR;"); retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "FR%1d", &fr) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse FR '%s'\n", __func__, splitbuf); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT;"); retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "FT%1d", &ft) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse FT '%s'\n", __func__, splitbuf); } // We can use the TQX; command but we have to check that we have R32 firmware or higher // Not sure it's much better than TQ; since it still seems to take 350ms // So we have to sleep for a while after sending it to avoid TCP timeouts which still needs to be fixed // See #if 0 if (rig->caps->rig_model == RIG_MODEL_K4) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "TQX;"); } else #endif { SNPRINTF(cmdbuf, sizeof(cmdbuf), "TQ;"); } retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "TQ%1d", &tq) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse TQ or TQX response of '%s'\n", __func__, splitbuf); } *vfo = STATE(rig)->tx_vfo = RIG_VFO_A; if (tq && ft == 1) { *vfo = STATE(rig)->tx_vfo = RIG_VFO_B; } else if (tq && ft == 0) { *vfo = STATE(rig)->tx_vfo = RIG_VFO_A; } if (!tq && fr == 1) { *vfo = STATE(rig)->rx_vfo = STATE(rig)->tx_vfo = RIG_VFO_B; } RETURNFUNC2(RIG_OK); } hamlib-4.6.5/rigs/kenwood/thf7.c0000664000175000017500000002412315056640443012104 /* * Hamlib Kenwood backend - TH-F7 description * Copyright (c) 2001-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tones.h" #include "kenwood.h" #include "th.h" #define THF7_MODES_TX (RIG_MODE_FM) #define THF7_HIGH_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_WFM) #define THF7_ALL_MODES (THF7_HIGH_MODES|RIG_MODE_SSB|RIG_MODE_CW) #define THF7_FUNC_ALL (RIG_FUNC_ARO|RIG_FUNC_LOCK|RIG_FUNC_BC) /* * How incredible, there's no RIG_LEVEL_STRENGTH! */ #define THF7_LEVEL_ALL (RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_ATT|\ RIG_LEVEL_BALANCE|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY) #define THF7_PARMS (RIG_PARM_APO|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define THF7_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define THF7_ANTS (RIG_ANT_1|RIG_ANT_2) /* * TODO: * scan_group can only be get. scan_group=channel_num%50; */ #define THF7_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define THF7_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* CTCSS 01..42 */ static tone_t thf7_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; static rmode_t thf7_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_WFM, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW }; /* * Band A & B */ #define THF7_VFO (RIG_VFO_A|RIG_VFO_B) static struct kenwood_priv_caps thf7_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thf7_mode_table, }; static int thf7e_init(RIG *rig); static int thf7e_open(RIG *rig); static int thf7e_get_vfo(RIG *rig, vfo_t *vfo); static int thf7e_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TH-F7E rig capabilities. * * Manual, thanks to K6MAY: http://www.k6may.com/KenwoodTHF6Tip1.shtml * * TODO: * - set/get_ctcss_tone/sql through set/get_channel() and VR/VW * - emulate RIG_FUNC_TONE|RIG_FUNC_TSQL by setting ctcss_tone/sql to 0/non zero? */ struct rig_caps thf7e_caps = { RIG_MODEL(RIG_MODEL_THF7E), .model_name = "TH-F7E", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .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 = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THF7_FUNC_ALL, .has_set_func = THF7_FUNC_ALL | RIG_FUNC_TBURST, .has_get_level = THF7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THF7_LEVEL_ALL), .has_get_parm = THF7_PARMS, .has_set_parm = THF7_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = thf7_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THF7_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, /* TBC */ .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 0, 399, RIG_MTYPE_MEM, {THF7_CHANNEL_CAPS}}, /* normal MEM */ { 400, 409, RIG_MTYPE_EDGE, {THF7_CHANNEL_CAPS}}, /* L0-L9 lower scan limit */ { 410, 419, RIG_MTYPE_EDGE, {THF7_CHANNEL_CAPS}}, /* U0-U9 upper scan limit */ { 420, 429, RIG_MTYPE_MEM, {THF7_CHANNEL_CAPS}}, /* I0-I9 info */ { 430, 431, RIG_MTYPE_PRIO, {THF7_CHANNEL_CAPS}}, /* PR0,PR1 priority */ { 432, 434, RIG_MTYPE_CALL, {THF7_CHANNEL_CAPS_WO_LO}}, /* Call (for each ham band) */ { 435, 449, RIG_MTYPE_BAND, {THF7_CHANNEL_CAPS_WO_LO}}, /* VFO */ /* 3 A-band VFO */ /* 11 B-band VFO */ /* TODO: 10 DTMF */ RIG_CHAN_END, }, .rx_range_list1 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(146), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF7_ALL_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF7_HIGH_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list1 = { /* power actually depends on DC power supply */ {MHz(144), MHz(146), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, /* region 2 is model TH-F6A in fact */ .rx_range_list2 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(148), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF7_ALL_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF7_HIGH_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list2 = { /* power actually depends on DC power supply */ {MHz(144), MHz(148), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, .tuning_steps = { /* This table is ordered according to protocol, from '0' to 'b' */ /* The steps are not available on every band/frequency limit 470MHz */ {THF7_ALL_MODES, kHz(5)}, {THF7_ALL_MODES, kHz(6.25)}, {THF7_ALL_MODES, kHz(8.33)}, {THF7_ALL_MODES, kHz(9)}, {THF7_ALL_MODES, kHz(10)}, {THF7_ALL_MODES, kHz(12.5)}, {THF7_ALL_MODES, kHz(15)}, {THF7_ALL_MODES, kHz(20)}, {THF7_ALL_MODES, kHz(25)}, {THF7_ALL_MODES, kHz(30)}, {THF7_ALL_MODES, kHz(50)}, {THF7_ALL_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* real width to be checked (missing specs) */ {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, /* narrow FM */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(150)}, /* or 230? */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, RIG_FLT_END, }, .priv = (void *)& thf7_priv_caps, .rig_init = thf7e_init, .rig_cleanup = kenwood_cleanup, .rig_open = thf7e_open, .rig_close = kenwood_close, .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, .get_vfo = thf7e_get_vfo, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .vfo_op = thf7e_vfo_op, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .get_parm = th_get_parm, .set_parm = th_set_parm, .get_info = th_get_info, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_ant = th_set_ant, .get_ant = th_get_ant, .reset = th_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int thf7e_init(RIG *rig) { return kenwood_init(rig); } int thf7e_open(RIG *rig) { return kenwood_open(rig); } /* * th_get_vfo * Assumes rig!=NULL */ int thf7e_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '3' : /* Fine Step Enable */ break; case '1' : /* MR */ case '2' : /* CALL */ case '4' : /* INFO */ *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * thf7e_vfo_op */ int thf7e_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); /* Not implemented! case RIG_OP_BAND_UP: return kenwood_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return kenwood_transaction(rig, "BD", NULL, 0); */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } hamlib-4.6.5/rigs/kenwood/k2.c0000664000175000017500000005155415056640443011560 /* * Hamlib Kenwood backend - Elecraft K2 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 Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include "kenwood.h" #include "elecraft.h" #define K2_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define K2_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_LOCK) #define K2_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD) #define K2_VFO (RIG_VFO_A|RIG_VFO_B) #define K2_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TUNE) #define K2_ANTS (RIG_ANT_1|RIG_ANT_2) static rmode_t k2_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_NONE, [5] = RIG_MODE_NONE, [6] = RIG_MODE_PKTLSB, /* AFSK */ [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode */ [9] = RIG_MODE_PKTUSB /* AFSK */ }; /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps k2_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = k2_mode_table, }; /* K2 Filter list, four per mode */ struct k2_filt_s { shortfreq_t width; /* Filter width in Hz */ char fslot; /* Crystal filter slot number--1-4 */ char afslot; /* AF filter slot number--0-2 */ }; /* Number of filter slot arrays to allocate (TNX Diane, VA3DB) */ #define K2_FILT_NUM 4 /* K2 Filter List * * This struct will be populated as modes are queried or in response * to a request to set a given mode. This way a cache can be maintained * of the installed filters and an appropriate filter can be selected * for a requested bandwidth. Each mode has up to four filter slots available. */ struct k2_filt_lst_s { struct k2_filt_s filt_list[K2_FILT_NUM]; }; struct k2_filt_lst_s k2_fwmd_ssb; struct k2_filt_lst_s k2_fwmd_cw; struct k2_filt_lst_s k2_fwmd_rtty; /* K2 specific rig_caps API function declarations */ int k2_open(RIG *rig); int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int k2_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int k2_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private function declarations */ int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv); int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw); int k2_pop_fw_lst(RIG *rig, const char *cmd); /* * KIO2 rig capabilities. * This kit can recognize a large subset of TS-570 commands. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K2 * look for KIO2 Programmer's Reference PDF */ struct rig_caps k2_caps = { RIG_MODEL(RIG_MODEL_K2), .model_name = "K2", .mfg_name = "Elecraft", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 100, /* Timing between command strings */ // Note that 2000 timeout exceeds usleep but hl_usleep handles it .timeout = 2000, /* FA and FB make take up to 500 ms on band change */ .retry = 10, .has_get_func = K2_FUNC_ALL, .has_set_func = K2_FUNC_ALL, .has_get_level = K2_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K2_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, /* FIXME: granularity */ .parm_gran = {}, .extlevels = elecraft_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 14, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K2_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */ {kHz(3500), kHz(3800) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(7), kHz(7100), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */ {kHz(3500), MHz(4) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(7), kHz(7300), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K2_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.5)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.5)}, RIG_FLT_END, }, .priv = (void *)& k2_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = k2_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k2_set_mode, .get_mode = k2_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .get_ext_level = k2_get_ext_level, .vfo_op = k2_vfo_op, .set_trn = kenwood_set_trn, .get_powerstat = kenwood_get_powerstat, .get_trn = kenwood_get_trn, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * K2 extension function definitions follow */ /* k2_open() * */ int k2_open(RIG *rig) { int err; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elecraft_open(rig); if (err != RIG_OK) { return err; } err = k2_probe_mdfw(rig, priv); if (err != RIG_OK) { return err; } return RIG_OK; } /* k2_set_mode() * * Based on the passed in bandwidth, looks up the nearest bandwidth filter * wider than the passed value and sets the radio accordingly. */ int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int err; char f = '*'; struct k2_filt_lst_s *flt; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Select the filter array per mode. */ switch (mode) { case RIG_MODE_LSB: case RIG_MODE_USB: flt = &k2_fwmd_ssb; break; case RIG_MODE_CW: case RIG_MODE_CWR: flt = &k2_fwmd_cw; break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: if (priv->k2_md_rtty == 0) { return -RIG_EINVAL; /* RTTY module not installed */ } else { flt = &k2_fwmd_rtty; } break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { shortfreq_t freq = 0; if (width < 0) { width = labs(width); } /* Step through the filter list looking for the best match * for the passed in width. The choice is to select the filter * that is wide enough for the width without being too narrow * if possible. */ if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if ((width > flt->filt_list[0].width) || (width > flt->filt_list[1].width)) { width = flt->filt_list[0].width; f = '1'; } // cppcheck-suppress knownConditionTrueFalse else if ((flt->filt_list[1].width >= width) && (width > flt->filt_list[2].width)) { width = flt->filt_list[1].width; f = '2'; } else if ((flt->filt_list[2].width >= width) && (width > flt->filt_list[3].width)) { width = flt->filt_list[2].width; f = '3'; } else if ((flt->filt_list[3].width >= width) && (width >= freq)) { width = flt->filt_list[3].width; f = '4'; } else { return -RIG_EINVAL; } } /* 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; } if (width != RIG_PASSBAND_NOCHANGE) { char fcmd[16]; err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } /* Construct the filter command and set the radio mode and width*/ SNPRINTF(fcmd, sizeof(fcmd), "FW0000%c", f); /* Set the filter slot */ err = kenwood_transaction(rig, fcmd, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* k2_get_mode() * * Uses the FW command in K22 mode to query the filter bandwidth reported * by the radio and returns it to the caller. */ int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; char buf[KENWOOD_MAX_BUF_LEN]; char tmp[16]; char *bufptr; pbwidth_t temp_w; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } err = kenwood_get_mode(rig, vfo, mode, &temp_w); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } /* Convert received filter string value's first four digits to width */ bufptr = buf; strncpy(tmp, bufptr + 2, 4); tmp[4] = '\0'; *width = atoi(tmp); rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode: %s, Width: %d\n", __func__, rig_strrmode(*mode), (int)*width); return RIG_OK; } /* TQ command is a quick transmit status query--K2/K3 only. * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ int k2_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { char buf[KENWOOD_MAX_BUF_LEN]; int err; const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } cfp = rig_ext_lookup_tok(rig, token); switch (token) { case TOK_TX_STAT: err = kenwood_safe_transaction(rig, "TQ", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } if (cfp->type == RIG_CONF_CHECKBUTTON) { val->i = atoi(&buf[2]); } else { rig_debug(RIG_DEBUG_ERR, "%s: protocol error, invalid token type\n", __func__); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* K2 private helper functions follow */ /* Probes for mode and filter settings, based on information * by Chris Bryant, G3WIE. */ int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv) { int err, i, c; char buf[KENWOOD_MAX_BUF_LEN]; char mode[16]; char fw[16]; char cmd[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!priv) { return -RIG_EINVAL; } /* The K2 extension level has been stored by elecraft_open(). Now set rig * to K22 for detailed query of mode and filter width values... */ err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } /* Check for mode and store it for later. */ err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } strcpy(mode, buf); /* Check for filter width and store it for later. */ err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } strcpy(fw, buf); rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode value: %s, Filter Width value: %s\n", __func__, mode, fw); /* Now begin the process of querying the available modes and filters. */ /* First try to put the K2 into RTTY mode and check if it's available. */ priv->k2_md_rtty = 0; /* Assume RTTY module not installed */ err = kenwood_transaction(rig, "MD6", NULL, 0); if (err != RIG_OK && err != -RIG_ERJCTED) { return err; } if (RIG_OK == err) { /* Read back mode and test to see if K2 reports RTTY. */ err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } if (!strcmp("MD6", buf)) { priv->k2_md_rtty = 1; /* set flag for RTTY mode enabled */ } } rig_debug(RIG_DEBUG_VERBOSE, "%s: RTTY flag is: %d\n", __func__, priv->k2_md_rtty); i = (priv->k2_md_rtty == 1) ? 2 : 1; /* Now loop through the modes checking for installed filters. */ for (c = 0; i > -1; i--, c++) { if (c == 0) { strcpy(cmd, "MD1"); /* SSB */ } else if (c == 1) { strcpy(cmd, "MD3"); /* CW */ } else if (c == 2) { strcpy(cmd, "MD6"); /* RTTY */ } else /* Oops! */ { err = k2_mdfw_rest(rig, mode, fw); if (err != RIG_OK) { return err; } return -RIG_EINVAL; } /* Now populate the Filter arrays */ err = k2_pop_fw_lst(rig, cmd); if (err != RIG_OK) { return err; } } /* Restore mode, filter, extension level */ if (strlen(fw) == 8) { fw[7] = '\0'; /* Truncate AFSlot to set filter slot */ } err = k2_mdfw_rest(rig, mode, fw); if (err != RIG_OK) { return err; } return RIG_OK; } /* Restore mode, filter, and ext_lvl to original values */ int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !fw) { return -RIG_EINVAL; } if (strlen(mode) != 3 || strlen(fw) != 7) { return -RIG_EINVAL; } err = kenwood_transaction(rig, mode, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, fw, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* Populate k2_filt_lst_s structure for each mode */ int k2_pop_fw_lst(RIG *rig, const char *cmd) { int err, f; char fcmd[16]; char buf[KENWOOD_MAX_BUF_LEN]; char tmp[16]; struct k2_filt_lst_s *flt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!cmd) { return -RIG_EINVAL; } /* Store filter data in the correct structure depending on mode */ if (strcmp(cmd, "MD1") == 0) { flt = &k2_fwmd_ssb; } else if (strcmp(cmd, "MD3") == 0) { flt = &k2_fwmd_cw; } else if (strcmp(cmd, "MD6") == 0) { flt = &k2_fwmd_rtty; } else { return -RIG_EINVAL; } /* Set the mode */ err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { return err; } for (f = 1; f < 5; f++) { char *bufptr = buf; SNPRINTF(fcmd, sizeof(fcmd), "FW0000%d", f); err = kenwood_transaction(rig, fcmd, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } /* buf should contain a string "FWxxxxfa;" which corresponds to: * xxxx = filter width in Hz * f = crystal filter slot number--1-4 * a = audio filter slot number--0-2 */ strncpy(tmp, bufptr + 2, 4); tmp[4] = '\0'; flt->filt_list[f - 1].width = atoi(tmp); strncpy(tmp, bufptr + 6, 1); tmp[1] = '\0'; flt->filt_list[f - 1].fslot = atoi(tmp); strncpy(tmp, bufptr + 7, 1); tmp[1] = '\0'; flt->filt_list[f - 1].afslot = atoi(tmp); rig_debug(RIG_DEBUG_VERBOSE, "%s: Width: %04li, FSlot: %i, AFSlot %i\n", __func__, flt->filt_list[f - 1].width, flt->filt_list[f - 1].fslot, flt->filt_list[f - 1].afslot); } return RIG_OK; } int k2_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[32]; switch (op) { case RIG_OP_TUNE: // K2 SNPRINTF(buf, sizeof(buf), "SWH20"); break; default: return kenwood_vfo_op(rig, vfo, op); } return kenwood_transaction(rig, buf, NULL, 0); } hamlib-4.6.5/rigs/kenwood/ts690.c0000664000175000017500000001561715056640443012131 /* * Hamlib Kenwood backend - TS690 description * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "bandplan.h" #include "kenwood.h" extern int ts450_open(RIG *rig); #define TS690_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_RTTYR|RIG_MODE_CWR|RIG_MODE_SSB) #define TS690_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_CWR) #define TS690_AM_TX_MODES RIG_MODE_AM /* FIXME: TBC */ #define TS690_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_AIP|RIG_FUNC_TONE) #define TS690_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define TS690_PARMS (RIG_PARM_ANN) /* optional */ #define TS690_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS690_SCAN_OPS (RIG_SCAN_VFO) #define TS690_VFO (RIG_VFO_A|RIG_VFO_B) #define TS690_ANTS (0) #define TS690_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps ts690_priv_caps = { .cmdtrm = EOM_KEN, }; /* * ts690 rig capabilities. * written from specs: * http://www.qsl.net/sm7vhs/radio/kenwood/ts690/specs.htm * * TODO: protocol to be checked with manual! * - how to set_split in vfo mode? * - ... */ struct rig_caps ts690s_caps = { RIG_MODEL(RIG_MODEL_TS690S), .model_name = "TS-690S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 1000, .retry = 10, .has_get_func = TS690_FUNC_ALL, .has_set_func = TS690_FUNC_ALL, .has_get_level = TS690_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS690_LEVEL_ALL), .has_get_parm = TS690_PARMS, .has_set_parm = RIG_LEVEL_SET(TS690_PARMS), /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(2.2), .max_xit = kHz(2.2), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TS690_VFO_OPS, .scan_ops = TS690_SCAN_OPS, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS690_CHANNEL_CAPS }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE, TS690_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS690_ALL_MODES, -1, -1, TS690_VFO}, {MHz(50), MHz(54), TS690_ALL_MODES, -1, -1, TS690_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS690_OTHER_TX_MODES, W(5), W(100), TS690_VFO, TS690_ANTS), FRQ_RNG_HF(1, TS690_AM_TX_MODES, W(4), W(40), TS690_VFO, TS690_ANTS), /* AM class */ FRQ_RNG_6m(1, TS690_OTHER_TX_MODES, W(2.5), W(50), TS690_VFO, TS690_ANTS), FRQ_RNG_6m(1, TS690_AM_TX_MODES, W(2), W(20), TS690_VFO, TS690_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS690_ALL_MODES, -1, -1, TS690_VFO}, {MHz(50), MHz(54), TS690_ALL_MODES, -1, -1, TS690_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS690_OTHER_TX_MODES, W(5), W(100), TS690_VFO, TS690_ANTS), FRQ_RNG_HF(2, TS690_AM_TX_MODES, W(4), W(40), TS690_VFO, TS690_ANTS), /* AM class */ FRQ_RNG_6m(2, TS690_OTHER_TX_MODES, W(2.5), W(50), TS690_VFO, TS690_ANTS), FRQ_RNG_6m(2, TS690_AM_TX_MODES, W(2), W(20), TS690_VFO, TS690_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS690_ALL_MODES, 1}, {TS690_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, Hz(500)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(6)}, RIG_FLT_END, }, .priv = (void *)& ts690_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = ts450_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .scan = kenwood_scan, .get_channel = kenwood_get_channel, .set_channel = kenwood_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/thg71.c0000664000175000017500000003463515056640443012177 /* * Hamlib Kenwood backend - TH-G71 description * Copyright (c) 2003-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #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 THG71_VFO (RIG_VFO_A) #define THG71_MODES (RIG_MODE_FM) #define THG71_FUNC_ALL (\ RIG_FUNC_TBURST \ ) #define THG71_LEVEL_ALL (\ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER\ ) #ifndef RIG_TONEMAX #define RIG_TONEMAX 38 #endif #define RIG_VFO_A_OP (RIG_OP_UP|RIG_OP_DOWN) #define ACKBUF_LEN 128 static rmode_t thg71_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps thg71_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thg71_mode_table, }; /* thg71 procs */ static int thg71_open(RIG *rig); static int thg71_decode_event(RIG *rig); static int thg71_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int thg71_set_vfo(RIG *rig, vfo_t vfo); static int thg71_get_vfo(RIG *rig, vfo_t *vfo); static int thg71_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); /* * th-g71 rig capabilities. * * http://www.iw5edi.com/ham-radio/files/TH-G71_Serial_Protocol.pdf */ struct rig_caps thg71_caps = { RIG_MODEL(RIG_MODEL_THG71), .model_name = "TH-G71", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .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 = THG71_FUNC_ALL, .has_get_level = THG71_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THG71_LEVEL_ALL), .level_gran = { #include "level_gran_kenwood.h" }, .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, 199, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* normal MEM */ { 200, 209, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* L MEM */ { 210, 219, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* U MEM */ { 220, 220, RIG_MTYPE_PRIO, {TH_CHANNEL_CAPS}}, /* Priority */ { 221, 222, RIG_MTYPE_CALL, {TH_CHANNEL_CAPS}}, /* Call 0/1 */ { 223, 231, RIG_MTYPE_BAND, {TH_CHANNEL_CAPS}}, /* Band VFO */ RIG_CHAN_END, }, /* no rx/tx_range_list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THG71_MODES, -1, -1, THG71_VFO}, {MHz(400), MHz(470), THG71_MODES, -1, -1, THG71_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), THG71_MODES, W(0.05), W(5), THG71_VFO}, {MHz(430), MHz(450), THG71_MODES, W(0.05), W(5), THG71_VFO}, RIG_FRNG_END, }, /* computed in thg71_open */ .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(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(30)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = { 3, { { 0, -60 }, {1, -30 }, {5, -13}}}, /* guessed from technical manual */ .priv = (void *)& thg71_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = thg71_open, .rig_close = kenwood_close, .set_freq = th_set_freq, .get_freq = th_get_freq, .get_mode = thg71_get_mode, .set_vfo = thg71_set_vfo, .get_vfo = thg71_get_vfo, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .set_func = thg71_set_func, .get_level = th_get_level, .set_level = th_set_level, .get_info = th_get_info, .vfo_op = th_vfo_op, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .decode_event = thg71_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* --------------------------------------------------------------------- */ int thg71_decode_event(RIG *rig) { char asyncbuf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); 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 = 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)\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,%u", &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 - %u\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 thg71_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char ackbuf[ACKBUF_LEN]; int retval; 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 %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } /* try to guess from frequency */ retval = kenwood_transaction(rig, "FQ", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } sscanf(ackbuf, "FQ %"SCNfreq",%d", &freq, &step); if (freq < MHz(136)) { *mode = RIG_MODE_AM; *width = kHz(9); } else { *mode = RIG_MODE_FM; *width = kHz(12); } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_set_vfo(RIG *rig, vfo_t vfo) { char vfobuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); break; case RIG_VFO_MEM: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,2"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_get_vfo(RIG *rig, vfo_t *vfo) { char ackbuf[ACKBUF_LEN]; int retval; int vch; retval = kenwood_transaction(rig, "VMC 0", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } sscanf(ackbuf, "VMC 0,%d", &vch); switch (vch) { case 0: *vfo = RIG_VFO_A; break; case 1: case 2: *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EVFO; } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { if (func != RIG_FUNC_TBURST) { return -RIG_EINVAL; } if (status == 1) { int retval = kenwood_transaction(rig, "TT", NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } if (status == 0) { return rig_set_ptt(rig, vfo, RIG_PTT_OFF); } return -RIG_EINVAL; } /* --------------------------------------------------------------------- */ int thg71_open(RIG *rig) { char ackbuf[ACKBUF_LEN]; int retval, i; const freq_range_t frend = RIG_FRNG_END; struct rig_state *rs = STATE(rig); /* this will check the model id */ retval = kenwood_open(rig); if (retval != RIG_OK) { return retval; } /* fill state.rx/tx range_list */ retval = kenwood_transaction(rig, "FL", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } strtok(ackbuf, " "); for (i = 0; i < HAMLIB_FRQRANGESIZ - 1; i++) { freq_range_t frng; char *strl, *stru; strl = strtok(NULL, ","); stru = strtok(NULL, ","); if (strl == NULL && stru == NULL) { break; } frng.startf = MHz(atoi(strl)); frng.endf = MHz(atoi(stru)); frng.vfo = RIG_VFO_A; frng.ant = 0; if (frng.endf <= MHz(135)) { frng.modes = RIG_MODE_AM; } else { frng.modes = RIG_MODE_FM; } frng.high_power = -1; frng.low_power = -1; frng.label = ""; rs->rx_range_list[i] = frng; if (frng.startf > MHz(200)) { frng.high_power = mW(5500); } else { frng.high_power = mW(6000); } frng.low_power = mW(50); rs->tx_range_list[i] = frng; } rs->rx_range_list[i] = frend; rs->tx_range_list[i] = frend; rs->vfo_list = RIG_VFO_A | RIG_VFO_MEM ; return RIG_OK; } hamlib-4.6.5/rigs/kenwood/xg3.c0000664000175000017500000004060315056640443011736 /* * Hamlib Kenwood backend - Elecraft XG3 description * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann, n0nb@arrl.net * Copyright (c) 2014 by Michael BlacK, W9MDB, mdblack98@yahoo.com * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include "serial.h" #include "kenwood.h" #include "elecraft.h" #define XG3_LEVEL_ALL (RIG_LEVEL_RFPOWER) #define XG3_PARM_ALL (RIG_PARM_BACKLIGHT) #define XG3_VFO (RIG_VFO_A|RIG_VFO_MEM) #define XG3_CHANNEL_CAPS { \ .freq=1\ } #define NB_CHAN 12 /* see caps->chan_list */ #if 0 struct xg3_priv_data { /* current vfo already in rig_state ? */ vfo_t last_vfo; ptt_t ptt; powerstat_t powerstat; value_t parms[RIG_SETTING_MAX]; channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ channel_t vfo_a; channel_t mem[NB_CHAN]; char *magic_conf; }; #endif /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps xg3_priv_caps = { .cmdtrm = EOM_KEN, }; /* XG3 specific rig_caps API function declarations */ int xg3_init(RIG *rig); int xg3_open(RIG *rig); int xg3_set_vfo(RIG *rig, vfo_t vfo); int xg3_get_vfo(RIG *rig, vfo_t *vfo); int xg3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int xg3_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int xg3_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int xg3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int xg3_set_powerstat(RIG *rig, powerstat_t status); int xg3_get_powerstat(RIG *rig, powerstat_t *status); int xg3_set_mem(RIG *rig, vfo_t vfo, int ch); int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch); int xg3_set_parm(RIG *rig, setting_t parm, value_t val); int xg3_get_parm(RIG *rig, setting_t parm, value_t *val); /* * XG3 rig capabilities. * This kit can recognize a small subset of TS-570 commands. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K2 * look for KIO2 Programmer's Reference PDF */ struct rig_caps xg3_caps = { RIG_MODEL(RIG_MODEL_XG3), .model_name = "XG3", .mfg_name = "Elecraft", .version = "20230305.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .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 = 0, /* Timing between bytes */ .post_write_delay = 25, /* Timing between command strings */ .timeout = 25, .retry = 3, .has_get_level = XG3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XG3_LEVEL_ALL), .has_get_parm = XG3_PARM_ALL, .has_set_parm = XG3_PARM_ALL, .level_gran = { #include "level_gran_elecraft.h" }, /* FIXME: granularity */ .parm_gran = {}, .extparms = kenwood_cfg_params, .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {0, 11, RIG_MTYPE_MEM, XG3_CHANNEL_CAPS}, RIG_CHAN_END, }, .tx_range_list1 = { // lo power is actually 5e-14W which can't be represented in hamlib as of 20200325 {kHz(1500), MHz(200), RIG_MODE_CW, 0, 2, RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, 0}, RIG_TS_END }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = (void *)& xg3_priv_caps, .rig_init = xg3_init, .rig_cleanup = kenwood_cleanup, .rig_open = xg3_open, .set_freq = xg3_set_freq, .get_freq = xg3_get_freq, .set_mem = xg3_set_mem, .get_mem = xg3_get_mem, .set_vfo = xg3_set_vfo, .get_vfo = xg3_get_vfo, .get_ptt = xg3_get_ptt, .set_ptt = xg3_set_ptt, .set_level = xg3_set_level, .get_level = xg3_get_level, .set_powerstat = xg3_set_powerstat, .get_powerstat = xg3_get_powerstat, .set_parm = xg3_set_parm, .get_parm = xg3_get_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * xg3_init() */ int xg3_init(RIG *rig) { struct kenwood_priv_data *priv; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct kenwood_priv_data *)calloc(1, sizeof(struct kenwood_priv_data)); if (!priv) { return -RIG_ENOMEM; } STATE(rig)->priv = (void *)priv; RIGPORT(rig)->type.rig = RIG_PORT_SERIAL; // Tried set_trn to turn transceiver on/off but turning it on isn't enabled in hamlib for some reason // So we use PTT instead // STATE(rig)->transceive = RIG_TRN_RIG; // this allows xg3_set_trn to be called STATE(rig)->current_vfo = RIG_VFO_A; // priv->last_vfo = RIG_VFO_A; // priv->ptt = RIG_PTT_ON; // priv->powerstat = RIG_POWER_ON; priv->no_id = 1; //memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); for (i = 0; i < NB_CHAN; i++) { //priv->mem[i].channel_num = i; //priv->mem[i].vfo = RIG_VFO_MEM; } return RIG_OK; } /* * XG3 extension function definitions follow */ /* * xg3_open() */ int xg3_open(RIG *rig) { int err; ptt_t ptt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elecraft_open(rig); if (err != RIG_OK) { return err; } xg3_get_ptt(rig, RIG_VFO_A, &ptt); // set our PTT status return RIG_OK; } int xg3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f < 0 || val.f > 3) { return -RIG_EINVAL; } /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "L,%02d", (int)val.f); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * kenwood_get_level */ int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[32], replybuf[32]; int retval; size_t replysize = sizeof(replybuf); struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "L;"); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s write_block failed\n", __func__); return retval; } retval = read_string(rp, (unsigned char *) replybuf, replysize, ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } sscanf(replybuf, "L,%f", &val->f); return RIG_OK; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_AF: case RIG_LEVEL_RF: case RIG_LEVEL_SQL: case RIG_LEVEL_MICGAIN: case RIG_LEVEL_AGC: case RIG_LEVEL_SLOPE_LOW: case RIG_LEVEL_SLOPE_HIGH: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * xg3_get_vfo */ int xg3_get_vfo(RIG *rig, vfo_t *vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } *vfo = STATE(rig)->current_vfo; // VFOA or MEM return RIG_OK; } /* * xg3_set_vfo */ int xg3_set_vfo(RIG *rig, vfo_t vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } if (vfo != RIG_VFO_A) { return -RIG_EINVAL; } // We don't actually set the vfo on the XG3 // But we need this so we can set frequencies on the band buttons STATE(rig)->current_vfo = vfo; return RIG_OK; } /* * xg3_set_freq */ int xg3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int err; vfo_t tvfo; char cmdbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: break; case RIG_VFO_MEM: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (tvfo == RIG_VFO_MEM) { int ch; xg3_get_mem(rig, vfo, &ch); SNPRINTF(cmdbuf, sizeof(cmdbuf), "M,%02d,%011ld", ch, (long)freq); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "F,%011ld", (long)freq); } err = kenwood_transaction(rig, cmdbuf, NULL, 0); return err; } /* * xg3_get_freq */ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct hamlib_port *rp; char freqbuf[50]; int freqsize = sizeof(freqbuf); char cmdbuf[16]; int retval; int offset; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; rp = RIGPORT(rig); switch (tvfo) { case RIG_VFO_A: break; case RIG_VFO_MEM: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (tvfo == RIG_VFO_MEM) { int ch; xg3_get_mem(rig, vfo, &ch); SNPRINTF(cmdbuf, sizeof(cmdbuf), "M,%02d;", ch); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "F;"); } retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s write_block failed\n", __func__); return retval; } retval = read_string(rp, (unsigned char *) freqbuf, freqsize, ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } offset = tvfo == RIG_VFO_A ? 2 : 5; sscanf(freqbuf + offset, "%" SCNfreq, freq); return RIG_OK; } /* * xg3_set_powerstat */ int xg3_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (status == RIG_POWER_OFF) { const char *cmd = "X"; //priv->powerstat = RIG_POWER_OFF; return kenwood_transaction(rig, cmd, NULL, 0); } rig_debug(RIG_DEBUG_VERBOSE, "%s invalid powerstat request status=%d\n", __func__, status); return -RIG_EINVAL; } /* * xg3_get_powerstat */ int xg3_get_powerstat(RIG *rig, powerstat_t *status) { const char *cmd = "G"; // any command to test will do char buf[6]; int retval = kenwood_transaction(rig, cmd, buf, 5); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (retval == RIG_OK) { *status = RIG_POWER_ON; //priv->powerstat = RIG_POWER_ON; } else { *status = RIG_POWER_OFF; // Error indicates power is off rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); //priv->powerstat = RIG_POWER_OFF; } return RIG_OK; // Always OK since it's a binary state } /* * xg3_set_mem */ int xg3_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[32]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ch < 0 || ch > 11) { rig_debug(RIG_DEBUG_VERBOSE, "%s invalid channel#%02d\n", __func__, ch); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "C,%02d;", ch); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s invalid set_mem cmd=%s\n", __func__, cmdbuf); return -RIG_EINVAL; } return RIG_OK; } /* * xg3_get_mem */ int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmdbuf[32]; char reply[32]; int retval; struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "C;"); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) reply, sizeof(reply), ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } sscanf(reply, "C,%d", ch); return RIG_OK; } /* * xg3_set_ptt */ int xg3_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_simple_transaction(rig, (ptt == RIG_PTT_ON) ? "O,01" : "O,00", 0); if (retval == RIG_OK) { //priv->ptt = RIG_PTT_ON; } return retval; } /* * kenwood_get_ptt */ int xg3_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "O", pttbuf, 6, 4); if (retval != RIG_OK) { return retval; } *ptt = pttbuf[3] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; //priv->ptt = *ptt; return RIG_OK; } /* * xg3_set_parm */ int xg3_set_parm(RIG *rig, setting_t parm, value_t val) { int ival; char cmdbuf[16]; int retval = -RIG_EINVAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: ival = 3 - (int)(val.f * 3); // gives us 0-3 bright-to-dim rig_debug(RIG_DEBUG_ERR, "%s: BACKLIGHT %d\n", __func__, ival); SNPRINTF(cmdbuf, sizeof(cmdbuf), "G,%02d", ival); retval = kenwood_simple_transaction(rig, cmdbuf, 0); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return retval; } /* * xg3_get_parm */ int xg3_get_parm(RIG *rig, setting_t parm, value_t *val) { int ival; char replybuf[6]; int retval = -RIG_EINVAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: retval = kenwood_safe_transaction(rig, "G", replybuf, 6, 4); if (retval == RIG_OK) { sscanf(&replybuf[3], "%d", &ival); val->f = (3.0f - (float) ival) / 3.0f; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return retval; } hamlib-4.6.5/rigs/kenwood/level_gran_elecraft.h0000664000175000017500000000542315056640443015226 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ #if !defined(NO_LVL_PREAMP) [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, #endif #if !defined(NO_LVL_ATT) [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 10 }, .step = { .i = 10 } }, #endif [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 800 }, .step = { .i = 10 } }, #endif /* levels with time units */ #if !defined(NO_LVL_CWPITCH) [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 50 } }, #endif /* levels with 0-1 values -- increment based on rig's range */ [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/10.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } }, [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_SWR] = { .min = { .f = 1.0 }, .max = { .f = 99.9 }, .step = { .f = 1.0f/10.0f } }, hamlib-4.6.5/rigs/kenwood/ts140.c0000664000175000017500000001335415056640443012113 /* * Hamlib Kenwood backend - TS140 description * Copyright (c) 2000-2009 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "kenwood.h" #define TS140_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_CWR) #define TS140_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_CWR) #define TS140_AM_TX_MODES RIG_MODE_AM #define TS140_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS140_ANTS (0) /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' static struct kenwood_priv_caps ts140_priv_caps = { .cmdtrm = EOM_KEN, }; static int ts140_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "ts140_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); /* The 680 and 140 need this to set the VFO on the radio */ return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts140 rig capabilities. * GW0VNR 09042006 */ struct rig_caps ts140_caps = { RIG_MODEL(RIG_MODEL_TS140S), .model_name = "TS-140S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, /* Rig only capable of 4800 baud from factory and 9k6 with jumper change */ .serial_data_bits = 8, .serial_stop_bits = 2, /* TWO stop bits. This is correct. */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* No PARAMS controllable */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* Not controllable */ .attenuator = { RIG_DBLST_END, }, /* Not controllable */ .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = Hz(0), /* Not controllable */ .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 19, RIG_MTYPE_MEM }, { 20, 30, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), kHz(34999), TS140_ALL_MODES, -1, -1, TS140_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS140_OTHER_TX_MODES, W(5), W(100), TS140_VFO, TS140_ANTS), FRQ_RNG_HF(1, TS140_AM_TX_MODES, W(2), W(40), TS140_VFO, TS140_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), kHz(34999), TS140_ALL_MODES, -1, -1, TS140_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS140_OTHER_TX_MODES, W(5), W(100), TS140_VFO, TS140_ANTS), FRQ_RNG_HF(2, TS140_AM_TX_MODES, W(2), W(40), TS140_VFO, TS140_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: Done */ {TS140_ALL_MODES, 10}, {TS140_ALL_MODES, 100}, {TS140_ALL_MODES, kHz(1)}, {TS140_ALL_MODES, kHz(5)}, {TS140_ALL_MODES, kHz(9)}, {TS140_ALL_MODES, kHz(10)}, {TS140_ALL_MODES, 12500}, {TS140_ALL_MODES, kHz(20)}, {TS140_ALL_MODES, kHz(25)}, {TS140_ALL_MODES, kHz(100)}, {TS140_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_CWR, 600}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts140_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts140_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/ts990s.c0000664000175000017500000006310515056640443012312 /* * Hamlib Kenwood backend - TS990s description * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2015 modified from ts2000.c by Bill Somerville G4WJS * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "ts990s.h" #include "cal.h" #define TS990S_AM_MODES RIG_MODE_AM #define TS990S_FM_MODES (RIG_MODE_FM|RIG_MODE_FMN) #define TS990S_OTHER_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_USBD1|RIG_MODE_USBD2|RIG_MODE_USBD3|RIG_MODE_LSBD1|RIG_MODE_LSBD2|RIG_MODE_LSBD3) #define TS990S_HP_MODES (TS990S_OTHER_MODES|TS990S_FM_MODES) #define TS990S_ALL_MODES (TS990S_OTHER_MODES|TS990S_AM_MODES|TS990S_FM_MODES) #define TS990S_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB) #define TS2000_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP) #define TS2000_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR) #define TS990S_VFO_OP (RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_TUNE) #define TS990S_SCAN_OP (RIG_SCAN_VFO) #define TS990S_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // Measurements from Wolfgang OE1MWW #define TS990S_STR_CAL {7, {\ {0x00, -54},\ {0x04, -48},\ {0x0B, -36},\ {0x13, -24},\ {0x1B, -12},\ {0x23, 0},\ {0x46, 60}}\ } #define TS990S_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 7, 1.5f }, \ { 36, 3.0f }, \ { 43, 6.0f }, \ { 70, 10.0f } \ } } /* memory capabilities */ #define TS990S_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* prototypes */ static int ts990s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts990s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); static rmode_t ts990s_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, [9] = RIG_MODE_RTTYR, [10] = RIG_MODE_NONE, /* A */ [11] = RIG_MODE_NONE, /* B */ [12] = RIG_MODE_LSBD1, /* C */ [13] = RIG_MODE_USBD1, /* D */ [14] = RIG_MODE_PKTFM, /* E */ [15] = RIG_MODE_NONE, /* F */ [16] = RIG_MODE_LSBD2, /* G */ [17] = RIG_MODE_USBD2, /* H */ [18] = RIG_MODE_PKTFM, /* I */ [19] = RIG_MODE_NONE, /* J */ [20] = RIG_MODE_LSBD3, /* K */ [21] = RIG_MODE_USBD3, /* L */ [22] = RIG_MODE_PKTFM, /* M */ [23] = RIG_MODE_NONE, /* N */ }; static struct kenwood_priv_caps ts990s_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = ts990s_mode_table, .tone_table_base = 0, }; /* * ts990s rig capabilities. * * part of infos comes from http://www.kenwood.net/ */ struct rig_caps ts990s_caps = { RIG_MODEL(RIG_MODEL_TS990S), .model_name = "TS-990S", .mfg_name = "Kenwood", .version = BACKEND_VER ".7", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, /* ms */ .timeout = 500, .retry = 10, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS2000_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_COMP #include "level_gran_kenwood.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_COMP [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1100 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0.0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = {}, .vfo_ops = TS990S_VFO_OP, .scan_ops = TS990S_SCAN_OP, .ctcss_list = kenwood42_ctcss_list, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_ON }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS990S_MEM_CAP }, { 1, 6, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS990S_ALL_MODES, -1, -1, TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(1830), kHz(1850), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), kHz(3800), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), kHz(3800), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7100), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7100), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(50.2), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(50.2), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS990S_ALL_MODES, -1, -1, TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(1800), MHz(2), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), MHz(4), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), MHz(4), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7300), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7300), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(54), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(54), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS990S_OTHER_MODES, 1}, {TS990S_OTHER_MODES, kHz(0.5)}, {TS990S_OTHER_MODES, kHz(1)}, {TS990S_OTHER_MODES, kHz(2.5)}, {TS990S_OTHER_MODES, kHz(5)}, {TS990S_OTHER_MODES, kHz(10)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(5)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(6.25)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(10)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(12.5)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(15)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(20)}, {TS990S_ALL_MODES, MHz(1)}, {TS990S_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.6)}, /* default normal */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.0)}, /* default narrow - arbitrary choice */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(3.2)}, /* default wide - arbitrary choice */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(4.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(3.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.4)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.4)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.2)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.0)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(0.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, /* default normal */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(250)}, /* default narrow - arbitrary choice */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.0)}, /* default wide - arbitrary choice */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.5)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.5)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* default normal */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, /* default narrow - arbitrary choice */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, /* default wide - arbitrary choice */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(400)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_AM, kHz(5)}, /* default normal */ {RIG_MODE_AM, kHz(2.5)}, /* default narrow - arbitrary choice */ {RIG_MODE_AM, kHz(4)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.6)}, /* default normal */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(500)}, /* default narrow - arbitrary choice */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(13)}, /* default wide - arbitrary choice */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.8)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.2)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.0)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.5)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.0)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(600)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(400)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(300)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(200)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(150)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(100)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(80)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(50)}, RIG_FLT_END, }, .str_cal = TS990S_STR_CAL, .swr_cal = TS990S_SWR_CAL, .priv = (void *)& ts990s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit_new, .get_rit = kenwood_get_rit_new, .set_xit = kenwood_set_rit_new, // Use same routines as for rit .get_xit = kenwood_get_rit_new, // Same .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo_main_sub, .get_vfo = kenwood_get_vfo_main_sub, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = ts990s_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts990s_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .get_clock = kenwood_get_clock, .set_clock = kenwood_set_clock, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * ts990s_get_level * Assumes rig!=NULL, val!=NULL */ int ts990s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; int lvl, retval = RIG_OK; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf), 4); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_MAIN: val->i = '1' == lvlbuf[2] ? STATE(rig)->preamp[0] : 0; break; case RIG_VFO_SUB: val->i = '1' == lvlbuf[3] ? STATE(rig)->preamp[0] : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } break; case RIG_LEVEL_ATT: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "RA%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 4); if (retval != RIG_OK) { return retval; } if ('0' == lvlbuf[3]) { val->i = 0; } else { val->i = STATE(rig)->attenuator[lvlbuf[3] - '1']; } } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_safe_transaction(rig, "VD0", lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->i = lvl * 3 / 2; /* 150ms units converted to 100ms units */ break; case RIG_LEVEL_AF: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "AG%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_RF: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "RG%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_SQL: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "SQ%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_RFPOWER: retval = kenwood_safe_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 200.0; /* TODO: should we detect AM and scale? */ break; case RIG_LEVEL_MICGAIN: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_KEYSPD: retval = kenwood_safe_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_COMP: retval = kenwood_safe_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf), 8); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; /* report input level */ val->f = lvl / 255.0; break; case RIG_LEVEL_AGC: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "GC%c", v); if (RIG_OK != (retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 4))) { return retval; } switch (lvlbuf[3]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_SLOW; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_FAST; break; } } break; case RIG_LEVEL_BKINDL: retval = kenwood_safe_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_SWR: retval = get_kenwood_meter_reading(rig, '2', &lvl); if (retval != RIG_OK) { return retval; } val->f = rig_raw2val_float(lvl, &rig->caps->swr_cal); val->f = round(val->f * 10) / 10.0; // 1 decimal place precision break; case RIG_LEVEL_METER: retval = kenwood_safe_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf), 7); if (retval != RIG_OK) { return retval; } switch (lvlbuf[2]) { case '1': val->i = RIG_METER_ALC; break; case '2': val->i = RIG_METER_SWR; break; case '3': val->i = RIG_METER_COMP; break; case '4': val->i = RIG_METER_IC; break; case '5': val->i = RIG_METER_VDD; break; default: val->i = RIG_METER_NONE; break; } break; case RIG_LEVEL_VOXGAIN: retval = get_kenwood_level(rig, "VG00", &val->f, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_ANTIVOX: retval = get_kenwood_level(rig, "VG00", &val->f, NULL); if (retval != RIG_OK) { return retval; } val->f = val->f * 255. / 20.; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "SM%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 7); if (retval != RIG_OK) { return retval; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-990s returns values from 0 - 70 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 54. / 70.) - 54; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } /* * Gets split VFO status * */ static int ts990s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { char buf[4]; int retval; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; if (RIG_OK == (retval = kenwood_safe_transaction(rig, "TB", buf, sizeof(buf), 3))) { if ('1' == buf[2]) { *split = RIG_SPLIT_ON; *txvfo = RIG_VFO_SUB; } else { *split = RIG_SPLIT_OFF; *txvfo = RIG_VFO_MAIN; } priv->tx_vfo = rs->tx_vfo = *txvfo; } return retval; } hamlib-4.6.5/rigs/kenwood/pihpsdr.c0000664000175000017500000012062515056640443012711 /* * Hamlib PiHPSDR backend - TS-2000 Emulation (derived from ts2000.c) * Copyright (c) 2017 by Jae Stutzman * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "kenwood.h" #include "tones.h" #define PIHPSDR_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define PIHPSDR_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define PIHPSDR_AM_TX_MODES RIG_MODE_AM #define PIHPSDR_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP) #define PIHPSDR_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define PIHPSDR_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define PIHPSDR_SUBVFO (RIG_VFO_C) #define PIHPSDR_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN) #define PIHPSDR_SCAN_OP (RIG_SCAN_VFO) #define PIHPSDR_ANTS (RIG_ANT_1|RIG_ANT_2) #define PIHPSDR_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } /* prototypes */ static int pihpsdr_open(RIG *rig); static int pihpsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int pihpsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int pihspdr_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int pihspdr_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static struct kenwood_priv_caps ts2000_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* memory capabilities */ #define PIHPSDR_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * PiHPSDR rig capabilities. (Emulates Kenwood TS-2000) */ struct rig_caps pihpsdr_caps = { RIG_MODEL(RIG_MODEL_HPSDR), .model_name = "PiHPSDR", .mfg_name = "OpenHPSDR", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, /* ms */ .timeout = 500, .retry = 1, .has_get_func = PIHPSDR_FUNC_ALL, .has_set_func = PIHPSDR_FUNC_ALL, .has_get_level = PIHPSDR_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(PIHPSDR_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .parm_gran = {}, .vfo_ops = PIHPSDR_VFO_OP, .scan_ops = PIHPSDR_SCAN_OP, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* FIXME: real preamp? */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, PIHPSDR_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(146), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(144), MHz(146), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, {MHz(430), MHz(440), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(1830), kHz(1850), PIHPSDR_AM_TX_MODES, 2000, 25000, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), kHz(3800), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), kHz(3800), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7100), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7100), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(50.2), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(50.2), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(146), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO}, {MHz(144), MHz(146), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_OTHER_TX_MODES, W(5), W(50), PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_AM_TX_MODES, W(5), W(12.5), PIHPSDR_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(142), MHz(152), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(420), MHz(450), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(118), MHz(174), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, {MHz(220), MHz(512), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(1800), MHz(2), PIHPSDR_AM_TX_MODES, 2000, 25000, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), MHz(4), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), MHz(4), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7300), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7300), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(54), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(54), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(148), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO}, {MHz(144), MHz(148), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO}, {MHz(430), MHz(450), PIHPSDR_OTHER_TX_MODES, W(5), W(50), PIHPSDR_MAINVFO}, {MHz(430), MHz(450), PIHPSDR_AM_TX_MODES, W(5), W(12.5), PIHPSDR_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {PIHPSDR_ALL_MODES, 10}, {PIHPSDR_ALL_MODES, 100}, {PIHPSDR_ALL_MODES, kHz(1)}, {PIHPSDR_ALL_MODES, kHz(2.5)}, {PIHPSDR_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {PIHPSDR_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {PIHPSDR_ALL_MODES, MHz(1)}, {PIHPSDR_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW, Hz(600)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 5}, .max = {.i = 50}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, }, .str_cal = PIHPSDR_STR_CAL, .priv = (void *)& ts2000_priv_caps, .rig_init = kenwood_init, .rig_open = pihpsdr_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = pihpsdr_set_level, .get_level = pihpsdr_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = pihspdr_get_channel, .set_channel = pihspdr_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * pihspdr_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int pihspdr_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; char buf[52]; char cmd[8]; size_t length; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int pihspdr_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype; char shift; char buf[128]; char mode, tx_mode = 0; int err; int tone = 0; int tstep; short code; short dcscode; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ sqltype = '0'; if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ code = 0; if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ dcscode = 0; if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } shift = '0'; if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } tstep = 0; if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } int pihpsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, kenwood_val; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { case RIG_LEVEL_RFPOWER: /* level is float between 0.0 and 1.0, maps to 0 ... 100 */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", kenwood_val); break; case RIG_LEVEL_RF: /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", kenwood_val); break; case RIG_LEVEL_AGC: if (kenwood_val == RIG_AGC_SUPERFAST) { kenwood_val = 5; } else if (kenwood_val == RIG_AGC_FAST) { kenwood_val = 10; } else if (kenwood_val == RIG_AGC_MEDIUM) { kenwood_val = 15; } else if (kenwood_val == RIG_AGC_SLOW) { kenwood_val = 20; } else if (kenwood_val != RIG_AGC_OFF) { rig_debug(RIG_DEBUG_ERR, "%s: unknown AGC level, expect OFF,SLOW,MEDIUM,FAST,SUPERFAST, got %d\n", __func__, kenwood_val); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_ATT: /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i]; i++) { if (val.i == rs->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i]; i++) { if (val.i == rs->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_SLOPE_HIGH: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", (val.i)); break; case RIG_LEVEL_SLOPE_LOW: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", (val.i)); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "PT%02d", (val.i / 50) - 8); break; case RIG_LEVEL_KEYSPD: if (val.i > 50 || val.i < 5) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * pihpsdr_get_level * Assumes rig!=NULL, val!=NULL */ int pihpsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval; lvl_len = 50; switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 4)) /*TS-2000 returns 4 chars for PA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 10) /* just checking for main receiver preamp setting */ { val->i = 0; } if (lvl > 9) { val->i = STATE(rig)->preamp[0]; } break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 6)) /* TS-2000 returns 6 chars for RA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 100) /* just checking main band attenuator */ { val->i = 0; } if (lvl > 99) { val->i = STATE( rig)->attenuator[0]; /* Since the TS-2000 only has one step on the attenuator */ } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_transaction(rig, "VD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_AF: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_CWPITCH: retval = kenwood_transaction(rig, "EX0310000", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 15) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d answer=%s\n", __func__, (int)lvl_len, lvlbuf); return -RIG_ERJCTED; } sscanf(lvlbuf + 8, "%d", &lvl); val->i = 400 + (50 * lvl); break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.0; /* FIXME: for 1.2GHZ need to divide by 10 */ break; case RIG_LEVEL_MICGAIN: retval = kenwood_transaction(rig, "MG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.0; break; case RIG_LEVEL_KEYSPD: retval = kenwood_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; val->f = lvl / 100.0; break; case RIG_LEVEL_AGC: /* pihpsdr defines the range 0 -20 for AGC (based on TS-2000) */ retval = kenwood_transaction(rig, "GT", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = RIG_AGC_OFF; } /*pihspdr: OFF */ else if (lvl < 6) { val->i = RIG_AGC_SUPERFAST; } /*pihspdr: 001-005 = FAST */ else if (lvl < 11) { val->i = RIG_AGC_FAST; } /*pihspdr: 006-010 = MEDIUM */ else if (lvl < 16) { val->i = RIG_AGC_MEDIUM; } /*pihspdr: 011-015 = SLOW */ else if (lvl <= 20) { val->i = RIG_AGC_SLOW; } /*pihspdr: 016-020 = LONG */ break; case RIG_LEVEL_BKINDL: retval = kenwood_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; break; case RIG_LEVEL_METER: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 10000; break; case RIG_LEVEL_VOXGAIN: retval = kenwood_transaction(rig, "VG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 9.0; break; case RIG_LEVEL_ANTIVOX: return -RIG_ENIMPL; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (((lvl_len != 7)) || lvlbuf[1] != 'M') { /* TS-2000 returns 8 bytes for S meter level */ rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-2000 main receiver returns values from 0 - 30 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 3.6) - 54; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* use custom open function since this rig emulates TS-2000 and we need to not use the TS-2000 backend open function */ int pihpsdr_open(RIG *rig) { char id[KENWOOD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* get id in buffer, will be null terminated */ kenwood_get_id(rig, id); if (!strcmp(id, "ID019")) /* matched */ { /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } /* driver mismatch */ rig_debug(RIG_DEBUG_ERR, "%s: wrong driver selected\n", __func__); return -RIG_EINVAL; } hamlib-4.6.5/rigs/kenwood/README.flex0000664000175000017500000000335315056640443012707 FlexRadio 6xxx series notes and Hamlib errata by Steve Conklin, AI4QR. Commands as documented from Flex ----------Kenwood Command Set---------- FA Slice receiver A frequency. FB Slice receiver B frequency. FR Receive VFO FT Transmit VFO IF Transceiver Status KS Keying speed MD DSP Mode RX Set receive (TX off) SH Set DSP filter high frequency SL Set DSP filter low frequency TX Set transmit (TX on) ----------FlexRadio Command Set---------- ZZFA Slice receiver A frequency ZZFB Slice receiver B frequency ZZFI Slice Receiver A DSP filter ZZFJ Slice Receiver B DSP filter ZZIF Transceiver Status ZZMD Slice receiver A DSP Mode ZZME Slice receiver B DSP Mode ZZSW Set slice Transmit flag (RX A or RX B) ZZTX Set MOX (on/off) ================================================ rigctl commands used to test operation (freq set and read) f F 14100000 F 14070000 also test to see if RX and TX can be set out of band (mode set and read with passband) m M USB 5 [Should set to USB and 1.6K] M USB 20000 [should set to USb and 4K] also test other modes (vfo set and read) v V VFOB [opens with a 5K split] (set and get split freq) i I 14078000 [ Even if split is turned off, this sets VFOB] (split set and read) NOTE: When split off, TX VFO is always A s [ shows split and VFOA is TX] S 1 VFOA s S 1 VFOB (keying speed) l KEYSPD L KEYSPD 25 l KEYSPD L KEYSPD 10 l KEYSPD (filter edges) l SLOPE_HIGH l SLOPE_LOW === Supported: case RIG_LEVEL_KEYSPD: 'KS' case RIG_LEVEL_SLOPE_HIGH: 'SH' needs list of frequencies case RIG_LEVEL_SLOPE_LOW: 'SL' Not supported: case RIG_LEVEL_RFPOWER: 'PC' case RIG_LEVEL_AF: 'AG' case RIG_LEVEL_RF: 'RG' case RIG_LEVEL_SQL: 'SQ' case RIG_LEVEL_AGC: 'GT' case RIG_LEVEL_ATT: 'RA' case RIG_LEVEL_PREAMP: 'PA' case RIG_LEVEL_CWPITCH: 'PT' hamlib-4.6.5/rigs/kenwood/README.k20000664000175000017500000000273515056640443012270 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). This function also probes the K2 for the RTTY option and then installed filters and bandwidths. This information is stored in a structure and used later. The probe adds about 10 seconds to the rig_open. kenwood_get/set_ext_parms() =========================== These functions are used to get and set RIT/XIT on and off. The special token names of 'rit' and 'xit' are used with the P/p commands of rigctl[d] for the 'parm'. Set/returned value is 0 or 1 for off or on. hamlib-4.6.5/rigs/kenwood/r5000.c0000664000175000017500000001147615056640443012011 /* * Hamlib Kenwood backend - R5000 description * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "ic10.h" #define R5000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define R5000_FUNC_ALL (RIG_FUNC_LOCK) #define R5000_LEVEL_ALL RIG_LEVEL_NONE #define R5000_PARM_ALL (RIG_PARM_TIME) #define R5000_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define R5000_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define R5000_SCAN_OPS (RIG_SCAN_VFO) #define R5000_ANTS (RIG_ANT_1|RIG_ANT_2) static struct kenwood_priv_caps r5000_priv_caps = { .cmdtrm = EOM_KEN, .if_len = 32, .tone_table_base = 1, }; /* * R5000 rig capabilities, with IF-10 interface (like TS440). * * TODO: scan, get/set_channel, RIT */ struct rig_caps r5000_caps = { RIG_MODEL(RIG_MODEL_R5000), .model_name = "R-5000", .mfg_name = "Kenwood", .version = IC10_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 2, .timeout = 500, .retry = 3, .has_get_func = R5000_FUNC_ALL, .has_set_func = R5000_FUNC_ALL, .has_get_level = R5000_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R5000_LEVEL_ALL), .has_get_parm = R5000_PARM_ALL, .has_set_parm = RIG_PARM_SET(R5000_PARM_ALL), .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = R5000_VFO_OPS, .scan_ops = R5000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, {IC10_CHANNEL_CAPS} }, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), R5000_ALL_MODES, -1, -1, R5000_VFO}, {MHz(108), MHz(174), R5000_ALL_MODES, -1, -1, R5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), R5000_ALL_MODES, -1, -1, R5000_VFO}, {MHz(108), MHz(174), R5000_ALL_MODES, -1, -1, R5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {R5000_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& r5000_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = ic10_set_freq, .get_freq = ic10_get_freq, .set_mode = ic10_set_mode, .get_mode = ic10_get_mode, .set_vfo = ic10_set_vfo, .get_vfo = ic10_get_vfo, .set_func = ic10_set_func, .get_func = ic10_get_func, .set_parm = ic10_set_parm, .get_parm = ic10_get_parm, .set_ant = ic10_set_ant, .get_ant = ic10_get_ant, .set_mem = ic10_set_mem, .get_mem = ic10_get_mem, .vfo_op = ic10_vfo_op, .set_trn = ic10_set_trn, .get_trn = ic10_get_trn, .scan = ic10_scan, .set_channel = ic10_set_channel, .get_channel = ic10_get_channel, .set_powerstat = ic10_set_powerstat, .get_powerstat = ic10_get_powerstat, .get_info = ic10_get_info, .decode_event = ic10_decode_event, .hamlib_check_rig_caps = "HAMLIB_CHECK_RIG_CAPS" }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/ts870s.c0000664000175000017500000004455615056640443012320 /* * Hamlib Kenwood backend - TS870S description * Copyright (c) 2000-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "bandplan.h" #define TS870S_ALL_MODES \ (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB \ |RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS870S_OTHER_TX_MODES \ (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS870S_AM_TX_MODES RIG_MODE_AM #define TS870S_FUNC_ALL \ (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR \ |RIG_FUNC_BC|RIG_FUNC_ANF|RIG_FUNC_LOCK) #define TS870S_LEVEL_SET \ (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_RFPOWER \ |RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_PREAMP) #define TS870S_LEVEL_GET \ (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR \ |RIG_LEVEL_COMP|RIG_LEVEL_ALC|RIG_LEVEL_AGC|RIG_LEVEL_RFPOWER \ |RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_PREAMP) #define TS870S_VFO (RIG_VFO_A|RIG_VFO_B) #define TS870S_ANTS (RIG_ANT_1|RIG_ANT_2) static struct kenwood_priv_caps ts870s_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* only the ts870s and ts2000 support get_vfo with the 'FR;' command NOTE: using byte 31 in 'IF' will also work. TODO: check other rigs */ static int ts870s_get_vfo(RIG *rig, vfo_t *vfo) { char vfobuf[50]; size_t vfo_len; int retval; /* query RX VFO */ retval = kenwood_transaction(rig, "FR", vfobuf, sizeof(vfobuf)); if (retval != RIG_OK) { return retval; } vfo_len = strlen(vfobuf); if (vfo_len != 3 || vfobuf[1] != 'R') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer %s, len=%d\n", __func__, vfobuf, (int)vfo_len); return -RIG_ERJCTED; } /* TODO: replace 0,1,2,.. constants by defines */ switch (vfobuf[2]) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, vfobuf[2]); return -RIG_EPROTO; } return RIG_OK; } static int ts870s_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[50]; size_t buf_len; int retval; retval = kenwood_transaction(rig, "MD", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 3 || buf[1] != 'D') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected MD answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } switch (buf[2]) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FSK: *mode = RIG_MODE_RTTY; break; case MD_FSKR: *mode = RIG_MODE_RTTYR; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, buf[2]); return -RIG_EINVAL; } retval = kenwood_transaction(rig, "FW", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 6 || buf[1] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected FW answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } *width = 10 * atoi(&buf[2]); if (RIG_MODE_USB == *mode || RIG_MODE_LSB == *mode || RIG_MODE_AM == *mode) { /* we only have HPF value and need LPF as well to calculate bandwidth */ retval = kenwood_transaction(rig, "IS", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 7 || buf[1] != 'S') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected IS answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } *width = atoi(&buf[3]) - *width; /* bandwidth <- LPF - HPF */ } return RIG_OK; } static int ts870s_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[16]; int kmode, retval; switch (mode) { case RIG_MODE_CW: kmode = MD_CW; break; case RIG_MODE_CWR: kmode = MD_CWR; break; case RIG_MODE_USB: kmode = MD_USB; break; case RIG_MODE_LSB: kmode = MD_LSB; break; case RIG_MODE_FM: kmode = MD_FM; break; case RIG_MODE_AM: kmode = MD_AM; break; case RIG_MODE_RTTY: kmode = MD_FSK; break; case RIG_MODE_RTTYR: kmode = MD_FSKR; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", kmode); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { if (RIG_PASSBAND_NORMAL != width) /* leave well alone if default passband requested */ { if (RIG_MODE_USB == mode || RIG_MODE_LSB == mode || RIG_MODE_AM == mode) { pbwidth_t mode_default_hpf; /* we assume the HPF is set to default and set the LPF to give the best approximation of the requested width */ if (RIG_MODE_AM == mode) { mode_default_hpf = 300; } else { mode_default_hpf = 100; } SNPRINTF(buf, sizeof(buf), "IS %04d", (int)(width + mode_default_hpf)); retval = kenwood_transaction(rig, buf, NULL, 0); } else { /* * This rig will simply use an IF bandpass which is closest to width, * so we don't need to check the value... */ SNPRINTF(buf, sizeof(buf), "FW%04d", (int)width / 10); retval = kenwood_transaction(rig, buf, NULL, 0); } } } return retval; } int ts870s_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int intval; switch (level) { case RIG_LEVEL_RFPOWER: intval = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", intval); return kenwood_transaction(rig, levelbuf, NULL, 0); break; default: return kenwood_set_level(rig, vfo, level, val); } return RIG_OK; } static int ts870s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval; int i, ret, agclevel; switch (level) { case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6 || lvlbuf[1] != 'M') { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: wrong answer len=%d\n", (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * 3.6) - 54; break; case RIG_LEVEL_SWR: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to SWR if needed */ if (lvlbuf[2] != '1') { retval = kenwood_transaction(rig, "RM1", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } i = atoi(&lvlbuf[3]); if (i == 30) { val->f = 150.0; /* infinity :-) */ } else { val->f = 60.0 / (30.0 - (float)i) - 1.0; } break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to COMP if needed */ if (lvlbuf[2] != '2') { retval = kenwood_transaction(rig, "RM2", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ALC: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to ALC if needed */ if (lvlbuf[2] != '3') { retval = kenwood_transaction(rig, "RM3", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: " "unexpected att level %d\n", lvl); return -RIG_EPROTO; } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_RFPOWER: /* RFPOWER is 0..100 and not 0..255 like all the other levels*/ retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5 || lvlbuf[1] != 'C') { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: wrong answer len=%d\n", (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.; break; case RIG_LEVEL_AF: return get_kenwood_level(rig, "AG", &val->f, NULL); case RIG_LEVEL_RF: return get_kenwood_level(rig, "RG", &val->f, NULL); case RIG_LEVEL_SQL: return get_kenwood_level(rig, "SQ", &val->f, NULL); case RIG_LEVEL_MICGAIN: return get_kenwood_level(rig, "MG", &val->f, NULL); case RIG_LEVEL_AGC: ret = get_kenwood_level(rig, "GT", &val->f, NULL); agclevel = 255 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; case RIG_LEVEL_PREAMP: return -RIG_ENAVAIL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * ts870s rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range 9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts870s_caps = { RIG_MODEL(RIG_MODEL_TS870S), .model_name = "TS-870S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS870S_FUNC_ALL, .has_set_func = TS870S_FUNC_ALL, .has_get_level = TS870S_LEVEL_GET, .has_set_level = TS870S_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_kenwood.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // Has GT command but ranges from 000-005(Off) to 255 max // Would take special processing .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), TS870S_ALL_MODES, -1, -1, TS870S_VFO, TS870S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS870S_OTHER_TX_MODES, W(5), W(100), TS870S_VFO, TS870S_ANTS), /* 100W class */ FRQ_RNG_HF(1, TS870S_AM_TX_MODES, W(2), W(25), TS870S_VFO, TS870S_ANTS), /* 25W class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS870S_ALL_MODES, -1, -1, TS870S_VFO, TS870S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS870S_OTHER_TX_MODES, W(5), W(100), TS870S_VFO, TS870S_ANTS), /* 100W class */ FRQ_RNG_HF(2, TS870S_AM_TX_MODES, W(2), W(25), TS870S_VFO, TS870S_ANTS), /* 25W class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS870S_ALL_MODES, 50}, {TS870S_ALL_MODES, 100}, {TS870S_ALL_MODES, kHz(1)}, {TS870S_ALL_MODES, kHz(5)}, {TS870S_ALL_MODES, kHz(9)}, {TS870S_ALL_MODES, kHz(10)}, {TS870S_ALL_MODES, 12500}, {TS870S_ALL_MODES, kHz(20)}, {TS870S_ALL_MODES, kHz(25)}, {TS870S_ALL_MODES, kHz(100)}, {TS870S_ALL_MODES, MHz(1)}, {TS870S_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, Hz(200)}, {RIG_MODE_SSB, Hz(0)}, {RIG_MODE_SSB, Hz(600)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(1000)}, {RIG_MODE_RTTY, Hz(1000)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, Hz(200)}, {RIG_MODE_AM, Hz(0)}, {RIG_MODE_AM, Hz(500)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& ts870s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = ts870s_set_mode, .get_mode = ts870s_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = ts870s_get_vfo, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = ts870s_set_level, .get_level = ts870s_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/transfox.c0000664000175000017500000002340715056640443013104 /* * Hamlib backend - SigFox Transfox description * Copyright (c) 2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. */ #include #include #include "kenwood.h" #define TRANSFOX_MODES (RIG_MODE_USB) /* SDR */ #define TRANSFOX_FUNC_ALL (RIG_FUNC_NONE) #define TRANSFOX_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define TRANSFOX_VFO (RIG_VFO_A) #define TRANSFOX_VFO_OP (RIG_OP_NONE) #define TRANSFOX_ANTS (RIG_ANT_1) /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps transfox_priv_caps = { .cmdtrm = EOM_KEN, }; /* TRANSFOX specific rig_caps API function declarations */ static int transfox_open(RIG *rig); static const char *transfox_get_info(RIG *rig); static int transfox_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int transfox_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int transfox_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * Transfox rig capabilities. * This SDR only share some basic Kenwood's protocol. * * Part of info comes from http://www.sigfox-system.com/TransFox-FE?lang=en */ struct rig_caps transfox_caps = { RIG_MODEL(RIG_MODEL_TRANSFOX), .model_name = "Transfox", .mfg_name = "SigFox", .version = "20111223.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 500, .retry = 3, .has_get_func = TRANSFOX_FUNC_ALL, .has_set_func = TRANSFOX_FUNC_ALL, .has_get_level = TRANSFOX_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TRANSFOX_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .extparms = NULL, .preamp = { 22, 44, RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TRANSFOX_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {MHz(1), MHz(1450), TRANSFOX_MODES, -1, -1, TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(1), MHz(1450), TRANSFOX_MODES, mW(100), mW(100), TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(1), MHz(1450), TRANSFOX_MODES, -1, -1, TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(1), MHz(1450), TRANSFOX_MODES, mW(100), mW(100), TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TRANSFOX_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {TRANSFOX_MODES, kHz(192)}, RIG_FLT_END, }, .priv = (void *)& transfox_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = transfox_open, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_level = transfox_set_level, .get_level = transfox_get_level, .set_ptt = kenwood_set_ptt, .get_ptt = transfox_get_ptt, .get_info = transfox_get_info, #ifdef XXREMOVEDXX .set_trn = transfox_set_trn, .get_trn = transfox_get_trn, .scan = transfox_scan, .set_conf = transfox_set_conf, .get_conf = transfox_get_conf, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * TRANSFOX extension function definitions follow */ /* transfox_open() * */ int transfox_open(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->current_vfo = RIG_VFO_A; /* do not call kenwood_open(rig), rig has no "ID" command */ return RIG_OK; } int transfox_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char buf[8]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "Cs", buf, 8, 2); if (retval != RIG_OK) { return retval; } *ptt = buf[0] == 'T' ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } const char *transfox_get_info(RIG *rig) { static char firmbuf[32]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); firmbuf[0] = '\0'; retval = kenwood_transaction(rig, "CS", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } return firmbuf; } int transfox_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret = RIG_OK; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: if (val.i == 0) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C20", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 10) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C21", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 20) { ret = kenwood_transaction(rig, "C31", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C21", NULL, 0); if (ret != RIG_OK) { return ret; } } break; case RIG_LEVEL_PREAMP: if (val.i == 0) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C20", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 22) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C22", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 44) { ret = kenwood_transaction(rig, "C32", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C22", NULL, 0); if (ret != RIG_OK) { return ret; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return ret; } int transfox_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "C2x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i = (lvlbuf[2] == '1') ? 10 : 0; retval = kenwood_safe_transaction(rig, "C3x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i += (lvlbuf[2] == '1') ? 10 : 0; break; case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "C2x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i = (lvlbuf[2] == '2') ? 22 : 0; retval = kenwood_safe_transaction(rig, "C3x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i += (lvlbuf[2] == '2') ? 22 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/kenwood/tx500.c0000664000175000017500000010544315056640443012121 /* * Hamlib Lab599 backend - TX-500 description * Copyright (c) 2021 by Michael Black W9MDB - borrowed from ts2000.c * Copyright (c) 2000-2011 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "kenwood.h" #define TX500_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TX500_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TX500_AM_TX_MODES RIG_MODE_AM #define TX500_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP|RIG_FUNC_RIT|RIG_FUNC_XIT) #define TX500_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define TX500_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define TX500_SUBVFO (RIG_VFO_C) #define TX500_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN) #define TX500_SCAN_OP (RIG_SCAN_VFO) #define TX500_ANTS (RIG_ANT_1|RIG_ANT_2) #define TX500_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } /* prototypes */ static int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); /* * 38 CTCSS sub-audible tones + 1750 tone */ tone_t tx500_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 17500, 0, }; /* * 103 available DCS codes */ tone_t tx500_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; static struct kenwood_priv_caps tx500_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, /* TS-2000 compatible ??? */ }; /* memory capabilities */ #define TX500_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * TX-500 rig capabilities. * */ struct rig_caps tx500_caps = { RIG_MODEL(RIG_MODEL_LAB599_TX500), .model_name = "TX-500", .mfg_name = "Lab599", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .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 = 0, .post_write_delay = 0, /* ms */ .timeout = 500, .retry = 10, .has_get_func = TX500_FUNC_ALL, .has_set_func = TX500_FUNC_ALL, .has_get_level = TX500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TX500_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, /* FIXME: granularity */ .parm_gran = {}, .vfo_ops = TX500_VFO_OP, .scan_ops = TX500_SCAN_OP, .ctcss_list = tx500_ctcss_list, .dcs_list = tx500_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* FIXME: real preamp? */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TX500_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TX500_ALL_MODES, -1, -1, TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(146), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(430), MHz(440), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(144), MHz(146), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, {MHz(430), MHz(440), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(1830), kHz(1850), TX500_AM_TX_MODES, 2000, 25000, TX500_MAINVFO, TX500_ANTS}, {kHz(3500), kHz(3800), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(3500), kHz(3800), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7100), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7100), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(50.2), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(50.2), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(146), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO}, {MHz(144), MHz(146), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO}, {MHz(430), MHz(440), TX500_OTHER_TX_MODES, W(5), W(50), TX500_MAINVFO}, {MHz(430), MHz(440), TX500_AM_TX_MODES, W(5), W(12.5), TX500_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TX500_ALL_MODES, -1, -1, TX500_MAINVFO, TX500_ANTS}, {MHz(142), MHz(152), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(420), MHz(450), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(118), MHz(174), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, {MHz(220), MHz(512), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(1800), MHz(2), TX500_AM_TX_MODES, 2000, 25000, TX500_MAINVFO, TX500_ANTS}, {kHz(3500), MHz(4), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(3500), MHz(4), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7300), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7300), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(54), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(54), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(148), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO}, {MHz(144), MHz(148), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO}, {MHz(430), MHz(450), TX500_OTHER_TX_MODES, W(5), W(50), TX500_MAINVFO}, {MHz(430), MHz(450), TX500_AM_TX_MODES, W(5), W(12.5), TX500_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TX500_ALL_MODES, 10}, {TX500_ALL_MODES, 100}, {TX500_ALL_MODES, kHz(1)}, {TX500_ALL_MODES, kHz(2.5)}, {TX500_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TX500_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TX500_ALL_MODES, MHz(1)}, {TX500_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW, Hz(600)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, RIG_FLT_END, }, .str_cal = TX500_STR_CAL, .priv = (void *)& tx500_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts2000_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = ts2000_get_channel, .set_channel = ts2000_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, //.set_powerstat = kenwood_set_powerstat, //.get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * ts2000_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; size_t length; char buf[52]; char cmd[8]; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype = '0'; char buf[128]; char mode, tx_mode = 0; char shift = '0'; short dcscode = 0; short code = 0; int tstep = 0; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } /* * ts2000_get_level * Assumes rig!=NULL, val!=NULL */ int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval, ret, agclevel; lvl_len = 50; switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 4)) /*TS-2000 returns 4 chars for PA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 10) /* just checking for main receiver preamp setting */ { val->i = 0; } if (lvl > 9) { val->i = STATE(rig)->preamp[0]; } break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 6)) /* TS-2000 returns 6 chars for RA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 100) /* just checking main band attenuator */ { val->i = 0; } if (lvl > 99) { val->i = STATE( rig)->attenuator[0]; /* Since the TS-2000 only has one step on the attenuator */ } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_transaction(rig, "VD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_AF: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_CWPITCH: retval = kenwood_transaction(rig, "EX0310000", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 15) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d answer=%s\n", __func__, (int)lvl_len, lvlbuf); return -RIG_ERJCTED; } sscanf(lvlbuf + 8, "%d", &lvl); val->i = 400 + (50 * lvl); break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 100.0; /* FIXME: for 1.2GHZ need to divide by 10 */ break; case RIG_LEVEL_MICGAIN: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_KEYSPD: retval = kenwood_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; val->f = lvl / 100.0; break; case RIG_LEVEL_AGC: /* FIX ME: ts2000 returns 0 -20 for AGC */ ret = get_kenwood_level(rig, "GT", &val->f, NULL); agclevel = 255.0 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; break; case RIG_LEVEL_BKINDL: retval = kenwood_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; break; case RIG_LEVEL_METER: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 10000; break; case RIG_LEVEL_VOXGAIN: retval = kenwood_transaction(rig, "VG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 9.0; break; case RIG_LEVEL_ANTIVOX: return -RIG_ENIMPL; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (((lvl_len != 7)) || lvlbuf[1] != 'M') { /* TS-2000 returns 8 bytes for S meter level */ rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-2000 main receiver returns values from 0 - 30 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 3.6) - 54; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.5/rigs/kenwood/flex6xxx.c0000664000175000017500000013356715056640443013045 /* * Hamlib FlexRadio backend - 6K series rigs * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (C) 2010,2011,2012,2013 by Nate Bargmann, n0nb@arrl.net * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include "kenwood.h" #include "bandplan.h" #include "misc.h" #include "flex.h" #define F6K_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define F6K_FUNC_ALL (RIG_FUNC_VOX|RIG_FUNC_TUNER) #define F6K_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER) #define F6K_VFO (RIG_VFO_A|RIG_VFO_B) #define POWERSDR_VFO_OP (RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_UP|RIG_OP_DOWN) #define F6K_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) /* PowerSDR differences */ #define POWERSDR_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_SPEC) #define POWERSDR_FUNC_ALL (RIG_FUNC_VOX|RIG_FUNC_SQL|RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MUTE|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER) #define POWERSDR_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR) #define POWERSDR_LEVEL_SET (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF) static rmode_t flex_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_PKTLSB, [7] = RIG_MODE_NONE, [8] = RIG_MODE_NONE, [9] = RIG_MODE_PKTUSB }; static rmode_t powersdr_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_LSB, [1] = RIG_MODE_USB, [2] = RIG_MODE_DSB, [3] = RIG_MODE_CWR, [4] = RIG_MODE_CW, [5] = RIG_MODE_FM, [6] = RIG_MODE_AM, [7] = RIG_MODE_PKTUSB, [8] = RIG_MODE_NONE, // SPEC -- not implemented [9] = RIG_MODE_PKTLSB, [10] = RIG_MODE_SAM, [11] = RIG_MODE_NONE // DRM -- not implemented }; static struct kenwood_priv_caps f6k_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = flex_mode_table, .if_len = 37 }; static struct kenwood_priv_caps powersdr_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = powersdr_mode_table, .if_len = 37, .swr = 0 }; #define DSP_BW_NUM 8 static int dsp_bw_ssb[DSP_BW_NUM] = { 4000, 3300, 2900, 2700, 2400, 2100, 1800, 1600 }; static int dsp_bw_am[DSP_BW_NUM] = { 20000, 16000, 14000, 12000, 10000, 8000, 6000, 5600 }; static int dsp_bw_cw[DSP_BW_NUM] = { 3000, 1500, 1000, 800, 400, 250, 100, 50 }; static int dsp_bw_dig[DSP_BW_NUM] = { 3000, 2000, 1500, 1000, 600, 300, 150, 100 }; // PowerSDR settings #define DSP_BW_NUM_POWERSDR 12 static int dsp_bw_ssb_powersdr[DSP_BW_NUM_POWERSDR] = { 5000, 4400, 3800, 3300, 2900, 2700, 2400, 2100, 1800, 1000, 0, 0 }; static int dsp_bw_am_powersdr[DSP_BW_NUM_POWERSDR] = { 16000, 12000, 10000, 8000, 6600, 5200, 4000, 3100, 2900, 2400, 0, 0 }; static int dsp_bw_cw_powersdr[DSP_BW_NUM_POWERSDR] = { 1000, 800, 600, 500, 400, 250, 150, 100, 50, 25, 0, 0 }; static int dsp_bw_dig_powersdr[DSP_BW_NUM_POWERSDR] = { 3000, 2500, 2000, 1500, 1000, 800, 600, 300, 150, 75, 0, 0 }; #if 0 // not used yet static int dsp_bw_sam_powersdr[DSP_BW_NUM_POWERSDR] = { 20000, 18000, 16000, 12000, 10000, 9000, 8000, 7000, 6000, 5000, 0, 0 }; #endif /* Private helper functions */ static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char modebuf[10]; int index; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "MD", modebuf, 6, 3); if (retval != RIG_OK) { return retval; } *mode = kenwood2rmode(modebuf[2] - '0', caps->mode_table); if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI * Have to determine what to do with receiver#2 if anybody ever asks */ switch (vfo) { case RIG_VFO_A: retval = kenwood_safe_transaction(rig, "ZZFI", modebuf, 10, 6); break; case RIG_VFO_B: retval = kenwood_safe_transaction(rig, "ZZFJ", modebuf, 10, 6); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } index = atoi(&modebuf[4]); if (index >= DSP_BW_NUM) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected ZZF[IJ] answer, index=%d\n", __func__, index); return -RIG_ERJCTED; } switch (*mode) { case RIG_MODE_AM: case RIG_MODE_DSB: *width = dsp_bw_am[index]; break; case RIG_MODE_CW: *width = dsp_bw_cw[index]; break; case RIG_MODE_USB: case RIG_MODE_LSB: *width = dsp_bw_ssb[index]; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: *width = dsp_bw_dig[index]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s, setting default BW\n", __func__, rig_strrmode(*mode)); *width = 3000; break; } return RIG_OK; } static int powersdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char modebuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "ZZMD", modebuf, 10, 6); if (retval != RIG_OK) { return retval; } *mode = kenwood2rmode(atoi(&modebuf[4]), caps->mode_table); if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { int lo, hi; case RIG_VFO_A: case RIG_VFO_B: retval = kenwood_safe_transaction(rig, "ZZFL", modebuf, 10, 9); if (retval != RIG_OK) { return retval; } lo = atoi(&modebuf[4]); retval = kenwood_safe_transaction(rig, "ZZFH", modebuf, 10, 9); if (retval != RIG_OK) { return retval; } hi = atoi(&modebuf[4]); rig_debug(RIG_DEBUG_VERBOSE, "%s: lo=%d, hi=%d\n", __func__, lo, hi); *width = hi - lo; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } return RIG_OK; } /* Private helper functions */ static int flex6k_find_width(rmode_t mode, pbwidth_t width, int *ridx) { int *w_a; // Width array, these are all ordered in descending order! int idx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (mode) { case RIG_MODE_AM: w_a = dsp_bw_am; break; case RIG_MODE_CW: w_a = dsp_bw_cw; break; case RIG_MODE_USB: case RIG_MODE_LSB: w_a = dsp_bw_ssb; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: w_a = dsp_bw_dig; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } // return the first smaller or equal possibility while ((idx < DSP_BW_NUM) && (w_a[idx] > width)) { idx++; } if (idx >= DSP_BW_NUM) { idx = DSP_BW_NUM - 1; } *ridx = idx; return RIG_OK; } static int powersdr_find_width(rmode_t mode, pbwidth_t width, int *ridx) { int *w_a; // Width array, these are all ordered in descending order! int idx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (mode) { case RIG_MODE_AM: w_a = dsp_bw_am_powersdr; break; case RIG_MODE_CW: case RIG_MODE_CWR: w_a = dsp_bw_cw_powersdr; break; case RIG_MODE_USB: case RIG_MODE_LSB: w_a = dsp_bw_ssb_powersdr; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: w_a = dsp_bw_dig_powersdr; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } // return the first smaller or equal possibility while ((idx < DSP_BW_NUM) && (w_a[idx] > width)) { idx++; } if (idx >= DSP_BW_NUM) { idx = DSP_BW_NUM - 1; } *ridx = idx; return RIG_OK; } static int flex6k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[10]; char kmode; int idx; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", '0' + kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } if (RIG_PASSBAND_NOCHANGE == width) { return err; } err = flex6k_find_width(mode, width, &idx); if (err != RIG_OK) { return err; } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { case RIG_VFO_A: SNPRINTF(buf, sizeof(buf), "ZZFI%02d;", idx); break; case RIG_VFO_B: SNPRINTF(buf, sizeof(buf), "ZZFJ%02d;", idx); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } static int powersdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[64]; char kmode; int idx; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called mode=%s, width=%d\n", __func__, rig_strrmode(mode), (int)width); kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "ZZMD%02d", kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } if (RIG_PASSBAND_NOCHANGE == width) { return err; } err = powersdr_find_width(mode, width, &idx); if (err != RIG_OK) { return err; } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { case RIG_VFO_B: case RIG_VFO_A: if ((mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) && width > 3000) { // 150Hz on the low end should be enough // Set high to the width requested SNPRINTF(buf, sizeof(buf), "ZZFL00150;ZZFH%05d;", (int)width); } else { SNPRINTF(buf, sizeof(buf), "ZZFI%02d;", idx); } break; // what do we do about RX2 ?? default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * flex6k_get_ptt */ int flex6k_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const char *ptt_cmd; int err; char response[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } ptt_cmd = "ZZTX"; err = kenwood_transaction(rig, ptt_cmd, response, sizeof(response)); if (err != RIG_OK) { return err; } *ptt = response[4] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } int flex6k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; char response[16] = ""; int err; int retry = 3; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON_DATA: case RIG_PTT_ON_MIC: case RIG_PTT_ON: ptt_cmd = "ZZTX1;ZZTX"; break; case RIG_PTT_OFF: ptt_cmd = "ZZTX0;ZZTX"; break; default: return -RIG_EINVAL; } do { err = kenwood_transaction(rig, ptt_cmd, response, sizeof(response)); if (ptt_cmd[4] != response[4]) { rig_debug(RIG_DEBUG_ERR, "%s: %s != %s\n", __func__, ptt_cmd, response); hl_usleep(20 * 1000); // takes a bit to do PTT off } } while (ptt_cmd[4] != response[4] && --retry); return err; } /* * powersdr_set_level */ int powersdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd[KENWOOD_MAX_BUF_LEN]; int retval; int ival; rmode_t mode; pbwidth_t width; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_AF: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAG%03d", ival); break; case RIG_LEVEL_IF: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZIT%+05d", val.i); break; case RIG_LEVEL_RF: if (val.f > 1.0) { return -RIG_EINVAL; } if (rig->caps->rig_model == RIG_MODEL_POWERSDR) { ival = val.f * (120 - -20) - 20; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAR%+04d", ival); } else { ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAR%03d", ival); } break; case RIG_LEVEL_MICGAIN: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * (10 - -40) - 40; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZMG%03d", ival); break; case RIG_LEVEL_AGC: if (val.i > 5) { val.i = 5; /* 0.. 255 */ } SNPRINTF(cmd, sizeof(cmd), "GT%03d", (int)val.i); break; case RIG_LEVEL_VOXGAIN: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 1000; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZVG%04d", ival); break; case RIG_LEVEL_SQL: if (val.f > 1.0) { return -RIG_EINVAL; } powersdr_get_mode(rig, vfo, &mode, &width); if (mode == RIG_MODE_FM) { ival = val.f * 100; // FM mode is 0 to 100 } else { ival = 160 - (val.f * 160); // all other modes 0 to 160 } SNPRINTF(cmd, sizeof(cmd) - 1, "ZZSQ%03d", ival); break; default: return kenwood_set_level(rig, vfo, level, val); } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s exiting\n", __func__); return RIG_OK; } /* * flek6k_set_level */ int flex6k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd[KENWOOD_MAX_BUF_LEN]; int retval; int ival; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZPC%03d", ival); break; default: return kenwood_set_level(rig, vfo, level, val); } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s exiting\n", __func__); return RIG_OK; } /* * flex6k_get_level */ int flex6k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RFPOWER: cmd = "ZZPC"; len = 4; ans = 3; break; default: return kenwood_get_level(rig, vfo, level, val); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans); if (retval != RIG_OK) { return retval; } int n; switch (level) { case RIG_LEVEL_RFPOWER: n = sscanf(lvlbuf, "ZZPC%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } /* * powersdr_get_level */ int powersdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rmode_t mode; pbwidth_t width; ptt_t ptt; double dval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_AGC: cmd = "GT"; len = 2; ans = 3; break; case RIG_LEVEL_AF: cmd = "ZZAG"; len = 4; ans = 3; break; case RIG_LEVEL_IF: cmd = "ZZIT"; len = 4; ans = 5; break; case RIG_LEVEL_RF: cmd = "ZZAR"; len = 4; ans = 4; break; case RIG_LEVEL_STRENGTH: flex6k_get_ptt(rig, vfo, &ptt); if (ptt) // not applicable if transmitting { val->f = 0; return RIG_OK; } cmd = "ZZRM0"; len = 5; ans = 9; break; case RIG_LEVEL_RFPOWER: cmd = "ZZPC"; len = 4; ans = 8; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: flex6k_get_ptt(rig, vfo, &ptt); if (!ptt) { val->f = 0; return RIG_OK; } cmd = "ZZRM5"; len = 5; ans = 3; break; case RIG_LEVEL_MICGAIN: cmd = "ZZMG"; len = 4; ans = 3; break; case RIG_LEVEL_VOXGAIN: cmd = "ZZVG"; len = 4; ans = 4; break; case RIG_LEVEL_SQL: cmd = "ZZSQ"; len = 4; ans = 3; break; case RIG_LEVEL_SWR: { struct kenwood_priv_caps *priv = kenwood_caps(rig); ptt = 0; rig_get_ptt(rig, RIG_VFO_CURR, &ptt); if (ptt == RIG_PTT_OFF) { val->f = priv->swr; return RIG_OK;} cmd = "ZZRM8"; // get SWR retval = kenwood_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { val->f = priv->swr; return RIG_OK;}; sscanf(lvlbuf, "ZZRM8%lg", &priv->swr); val->f = priv->swr; rig_debug(RIG_DEBUG_ERR, "%s(%d) swr=%.1f\n", __func__, __LINE__, val->f); return RIG_OK; } default: return kenwood_get_level(rig, vfo, level, val); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans); if (retval != RIG_OK) { return retval; } int n; switch (level) { case RIG_LEVEL_AGC: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } break; case RIG_LEVEL_IF: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } break; case RIG_LEVEL_STRENGTH: n = sscanf(lvlbuf, "ZZRM0%lf", &dval); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->i = 0; return -RIG_EPROTO; } val->i = dval + 73; // dbm to S9-based=0dB break; case RIG_LEVEL_AF: n = sscanf(lvlbuf, "ZZAG%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100.0; break; case RIG_LEVEL_RFPOWER: n = sscanf(lvlbuf, "ZZPC%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { // if not ptt then no power is going out so return 0W ptt = 0; rig_get_ptt(rig, RIG_VFO_TX, &ptt); if (!ptt) { val->f = 0; return RIG_OK; } n = sscanf(lvlbuf, "ZZRM5%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } } if (level != RIG_LEVEL_RFPOWER_METER_WATTS) { val->f /= 100; } break; case RIG_LEVEL_RF: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } n = val->i; val->f = (n + 20.0) / (120.0 - -20.0); break; case RIG_LEVEL_MICGAIN: n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } // Thetis returns -40 to 10 -- does PowerSDR do the same? // Setting val->f = (val->f - -40) / (10 - -40); break; case RIG_LEVEL_VOXGAIN: // return is 0-1000 n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f /= 1000; break; case RIG_LEVEL_SQL: n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } powersdr_get_mode(rig, vfo, &mode, &width); if (mode == RIG_MODE_FM) { val->f /= 100; // FM mode is 0 to 100 } else { val->f = fabs((val->f - 160) / -160); // all other modes 0 to 160 } break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } int powersdr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmd[KENWOOD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MUTE: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZMA%01d", status); break; case RIG_FUNC_VOX: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZVE%01d", status); break; case RIG_FUNC_SQL: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZSO%01d", status); break; case RIG_FUNC_TUNER: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZTU%01d", status); break; default: return kenwood_set_func(rig, vfo, func, status); } return kenwood_transaction(rig, cmd, NULL, 0); } int powersdr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_MUTE: cmd = "ZZMA"; len = 4; ans = 1; break; case RIG_FUNC_VOX: cmd = "ZZVE"; len = 4; ans = 1; break; case RIG_FUNC_SQL: cmd = "ZZSO"; len = 4; ans = 1; break; default: return kenwood_get_func(rig, vfo, func, status); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + ans); if (retval != RIG_OK) { return retval; } switch (func) { case RIG_FUNC_MUTE: case RIG_FUNC_VOX: case RIG_FUNC_SQL: sscanf(lvlbuf + len, "%d", status); break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } int powersdr_set_parm(RIG *rig, setting_t parm, value_t val) { ENTERFUNC; char cmd[KENWOOD_MAX_BUF_LEN]; int retval = -RIG_EINTERNAL; int band = 999; // default to the weird WWV band rig_debug(RIG_DEBUG_VERBOSE, "%s: val=%s\n", __func__, val.s); switch (parm) { case RIG_PARM_BANDSELECT: if (strcmp(val.s, "BANDWWV") != 0) { int n = sscanf(val.s, "BAND%d", &band); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%s\n", __func__, val.s); } } SNPRINTF(cmd, sizeof(cmd), "ZZBS%03d;", band); retval = kenwood_transaction(rig, cmd, NULL, 0); } RETURNFUNC(retval); } int powersdr_get_parm(RIG *rig, setting_t parm, value_t *val) { char cmd[KENWOOD_MAX_BUF_LEN]; char buf[KENWOOD_MAX_BUF_LEN]; int retval; int len, ans; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: len = 4; ans = 3; SNPRINTF(cmd, sizeof(cmd), "%s", "ZZBS;"); break; default: RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, cmd, buf, 10, len + ans); if (retval != RIG_OK) { RETURNFUNC(retval); } int band; int n = sscanf(buf, "ZZBS%3d", &band); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%s\n", __func__, buf); RETURNFUNC(-RIG_EPROTO); } switch (band) { case 160: val->cs = "BAND160M"; break; case 80: val->cs = "BAND80M"; break; case 60: val->cs = "BAND60M"; break; case 40: val->cs = "BAND40M"; break; case 30: val->cs = "BAND30M"; break; case 20: val->cs = "BAND20M"; break; case 17: val->cs = "BAND17M"; break; case 15: val->cs = "BAND15M"; break; case 12: val->cs = "BAND12M"; break; case 10: val->cs = "BAND10M"; break; case 6: val->cs = "BAND6M"; break; case 999: val->cs = "BANDWWV"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%d\n", __func__, band); val->cs = "BAND???"; } RETURNFUNC(RIG_OK); } #define NO_LVL_KEYSPD #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH /* * F6K rig capabilities. */ struct rig_caps f6k_caps = { RIG_MODEL(RIG_MODEL_F6K), .model_name = "6xxx", .mfg_name = "FlexRadio", .version = "20240829.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NETWORK, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change .timeout = 700, .retry = 13, .has_get_func = RIG_FUNC_NONE, /* has VOX but not implemented here */ .has_set_func = RIG_FUNC_NONE, .has_get_level = F6K_LEVEL_ALL, .has_set_level = F6K_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, [LVL_SLOPE_LOW] = { .min = { .i = 10}, .max = { .i = 1000}, .step = { .i = 50} }, [LVL_SLOPE_HIGH] = { .min = { .i = 1000}, .max = { .i = 5000}, .step = { .i = 10} }, }, /* FIXME: granularity */ .parm_gran = {}, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .post_write_delay = 20, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(99999), .max_xit = Hz(99999), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_NONE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), F6K_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {F6K_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& f6k_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = flex6k_set_mode, .get_mode = flex6k_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = flex6k_set_level, .get_level = flex6k_get_level, //.set_ant = kenwood_set_ant_no_ack, //.get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * PowerSDR rig capabilities. */ struct rig_caps powersdr_caps = { RIG_MODEL(RIG_MODEL_POWERSDR), .model_name = "PowerSDR", .mfg_name = "FlexRadio/Apache", .version = "20231107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change // Flex 1500 needs about 6 seconds for a band change in PowerSDR .timeout = 800, // some band transitions can take 600ms .retry = 10, .has_get_func = POWERSDR_FUNC_ALL, .has_set_func = POWERSDR_FUNC_ALL, .has_get_level = POWERSDR_LEVEL_ALL, .has_set_level = POWERSDR_LEVEL_SET, .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_KEYSPD #include "level_gran_kenwood.h" #undef NO_LVL_KEYSPD [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, }, /* FIXME: granularity */ .parm_gran = { // there are V00 thru V13 but we don't cover them as of yet -- what rig? [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND2M,BANDWWV,BANDGEN"}} }, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_op = kenwood_vfo_op, .vfo_ops = POWERSDR_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_LONG, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_USER }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), POWERSDR_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {POWERSDR_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& powersdr_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = powersdr_set_mode, .get_mode = powersdr_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = flex6k_get_ptt, .set_ptt = flex6k_set_ptt, .get_powerstat = kenwood_get_powerstat, .set_powerstat = kenwood_set_powerstat, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = powersdr_set_level, .get_level = powersdr_get_level, .get_func = powersdr_get_func, .set_func = powersdr_set_func, .get_parm = powersdr_get_parm, .set_parm = powersdr_set_parm, //.set_ant = kenwood_set_ant_no_ack, //.get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Thetis rig capabilities. Same as PowerSDR for now but may get new functions */ struct rig_caps thetis_caps = { RIG_MODEL(RIG_MODEL_THETIS), .model_name = "", .mfg_name = "Thetis", .version = "20231222.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change // Flex 1500 needs about 6 seconds for a band change in PowerSDR .timeout = 800, // some band transitions can take 600ms .retry = 10, .has_get_func = POWERSDR_FUNC_ALL, .has_set_func = POWERSDR_FUNC_ALL, .has_get_level = POWERSDR_LEVEL_ALL, .has_set_level = POWERSDR_LEVEL_SET, .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_KEYSPD #include "level_gran_kenwood.h" #undef NO_LVL_KEYSPD [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, }, /* FIXME: granularity */ .parm_gran = { // there are V00 thru V13 but we don't cover them as of yet -- what rig? [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND2M,BANDWWV,BANDGEN"}} }, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_op = kenwood_vfo_op, .vfo_ops = POWERSDR_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_LONG, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_USER }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), POWERSDR_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {POWERSDR_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& powersdr_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = powersdr_set_mode, .get_mode = powersdr_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = flex6k_get_ptt, .set_ptt = flex6k_set_ptt, .get_powerstat = kenwood_get_powerstat, .set_powerstat = kenwood_set_powerstat, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = powersdr_set_level, .get_level = powersdr_get_level, .get_func = powersdr_get_func, .set_func = powersdr_set_func, .get_parm = powersdr_get_parm, .set_parm = powersdr_set_parm, //.set_ant = kenwood_set_ant_no_ack, //.get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/kenwood/ts930.c0000664000175000017500000001332515056640443012120 /* * Hamlib Kenwood backend - TS930 description * Copyright (c) 2000-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS930_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TS930_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TS930_AM_TX_MODES RIG_MODE_AM /* FIXME: TBC */ #define TS930_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_LOCK) #define TS930_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_AGC) #define TS930_VFO (RIG_VFO_A|RIG_VFO_B) #define TS930_ANTS (0) static struct kenwood_priv_caps ts930_priv_caps = { .cmdtrm = EOM_KEN, }; /* * ts930 rig capabilities. * Notice that some rigs share the same functions. * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts930_caps = { RIG_MODEL(RIG_MODEL_TS930), .model_name = "TS-930", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS930_FUNC_ALL, .has_set_func = TS930_FUNC_ALL, .has_get_level = TS930_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS930_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_kenwood.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, /* TBC */ .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // AGC levels unknown .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), TS930_ALL_MODES, -1, -1, TS930_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS930_OTHER_TX_MODES, W(5), W(250), TS930_VFO, TS930_ANTS), FRQ_RNG_HF(1, TS930_AM_TX_MODES, W(4), W(80), TS930_VFO, TS930_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30), TS930_ALL_MODES, -1, -1, TS930_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(1, TS930_OTHER_TX_MODES, W(5), W(250), TS930_VFO, TS930_ANTS), FRQ_RNG_HF(1, TS930_AM_TX_MODES, W(4), W(80), TS930_VFO, TS930_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS930_ALL_MODES, 50}, {TS930_ALL_MODES, 100}, {TS930_ALL_MODES, kHz(1)}, {TS930_ALL_MODES, kHz(5)}, {TS930_ALL_MODES, kHz(9)}, {TS930_ALL_MODES, kHz(10)}, {TS930_ALL_MODES, 12500}, {TS930_ALL_MODES, kHz(20)}, {TS930_ALL_MODES, kHz(25)}, {TS930_ALL_MODES, kHz(100)}, {TS930_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.7)}, RIG_FLT_END, }, .priv = (void *)& ts930_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, // we don't know the ID for this rig .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.5/rigs/kenwood/flex.h0000664000175000017500000000246115056640443012200 /* * Hamlib Elecraft backend--support extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLEXRADIO_H #define _FLEXRADIO_H 1 #include #define EXT_LEVEL_NONE -1 #define FLEXRADIO_MAX_BUF_LEN 50 struct flexradio_priv_data { char info[FLEXRADIO_MAX_BUF_LEN]; split_t split; /* current split state */ }; /* Flexradio extension function declarations */ int flexradio_open(RIG *rig); #endif /* _FLEXRADIO_H */ hamlib-4.6.5/rigs/kenwood/kenwood.h0000664000175000017500000003443715056640443012720 /* * Hamlib Kenwood backend - main header * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KENWOOD_H #define _KENWOOD_H 1 #include #include "token.h" #include "idx_builtin.h" #define BACKEND_VER "20250515" #define EOM_KEN ';' #define EOM_TH '\r' #define KENWOOD_MODE_TABLE_MAX 24 #define KENWOOD_MAX_BUF_LEN 128 /* max answer len, arbitrary */ /* Tokens for Parameters common to multiple rigs. * Use token # >= 1 or <= 100. Defined here so they will be * available in Kenwood name space. */ #define TOK_VOICE TOKEN_BACKEND(1) #define TOK_FINE TOKEN_BACKEND(2) #define TOK_XIT TOKEN_BACKEND(3) #define TOK_RIT TOKEN_BACKEND(4) #define TOK_NO_ID TOKEN_BACKEND(5) #define TOK_FUNC_FILTER_WIDTH_DATA TOKEN_BACKEND(6) // Data communications mode that affects SL/SH/FW commands /* Token structure assigned to .cfgparams in rig_caps */ extern struct confparams kenwood_cfg_params[]; /* * modes in use by the "MD" command */ #define MD_NONE '0' #define MD_LSB '1' #define MD_USB '2' #define MD_CW '3' #define MD_FM '4' #define MD_AM '5' #define MD_FSK '6' #define MD_CWR '7' // MD_DIG used by SDRPlay #define MD_DIG '8' #define MD_FSKR '9' /* S-meter calibration tables */ /* This one for the TS590 no doubt applies elsewhere */ #define TS590_SM_CAL { 10, \ { \ { 0, -54 }, \ { 3, -48 }, \ { 6, -36 }, \ { 9, -24 }, \ { 12, -12 }, \ { 15, 0 }, \ { 20, 20 }, \ { 25, 40 }, \ { 30, 60 }, \ } } #define RIG_IS_HPSDR (rig->caps->rig_model == RIG_MODEL_HPSDR) #define RIG_IS_K2 (rig->caps->rig_model == RIG_MODEL_K2) #define RIG_IS_K3 (rig->caps->rig_model == RIG_MODEL_K3) #define RIG_IS_K3S (rig->caps->rig_model == RIG_MODEL_K3S) #define RIG_IS_KX2 (rig->caps->rig_model == RIG_MODEL_KX2) #define RIG_IS_KX3 (rig->caps->rig_model == RIG_MODEL_KX3) #define RIG_IS_K4 (rig->caps->rig_model == RIG_MODEL_K4) #define RIG_IS_THD7A (rig->caps->rig_model == RIG_MODEL_THD7A) #define RIG_IS_THD74 (rig->caps->rig_model == RIG_MODEL_THD74) #define RIG_IS_TMD700 (rig->caps->rig_model == RIG_MODEL_TMD700) #define RIG_IS_TS2000 (rig->caps->rig_model == RIG_MODEL_TS2000) #define RIG_IS_TS50 (rig->caps->rig_model == RIG_MODEL_TS50) #define RIG_IS_TS450S (rig->caps->rig_model == RIG_MODEL_TS450S) #define RIG_IS_TS480 (rig->caps->rig_model == RIG_MODEL_TS480) #define RIG_IS_TS590S (rig->caps->rig_model == RIG_MODEL_TS590S) #define RIG_IS_TS590SG (rig->caps->rig_model == RIG_MODEL_TS590SG) #define RIG_IS_TS690S (rig->caps->rig_model == RIG_MODEL_TS690S) #define RIG_IS_TS790 (rig->caps->rig_model == RIG_MODEL_TS790) #define RIG_IS_TS850 (rig->caps->rig_model == RIG_MODEL_TS850) #define RIG_IS_TS890S (rig->caps->rig_model == RIG_MODEL_TS890S) #define RIG_IS_TS940 (rig->caps->rig_model == RIG_MODEL_TS940) #define RIG_IS_TS950SDX (rig->caps->rig_model == RIG_MODEL_TS950SDX) #define RIG_IS_TS950S (rig->caps->rig_model == RIG_MODEL_TS950S) #define RIG_IS_TS990S (rig->caps->rig_model == RIG_MODEL_TS990S) #define RIG_IS_XG3 (rig->caps->rig_model == RIG_MODEL_XG3) #define RIG_IS_PT8000A (rig->caps->rig_model == RIG_MODEL_PT8000A) #define RIG_IS_POWERSDR (rig->caps->rig_model == RIG_MODEL_POWERSDR) #define RIG_IS_THETIS (rig->caps->rig_model == RIG_MODEL_THETIS) #define RIG_IS_MALACHITE (rig->caps->rig_model == RIG_MODEL_MALACHITE) #define RIG_IS_QRPLABS (rig->caps->rig_model == RIG_MODEL_QRPLABS) struct kenwood_filter_width { rmode_t modes; int value; pbwidth_t width_hz; }; struct kenwood_slope_filter { rmode_t modes; int data_mode_filter; int value; pbwidth_t frequency_hz; }; struct kenwood_priv_caps { char cmdtrm; /* Command termination chars (ken=';' or th='\r') */ int if_len; /* length of IF; answer excluding ';' terminator */ rmode_t *mode_table; struct kenwood_filter_width *filter_width; /* Last entry should have value == -1 and width_hz == -1 */ struct kenwood_slope_filter *slope_filter_high; /* Last entry should have value == -1 and frequency_hz == -1 */ struct kenwood_slope_filter *slope_filter_low; /* Last entry should have value == -1 and frequency_hz == -1 */ double swr; int tone_table_base; /* Offset of first value in rigs tone tables, default=0 */ }; struct kenwood_priv_data { char info[KENWOOD_MAX_BUF_LEN]; split_t split; /* current split state */ vfo_t tx_vfo; /* split tx vfo */ int k2_ext_lvl; /* Initial K2 extension level */ int k3_ext_lvl; /* Initial K3 extension level */ int k2_md_rtty; /* K2 RTTY mode available flag, 1 = RTTY, 0 = N/A */ int has_kpa3; /* Elecraft K3 has k3pa for PC command */ int has_kpa100; /* Elecraft KX3/KX2 has kpa100 for PC command */ char *fw_rev; /* firmware revision level */ int trn_state; /* AI state discovered at startup */ unsigned fw_rev_uint; /* firmware revision as a number 1.07 -> 107 */ char verify_cmd[4]; /* command used to verify set commands */ int is_emulation; /* flag for TS-2000 emulations */ void *data; /* model specific data */ rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ struct timespec cache_start; char last_if_response[KENWOOD_MAX_BUF_LEN]; int poweron; /* to avoid powering on more than once */ int has_ps; /* rig has PS cmd */ int ag_format; /* which AG command is being used...see LEVEL_AF in kenwood.c*/ int has_rit2; /* rig has set 2 rit command -- can set rit 0-99999 directly */ int micgain_min, micgain_max; /* varies by rig so we figure it out automagically */ int is_k2; int is_k3; int is_k3s; int is_kx3; int is_kx2; int is_k4; int is_k4d; int is_k4hd; int no_id; // if true will not send ID; with every set command int opened; // true once rig_open is called to avoid setting VFOA every open call rmode_t modeA; rmode_t modeB; int datamodeA; // datamode status from get_mode or set_mode int datamodeB; // datamode status from get_mode or set_mode int question_mark_response_means_rejected; /* the question mark response has multiple meanings */ int save_k2_ext_lvl; // so we can restore to original int save_k3_ext_lvl; // so we can restore to original -- for future use if needed int voice_bank; /* last voice bank send for use by stop_voice_mem */ rmode_t last_mode_pc; // last mode memory for PC command int power_now,power_min,power_max; }; #define kenwood_caps(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv) extern rmode_t kenwood_mode_table[KENWOOD_MODE_TABLE_MAX]; extern tone_t kenwood38_ctcss_list[]; extern tone_t kenwood42_ctcss_list[]; extern tone_t kenwood51_ctcss_list[]; int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize); int kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected); rmode_t kenwood2rmode(unsigned char mode, const rmode_t mode_table[]); char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]); int kenwood_init(RIG *rig); int kenwood_cleanup(RIG *rig); int kenwood_open(RIG *rig); int kenwood_close(RIG *rig); int kenwood_set_vfo(RIG *rig, vfo_t vfo); int kenwood_set_vfo_main_sub(RIG *rig, vfo_t vfo); int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo); int kenwood_get_vfo_main_sub(RIG *rig, vfo_t *vfo); int kenwood_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); int kenwood_get_vfo_frft(RIG *rig, vfo_t *vfo); int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq); int kenwood_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); int kenwood_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t rit); // Also use this for xit int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); int kenwood_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *rit); // Also use this for xit int kenwood_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); int kenwood_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int kenwood_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int kenwood_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int kenwood_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int kenwood_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int kenwood_set_powerstat(RIG *rig, powerstat_t status); int kenwood_get_powerstat(RIG *rig, powerstat_t *status); int kenwood_reset(RIG *rig, reset_t reset); int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg); int kenwood_stop_morse(RIG *rig, vfo_t vfo); int kenwood_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int kenwood_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt); int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int kenwood_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch); int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch); int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch); int kenwood_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int kenwood_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int kenwood_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char *kenwood_get_info(RIG *rig); int kenwood_get_id(RIG *rig, char *buf); int kenwood_get_if(RIG *rig); int kenwood_send_voice_mem(RIG *rig, vfo_t vfo, int bank); int kenwood_stop_voice_mem(RIG *rig, vfo_t vfo); int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int kenwood_set_trn(RIG *rig, int trn); int kenwood_get_trn(RIG *rig, int *trn); /* only use if returned string has length 6, e.g. 'SQ011;' */ int get_kenwood_level(RIG *rig, const char *cmd, float *fval, int *ival); int get_kenwood_func(RIG *rig, const char *cmd, int *status); int get_kenwood_meter_reading(RIG *rig, char meter, int *pips); extern struct rig_caps ts950s_caps; extern struct rig_caps ts950sdx_caps; extern struct rig_caps ts50s_caps; extern struct rig_caps ts140_caps; extern struct rig_caps ts450s_caps; extern struct rig_caps ts570d_caps; extern struct rig_caps ts570s_caps; extern struct rig_caps ts680s_caps; extern struct rig_caps ts690s_caps; extern struct rig_caps ts790_caps; extern struct rig_caps ts850_caps; extern struct rig_caps ts870s_caps; extern struct rig_caps ts930_caps; extern struct rig_caps ts2000_caps; extern struct rig_caps k2_caps; extern struct rig_caps k3_caps; extern struct rig_caps k3s_caps; extern struct rig_caps kx2_caps; extern struct rig_caps kx3_caps; extern struct rig_caps k4_caps; extern struct rig_caps xg3_caps; extern struct rig_caps trc80_caps; extern struct rig_caps sdrconsole_caps; extern struct rig_caps thd7a_caps; extern struct rig_caps thd72a_caps; extern struct rig_caps thd74_caps; extern struct rig_caps tmd700_caps; extern struct rig_caps thf7a_caps; extern struct rig_caps thf7e_caps; extern struct rig_caps thg71_caps; extern struct rig_caps tmv7_caps; extern struct rig_caps tmv71_caps; extern struct rig_caps tmd710_caps; extern struct rig_caps ts440_caps; extern struct rig_caps ts940_caps; extern struct rig_caps ts711_caps; extern struct rig_caps ts811_caps; extern struct rig_caps r5000_caps; extern struct rig_caps ts480_caps; extern struct rig_caps ts590_caps; extern struct rig_caps ts590sg_caps; extern struct rig_caps thf6a_caps; extern struct rig_caps transfox_caps; extern struct rig_caps f6k_caps; extern struct rig_caps powersdr_caps; extern struct rig_caps pihpsdr_caps; extern struct rig_caps ts890s_caps; extern struct rig_caps pt8000a_caps; extern struct rig_caps malachite_caps; extern struct rig_caps tx500_caps; extern struct rig_caps sdruno_caps; extern struct rig_caps qrplabs_caps; extern struct rig_caps qrplabs_qmx_caps; extern struct rig_caps fx4_caps; extern struct rig_caps thetis_caps; extern struct rig_caps trudx_caps; /* use when not interested in the answer, but want to check its len */ static int inline kenwood_simple_transaction(RIG *rig, const char *cmd, size_t expected) { struct kenwood_priv_data *priv = STATE(rig)->priv; return kenwood_safe_transaction(rig, cmd, priv->info, KENWOOD_MAX_BUF_LEN, expected); } #endif /* _KENWOOD_H */ hamlib-4.6.5/rigs/kenwood/elecraft.h0000664000175000017500000000775015056640443013035 /* * Hamlib Elecraft backend--support extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ELECRAFT_H #define _ELECRAFT_H 1 #include #include "token.h" /* The Elecraft Programmer's Reference details the extension level that * a K2 or K3 may have in effect which modify certain commands. */ enum elec_ext_id_e { K20 = 0, /* K2 Normal mode */ K21, /* K2 Normal/rtty_off */ K22, /* K2 Extended mode */ K23, /* K2 Extended mode/rtty_off */ K30, /* K3 Normal mode */ K31, /* K3 Extended mode */ XG3, /* XG3 */ EXT_LEVEL_NONE }; struct elec_ext_id_str { enum elec_ext_id_e level; const char *id; }; /* 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; */ K3_MODE_FSK_D, /* DT2; */ K3_MODE_PSK_D /* DT3; */ }; /* Private tokens used for ext_lvl function in Elecraft backends. * Extra levels which are rig specific should be coded in * the individual rig files and token #s >= 101. * * See Private Elecraft extra levels definitions in elecraft.c */ #define TOK_IF_FREQ TOKEN_BACKEND(101) /* K3 FI command - IF center frequency (K3/K3S only) */ #define TOK_TX_STAT TOKEN_BACKEND(102) /* K3 TQ command - transmit query (K3/K3S/KX3/KX2) */ #define TOK_RIT_CLR TOKEN_BACKEND(103) /* K3 RC command - RIT/XIT clear (K3/K3S/KX3/KX2) */ #define TOK_ESSB TOKEN_BACKEND(104) /* K3 ES command - ESSB mode (K3/K3S/KX3/KX2) */ #define TOK_RX_ANT TOKEN_BACKEND(105) /* K3 AR command - RX antenna on/off (K3/K3S only) */ #define TOK_LINK_VFOS TOKEN_BACKEND(106) /* K3 LN command - link VFOs on/off (K3/K3S only) */ #define TOK_TX_METER TOKEN_BACKEND(107) /* K3 TM command - Transmit meter mode, SWR/ALC (K3/K3S only) */ #define TOK_IF_NB TOKEN_BACKEND(108) /* K3 NL command - IF noise blanker level (K3/K3S only) */ /* Token structure assigned to .cfgparams in rig_caps */ extern const struct confparams elecraft_ext_levels[]; /* Elecraft extension function declarations */ int elecraft_open(RIG *rig); int elecraft_close(RIG *rig); /* S-meter calibration tables */ /* K3 defines 16 values--0-15. * Table is RASTR value from SM command and dB relative to S9 == 0 * (see rig_get_level() in src/settings.c */ #define K3_SM_CAL { 16, \ { \ { 0, -54 }, \ { 1, -42 }, \ { 2, -36 }, \ { 3, -24 }, \ { 4, -12 }, \ { 5, -6 }, \ { 6, 0 }, \ { 7, 10 }, \ { 8, 15 }, \ { 9, 20 }, \ { 10, 30 }, \ { 11, 35 }, \ { 12, 40 }, \ { 13, 50 }, \ { 14, 55 }, \ { 15, 60 }, \ } } /* K3 defines 100 values--0-100 in high resolution mode. * Table is RASTR value from SMH command and dB relative to S9 == 0 * (see rig_get_level() in src/settings.c */ #define K3_SMH_CAL { 22, \ { \ { 0, -54 }, \ { 5, -48 }, \ { 9, -42 }, \ { 14, -36 }, \ { 22, -30 }, \ { 24, -24 }, \ { 28, -18 }, \ { 33, -12 }, \ { 38, -6 }, \ { 42, 0 }, \ { 47, 5 }, \ { 53, 10 }, \ { 58, 15 }, \ { 63, 20 }, \ { 68, 25 }, \ { 73, 30 }, \ { 78, 35 }, \ { 83, 40 }, \ { 88, 45 }, \ { 93, 50 }, \ { 98, 55 }, \ { 103, 60 }, \ } } // K4 is the only we know that has this as of 2021-11-09 int elecraft_get_vfo_tq(RIG *rig, vfo_t *vfo); #endif /* _ELECRAFT_H */ hamlib-4.6.5/rigs/kenwood/thf6a.c0000664000175000017500000002414215056640443012245 /* * Hamlib Kenwood backend - TH-F6A Cloned from TH-F7E description * Copyright (c) 2001-2009 by Stephane Fillod * Copyright (c) 2010 by Scott Martin * * 10-03-2010 * Ported from Stephane Fillod's thf7.c * Changed TH-F7E parameters to reflect TH-F6A * Changed RIG_ITU_REGION from 1 to 2 * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tones.h" #include "kenwood.h" #include "th.h" #define THF6_MODES_TX (RIG_MODE_FM) #define THF6_HIGH_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_WFM) #define THF6_ALL_MODES (THF6_HIGH_MODES|RIG_MODE_SSB|RIG_MODE_CW) #define THF6_FUNC_ALL (RIG_FUNC_ARO|RIG_FUNC_LOCK|RIG_FUNC_BC) /* * How incredible, there's no RIG_LEVEL_STRENGTH! */ #define THF6_LEVEL_ALL (RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_ATT|\ RIG_LEVEL_BALANCE|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY) #define THF6_PARMS (RIG_PARM_APO|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define THF6_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define THF6_ANTS (RIG_ANT_1|RIG_ANT_2) /* * TODO: * scan_group can only be get. scan_group=channel_num%50; */ #define THF6_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define THF6_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* CTCSS 01..42 */ static tone_t thf6_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; static rmode_t thf6_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_WFM, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW }; /* * Band A & B */ #define THF6_VFO (RIG_VFO_A|RIG_VFO_B) static struct kenwood_priv_caps thf6_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thf6_mode_table, }; static int thf6a_init(RIG *rig); static int thf6a_open(RIG *rig); static int thf6a_get_vfo(RIG *rig, vfo_t *vfo); static int thf6a_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TH-F6A rig capabilities. * * Manual, thanks to K6MAY: http://www.k6may.com/KenwoodTHF6Tip1.shtml * * TODO: * - set/get_ctcss_tone/sql through set/get_channel() and VR/VW * - emulate RIG_FUNC_TONE|RIG_FUNC_TSQL by setting ctcss_tone/sql to 0/non zero? */ struct rig_caps thf6a_caps = { RIG_MODEL(RIG_MODEL_THF6A), .model_name = "TH-F6A", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .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 = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THF6_FUNC_ALL, .has_set_func = THF6_FUNC_ALL | RIG_FUNC_TBURST, .has_get_level = THF6_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THF6_LEVEL_ALL), .has_get_parm = THF6_PARMS, .has_set_parm = THF6_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = thf6_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THF6_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, /* TBC */ .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 0, 399, RIG_MTYPE_MEM, {THF6_CHANNEL_CAPS}}, /* normal MEM */ { 400, 409, RIG_MTYPE_EDGE, {THF6_CHANNEL_CAPS}}, /* L0-L9 lower scan limit */ { 410, 419, RIG_MTYPE_EDGE, {THF6_CHANNEL_CAPS}}, /* U0-U9 upper scan limit */ { 420, 429, RIG_MTYPE_MEM, {THF6_CHANNEL_CAPS}}, /* I0-I9 info */ { 430, 431, RIG_MTYPE_PRIO, {THF6_CHANNEL_CAPS}}, /* PR0,PR1 priority */ { 432, 434, RIG_MTYPE_CALL, {THF6_CHANNEL_CAPS_WO_LO}}, /* Call (for each ham band) */ { 435, 449, RIG_MTYPE_BAND, {THF6_CHANNEL_CAPS_WO_LO}}, /* VFO */ /* 3 A-band VFO */ /* 11 B-band VFO */ /* TODO: 10 DTMF */ RIG_CHAN_END, }, .rx_range_list1 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(146), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF6_ALL_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF6_HIGH_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list1 = { /* power actually depends on DC power supply */ {MHz(144), MHz(146), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, /* region 2 is model TH-F6A in fact */ .rx_range_list2 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(148), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF6_ALL_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF6_HIGH_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list2 = { /* power actually depends on DC power supply */ {MHz(144), MHz(148), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, .tuning_steps = { /* This table is ordered according to protocol, from '0' to 'b' */ /* The steps are not available on every band/frequency limit 470MHz */ {THF6_ALL_MODES, kHz(5)}, {THF6_ALL_MODES, kHz(6.25)}, {THF6_ALL_MODES, kHz(8.33)}, {THF6_ALL_MODES, kHz(9)}, {THF6_ALL_MODES, kHz(10)}, {THF6_ALL_MODES, kHz(12.5)}, {THF6_ALL_MODES, kHz(15)}, {THF6_ALL_MODES, kHz(20)}, {THF6_ALL_MODES, kHz(25)}, {THF6_ALL_MODES, kHz(30)}, {THF6_ALL_MODES, kHz(50)}, {THF6_ALL_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* real width to be checked (missing specs) */ {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, /* narrow FM */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(150)}, /* or 230? */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, RIG_FLT_END, }, .priv = (void *)& thf6_priv_caps, .rig_init = thf6a_init, .rig_cleanup = kenwood_cleanup, .rig_open = thf6a_open, .rig_close = kenwood_close, .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, .get_vfo = thf6a_get_vfo, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .vfo_op = thf6a_vfo_op, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .get_parm = th_get_parm, .set_parm = th_set_parm, .get_info = th_get_info, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_ant = th_set_ant, .get_ant = th_get_ant, .reset = th_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int thf6a_init(RIG *rig) { return kenwood_init(rig); } int thf6a_open(RIG *rig) { return kenwood_open(rig); } /* * th_get_vfo * Assumes rig!=NULL */ int thf6a_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '3' : /* Fine Step Enable */ break; case '1' : /* MR */ case '2' : /* CALL */ case '4' : /* INFO */ *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * thf6a_vfo_op */ int thf6a_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); /* Not implemented! case RIG_OP_BAND_UP: return kenwood_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return kenwood_transaction(rig, "BD", NULL, 0); */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } hamlib-4.6.5/rigs/kenwood/thd7.c0000664000175000017500000001356115056640443012106 /* * Hamlib Kenwood backend - TH-D7 description * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #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) #define THD7_MODES_TX (RIG_MODE_FM) #define THD7_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_MON| \ RIG_FUNC_SQL| \ RIG_FUNC_TONE| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO) #define THD7_LEVEL_ALL (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_AF| \ RIG_LEVEL_RF|\ RIG_LEVEL_MICGAIN) #define THD7_PARMS (RIG_PARM_BACKLIGHT) #define THD7_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) /* * TODO: Band A & B */ #define THD7_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t td7_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps thd7_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = td7_mode_table, }; /* * th-d7a rig capabilities. * * http://www.qsl.net/ta1dx/kenwood/thd7kom.htm */ struct rig_caps thd7a_caps = { RIG_MODEL(RIG_MODEL_THD7A), .model_name = "TH-D7A", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .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 = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THD7_FUNC_ALL, .has_set_func = THD7_FUNC_ALL, .has_get_level = THD7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD7_LEVEL_ALL), .has_get_parm = THD7_PARMS, .has_set_parm = THD7_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, }, .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 = THD7_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, .chan_list = { { 1, 199, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* normal MEM */ { 200, 219, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* U/L MEM */ { 221, 222, RIG_MTYPE_CALL, {TH_CHANNEL_CAPS}}, /* Call 0/1 */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148), THD7_MODES, -1, -1, THD7_VFO}, {MHz(430), MHz(440), THD7_MODES, -1, -1, THD7_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), THD7_MODES_TX, W(5.5), W(5.5), THD7_VFO}, {MHz(430), MHz(440), THD7_MODES_TX, W(5.5), W(5.5), THD7_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {THD7_MODES, kHz(5)}, {THD7_MODES, kHz(6.25)}, {THD7_MODES, kHz(10)}, {THD7_MODES, kHz(12.5)}, {THD7_MODES, kHz(15)}, {THD7_MODES, kHz(20)}, {THD7_MODES, kHz(25)}, {THD7_MODES, kHz(30)}, {THD7_MODES, kHz(50)}, {THD7_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(14)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd7_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .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, .get_vfo = th_get_vfo, .set_ctcss_tone = th_set_ctcss_tone, .get_ctcss_tone = th_get_ctcss_tone, .set_ctcss_sql = th_set_ctcss_sql, .get_ctcss_sql = th_get_ctcss_sql, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .get_func = th_get_func, .get_level = th_get_level, .get_parm = th_get_parm, .get_info = th_get_info, .get_dcd = th_get_dcd, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* end of file */ hamlib-4.6.5/rigs/kenwood/ic10.h0000664000175000017500000000554215056640443012001 /* * Hamlib Kenwood backend - IC-10 header * Copyright (c) 2000-2004 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _IC10_H #define _IC10_H 1 #define IC10_VER "20231002" int ic10_cmd_trim (char *data, int data_len); int ic10_transaction (RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int ic10_set_vfo(RIG *rig, vfo_t vfo); int ic10_get_vfo(RIG *rig, vfo_t *vfo); int ic10_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int ic10_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int ic10_set_split_vfo(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int ic10_get_split_vfo(RIG *rig, vfo_t vfo , split_t *split, vfo_t *txvfo); int ic10_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ic10_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ic10_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int ic10_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int ic10_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ic10_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ic10_set_parm(RIG *rig, setting_t parm, value_t val); int ic10_get_parm(RIG *rig, setting_t parm, value_t *val); int ic10_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ic10_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ic10_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int ic10_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int ic10_set_mem(RIG *rig, vfo_t vfo, int ch); int ic10_get_mem(RIG *rig, vfo_t vfo, int *ch); int ic10_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int ic10_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int ic10_set_powerstat(RIG *rig, powerstat_t status); int ic10_get_powerstat(RIG *rig, powerstat_t *status); int ic10_set_trn(RIG *rig, int trn); int ic10_get_trn(RIG *rig, int *trn); int ic10_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int ic10_scan(RIG * rig, vfo_t vfo, scan_t scan, int ch); const char* ic10_get_info(RIG *rig); int ic10_decode_event (RIG *rig); #define IC10_CHANNEL_CAPS \ .freq=1,\ .tx_freq=1,\ .mode=1,\ .tx_mode=1 #endif /* _IC10_H */ hamlib-4.6.5/rigs/kenwood/Makefile.am0000664000175000017500000000125415056640443013124 TSSRC = ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c xg3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c ts890s.c \ ts990s.c ts990s.h flex6xxx.c pihpsdr.c tx500.c IC10SRC = ts440.c ts940.c ts711.c ts811.c r5000.c THSRC = thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c thd74.c KENWOODSRC = kenwood.c kenwood.h th.c th.h ic10.c ic10.h elecraft.c elecraft.h \ transfox.c flex.c flex.h level_gran_kenwood.h level_gran_elecraft.h noinst_LTLIBRARIES = libhamlib-kenwood.la libhamlib_kenwood_la_SOURCES = $(TSSRC) $(THSRC) $(IC10SRC) $(KENWOODSRC) EXTRA_DIST = README.kenwood README.k2 README.k3 README.flex Android.mk hamlib-4.6.5/rigs/kenwood/ic10.c0000664000175000017500000007130215056640443011771 /* * Hamlib Kenwood backend - IC-10 interface for: * TS-940, TS-811, TS-711, TS-440, and R-5000 * * Copyright (c) 2000-2010 by Stephane Fillod and others * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include /* character class tests */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "kenwood.h" #include "ic10.h" /**** * ic10_cmd_trim * gobbles up additional spaces at the end of a line * ****/ int ic10_cmd_trim(char *data, int data_len) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: incoming data_len is '%d'\n", __func__, data_len); /* suck up additional spaces at end of the data buffer */ for (i = data_len; !isdigit((int)data[i - 1]); i--) { data_len = data_len - 1; rig_debug(RIG_DEBUG_TRACE, "%s: data['%d'] is '%c'\n", __func__, i - 1, data[i - 1]); rig_debug(RIG_DEBUG_TRACE, "%s: For i='%d' data_len is now '%d'\n", __func__, i, data_len); } rig_debug(RIG_DEBUG_TRACE, "%s: finished loop.. i='%d' data_len='%d' data[i-1]='%c'\n", __func__, i, data_len, data[i - 1]); return data_len; } /** * ic10_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL **/ int ic10_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; int retry_cmd = 0; struct hamlib_port *rp = RIGPORT(rig); if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: cmd==NULL?\n", __func__); return -RIG_EARG; } rig_debug(RIG_DEBUG_TRACE, "%s: called cmd='%s', len=%d, data=%p, data_len=%p\n", __func__, cmd, cmd_len, data, data_len); transaction: rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { char buffer[50]; const struct kenwood_priv_data *priv = STATE(rig)->priv; if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { return retval; } // this should be the ID response retval = read_string(rp, (unsigned char *) buffer, sizeof(buffer), ";", 1, 0, 1); // might be ?; too if (buffer[0] == '?' && retry_cmd++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: retrying cmd #%d\n", __func__, retry_cmd); goto transaction; } if (strncmp("ID", buffer, 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: expected ID response and got %s\n", __func__, buffer); return retval; } return RIG_OK; } retval = read_string(rp, (unsigned char *) data, 50, ";", 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * Get the answer of IF command, with retry handling */ static int get_ic10_if(RIG *rig, char *data) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; int i, data_len, retval = RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; retval != RIG_OK && i < RIGPORT(rig)->retry; i++) { data_len = 37; retval = ic10_transaction(rig, "IF;", 3, data, &data_len); if (retval != RIG_OK) { continue; } if (data_len < priv->if_len || data[0] != 'I' || data[1] != 'F') { rig_debug(RIG_DEBUG_WARN, "%s: unexpected answer %s, len=%d\n", __func__, data, data_len); retval = -RIG_ERJCTED; } } return retval; } /* * ic10_set_vfo * Assumes rig!=NULL */ int ic10_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[6]; int retval; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_SUB: case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c;", vfo_function); retval = ic10_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, 0); return retval; } /* * ic10_get_vfo * Assumes rig!=NULL, !vfo */ int ic10_get_vfo(RIG *rig, vfo_t *vfo) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char vfobuf[50]; unsigned char c; int retval, iflen; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* query RX VFO */ retval = get_ic10_if(rig, vfobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(vfobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = vfobuf[iflen - 3]; switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, c); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning VFO=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } int ic10_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s tx_freq=%.0f\n", __func__, rig_strvfo(vfo), tx_freq); return ic10_set_freq(rig, RIG_VFO_B, tx_freq); } int ic10_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); return ic10_get_freq(rig, RIG_VFO_B, tx_freq); } int ic10_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return ic10_transaction(rig, split == RIG_SPLIT_ON ? "SP1;" : "SP0;", 4, NULL, 0); } int ic10_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char infobuf[50]; int retval, iflen; retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(infobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ *split = infobuf[iflen - 1] == '0' ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } /* * ic10_get_mode * Assumes rig!=NULL, !vfo */ int ic10_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char modebuf[50]; unsigned char c; int retval, iflen; /* query RX VFO */ retval = get_ic10_if(rig, modebuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(modebuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = modebuf[iflen - 4]; switch (c) { case MD_CW : *mode = RIG_MODE_CW; break; case MD_USB : *mode = RIG_MODE_USB; break; case MD_LSB : *mode = RIG_MODE_LSB; break; case MD_FM : *mode = RIG_MODE_FM; break; case MD_AM : *mode = RIG_MODE_AM; break; case MD_FSK : *mode = RIG_MODE_RTTY; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, c); return -RIG_EINVAL; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * ic10_set_mode * Assumes rig!=NULL */ int ic10_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char modebuf[6]; int retval; char mode_letter; switch (mode) { case RIG_MODE_LSB : mode_letter = MD_LSB; break; case RIG_MODE_USB : mode_letter = MD_USB; break; case RIG_MODE_CW : mode_letter = MD_CW; break; case RIG_MODE_FM : mode_letter = MD_FM; break; case RIG_MODE_AM : mode_letter = MD_AM; break; case RIG_MODE_RTTY : mode_letter = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(modebuf, sizeof(modebuf), "MD%c;", mode_letter); retval = ic10_transaction(rig, modebuf, strlen(modebuf), NULL, 0); return retval; } /* * ic10_get_freq * Assumes rig!=NULL, freq!=NULL */ int ic10_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char infobuf[50]; int retval; if (vfo != RIG_VFO_CURR) { /* targeted freq retrieval */ return kenwood_get_freq(rig, vfo, freq); } retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ infobuf[13] = '\0'; sscanf(infobuf + 2, "%011"SCNfreq, freq); return RIG_OK; } /* * ic10_set_freq * Assumes rig!=NULL */ int ic10_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[64]; int retval; unsigned char vfo_letter; vfo_t tvfo; if (vfo == RIG_VFO_CURR) { tvfo = STATE(rig)->current_vfo; } else { tvfo = vfo; } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll";", vfo_letter, (int64_t)freq); retval = ic10_transaction(rig, freqbuf, strlen(freqbuf), NULL, 0); return retval; } /* * ic10_set_ant * Assumes rig!=NULL */ int ic10_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char buf[6], ackbuf[64]; int ack_len, retval; SNPRINTF(buf, sizeof(buf), "AN%c;", ant == RIG_ANT_1 ? '1' : '2'); retval = ic10_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * ic10_get_ant * Assumes rig!=NULL, ptt!=NULL */ int ic10_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char infobuf[50]; int info_len, retval; info_len = 4; retval = ic10_transaction(rig, "AN;", 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } if (info_len < 4 || infobuf[0] != 'A' || infobuf[1] != 'N') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, info_len); return -RIG_ERJCTED; } *ant_curr = infobuf[2] == '1' ? RIG_ANT_1 : RIG_ANT_2; return RIG_OK; } /* * ic10_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int ic10_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char infobuf[50]; int retval, iflen, offset; retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(infobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp#### what should be if p13/p14/p15 included */ /* IF00014074000 +00000000003000000 ; QRP QDX bad IF command -- 36 bytes instead of 33 */ /* QRP QDX should be 37 bytes but used only 1 byte for p14 instead of 2 bytes */ /* 12345678901234567890123456789012345678 */ offset = 5; if (iflen == 36) { offset = 8; } // QRP QDX gets completely bogus length else if (iflen == 37) { offset = 9; } // just in case somebody does this add p13/p14x2/p15 *ptt = infobuf[iflen - offset] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } // Not referenced anywhere /* * ic10_set_ptt * Assumes rig!=NULL */ int ic10_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char pttbuf[4]; int retval; unsigned char ptt_letter; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_OFF: ptt_letter = 'R'; break; case RIG_PTT_ON : ptt_letter = 'T'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT %d\n", __func__, ptt); return -RIG_EINVAL; } SNPRINTF(pttbuf, sizeof(pttbuf), "%cX;", ptt_letter); retval = ic10_transaction(rig, pttbuf, strlen(pttbuf), NULL, 0); return retval; } /* * ic10_get_mem * Assumes rig!=NULL */ int ic10_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char membuf[50]; int retval, iflen; retval = get_ic10_if(rig, membuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(membuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ membuf[iflen - 5] = '\0'; *ch = atoi(membuf + priv->if_len - 7); return RIG_OK; } /* * ic10_set_mem * Assumes rig!=NULL */ int ic10_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[8], ackbuf[64]; int ack_len, retval; SNPRINTF(membuf, sizeof(membuf), "MC%02d;", ch); retval = ic10_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len); return retval; } int ic10_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char membuf[16], infobuf[32]; int retval, info_len; SNPRINTF(membuf, sizeof(membuf), "MR00%02d;", chan->channel_num); info_len = 24; retval = ic10_transaction(rig, membuf, strlen(membuf), infobuf, &info_len); if (retval != RIG_OK) { return retval; } /* MRs-ccfffffffffffml----; */ /* 012345678901234567890123 */ switch (infobuf[17]) { case MD_CW : chan->mode = RIG_MODE_CW; break; case MD_USB : chan->mode = RIG_MODE_USB; break; case MD_LSB : chan->mode = RIG_MODE_LSB; break; case MD_FM : chan->mode = RIG_MODE_FM; break; case MD_AM : chan->mode = RIG_MODE_AM; break; case MD_FSK : chan->mode = RIG_MODE_RTTY; break; case MD_NONE: chan->mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[17]); return -RIG_EINVAL; } chan->width = rig_passband_normal(rig, chan->mode); sscanf(infobuf + 6, "%011"SCNfreq, &chan->freq); chan->vfo = RIG_VFO_MEM; if (chan->channel_num >= 90) { chan->split = 1; /* TX VFO (Split channel only) */ SNPRINTF(membuf, sizeof(membuf), "MR10%02d;", chan->channel_num); info_len = 24; retval = ic10_transaction(rig, membuf, strlen(membuf), infobuf, &info_len); if (retval == RIG_OK && info_len > 17) { /* MRn rrggmmmkkkhhhdz ; */ switch (infobuf[17]) { case MD_CW : chan->tx_mode = RIG_MODE_CW; break; case MD_USB : chan->tx_mode = RIG_MODE_USB; break; case MD_LSB : chan->tx_mode = RIG_MODE_LSB; break; case MD_FM : chan->tx_mode = RIG_MODE_FM; break; case MD_AM : chan->tx_mode = RIG_MODE_AM; break; case MD_FSK : chan->tx_mode = RIG_MODE_RTTY; break; case MD_NONE: chan->tx_mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[17]); return -RIG_EINVAL; } chan->tx_width = rig_passband_normal(rig, chan->tx_mode); sscanf(infobuf + 6, "%011"SCNfreq, &chan->tx_freq); } } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ic10_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[64]; int retval, md; int64_t freq; freq = (int64_t) chan->freq; if (chan->channel_num < 90 && chan->tx_freq != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Transmit/split can only be on channels 90-99\n", __func__); return -RIG_EINVAL; } switch (chan->mode) { case RIG_MODE_CW : md = MD_CW; break; case RIG_MODE_USB : md = MD_USB; break; case RIG_MODE_LSB : md = MD_LSB; break; case RIG_MODE_FM : md = MD_FM; break; case RIG_MODE_AM : md = MD_AM; break; case RIG_MODE_RTTY: md = MD_FSK; break; case RIG_MODE_NONE: md = MD_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } /* MWnxrrggmmmkkkhhhdzxxxx; */ SNPRINTF(membuf, sizeof(membuf), "MW0 %02d%011"PRIll"%c0 ;", chan->channel_num, freq, md ); retval = ic10_transaction(rig, membuf, strlen(membuf), NULL, 0); if (retval != RIG_OK) { return retval; } /* TX VFO (Split channel only) */ freq = chan->tx_freq; switch (chan->tx_mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_AM: md = MD_AM; break; case RIG_MODE_RTTY: md = MD_FSK; break; case RIG_MODE_NONE: md = MD_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } if (chan->channel_num >= 90) { /* MWnxrrggmmmkkkhhhdzxxxx; */ SNPRINTF(membuf, sizeof(membuf), "MW1 %02d%011"PRIll"%c0 ;", chan->channel_num, freq, md ); retval = ic10_transaction(rig, membuf, strlen(membuf), NULL, 0); // I assume we need to check the retval here -- W9MDB // This was found from cppcheck if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed: %s\n", __func__, rigerror(retval)); return retval; } } return RIG_OK; } /* * ic10_get_func * Assumes rig!=NULL, val!=NULL */ int ic10_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char cmdbuf[6], fctbuf[50]; int fct_len, retval; fct_len = 4; switch (func) { case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LK;"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } retval = ic10_transaction(rig, cmdbuf, strlen(cmdbuf), fctbuf, &fct_len); if (retval != RIG_OK) { return retval; } if (fct_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, fct_len); return -RIG_ERJCTED; } *status = fctbuf[2] == '0' ? 0 : 1; return RIG_OK; } /* * ic10_set_func * Assumes rig!=NULL, val!=NULL */ int ic10_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[4], fctbuf[16], ackbuf[64]; int ack_len; switch (func) { case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LK"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } SNPRINTF(fctbuf, sizeof(fctbuf), "%s%c;", cmdbuf, status == 0 ? '0' : '1'); return ic10_transaction(rig, fctbuf, strlen(fctbuf), ackbuf, &ack_len); } /* * ic10_set_parm * Assumes rig!=NULL */ int ic10_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[50]; int hours; int minutes; int seconds; switch (parm) { case RIG_PARM_TIME: minutes = val.i / 60; hours = minutes / 60; seconds = val.i - (minutes * 60); minutes = minutes % 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "CK1%02d%02d%02d;", hours, minutes, seconds); return ic10_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * ic10_get_parm * Assumes rig!=NULL, val!=NULL */ int ic10_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, lvl_len, i; char lvlbuf[50]; switch (parm) { case RIG_PARM_TIME: lvl_len = 10; retval = ic10_transaction(rig, "CK1;", 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* "CK1hhmmss;"*/ if (lvl_len != 10) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, lvl_len); return -RIG_ERJCTED; } /* convert ASCII to numeric 0..9 */ for (i = 3; i < 9; i++) { lvlbuf[i] -= '0'; } val->i = ((10 * lvlbuf[3] + lvlbuf[4]) * 60 + /* hours */ 10 * lvlbuf[5] + lvlbuf[6]) * 60 + /* minutes */ 10 * lvlbuf[7] + lvlbuf[8]; /* seconds */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * ic10_set_powerstat * Assumes rig!=NULL */ int ic10_set_powerstat(RIG *rig, powerstat_t status) { char pwrbuf[16], ackbuf[64]; int ack_len; SNPRINTF(pwrbuf, sizeof(pwrbuf), "PS%c;", status == RIG_POWER_ON ? '1' : '0'); return ic10_transaction(rig, pwrbuf, strlen(pwrbuf), ackbuf, &ack_len); } /* * ic10_get_powerstat * Assumes rig!=NULL, trn!=NULL */ int ic10_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[50]; int pwr_len, retval; pwr_len = 4; retval = ic10_transaction(rig, "PS;", 3, pwrbuf, &pwr_len); if (retval != RIG_OK) { return retval; } if (pwr_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, pwr_len); return -RIG_ERJCTED; } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } /* * ic10_set_trn * Assumes rig!=NULL */ int ic10_set_trn(RIG *rig, int trn) { char trnbuf[16], ackbuf[64]; int ack_len; SNPRINTF(trnbuf, sizeof(trnbuf), "AI%c;", trn == RIG_TRN_RIG ? '1' : '0'); return ic10_transaction(rig, trnbuf, strlen(trnbuf), ackbuf, &ack_len); } /* * ic10_get_trn * Assumes rig!=NULL, trn!=NULL */ int ic10_get_trn(RIG *rig, int *trn) { char trnbuf[50]; int trn_len, retval; trn_len = 38; retval = ic10_transaction(rig, "AI;", 3, trnbuf, &trn_len); if (retval != RIG_OK) { return retval; } if (trn_len != 38) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, trn_len); return -RIG_ERJCTED; } *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * ic10_vfo_op * Assumes rig!=NULL */ int ic10_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char *cmd, ackbuf[64]; int ack_len; switch (op) { case RIG_OP_UP : cmd = "UP;"; break; case RIG_OP_DOWN : cmd = "DN;"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } return ic10_transaction(rig, cmd, 3, ackbuf, &ack_len); } /* * ic10_scan * Assumes rig!=NULL, val!=NULL */ int ic10_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char ackbuf[64]; int ack_len; return ic10_transaction(rig, scan == RIG_SCAN_STOP ? "SC0;" : "SC1;", 4, ackbuf, &ack_len); } /* * ic10_get_info * Assumes rig!=NULL */ const char *ic10_get_info(RIG *rig) { char firmbuf[50]; int firm_len, retval; firm_len = 6; retval = ic10_transaction(rig, "ID;", 3, firmbuf, &firm_len); if (retval != RIG_OK) { return NULL; } if (firm_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, firm_len); return NULL; } switch (firmbuf[4]) { case '4': return "ID: TS-440S"; case '5': return "ID: R-5000"; default: return "ID: unknown"; } } /* * ic10_decode_event is called by sa_sigio, when some asynchronous * data has been received from the rig. */ int ic10_decode_event(RIG *rig) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char asyncbuf[128], c; int retval, async_len = 128, iflen; vfo_t vfo; freq_t freq; rmode_t mode; ptt_t ptt; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = ic10_transaction(rig, NULL, 0, asyncbuf, &async_len); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); /* --------------------------------------------------------------------- */ if (async_len < priv->if_len || asyncbuf[0] != 'I' || asyncbuf[1] != 'F') { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } /* trim extra spaces */ iflen = ic10_cmd_trim(asyncbuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = asyncbuf[iflen - 3]; switch (c) { case '0': vfo = RIG_VFO_A; break; case '1': vfo = RIG_VFO_B; break; case '2': vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, c); return -RIG_EPROTO; } c = asyncbuf[iflen - 4]; switch (c) { case MD_CW : mode = RIG_MODE_CW; break; case MD_USB : mode = RIG_MODE_USB; break; case MD_LSB : mode = RIG_MODE_LSB; break; case MD_FM : mode = RIG_MODE_FM; break; case MD_AM : mode = RIG_MODE_AM; break; case MD_FSK : mode = RIG_MODE_RTTY; break; case MD_NONE: mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, c); return -RIG_EINVAL; } ptt = asyncbuf[iflen - 5] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; asyncbuf[13] = '\0'; sscanf(asyncbuf + 2, "%011"SCNfreq, &freq); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, vfo, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } if (rig->callbacks.ptt_event) { rig->callbacks.ptt_event(rig, vfo, ptt, rig->callbacks.ptt_arg); } return RIG_OK; } hamlib-4.6.5/rigs/kenwood/ts590.c0000664000175000017500000022744715056640443012136 /* * Hamlib Kenwood backend - TS-590(S/SG) description * Copyright (c) 2010 by Stephane Fillod * Copyright (c) 2023 by Mikael Nousiainen OH3BHX * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "misc.h" #include "cal.h" #include "iofunc.h" #define FX4_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define TS590_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PKTAM) #define FX4_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS590_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define FX4_AM_TX_MODES (RIG_MODE_AM) #define TS590_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define FX4_VFO (RIG_VFO_A|RIG_VFO_B) #define TS590_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS590_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_STRENGTH|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS590_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS590_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK) #define TS590_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_CPY|RIG_OP_TUNE) #define TS590_SCAN_OPS (RIG_SCAN_VFO) #define FX4_ANTS (RIG_ANT_1) #define TS590_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS590_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } #define TS590_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } #define TS590_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 6, 1.5f }, \ { 12, 2.0f }, \ { 18, 3.0f }, \ { 30, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) #define TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL TOKEN_BACKEND(109) #define TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL TOKEN_BACKEND(110) // these two USB_AUDIO items are being kept for backwards compatibility // replaced by RIG_LEVEL_USB_AF and RIG_LEVEL_USB_AF_INPUT #define TOK_LEVEL_USB_AUDIO_INPUT_LEVEL TOKEN_BACKEND(113) #define TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL TOKEN_BACKEND(114) #define TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER TOKEN_BACKEND(115) #define TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER TOKEN_BACKEND(116) #define TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER TOKEN_BACKEND(117) #define TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER TOKEN_BACKEND(118) int ts590_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL, TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL, TOK_LEVEL_USB_AUDIO_INPUT_LEVEL, TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL, TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER, TOK_BACKEND_NONE, }; const struct confparams ts590_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts590_ext_levels[] = { { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "flat", "U", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 20, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 20, .step = 1 } } }, { TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL, "ACC2_AUDIO_INPUT_LEVEL", "ACC2 audio input level", "ACC2 audio input level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL, "ACC2_AUDIO_OUTPUT_LEVEL", "ACC2 audio output level", "ACC2 audio output level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_USB_AUDIO_INPUT_LEVEL, "USB_AUDIO_INPUT_LEVEL", "USB audio input level", "USB audio input level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL, "USB_AUDIO_OUTPUT_LEVEL", "USB audio output level", "USB audio output level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER, "DSP_TX_SSB_AM_LOW_CUT_FILTER", "DSP TX SSB/AM low-cut", "DSP TX low-cut filter for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "10 Hz", "100 Hz", "200 Hz", "300 Hz", "400 Hz", "500 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER, "DSP_TX_SSB_AM_HIGH_CUT_FILTER", "DSP TX SSB/AM high-cut", "DSP TX high-cut filter for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2500 Hz", "2600 Hz", "2700 Hz", "2800 Hz", "2900 Hz", "3000 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER, "DSP_TX_SSB_DATA_LOW_CUT_FILTER", "DSP TX SSB data low-cut", "DSP TX low-cut filter for SSB data", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "10 Hz", "100 Hz", "200 Hz", "300 Hz", "400 Hz", "500 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER, "DSP_TX_SSB_DATA_HIGH_CUT_FILTER", "DSP TX SSB data high-cut", "DSP TX high-cut filter for SSB data", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2500 Hz", "2600 Hz", "2700 Hz", "2800 Hz", "2900 Hz", "3000 Hz", NULL } } } }, { RIG_CONF_END, NULL, } }; /* * ts590_get_info * This is not documented in the manual as of 3/11/15 but confirmed from Kenwood * "TY" produces "TYK 00" for example */ const char *ts590_get_info(RIG *rig) { char firmbuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "TY", firmbuf, 10, 6); if (retval != RIG_OK) { return NULL; } switch (firmbuf[2]) { case 'K': return "Firmware: USA version"; case 'E': return "Firmware: European version"; default: return "Firmware: unknown"; } } // keep track of SF command ability static int sf_fails; static int ts590_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char kmode = rmode2kenwood(mode, caps->mode_table); char cmd[32], c; int retval = -RIG_EINTERNAL; int hwidth = 0; // int lwidth; // not implemented yet until new API is created if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC2(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } if (!sf_fails) { SNPRINTF(cmd, sizeof(cmd), "SF%d%011.0f%c", vfo == RIG_VFO_A ? 0 : 1, vfo == RIG_VFO_A ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB, c); retval = kenwood_transaction(rig, cmd, NULL, 0); } if (retval != RIG_OK || sf_fails) { return kenwood_set_mode(rig, vfo, mode, width); } if (width != RIG_PASSBAND_NOCHANGE) { if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { const int cw_table[] = { 50, 80, 100, 150, 200, 250, 300, 400, 500, 600, 1000, 1500, 2000, 2500 }; int twidth = 2500; // maximum for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) { if (cw_table[i] >= width) { twidth = cw_table[i]; break; } } SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } else if (mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) { const int cw_table[] = { 250, 500, 1000, 1500 }; int twidth = 1500; // maximum for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) { if (cw_table[i] >= width) { twidth = cw_table[i]; break; } } SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } else if (mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) { const int pkt_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; // not setting SL since no API for it yet // we will just set SH based on requested bandwidth not taking SL into account //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; for (int i = 0; i < sizeof(pkt_htable) / sizeof(int); ++i) { if (pkt_htable[i] >= width) { hwidth = i; break; } } } else if (mode == RIG_MODE_AM || mode == RIG_MODE_PKTAM) { const int am_htable[] = { 2500, 3000, 4000, 5000 }; //const int am_ltable[] = { 0, 100, 200, 300 }; for (int i = 0; i < sizeof(am_htable) / sizeof(int); ++i) { if (am_htable[i] >= width) { hwidth = i; break; } } } else if (mode == RIG_MODE_SSB || mode == RIG_MODE_LSB || mode == RIG_MODE_USB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; for (int i = 0; i < sizeof(ssb_htable) / sizeof(int); ++i) { if (ssb_htable[i] >= width) { hwidth = i; break; } } } SNPRINTF(cmd, sizeof(cmd), "SH%02d;", hwidth); retval = kenwood_transaction(rig, cmd, NULL, 0); } return retval; } static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char cmd[32], ackbuf[32]; int retval; if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_TX || vfo == RIG_VFO_RX) { vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } retval = RIG_OK; if (!sf_fails) { SNPRINTF(cmd, sizeof(cmd), "SF%d", vfo == RIG_VFO_A ? 0 : 1); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 15); } // if this fails fall back to old method if (retval != RIG_OK || sf_fails) { sf_fails = 1; return kenwood_get_mode(rig, vfo, mode, width); } *mode = ackbuf[14]; if (*mode >= 'A') { *mode = *mode - 'A' + 10; } else { *mode -= '0'; } *mode = kenwood2rmode(*mode, caps->mode_table); // now let's get our widths // CW is different then other modes if (*mode == RIG_MODE_CW || *mode == RIG_MODE_CWR || *mode == RIG_MODE_RTTY || *mode == RIG_MODE_RTTYR) { SNPRINTF(cmd, sizeof(cmd), "FW"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 6); if (retval == RIG_OK) { int twidth; sscanf(ackbuf, "FW%d", &twidth); *width = twidth; } return retval; } SNPRINTF(cmd, sizeof(cmd), "SH"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SH command failed: %s\n", __func__, rigerror(retval)); return retval; } int hwidth; sscanf(ackbuf, "SH%d", &hwidth); int lwidth; int shift = 0; SNPRINTF(cmd, sizeof(cmd), "SL"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); sscanf(ackbuf, "SL%d", &lwidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SL command failed: %s\n", __func__, rigerror(retval)); return retval; } if (*mode == RIG_MODE_PKTUSB || *mode == RIG_MODE_PKTLSB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; *width = ssb_htable[hwidth]; // we don't do anything with shift yet which will be just the hwidth value shift = ssb_ltable[lwidth]; } else if (*mode == RIG_MODE_AM || *mode == RIG_MODE_PKTAM) { const int am_htable[] = { 2500, 3000, 4000, 5000 }; const int am_ltable[] = { 0, 100, 200, 300 }; *width = am_htable[hwidth] - am_ltable[lwidth]; } else if (*mode == RIG_MODE_SSB || *mode == RIG_MODE_LSB || *mode == RIG_MODE_USB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; *width = ssb_htable[hwidth] - ssb_ltable[lwidth]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: width=%ld, shift=%d, lwidth=%d, hwidth=%d\n", __func__, *width, shift, lwidth, hwidth); return RIG_OK; } static int ts590_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts590_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts590_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; ENTERFUNC; switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c0", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TUNER: SNPRINTF(buf, sizeof(buf), "AC%c%c0", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); default: RETURNFUNC(kenwood_set_func(rig, vfo, func, status)); } } static int ts590_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0'; break; case RIG_FUNC_TUNER: retval = kenwood_safe_transaction(rig, "AC", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[3] != '0' ? 1 : 0; RETURNFUNC(RIG_OK); default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } static int ts590_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char levelbuf[16]; int kenwood_val; int result; int cmd; ENTERFUNC; switch (level) { case RIG_LEVEL_USB_AF: kenwood_val = roundl((val.f + .045) * 9); cmd = 65; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val); break; case RIG_LEVEL_USB_AF_INPUT: kenwood_val = roundl((val.f + .045) * 9); cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val); break; case RIG_LEVEL_RF: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: RETURNFUNC(kenwood_set_level(rig, vfo, level, val)); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", kenwood_val); break; case RIG_LEVEL_AGC: /* Possible values for TS-2000 are 0(=off)-020(=slow) */ switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: kenwood_val = 1; break; case RIG_AGC_FAST: kenwood_val = 5; break; case RIG_AGC_MEDIUM: kenwood_val = 10; break; case RIG_AGC_SLOW: kenwood_val = 20; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%02d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: if (rig->caps->rig_model == RIG_MODEL_TS590S) { kenwood_val = val.f * 9.0f; } else { kenwood_val = val.f * 20.0f; } SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: priv->question_mark_response_means_rejected = 1; kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: priv->question_mark_response_means_rejected = 1; kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 300) { RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(ts590_set_ex_menu(rig, 40, 2, (val.i - 300) / 50)); default: RETURNFUNC(kenwood_set_level(rig, vfo, level, val)); } result = kenwood_transaction(rig, levelbuf, NULL, 0); priv->question_mark_response_means_rejected = 0; RETURNFUNC(result); } static int ts590_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-590 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM1%d;RM2%d;RM3%d;", swr, comp, alc); if (retval != 3) { rig_debug(RIG_DEBUG_ERR, "%s: expected 3 meter values to parse, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } static int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint = 0; int retval; int cmd; ENTERFUNC; switch (level) { case RIG_LEVEL_USB_AF: cmd = 65; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); if (levelint == 9) { val->f = 1.0; } else { val->f = roundl(levelint * 10 / 10.0 + .04) / 10.0; } RETURNFUNC(retval); case RIG_LEVEL_USB_AF_INPUT: cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); if (levelint == 9) { val->f = 1.0; } else { val->f = roundl(levelint * 10 / 10.0) / 10.0; } RETURNFUNC(retval); case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 255; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); priv->question_mark_response_means_rejected = 0; ack_len_expected = 4; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } if (levelint == 0) { val->i = RIG_AGC_OFF; } else if (levelint <= 1) { val->i = RIG_AGC_SUPERFAST; } else if (levelint <= 5) { val->i = RIG_AGC_FAST; } else if (levelint <= 10) { val->i = RIG_AGC_MEDIUM; } else { val->i = RIG_AGC_SLOW; } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); if (rig->caps->rig_model == RIG_MODEL_TS590S) { val->f = (float) raw_value / 9.0f; } else { val->f = (float) raw_value / 20.0f; } break; } case RIG_LEVEL_NB: { int raw_value; priv->question_mark_response_means_rejected = 1; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; priv->question_mark_response_means_rejected = 1; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int swr; int comp; int alc; retval = ts590_read_meters(rig, &swr, &comp, &alc); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 30 break; case RIG_LEVEL_ALC: // Maximum value is 30, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 6.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { int raw_value; const static cal_table_t power_meter = { 7, { { 0, 0}, { 3, 5}, { 6, 10}, { 8, 15}, {12, 25}, { 17, 50}, { 30, 100} } }; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } retval = kenwood_safe_transaction(rig, "SM0", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM0%d", &raw_value); if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = roundf(rig_raw2val(raw_value, &power_meter)); if (val->f < 10) { val->f = roundf(rig_raw2val(raw_value, &power_meter) * 10.0) / 10.0; } } else { val->f = (float) raw_value / 30.0f; } break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts590_get_ex_menu(rig, 40, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 300 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts590_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -9999 || rit > 9999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts590_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts590_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 31, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 37, 1, val.i); } break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 30, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 36, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 25, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 31, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 26, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 32, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 27, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 33, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 28, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 34, 1, val.i); } break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 20) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 3, 2, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 5, 2, (int) val.f); } break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 20) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 4, 2, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 6, 2, (int) val.f); } break; case TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 66, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 73, 1, (int) val.f); } break; case TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 67, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 74, 1, (int) val.f); } break; case TOK_LEVEL_USB_AUDIO_INPUT_LEVEL: // keep for backwards compatibility if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 64, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 71, 1, (int) val.f); } break; case TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL: // keep for backwards compatibility if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 65, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 72, 1, (int) val.f); } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 31, 1, &value); } else { retval = ts590_get_ex_menu(rig, 37, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 30, 1, &value); } else { retval = ts590_get_ex_menu(rig, 36, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 25, 1, &value); } else { retval = ts590_get_ex_menu(rig, 31, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 26, 1, &value); } else { retval = ts590_get_ex_menu(rig, 32, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 27, 1, &value); } else { retval = ts590_get_ex_menu(rig, 33, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 28, 1, &value); } else { retval = ts590_get_ex_menu(rig, 34, 1, &value); } val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 3, 2, &value); } else { retval = ts590_get_ex_menu(rig, 5, 2, &value); } val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 4, 2, &value); } else { retval = ts590_get_ex_menu(rig, 6, 2, &value); } val->f = value; break; case TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 66, 1, &value); } else { retval = ts590_get_ex_menu(rig, 73, 1, &value); } val->f = value; break; case TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 67, 1, &value); } else { retval = ts590_get_ex_menu(rig, 74, 1, &value); } val->f = value; break; case TOK_LEVEL_USB_AUDIO_INPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 64, 1, &value); } else { retval = ts590_get_ex_menu(rig, 71, 1, &value); } val->f = value; break; case TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 65, 1, &value); } else { retval = ts590_get_ex_menu(rig, 72, 1, &value); } val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static struct kenwood_filter_width ts590_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 250, 250 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 1500, 1500 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2500, 2500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_FM, 0, 12000 }, { RIG_MODE_AM, 0, 6000 }, { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts590_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 1600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 1800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 2600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 2800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 3000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 3400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 12, 4000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 13, 5000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 0, 2500 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 1, 3000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 2, 4000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 3, 5000 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts590_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 1000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 0, 0 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 1, 100 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 2, 200 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 3, 300 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts590_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts590_filter_width, .slope_filter_high = ts590_slope_filter_high, .slope_filter_low = ts590_slope_filter_low, .tone_table_base = 0, }; /** * TS-590 rig capabilities */ struct rig_caps ts590_caps = { RIG_MODEL(RIG_MODEL_TS590S), .model_name = "TS-590S", .mfg_name = "Kenwood", .version = BACKEND_VER ".18", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), // .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST, RIG_AGC_ON }, .chan_list = { /* TBC */ { 0, 89, RIG_MTYPE_MEM, TS590_CHANNEL_CAPS }, { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1810), kHz(1850), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), kHz(3800), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), kHz(3800), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS590_ALL_MODES, kHz(1)}, {TS590_ALL_MODES, Hz(2500)}, {TS590_ALL_MODES, kHz(5)}, {TS590_ALL_MODES, Hz(6250)}, {TS590_ALL_MODES, kHz(10)}, {TS590_ALL_MODES, Hz(12500)}, {TS590_ALL_MODES, kHz(15)}, {TS590_ALL_MODES, kHz(20)}, {TS590_ALL_MODES, kHz(25)}, {TS590_ALL_MODES, kHz(30)}, {TS590_ALL_MODES, kHz(100)}, {TS590_ALL_MODES, kHz(500)}, {TS590_ALL_MODES, MHz(1)}, {TS590_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS590_STR_CAL, .swr_cal = TS590_SWR_CAL, .ext_tokens = ts590_ext_tokens, .extfuncs = ts590_ext_funcs, .extlevels = ts590_ext_levels, .priv = (void *)& ts590_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts590_set_rit, .get_rit = ts590_get_rit, .set_xit = ts590_set_rit, .get_xit = ts590_get_rit, .set_mode = ts590_set_mode, .get_mode = ts590_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = ts590_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan_ops = TS590_SCAN_OPS, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS590_LEVEL_SET, .has_get_level = TS590_LEVEL_GET, .set_level = ts590_set_level, .get_level = ts590_get_level, .set_ext_level = ts590_set_ext_level, .get_ext_level = ts590_get_ext_level, .has_get_func = TS590_FUNC_ALL, .has_set_func = TS590_FUNC_ALL, .set_func = ts590_set_func, .get_func = ts590_get_func, .set_ext_func = ts590_set_ext_func, .get_ext_func = ts590_get_ext_func, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .ctcss_list = kenwood38_ctcss_list, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .vfo_ops = TS590_VFO_OPS, .vfo_op = kenwood_vfo_op, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /** * BG2FX FX-4C/FX-4CR rig capabilities * Supposed to be 590S compatible * Separate entry allows for customization */ struct rig_caps fx4_caps = { RIG_MODEL(RIG_MODEL_FX4), .model_name = "FX4/C/CR/L", .mfg_name = "BG2FX", .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), // .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST, RIG_AGC_ON }, .chan_list = { /* TBC */ { 0, 89, RIG_MTYPE_MEM, TS590_CHANNEL_CAPS }, { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), Hz(59999999), FX4_ALL_MODES, -1, -1, FX4_VFO, FX4_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(3500), kHz(3800), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(3500), kHz(3800), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(7), kHz(7200), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(7), kHz(7200), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(10100), kHz(10150), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(10100), kHz(10150), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(14), kHz(14350), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(14), kHz(14350), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(18068), kHz(18168), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(18068), kHz(18168), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(21), kHz(21450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(21), kHz(21450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(24890), kHz(24990), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(24890), kHz(24990), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(28), kHz(29700), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(28), kHz(29700), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(50), kHz(52000), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(50), kHz(52000), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(30), Hz(59999999), FX4_ALL_MODES, -1, -1, FX4_VFO, FX4_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(3500), MHz(4) - 1, FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(3500), MHz(4) - 1, FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(5250), kHz(5450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(5250), kHz(5450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(7), kHz(7300), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(7), kHz(7300), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(10100), kHz(10150), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(10100), kHz(10150), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(14), kHz(14350), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(14), kHz(14350), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(18068), kHz(18168), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(18068), kHz(18168), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(21), kHz(21450), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(21), kHz(21450), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {kHz(24890), kHz(24990), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {kHz(24890), kHz(24990), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(28), kHz(29700), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(28), kHz(29700), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, {MHz(50), kHz(52000), FX4_OTHER_TX_MODES, 5000, 100000, FX4_VFO, FX4_ANTS}, {MHz(50), kHz(52000), FX4_AM_TX_MODES, 5000, 25000, FX4_VFO, FX4_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS590_ALL_MODES, kHz(1)}, {TS590_ALL_MODES, Hz(2500)}, {TS590_ALL_MODES, kHz(5)}, {TS590_ALL_MODES, Hz(6250)}, {TS590_ALL_MODES, kHz(10)}, {TS590_ALL_MODES, Hz(12500)}, {TS590_ALL_MODES, kHz(15)}, {TS590_ALL_MODES, kHz(20)}, {TS590_ALL_MODES, kHz(25)}, {TS590_ALL_MODES, kHz(30)}, {TS590_ALL_MODES, kHz(100)}, {TS590_ALL_MODES, kHz(500)}, {TS590_ALL_MODES, MHz(1)}, {TS590_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIND_LYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS590_STR_CAL, .swr_cal = TS590_SWR_CAL, .ext_tokens = ts590_ext_tokens, .extfuncs = ts590_ext_funcs, .extlevels = ts590_ext_levels, .priv = (void *)& ts590_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts590_set_rit, .get_rit = ts590_get_rit, .set_xit = ts590_set_rit, .get_xit = ts590_get_rit, .set_mode = ts590_set_mode, .get_mode = ts590_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = ts590_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan_ops = TS590_SCAN_OPS, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS590_LEVEL_SET, .has_get_level = TS590_LEVEL_GET, .set_level = ts590_set_level, .get_level = ts590_get_level, .set_ext_level = ts590_set_ext_level, .get_ext_level = ts590_get_ext_level, .has_get_func = TS590_FUNC_ALL, .has_set_func = TS590_FUNC_ALL, .set_func = ts590_set_func, .get_func = ts590_get_func, .set_ext_func = ts590_set_ext_func, .get_ext_func = ts590_get_ext_func, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .ctcss_list = kenwood38_ctcss_list, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .vfo_ops = TS590_VFO_OPS, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /** * TS-590SG rig capabilities */ struct rig_caps ts590sg_caps = { RIG_MODEL(RIG_MODEL_TS590SG), .model_name = "TS-590SG", .mfg_name = "Kenwood", .version = BACKEND_VER ".12", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), // .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST, RIG_AGC_ON }, .chan_list = { /* TBC */ { 0, 89, RIG_MTYPE_MEM, TS590_CHANNEL_CAPS }, { 90, 99, RIG_MTYPE_EDGE, TS590_CHANNEL_CAPS }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1810), kHz(1850), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), kHz(3800), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), kHz(3800), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS590_ALL_MODES, kHz(1)}, {TS590_ALL_MODES, Hz(2500)}, {TS590_ALL_MODES, kHz(5)}, {TS590_ALL_MODES, Hz(6250)}, {TS590_ALL_MODES, kHz(10)}, {TS590_ALL_MODES, Hz(12500)}, {TS590_ALL_MODES, kHz(15)}, {TS590_ALL_MODES, kHz(20)}, {TS590_ALL_MODES, kHz(25)}, {TS590_ALL_MODES, kHz(30)}, {TS590_ALL_MODES, kHz(100)}, {TS590_ALL_MODES, kHz(500)}, {TS590_ALL_MODES, MHz(1)}, {TS590_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_SLOPE_LOW] = {.min = {.i = 0}, .max = {.i = 2400}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .str_cal = TS590_STR_CAL, .swr_cal = TS590_SWR_CAL, .ext_tokens = ts590_ext_tokens, .extfuncs = ts590_ext_funcs, .extlevels = ts590_ext_levels, .priv = (void *)& ts590_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts590_set_rit, .get_rit = ts590_get_rit, .set_xit = ts590_set_rit, .get_xit = ts590_get_rit, .set_mode = ts590_set_mode, .get_mode = ts590_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = ts590_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .scan_ops = TS590_SCAN_OPS, .scan = kenwood_scan, /* not working, invalid arguments using rigctl; kenwood_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = TS590_LEVEL_SET, .has_get_level = TS590_LEVEL_GET, .set_level = ts590_set_level, .get_level = ts590_get_level, .set_ext_level = ts590_set_ext_level, .get_ext_level = ts590_get_ext_level, .has_get_func = TS590_FUNC_ALL, .has_set_func = TS590_FUNC_ALL, .set_func = ts590_set_func, .get_func = ts590_get_func, .set_ext_func = ts590_set_ext_func, .get_ext_func = ts590_get_ext_func, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .ctcss_list = kenwood38_ctcss_list, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .vfo_ops = TS590_VFO_OPS, .vfo_op = kenwood_vfo_op, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/commradio/0000775000175000017500000000000015056640501011445 5hamlib-4.6.5/rigs/commradio/commradio.c0000664000175000017500000001225115056640443013511 /* * Hamlib CommRadio backend * idk, copyright and GPL here */ #include #include #include #include #include #include #include "misc.h" #include "commradio.h" #include "frame.h" /* * As far as I can tell, the commands and their structure are the same for the * CR-1a as they are for the CTX-10, but I don't have a CR1a to test with. * I'm putting these functions here in case they are reusable. */ int commradio_transaction(RIG *rig, const unsigned char *cmd, int cmd_len, unsigned char *data, int *data_len) { int ret = -RIG_EINTERNAL; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rs = STATE(rig); rs->transaction_active = 1; /* * Flush is needed until async mode is done. The CTX-10 sends frames every * time the VFO changes. */ rig_flush(rp); int frame_len; unsigned char frame[3 + 2 * (cmd_len + 2)]; size_t rx_len = CR_FRAMELENGTH; unsigned char rx[rx_len]; frame_len = frame_message(frame, cmd, cmd_len); ret = write_block(rp, frame, frame_len); if (ret < RIG_OK) { goto transaction_quit; } const char stopset[] = { CR_EOF }; ret = read_string(rp, rx, rx_len - 1, stopset, 1, 0, 1); if (ret < RIG_OK) { goto transaction_quit; } ret = commradio_unpack_frame(data, rx, ret); if (ret < RIG_OK) { goto transaction_quit; } *data_len = ret; //TODO: check for error response 0x11 transaction_quit: rs->transaction_active = 0; RETURNFUNC(ret); } int commradio_init(RIG *rig) { ENTERFUNC; // I can't think of anything that goes in here yet. RETURNFUNC(RIG_OK); } int commradio_cleanup(RIG *rig) { ENTERFUNC; // dealloc stuff if it gets added to _init RETURNFUNC(RIG_OK); } int commradio_rig_open(RIG *rig) { ENTERFUNC; // Possibly check if our serial port is configured right and we are not // doing bad things to the GPIO lines RETURNFUNC(RIG_OK); } int commradio_rig_close(RIG *rig) { ENTERFUNC; // i don't really know RETURNFUNC(RIG_OK); } /* * The CTX-10 sends VFO frequency updates when the knob is turned by the * operator, so this is really a good case for async events. Unfortunately * I can't find any good examples of how to do that, so instead just flush * and send a request... */ int commradio_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const unsigned char cmd[] = {0x32}; // Get frequency request unsigned char data[CR_FRAMELENGTH]; int data_len; int ret = -RIG_EINTERNAL; ENTERFUNC; ret = commradio_transaction(rig, cmd, 1, data, &data_len); if (data_len == 5 && (data[0] == 0x33 || data[0] == 0x34)) { *freq = (data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4]); ret = RIG_OK; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected response to 0x32\n", __func__); } RETURNFUNC(ret); } int commradio_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[CR_FRAMELENGTH]; int data_len; int ret = -RIG_EINTERNAL; ENTERFUNC; if (freq < 150000 || freq > 30000000) { RETURNFUNC(-RIG_EINVAL); } uint32_t int_freq = freq; rig_debug(RIG_DEBUG_VERBOSE, "%s: Got freq=%f, int_freq=%u\n", __func__, freq, int_freq); unsigned char cmd[] = { 0x30, // Set frequency request 0xFF & (int_freq >> 24), 0xFF & (int_freq >> 16), 0xFF & (int_freq >> 8), 0xFF & (int_freq) }; ret = commradio_transaction(rig, cmd, 5, data, &data_len); if (data_len == 5 && (data[0] == 0x31 || data[0] == 0x34)) { uint32_t new_freq = (data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4]); if (int_freq == new_freq) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ERJCTED); } } // CTX-10 returns 11 02 30 00 00 00 01 if we try to go out of its // general-coverage frequency range 150kHz - 30MHz. I'm not sure why Hamlib // even tries to do this, since its defined in the caps... else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected response to 0x30\n", __func__); ret = -RIG_ERJCTED; } RETURNFUNC(ret); } /* * Stubs. I'm not aware of a way to get or set the mode on the CTX-10. */ int commradio_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return (RIG_OK); } int commradio_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = RIG_MODE_NONE; return (RIG_OK); } /* * Stubs. The CTX-10 has only one VFO and split mode doesn't change how it * responds via the serial port. */ int commradio_set_vfo(RIG *rig, vfo_t vfo) { return (RIG_OK); } int commradio_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; return (RIG_OK); } DECLARE_INITRIG_BACKEND(commradio) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ctx10_caps); return (RIG_OK); } /* * For some reason, I can't get this to even link without this function. */ DECLARE_PROBERIG_BACKEND(commradio) { return (RIG_MODEL_NONE); } hamlib-4.6.5/rigs/commradio/frame.h0000664000175000017500000000073515056640443012642 /* * Hamlib CommRadio backend * idk, copyright and GPL here */ #ifndef _FRAME_H #define _FRAME_H #define CR_SOF 0xFE #define CR_EOF 0xFD #define CR_ESC 0xFC //TODO: Find out what the frame length actually is for IQ/spectrum data #define CR_FRAMELENGTH 256 int frame_message(unsigned char frame[], const unsigned char *data, int data_len); int commradio_unpack_frame(unsigned char msg[], const unsigned char *frame, int frame_len); #endif /* _FRAME_H */ hamlib-4.6.5/rigs/commradio/ctx10.c0000664000175000017500000000604515056640443012502 #include #include "hamlib/rig.h" #include "bandplan.h" #include "commradio.h" /* * The CTX-10 has only one VFO, but can be set into some sort of "split" mode * where the screen shows two different frequencies. * So far I have not figured out how to access these via serial. */ #define CTX10_VFO (RIG_VFO_A) #define CTX10_RX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM) #define CTX10_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB) struct rig_caps ctx10_caps = { RIG_MODEL(RIG_MODEL_CTX10), .model_name = "CTX-10", .mfg_name = "Commradio", .version = "20240809.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 3000000, .serial_rate_max = 3000000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = {}, // .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, // .preamp = { RIG_DBLST_END, }, // .attenuator = { RIG_DBLST_END, }, // .max_rit = Hz(0), // .max_xit = Hz(0), // .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = (RIG_OP_FROM_VFO | RIG_OP_TO_VFO), .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), CTX10_RX_MODES, -1, -1, CTX10_VFO, 0}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_80m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_60m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_40m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_30m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_20m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_17m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_15m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_12m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_10m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), }, .tuning_steps = { {CTX10_RX_MODES, 10}, RIG_TS_END, }, // .async_data_supported = 1, //TODO: Revisit this // .decode_event = commradio_decode_event, .rig_init = commradio_init, // .rig_cleanup = commradio_cleanup, // .rig_open = commradio_rig_open, // .rig_close = commradio_rig_close, .get_freq = commradio_get_freq, .set_freq = commradio_set_freq, .get_mode = commradio_get_mode, .set_mode = commradio_set_mode, .get_vfo = commradio_get_vfo, .set_vfo = commradio_set_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.5/rigs/commradio/frame.c0000664000175000017500000001214315056640443012631 /* * Hamlib CommRadio backend * idk, copyright and GPL here */ #include #include #include #include #include #include "frame.h" /* * Brute-force determined to be polynomial = 0x1021. * Seems to be the same CRC16 as Kermit. Initialized with 0. */ uint16_t crc16tab[] = { 0, 4489, 8978, 12955, 17956, 22445, 25910, 29887, 35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735, 4225, 264, 13203, 8730, 22181, 18220, 30135, 25662, 40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510, 8450, 12427, 528, 5017, 26406, 30383, 17460, 21949, 44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797, 12675, 8202, 4753, 792, 30631, 26158, 21685, 17724, 48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572, 16900, 21389, 24854, 28831, 1056, 5545, 10034, 14011, 52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859, 21125, 17164, 29079, 24606, 5281, 1320, 14259, 9786, 57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634, 25350, 29327, 16404, 20893, 9506, 13483, 1584, 6073, 61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921, 29575, 25102, 20629, 16668, 13731, 9258, 5809, 1848, 65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696, 33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623, 2112, 6601, 11090, 15067, 20068, 24557, 28022, 31999, 38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398, 6337, 2376, 15315, 10842, 24293, 20332, 32247, 27774, 42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685, 10562, 14539, 2640, 7129, 28518, 32495, 19572, 24061, 46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460, 14787, 10314, 6865, 2904, 32743, 28270, 23797, 19836, 50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747, 19012, 23501, 26966, 30943, 3168, 7657, 12146, 16123, 54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522, 23237, 19276, 31191, 26718, 7393, 3432, 16371, 11898, 59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809, 27462, 31439, 18516, 23005, 11618, 15595, 3696, 8185, 63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584, 31687, 27214, 22741, 18780, 15843, 11370, 7921, 3960 }; static uint16_t crc16byte(const unsigned char byte, uint16_t crc) { return crc16tab[(crc & 0xFF) ^ byte] ^ (crc >> 8); } static uint16_t crc16(const unsigned char *data, int data_len, uint16_t crc) { for (int i = 0; i < data_len; i++) { crc = crc16byte(data[i], crc); } return crc; } static int esc_append(unsigned char frame[], int idx, const unsigned char a) { switch (a) { case CR_SOF: case CR_EOF: case CR_ESC: frame[idx] = CR_ESC; frame[idx + 1] = a ^ 20; return idx + 2; break; default: frame[idx] = a; return idx + 1; } } /* * frame[] might be 2x the size of data and crc +3 bytes if it is just a long * string of 0xFC, 0xFD, or 0xFE for some insane reason. * */ int frame_message(unsigned char frame[], const unsigned char *data, const int data_len) { uint16_t crc = 0; frame[0] = CR_SOF; frame[1] = 0x21; /* Messages to the radio are always 0x21 */ crc = crc16byte(frame[1], crc); frame[2] = data[0]; crc = crc16byte(frame[2], crc); int frame_len = 3; for (int i = 1; i < data_len; i++) { crc = crc16byte(data[i], crc); frame_len = esc_append(frame, frame_len, data[i]); } frame_len = esc_append(frame, frame_len, crc >> 8); frame_len = esc_append(frame, frame_len, crc & 0xFF); frame[frame_len] = CR_EOF; frame_len++; return frame_len; } int commradio_unpack_frame(unsigned char msg[], const unsigned char *frame, const int frame_len) { if (frame_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s Got a frame that was too small (<5) to be valid\n", __func__); return -RIG_ETRUNC; } if ((frame[0] != CR_SOF) || (frame[frame_len - 1] != CR_EOF)) { rig_debug(RIG_DEBUG_ERR, "%s Tried to unpack a frame without start or end\n", __func__); return -RIG_EPROTO; } if (frame[1] != 0x11) { rig_debug(RIG_DEBUG_ERR, "%s Message address is not for host (0x11)\n", __func__); return -RIG_EPROTO; } int msg_len = 0; for (int i = 2; i < frame_len; i++) { switch (frame[i]) { case CR_SOF: return -RIG_EPROTO; break; case CR_EOF: i = frame_len; break; case CR_ESC: i++; msg[msg_len] = frame[i] ^ 20; msg_len++; break; default: msg[msg_len] = frame[i]; msg_len++; } } uint16_t msg_crc = (msg[msg_len - 2] << 8) | msg[msg_len - 1]; msg_len = msg_len - 2; uint16_t crc = crc16(msg, msg_len, crc16byte(frame[1], 0)); if (msg_crc != crc) { rig_debug(RIG_DEBUG_ERR, "%s CRC check failed. msg_crc=%x, crc=%x\n", __func__, msg_crc, crc); } return msg_len; } hamlib-4.6.5/rigs/commradio/commradio.h0000664000175000017500000000131215056640443013512 #ifndef _COMMRADIO_H #define _COMMRADIO_H int commradio_transaction(RIG *rig, const unsigned char *cmd, int cmd_len, unsigned char *data, int *data_len); int commradio_init(RIG *rig); int commradio_cleanup(RIG *rig); int commradio_rig_open(RIG *rig); int commradio_rig_close(RIG *rig); int commradio_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int commradio_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int commradio_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int commradio_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int commradio_set_vfo(RIG *rig, vfo_t vfo); int commradio_get_vfo(RIG *rig, vfo_t *vfo); extern struct rig_caps ctx10_caps; #endif /* _COMMRADIO_H */ hamlib-4.6.5/rigs/commradio/Android.mk0000664000175000017500000000042215056640443013301 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := commradio.c ctx10.c frame.c LOCAL_MODULE := commradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/rigs/commradio/Makefile.in0000664000175000017500000005333615056640452013451 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/commradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_commradio_la_LIBADD = am__objects_1 = commradio.lo frame.lo ctx10.lo am_libhamlib_commradio_la_OBJECTS = $(am__objects_1) libhamlib_commradio_la_OBJECTS = $(am_libhamlib_commradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/commradio.Plo ./$(DEPDIR)/ctx10.Plo \ ./$(DEPDIR)/frame.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_commradio_la_SOURCES) DIST_SOURCES = $(libhamlib_commradio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ COMMRADIOSRC = commradio.c commradio.h frame.c frame.h ctx10.c noinst_LTLIBRARIES = libhamlib-commradio.la libhamlib_commradio_la_SOURCES = $(COMMRADIOSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/commradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/commradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-commradio.la: $(libhamlib_commradio_la_OBJECTS) $(libhamlib_commradio_la_DEPENDENCIES) $(EXTRA_libhamlib_commradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_commradio_la_OBJECTS) $(libhamlib_commradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctx10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/commradio.Plo -rm -f ./$(DEPDIR)/ctx10.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/commradio.Plo -rm -f ./$(DEPDIR)/ctx10.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/rigs/commradio/Makefile.am0000664000175000017500000000026615056640443013432 COMMRADIOSRC = commradio.c commradio.h frame.c frame.h ctx10.c noinst_LTLIBRARIES = libhamlib-commradio.la libhamlib_commradio_la_SOURCES = $(COMMRADIOSRC) EXTRA_DIST = Android.mk hamlib-4.6.5/README.multicast0000664000175000017500000001634715056640442011352 Planned for version 4.6 -- comments/suggestions about this are more than welcome Example of multicast packet as of 2023-10-20 =================================================================== { "app": "Hamlib", "version": "4.6~git 2023-10-20T16:52:59Z SHA=d87671", "seq": 183, "time": "2023-10-20T20:13:53.139869-0000", "crc": 0, "rig": { "id": "FLRig:127.0.0.1:12345:30508", "status": "OK", "errorMsg": "", "name": "FLRig", "split": false, "splitVfo": "VFOA", "satMode": false, "modelist": "AM CW USB LSB FM CWR PKTLSB PKTUSB " }, "vfos": [ { "name": "VFOA", "freq": 14074270, "mode": "PKTUSB", "width": 3, "ptt": false, "rx": true, "tx": true }, { "name": "VFOB", "freq": 14074500, "mode": "", "width": 0, "ptt": false, "rx": false, "tx": false } ], "spectra": [ { "id": 0, "name": "?", "type": "FIXED", "minLevel": 0, "maxLevel": 0, "minStrength": 0, "maxStrength": 0, "centerFreq": 0, "span": 0, "lowFreq": 0, "highFreq": 0, "length": 0, "data": "" } ] } =========================================================== Multicast UDP broadcast containing rig snapshot data Bidirectional rig control and status Choice of token pairs or JSON All packets will be tagged with ID=[unique name] -- so multiple rigs can broadcast/rx on the same port Will eventually be able to set freq, mode, width, ptt, satmode, and split to start since those are common to many apps. More functions will be added as time goes on. Broadcast packet contents to be based on get_rig_info output Can be multiple VFO lines Parsers should allow for unknown tags that may be added in the future Rig command: \get_rig_info VFO=Main Freq=145000000 Mode=None Width=0 RX=1 TX=1 VFO=VFOB Freq=145000000 Mode=FM Width=15000 RX=0 TX=0 Split=0 SatMode=0 PTT=1 (1=On, 0=Off) Rig=Dummy (name of connected rig) App=Hamlib (name of application providing the packet) Version=20210429 1.0.0 (version YYYYMMDD) Status=OK (possible values OK, Offline, Error) ErrorMsg=msg text (pipe delimited multi-line error message) CRC=0xf49f4708 (this is just an example CRC and not accurate for this example) JSON data snapshot format for UDP packets: { "app": "Hamlib", "__comment_version__": "protocol version YYYYMMDD x.x.x, 1.0.0 will be used when this is implemented", "version": "20210521 0.0.0", "__comment_seq__": "Seq is 1-up sequence number 32-bit -- wraps around to 1 from 2^32-1", "seq": 1, "__comment_crc__": "32-bit CRC of the entire JSON record replacing the CRC value with 0", "crc": 0, "rig": { "__comment1__": "customizable rig identification -- will allow multiple rigs to be on the multicast", "id": { "model":"IC-7300", "endpoint":"com1", "process":"53535", } "name": "IC-7300", "ptt" : false, "split": true, "splitVfo": "VFOB", "satMode": false, "status": "OK"; "errorMsg": "OK", "modes":[ "AM", "CW", "USB" ] }, "vfos": [ { "name": "VFOA", "freq": 14074000, "mode": "USB", "width": 5000, "rx": true, "tx": false }, { "name": "VFOB", "freq": 14076000, "mode": "USB", "width": 5000, "rx": false, "tx": true }], "__comment_spectra__": "Rigs that have spectrum output may include this array data", "spectra": [ { "__comment_id__": "A numeric ID for the spectrum data stream. These IDs are exposed in rig caps.", "id": 0, "__comment_name__": "Name identifying the spectrum data stream and matching the ID. The name corresponds to VFOs.", "name": "Main", "__comment_spectrum_length__": "Length of spectrum FFT data in bytes", "length": 475, "__comment_spectrum_data__": "Spectrum FFT data in 2-char hexadecimal byte format, so that length of the string is 2 * length", "data": "00AAFF75BD2AAA...", "type": "FIXED|CENTER", "minLevel": 0, "maxLevel": 140, "minStrength": -100, "maxStrength": 0, "__comment_spectrum_frequencies__": "The following fields will be calculated automatically by Hamlib based on the spectrum information exposed by the rig", "centerFreq": 14267000, "span": 25000, "lowFreq": 14000000, "highFreq": 14250000 }, { "__comment_id__": "A numeric ID for the spectrum data stream. These IDs are exposed in rig caps.", "id": 1, "__comment_name__": "Name identifying the spectrum data stream and matching the ID. The name corresponds to VFOs.", "name": "Sub", "__comment_spectrum_length__": "Length of spectrum FFT data in bytes", "length": 475, "__comment_spectrum_data__": "Spectrum FFT data in 2-char hexadecimal byte format, so that length of the string is 2 * length", "data": "00AAFF75BD2AAA...", "type": "FIXED|CENTER", "minLevel": 0, "maxLevel": 140, "minStrength": -100, "maxStrength": 0, "__comment_spectrum_frequencies__": "The following fields will be calculated automatically by Hamlib based on the spectrum information exposed by the rig", "centerFreq": 14267000, "span": 25000, "lowFreq": 14000000, "highFreq": 14250000 }], "lastCommand": { "id": "MyApp 123", "command": "set_freq VFOA 14074000", "status": "OK" }, } An example UDP packet containing spectrum data from IC-7300 (crc, id and lastCommand not implemented yet): { "app": "Hamlib", "version": "4.5~git Sun Dec 19 20:56:24 2021 +0000 SHA=0fe723", "seq": 109, "crc": 0, "rig": { "id": "rig_id", "status": "OK", "errorMsg": "", "name": "IC-7300", "split": false, "splitVfo": "VFOA", "satMode": false }, "vfos": [ { "name": "VFOA", "freq": 3718000, "mode": "LSB", "width": 3000, "ptt": false, "rx": true, "tx": true }, { "name": "VFOB", "freq": 3698750, "mode": "", "width": 0, "ptt": false, "rx": false, "tx": false } ], "spectra": [ { "id": 0, "name": "Main", "type": "CENTER", "minLevel": 0, "maxLevel": 160, "minStrength": -80, "maxStrength": 0, "centerFreq": 3718000, "span": 50000, "lowFreq": 3693000, "highFreq": 3743000, "length": 475, "data": "121514000000000000000811070000060F12090000000000000908000A0B000000000A130D000A04100C0C17141D1B20353A2D404537341D06110608070200000D0D02000000000B0A000709000005050504000D0B00040400000000070F0D081F29240E262E2C21222E3D3E343C383235393E505361624E4445252A2220191A2B2D28222217121619130D0C1513130F060100000509090200090B03000000000003000000000001000A0802000500000000010C0907000100000000050B0B000100000600000808000306000806000000000C030000000000070000000000020E000A000001000C0B0008000B080700020709000400070100000000000000000A07000A0905000000000002000000000B05010307050506080B050C0F0E100702131528230A0B1E13160B10000000050812231B001422251209181B1A201E0B1713050C020C0D001B1A2209000100000C050400040B0B110D07000009192010040700000910020D0C1928302526282D353F3B2E1F191C25281F0D0A0B1518140A0603030907030100000300060B0000060000000403000400000811221B0A131200040E070000110F0B150005141515211B1F0C0000040500000000000400000000000000000808070D0B00000000000000000000000000000000" } ] } hamlib-4.6.5/simulators/0000775000175000017500000000000015056640475010743 5hamlib-4.6.5/simulators/simxiegux108g.c0000664000175000017500000002470515056640443013454 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_CW; mode_t modeB = RIG_MODE_USB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int keyspd = 20; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } } //printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; write(fd, frame, 11); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xb0: freq = freqA; freqA = freqB; freqB = freq; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; #if 0 case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("n=write 8 bytes\n"); dump_hex(frame, 8); write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; write(fd, frame, 7); break; #endif case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; write(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; write(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic7700.c0000664000175000017500000004520415056640443012451 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; int keyspd = 85; // 85=20WPM int band = 8; int filter = 1; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 1; pbwidth_t widthB = 2; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyertype = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; printf("i=%d, c=0x%02x\n", i, c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { dump_hex(frame, 11); n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("cmd=0x14\n"); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x01: // band if (frame[6] == 0xfd) { frame[6] = band; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { band = frame[6]; printf("Band select=%d\n", band); frame[4] = 0xfb; frame[5] = 0xfe; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x05: { int item = frame[6] * 256 + frame[7]; printf("0x05 *************************** item=%04x\n", item); if (frame[8] != 0xfd) // then we're setting it { switch (item) { case 164: keyertype = frame[8]; break; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else // we're reading it { switch (item) case 164: frame[8] = keyertype; frame[9] = 0xfb; break; } n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #if 0 // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = filter; frame[9] = 0xfd; n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; filter = frame[9]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic910.c0000664000175000017500000003641015056640443012364 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #define BUFSIZE 256 //#define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup double freqA = 145123456; double freqB = 1407450; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 1; int filterB = 2; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 25; int datamode = 0; int filter = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } frame[2] = 0xe0; frame[3] = 0x60; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); int freq_len = 5; if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { if (freqA > 5.85e9) { freq_len = 6; } printf("get_freqA len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqA, freq_len * 2); } else { if (freqB > 5.85e9) { freq_len = 6; } printf("get_freqB len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqB, freq_len * 2); } frame[5 + freq_len] = 0xfd; if (powerstat) { WRITE(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: freqB = freqA; modeB = modeA; break; case 0xb0: current_vfo = RIG_VFO_SUB; exit(1); break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; WRITE(fd, frame, 7); } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; WRITE(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; WRITE(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x06: // datamode if (frame[5] == 0xfd) { frame[6] = datamode; frame[7] = filter; frame[8] = 0xfd; WRITE(fd, frame, 9); } else { datamode = frame[6]; filter = frame[7]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { freq_len = 5; if (frame[5] == 0x00) { if (freqA > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqA, freq_len * 2); printf("X25 get_freqA=%.0f\n", freqA); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } else { if (freqB > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqB, freq_len * 2); printf("X25 get_freqB=%.0f\n", freqB); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } //unsigned char frame2[12]; #if 0 frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0x00; frame2[11] = 0xfd; WRITE(fd, frame2, 12); #endif } else { freq_len = 5; if (frame[11] != 0xfd) { freq_len = 6; } freq = from_bcd(&frame[6], freq_len * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); #if 0 // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; WRITE(fd, frame, 11); #endif } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simts950.c0000664000175000017500000002405115056640443012421 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum1 = 7; int filternum2 = 8; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 1, modeB = 2; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM5100000;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); // pbuf = "IF000503130001000+0000000000030000000;" sprintf(ifbuf, "IF%011d1000+0000002000000000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "IS", 2) == 0) { continue; } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "FW", 2) == 0) { continue; } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); continue; } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); continue; } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA + '0' : modeB + '0'); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; if (buf[2] == '0') { modeA = tmpmode - '0'; } else { modeB = tmpmode - '0'; } printf("modeA=%c, modeB=%c\n", modeA, modeB); continue; } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d%03d;", filternum1, filternum2); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%3d%3d", &filternum1, &filternum2); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } continue; } else if (strcmp(buf, "RX;") == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simtmd710.c0000664000175000017500000000605215056640443012552 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == 0x0d) { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 0; // , modeB = 0; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } if (strncmp(buf, "BC", 2) == 0) { SNPRINTF(buf, sizeof(buf), "BC %d %d%c", vfo, vfo_tx, 0x0d); printf("R:%s\n", buf); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FO", 2) == 0) { if (buf[3] == '0') { SNPRINTF(buf, sizeof(buf), "FO 0 %d%c", freqA, 0x0d); } else { SNPRINTF(buf, sizeof(buf), "FO 1 %d%c", freqB, 0x0d); } printf("R:%s\n", buf); write(fd, buf, strlen(buf)); continue; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simts990.c0000664000175000017500000004476215056640443012440 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; int freqA = 14074000; int freqB = 14074500; int filternum1 = 7; int filternum2 = 8; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int operatingband; int split; int keyspd = 20; int rg0 = 50; int rg1 = 50; int sq0 = 0; int sq1 = 0; int mg = 0; int nt0 = 0; int nt1 = 0; int nr0 = 0; int nr1 = 0; int gc0 = 0; int gc1 = 0; int mv0 = 0; int mv1 = 0; int pa0 = 0; int pa1 = 0; int ra0 = 0; int ra1 = 0; int rl0 = 0; int rl1 = 0; int ml = 0; int ag0 = 0; int ag1 = 0; int sl0 = 0; int sl1 = 0; int sh0 = 0; int sh1 = 0; int mo0 = 0; int mo1 = 0; int pc = 50; #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); int retval; while ((retval = read(fd, &c, 1)) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (retval != 0) { perror("read failed:"); close(fd); fd = openPort(""); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); char modeA = '1', modeB = '2'; while (1) { hl_usleep(10); buf[0] = 0; //if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } getmyline(fd, buf); // else { return 0; } if (strncmp(buf, "AC000;", 3) == 0) { continue; } else if (strncmp(buf, "RMA2", 3) == 0) { pbuf = "RM20020;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM51;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RM5100001;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; hl_usleep(mysleep * 1000); // pbuf = "IF000503130001000+0000000000030000000;" sprintf(ifbuf, "IF%011d1000+0000002000000000000;", freqA); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "IS", 2) == 0) { continue; } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "FW", 2) == 0) { continue; } else if (strcmp(buf, "ID;") == 0) { hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqA); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqB); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqA); continue; } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqB); continue; } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011d%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA : modeB); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; modeA = tmpmode; printf("modeA=%c, modeB=%c\n", modeA, modeB); continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d%03d;", filternum1, filternum2); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%3d%3d", &filternum1, &filternum2); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strcmp(buf, "RX;") == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } continue; } else if (strncmp(buf, "CB;", 3) == 0) { sprintf(buf, "CB%d;", operatingband); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "CB", 2) == 0) { sscanf(buf, "CB%d", &operatingband); } else if (strncmp(buf, "TB;", 3) == 0) { sprintf(buf, "TB%d;", split); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TB", 2) == 0) { sscanf(buf, "TB%d", &split); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "OM0;", 4) == 0) { sprintf(buf, "OM0%c;", modeA); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "OM0", 3) == 0) { modeA = buf[3]; } else if (strncmp(buf, "OM1;", 4) == 0) { sprintf(buf, "OM1%c;", modeB); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "OM1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "RM;") == 0) { sprintf(buf, "RM2%04d;", 10); write(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG0;") == 0) { sprintf(buf, "RG0%03d;", rg0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG0", 3) == 0) { sscanf(buf, "RG0%d", &rg0); } else if (strcmp(buf, "RG1;") == 0) { sprintf(buf, "RG1%03d;", rg1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG1", 3) == 0) { sscanf(buf, "RG0%d", &rg1); } else if (strcmp(buf, "SQ0;") == 0) { sprintf(buf, "SQ0%03d;", sq0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SQ0", 3) == 0) { sscanf(buf, "SQ0%d", &sq0); } else if (strcmp(buf, "SQ1;") == 0) { sprintf(buf, "SQ1%03d;", sq1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SQ1", 3) == 0) { sscanf(buf, "SQ1%d", &sq1); } else if (strcmp(buf, "MG;") == 0) { sprintf(buf, "MG%03d;", mg); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mg); } else if (strcmp(buf, "ML;") == 0) { sprintf(buf, "ML%03d;", ml); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "ML", 2) == 0) { sscanf(buf, "ML%d", &ml); } else if (strcmp(buf, "NT0;") == 0) { sprintf(buf, "NT0%03d;", nt0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NT0", 3) == 0) { sscanf(buf, "NT0%d", &nt0); } else if (strcmp(buf, "NT1;") == 0) { sprintf(buf, "NT1%03d;", nt1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NT1", 3) == 0) { sscanf(buf, "NT1%d", &nt1); } else if (strcmp(buf, "NR0;") == 0) { sprintf(buf, "NR0%03d;", nr0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr0); } else if (strcmp(buf, "NR1;") == 0) { sprintf(buf, "NR1%03d;", nr1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NR1", 3) == 0) { sscanf(buf, "NR1%d", &nr1); } else if (strcmp(buf, "GC0;") == 0) { sprintf(buf, "GC0%03d;", gc0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "GC0", 3) == 0) { sscanf(buf, "GC0%d", &gc0); } else if (strcmp(buf, "GC1;") == 0) { sprintf(buf, "GC1%03d;", gc1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "GC1", 3) == 0) { sscanf(buf, "GC1%d", &gc1); } else if (strcmp(buf, "MV0;") == 0) { sprintf(buf, "MV0%03d;", mv0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MV0", 3) == 0) { sscanf(buf, "MV0%d", &mv0); } else if (strcmp(buf, "MV1;") == 0) { sprintf(buf, "MV1%03d;", mv1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MV1", 3) == 0) { sscanf(buf, "MV1%d", &mv1); } else if (strcmp(buf, "PA0;") == 0) { sprintf(buf, "PA0%03d;", pa0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA0", 3) == 0) { sscanf(buf, "PA0%d", &pa0); } else if (strcmp(buf, "PA1;") == 0) { sprintf(buf, "PA1%03d;", pa1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA1", 3) == 0) { sscanf(buf, "PA1%d", &pa1); } else if (strcmp(buf, "RA0;") == 0) { sprintf(buf, "RA0%03d;", ra0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA0", 3) == 0) { sscanf(buf, "RA0%d", &ra0); } else if (strcmp(buf, "RA1;") == 0) { sprintf(buf, "RA1%03d;", ra1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA1", 3) == 0) { sscanf(buf, "RA1%d", &ra1); } else if (strcmp(buf, "RL10;") == 0) { sprintf(buf, "RL10%02d;", rl0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RL10", 3) == 0) { sscanf(buf, "RL10%d", &rl0); } else if (strcmp(buf, "RL11;") == 0) { sprintf(buf, "RL11%02d;", rl1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RL1", 3) == 0) { sscanf(buf, "RL1%d", &rl1); } else if (strcmp(buf, "AG0;") == 0) { sprintf(buf, "AG0%03d;", ag0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG0", 3) == 0) { sscanf(buf, "AG0%d", &ag0); } else if (strcmp(buf, "AG1;") == 0) { sprintf(buf, "AG1%03d;", ag1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG1", 3) == 0) { sscanf(buf, "AG1%d", &ag1); } else if (strcmp(buf, "SL0;") == 0) { sprintf(buf, "SL0%03d;", sl0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL0", 3) == 0) { sscanf(buf, "SL0%d", &sl0); } else if (strcmp(buf, "SL1;") == 0) { sprintf(buf, "SL1%03d;", sl1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL1", 3) == 0) { sscanf(buf, "SL1%d", &sl1); } else if (strcmp(buf, "SH0;") == 0) { sprintf(buf, "SH0%03d;", sh0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh0); } else if (strcmp(buf, "SH1;") == 0) { sprintf(buf, "SH1%03d;", sh1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH1", 3) == 0) { sscanf(buf, "SH1%d", &sh1); } else if (strcmp(buf, "MO0;") == 0) { sprintf(buf, "MO0%d;", mo0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MO0", 3) == 0) { sscanf(buf, "MO0%d", &mo0); } else if (strcmp(buf, "MO1;") == 0) { sprintf(buf, "MO1%d;", mo1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MO1", 3) == 0) { sscanf(buf, "MO1%d", &mo1); } else if (strncmp(buf, "CK0", 3) == 0) { continue; // setting clock no action } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simft817.c0000664000175000017500000000656115056640443012414 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 int vfo = 0; // 0=A, !0=B float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[4]) { case 0x00: printf("LOCK ON\n"); break; case 0x80: printf("LOCK OFF\n"); break; case 0x08: printf("PTT ON\n"); break; case 0x88: printf("PTT OFF\n"); break; case 0x07: printf("MODE %0xx\n", buf[0]); if (vfo == 0) { modeA = buf[0]; } else { modeB = buf[0]; } break; case 0x05: printf("CLAR ON\n"); break; case 0x85: printf("CLAR OFF\n"); break; case 0xF5: printf("FREQ\n"); break; case 0x81: vfo = !vfo; printf("VFO TOGGLE, %s active\n", vfo == 0 ? "VFOA" : "VFOB"); break; case 0x02: printf("SPLIT ON\n"); break; case 0x82: printf("SPLIT OFF\n"); break; case 0x09: printf("REPEATER SHIFT\n"); break; case 0xF9: printf("REPEATER FREQ\n"); break; case 0x0A: printf("CTCSS/DCS MODE\n"); break; case 0x0B: printf("CTCSS TONE\n"); break; case 0x0C: printf("DCS CODE\n"); break; case 0xE7: printf("READ RX STATUS\n"); break; case 0xF7: printf("READ TX STATUS\n"); break; case 0x03: printf("READ RX STATUS\n"); buf[0] = 0x01; buf[1] = 0x40; buf[2] = 0x74; buf[3] = 0x00; buf[4] = 0x03; write(fd, buf, 5); break; case 0xbb: buf[0] = 80; buf[1] = 0; printf("READ EPROM\n"); write(fd, buf, 2); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.5/simulators/simftdx101.c0000664000175000017500000002153315056640443012726 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int modeA = 0xc; int modeB = 0xc; int vs = 0; int tx = 0; int ai = 0; int sh = 19; int na = 0; int ex039 = 0; int keyspd = 20; int split = 0; int power = 50; int rport_gain_ssb = 50; int rport_gain_am = 50; int rport_gain_fm = 50; int rport_gain_psk = 50; int syncvfo = 0; int ant = 1; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AN0%d;", ant); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("AN"); } } else if (strncmp(buf, "AN", 2) == 0) { sscanf(buf,"AN%d",&ant); printf("Ant set to %d\n", ant); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "EX032;") == 0) { ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%X;", modeA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 3) == 0) { sscanf(buf, "MD0%d", &modeA); } else if (strcmp(buf, "MD1;") == 0) { SNPRINTF(buf, sizeof(buf), "MD1%X;", modeB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD1", 3) == 0) { sscanf(buf, "MD1%d", &modeB); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "PC;") == 0) { SNPRINTF(buf, sizeof(buf), "PC%d;", power); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &power); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "ST;", 3) == 0) { sprintf(buf, "ST%d;", split); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "ST", 2) == 0) { sscanf(buf, "ST%d", &split); } else if (strcmp(buf, "EX010415;") == 0) { sprintf(buf, "EX010415%03d;", rport_gain_psk); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX010415", 8) == 0) { printf("Here#1"); sscanf(buf, "EX010415%d", &rport_gain_psk); } else if (strcmp(buf, "SY;") == 0) { sprintf(buf, "SY%d;", syncvfo); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SY", 2) == 0) { sscanf(buf, "SY%d", &syncvfo); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simftdx5000.c0000664000175000017500000001671015056640443013012 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md0 = 1; int md1 = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; int ex103 = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { int tmp; sscanf(buf, "FT%d", &tmp); if (tmp == 2) { ft = 0; } else if (tmp == 3) { ft = 1; } else { printf("%s expected FT2; or FT3;\n", buf); } } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 2) == 0) { sscanf(buf, "MD0%d", &md0); } else if (strcmp(buf, "MD1;") == 0) { SNPRINTF(buf, sizeof(buf), "MD1%d;", md1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD1", 2) == 0) { sscanf(buf, "MD1%d", &md1); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "EX103;") == 0) { SNPRINTF(buf, sizeof(buf), "EX103%d;", ex103); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX103", 3) == 0) { sscanf(buf, "EX103%d", &ex103); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simft990.c0000664000175000017500000000625615056640443012417 // can run this using rigctl/rigctld and socat pty devices // emulates 1.2 ROM FT990 which can only read 1492 bytes #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; void load_dat(const char *filename, unsigned char buf[1492]) { FILE *fp = fopen(filename, "r"); char line[4096]; int n = 0; while (fgets(line, sizeof(line), fp)) { char *s = strdup(line); unsigned int val; char *p = strtok(line, " \r\n"); do { sscanf(p, "%x", &val); buf[n++] = val; } while (p = strtok(NULL, " \r\n")); strtok(s, "\r\n"); //printf("n=%d, %s\n",n,s); free(s); } fclose(fp); printf("%d bytes read\n", n); } static unsigned char alldata[1492]; int getmyline(int fd, char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); #if 1 while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } #else n = read(fd, buf, 5); #endif printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; int fd = openPort(argv[1]); load_dat("simft990.dat", alldata); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { continue; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } if (buf[4] == 0x10) { write(fd, alldata, 1492); } } return 0; } hamlib-4.6.5/simulators/simft818.c0000664000175000017500000002111315056640443012403 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; vfo_t curr_vfo = RIG_VFO_A; char modeA = '1'; char modeB = '1'; int width = 0; int ptt; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX3000DM = 462, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char resp[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { buf[0] = 0; if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } //else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "FA;") == 0) { //SNPRINTF(resp, sizeof(resp), "FA%010.0f;", freqA); SNPRINTF(resp, sizeof(resp), "FA%08.0f;", freqA); freqA += 10; n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { //SNPRINTF(resp, sizeof(resp), "FB%0010.0f;", freqB); SNPRINTF(resp, sizeof(resp), "FB%08.0f;", freqB); n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF00107041000+000000200000;"; pbuf = "IF00010138698 +00000000002000000 ;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000DM; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "AB;") == 0) { freqB = freqA; modeB = modeA; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS") == 0 && strlen(buf) > 3) { curr_vfo = buf[3] == '1' ? RIG_VFO_B : RIG_VFO_A; hl_usleep(50 * 1000); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = strdup("VS0;"); if (curr_vfo == RIG_VFO_B || curr_vfo == RIG_VFO_SUB) { pbuf[2] = '1'; } n = write(fd, pbuf, strlen(pbuf)); printf("%s\n", pbuf); free(pbuf); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", resp, tx_vfo); n = write(fd, resp, strlen(resp)); printf(" FT response#2=%s\n", resp); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD0%c;", modeA); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD1%c;", modeB); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "SM0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "SM0111;"); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("SM"); } } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "TX%d;", ptt); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { hl_usleep(50 * 1000); ptt = buf[2] == '0' ? 0 : 1; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%02d;", width); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); printf("%s n=%d\n", buf, n); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA00;"); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); printf("%s n=%d\n", buf, n); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } if (n == 0) { fprintf(stderr, "Write error? n==0\n"); } } return 0; } hamlib-4.6.5/simulators/simic9100.c0000664000175000017500000003330515056640443012444 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include #include #include "sim.h" #define BUFSIZE 256 //#define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int subband = 1; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { WRITE(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; printf("+++++++++++++++ SETTING VFO +++++++++++++++++\n"); dump_hex(frame, 6); WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; WRITE(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; case 0x59: frame[6] = subband; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; WRITE(fd, frame2, 11); WRITE(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; WRITE(fd, frame, 11); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simft450.c0000664000175000017500000003624415056640443012406 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int ks = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; int vs = 0; int vx = 0; int pa = 0; int ra = 0; int ag = 0; int pc = 100; int is = 0; int bp_on = 0; int bp_pos = 0; int rl = 0; int nb = 0; int nr = 0; int tx = 0; int mg = 0; int rg = 100; int vg = 0; int kr = 0; int bi = 0; int gt = 0; int ex016 = 0; int ex020 = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { // printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM4;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM4"); } } else if (strcmp(buf, "RM5;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM6;") == 0) { hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; } else if (strcmp(buf, "MD0;") == 0) { printf("MD=%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VS"); } } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "KR;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "KR%d;", kr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("KR"); } } else if (strncmp(buf, "KR", 2) == 0) { sscanf(buf, "KR%d", &kr); } else if (strcmp(buf, "BI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BI%d;", bi); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BI"); } } else if (strncmp(buf, "BI", 2) == 0) { sscanf(buf, "BI%d", &bi); } else if (strcmp(buf, "VX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VX%d;", vx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VX"); } } else if (strncmp(buf, "VX", 2) == 0) { sscanf(buf, "VX%d", &vx); } else if (strcmp(buf, "PA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PA%d;", pa); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PA"); } } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &vs); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RA%d;", ra); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RA"); } } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AG%d;", ag); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("AG"); } } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "PC;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PC"); } } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "VG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VG%03d;", vg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VG"); } } else if (strncmp(buf, "VG", 2) == 0) { sscanf(buf, "VG%d", &vg); } else if (strcmp(buf, "RG0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RG0%03d;", rg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RG"); } } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG0%d", &rg); } else if (strcmp(buf, "GT0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "GT0%0d;", gt); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("GT"); } } else if (strncmp(buf, "GT", 2) == 0) { sscanf(buf, "GT0%d", >); } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "IS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "IS+%04d;", is); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("IS"); } } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strcmp(buf, "RL0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RL0%d;", rl); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RL"); } } else if (strncmp(buf, "RL", 2) == 0) { sscanf(buf, "RL0%02d", &rl); } else if (strcmp(buf, "BP00;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_on); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP00", 4) == 0) { sscanf(buf, "BP00%d", &bp_on); } else if (strcmp(buf, "BP01;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_pos); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP01", 4) == 0) { sscanf(buf, "BP01%d", &bp_pos); } else if (strcmp(buf, "NB0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NB0%d;", nb); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NB"); } } else if (strncmp(buf, "NB0", 3) == 0) { sscanf(buf, "NB0%d", &nb); } else if (strcmp(buf, "NR0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NR0%d;", nr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NR"); } } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "EX016;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX016%04d;", ex016); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strcmp(buf, "EX020;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX020%04d;", ex020); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strncmp(buf, "EX020", 5) == 0) { sscanf(buf, "EX020%d\n", &ex020); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", ks); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &ks); } else if (strncmp(buf, "MG;", 3) == 0) { sprintf(buf, "MG%03d;", mg); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%03d", &mg); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simic7851.c0000664000175000017500000005371515056640443012466 // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = 1; mode_t modeB = 0; int datamodeA = 1; int datamodeB = 1; int filterA = 3; int filterB = 2; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int datamode = 0; int keyspd = 130; // 130=20WPM int attenuator; int notch = 0; int speechcompressor = 0; int vox = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c = 0xff; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { // printf("Read: "); // dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } //dumphex(frame, len); if (len == 0) { printf("%s: len==0\n", __func__); return; } if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int echo = 0; // cppcheck-suppress knownConditionTrueFalse if (echo) { n = write(fd, frame, len); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } frame[3] = frame[2]; frame[2] = 0xe0; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { //printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { //printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { //printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { //printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); //printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: //printf("******* [5] = 0x07\n"); switch (frame[5]) { case 0xd2: //printf("******* [6] = 0x07\n"); switch (frame[6]) { case 0x00: current_vfo = RIG_VFO_MAIN; break; case 0x01: current_vfo = RIG_VFO_SUB; break; } } //printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; //printf("0x07 0xd2 answer: \n"); dump_hex(frame, 6); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { //printf("get split %d\n", 1); frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { //printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x11: if (frame[5] != 0xfd) { attenuator = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { frame[5] = attenuator; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { //printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { //printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; //printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: //printf("******** 0x14 received frame[5]=0x%02x\n", frame[5]); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { //printf("DEBUG#1\n"); frame[4] = 0xfb; frame[5] = 0xfd; dumphex(frame, 6); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } //printf("ACK x14 x08\n"); } else { //printf("DEBUG#2\n"); to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; frame[9] = 0xfd; dumphex(frame, 10); n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } //printf("SEND x14 x08\n"); } break; case 0x0a: //printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: if (frame[6] != 0xfd) { keyspd = frame[5]; } else { frame[6] = keyspd; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; default: //printf("*********** NAK\n"); frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: //printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; default: frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x44: if (frame[6] == 0xfe) { frame[6] = speechcompressor; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { speechcompressor = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x46: if (frame[6] == 0xfe) { frame[6] = vox; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { vox = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x48: if (frame[6] == 0xfe) { frame[6] = notch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { notch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x04: // AGC TIME //printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { //printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); //printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); //printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 // async frame unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); //printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x26: for (int i = 0; i < 7; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { printf("GET MODE XXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); // fe fe e0 8e 26 00 01 00 01 fd // 0 1 2 3 4 5 6 7 8 // AB MD DM FF frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; printf("x26 response: "); dumphex(frame, 10); n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("SET MODE YYYYYYYYYYYYYYYYYYYYYYYYYYYYY\n"); for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; filterA = frame[8]; } else { modeB = frame[6]; datamodeB = frame[7]; filterB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } //rigStatus(); } return 0; } hamlib-4.6.5/simulators/simtmd700.c0000664000175000017500000000767015056640443012560 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 double freqA = 147000000; double freqB = 148000000; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '0'; char modeB = '0'; int band = 0; int control = 1; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { if (c == 0x0d) { return strlen(buf); } buf[i++] = c; } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "ID") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "ID TM-D700\r"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "BC") == 0) { SNPRINTF(buf, sizeof(buf), "BC %d,%d\r", band, control); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "BC ", 3) == 0) { sscanf(buf, "BC %d,%d", &band, &control); SNPRINTF(buf, sizeof(buf), "BC %d,%d\r", band, control); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VMC ", 4) == 0) { SNPRINTF(buf, sizeof(buf), "VMC 0,0\r"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { SNPRINTF(buf, sizeof(buf), "AI 0\r"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FQ", 2) == 0) { SNPRINTF(buf, sizeof(buf), "FQ %011.0f,0\r", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FQ ", 3) == 0) { sscanf(buf, "FQ %lf,0", &freqA); SNPRINTF(buf, sizeof(buf), "FQ %011.0f,0\r", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { SNPRINTF(buf, sizeof(buf), "MD 0\r"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simic7610.c0000664000175000017500000005041415056640443012450 // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int datamode = 0; int keyspd = 130; // 130=20WPM int ipp = 0; int tx_inhibit = 0; int dpp = 0; int dualwatch = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0xd0: current_vfo = RIG_VFO_A; break; case 0xd1: current_vfo = RIG_VFO_B; break; case 0xc2: if (frame[6] == 0xfd) { frame[6] = dualwatch; frame[7] = 0xfd; n = write(fd,frame,8); } else { dualwatch = frame[6]; frame[4]=0xfb; frame[5]=0xfd; n = write(fd,frame,6); } } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("******** 0x14 received frame[5]=0x%02x\n", frame[5]); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: if (frame[6] != 0xfd) { keyspd = frame[5]; } else { frame[6] = keyspd; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; default: printf("*********** NAK\n"); frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; default: frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfd) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x65: if (frame[6] == 0xfd) { ipp = frame[6]; } else { frame[6] = ipp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x66: if (frame[6] == 0xfd) { tx_inhibit = frame[6]; } else { frame[6] = tx_inhibit; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x67: if (frame[6] == 0xfd) { dpp = frame[6]; } else { frame[6] = dpp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 // async frame unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); printf("#1 ========================================\n"); if (len <= 0) { printf("#2 ========================================"); close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(100 * 1000); } printf("#3 ========================================"); rigStatus(); printf("#3 ========================================"); } return 0; } hamlib-4.6.5/simulators/simqrplabs.c0000664000175000017500000002415015056640443013201 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int tomode = 0; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 1, modeB = 2; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM5100000;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; // from QMX 1_09 firmware "IF00007074000 +0.0000000002000000 ;" sprintf(ifbuf, "IF%011d +0.0000000002000000 ;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "IS", 2) == 0) { continue; } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "FW", 2) == 0) { continue; } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "ID%03d;", 10); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AI0;"; write(fd, pbuf, strlen(pbuf)); } } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); continue; } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); continue; } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA + '0' : modeB + '0'); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; if (buf[2] == '0') { modeA = tmpmode - '0'; } else { modeB = tmpmode - '0'; } printf("modeA=%c, modeB=%c\n", modeA, modeB); continue; } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); continue; } else if (strncmp(buf, "TO;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } continue; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simelecraftk4.c0000664000175000017500000002720115056640443013561 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 int freqA = 14074000; int freqB = 14074500; int afgain = 180; int rfgain = 190; int micgain = 30; int noiseblanker = 0; int bandwidthA = 200; int bandwidthB = 200; int ifshift = 0; int preampA = 0; int preampB = 0; int rxattenuatorA = 0; int rxattenuatorB = 0; int keyspd = 20; int ai = 0; int dt = 0; int modeA = 2; int modeB = 2; int ptt = 0; // int freqa = 14074000, freqb = 14073500; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { buf[0] = 0; if ((n = getmyline(fd, buf)) > 0) { if (strstr(buf, "BW0")) printf("Cmd:%s, len=%d\n", buf, n); } else {continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF059014200000+000000700000;"; pbuf = "IF00007230000 -000000 0001000001 ;" ; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "BW$;") == 0) { fprintf(stderr, "***** %d\n", __LINE__); SNPRINTF(buf, sizeof(buf), "BW$%04d;", bandwidthB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW$", 3) == 0) { sscanf(buf, "BW$%d", &bandwidthB); } else if (strcmp(buf, "BW;") == 0) { SNPRINTF(buf, sizeof(buf), "BW%04d;", bandwidthA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW", 2) == 0) { sscanf(buf, "BW%d", &bandwidthA); } else if (strcmp(buf, "DT;") == 0) { SNPRINTF(buf, sizeof(buf), "DT%d;", dt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT", 2) == 0) { sscanf(buf, "DT%d", &dt); } else if (strcmp(buf, "BN;") == 0) { SNPRINTF(buf, sizeof(buf), "BN03;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "SM;") == 0) { static int meter = 0; SNPRINTF(buf, sizeof(buf), "SM%04d;", meter++); if (meter > 15) { meter = 0; } WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG;") == 0) { SNPRINTF(buf, sizeof(buf), "RG%03d;", rfgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rfgain); } else if (strcmp(buf, "MG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", micgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &micgain); } else if (strcmp(buf, "AG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &afgain); } else if (strcmp(buf, "NB;") == 0) { SNPRINTF(buf, sizeof(buf), "NB%d;", noiseblanker); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "NB", 2) == 0) { sscanf(buf, "NB%d", &noiseblanker); } else if (strcmp(buf, "IS;") == 0) { SNPRINTF(buf, sizeof(buf), "IS %04d;", ifshift); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS %d", &ifshift); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "OM;") == 0) { // KPA3 SNPRINTF(buf, sizeof(buf), "OM AP----L-----;"); // K4+KPA3 SNPRINTF(buf, sizeof(buf), "OM AP-S----4---;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "K2;") == 0) { WRITE(fd, "K20;", 4); } else if (strcmp(buf, "K3;") == 0) { WRITE(fd, "K30;", 4); } else if (strncmp(buf, "RV", 2) == 0) { WRITE(fd, "RV02.37;", 8); } else if (strcmp(buf, "MD;") == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD$;") == 0) { SNPRINTF(buf, sizeof(buf), "MD$%d;", modeB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { if (buf[2] == '$') { sscanf(buf, "MD$%d;", &modeB); } else { sscanf(buf, "MD%d;", &modeA); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqA); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqA); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqB); } else if (strncmp(buf, "FR;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FR0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { // we ignore FR for the K3 } else if (strncmp(buf, "FT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FT0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "TQ;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TQ%d;", ptt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC0980;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PA%d;", preampA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "PA$%d;", preampB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d;", &preampA); } else if (strncmp(buf, "PA$", 3) == 0) { sscanf(buf, "PA$%d;", &preampB); } else if (strncmp(buf, "RA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "RA%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "RA$%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d;", &rxattenuatorB); } else if (strncmp(buf, "RA$", 3) == 0) { sscanf(buf, "RA$%d;", &rxattenuatorB); } else if (strncmp(buf, "KY;", 3) == 0) { int status = 0; printf("KY query\n"); SNPRINTF(buf, sizeof(buf), "KY%d;", status); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KY", 2) == 0) { printf("Morse: %s\n", buf); } else if (strncmp(buf, "TM", 2) == 0) { SNPRINTF(buf, sizeof(buf), "TM001002003004;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { ptt = 1; } else if (strncmp(buf, "RX", 2) == 0) { ptt = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simts590.c0000664000175000017500000002730415056640443012425 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 25; int width_high = 0; int width_low = 0; int afgain = 50; int usb_af = 9; int usb_af_input = 9; int mic_gain = 50; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); hl_usleep(5 * 1000); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 1, modeB = 2; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM50005;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d1000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "MG%03d;", mic_gain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mic_gain); } else if (strcmp(buf, "AG0;") == 0) { SNPRINTF(buf, sizeof(buf), "AG0%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG0", 3) == 0) { sscanf(buf, "AG0%d", &afgain); } else if (strncmp(buf, "AG", 2) == 0) { WRITE(fd, "?;", 2); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX0640000;") == 0) // TS-590S version { SNPRINTF(buf, sizeof(buf), "EX0640000%d;", usb_af_input); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0640000", 9) == 0) // TS-590S version { sscanf(buf, "EX0640000%d", &usb_af_input); } else if (strcmp(buf, "EX0650000;") == 0) // TS-590S version { SNPRINTF(buf, sizeof(buf), "EX0650000%d;", usb_af); // TS-590S version WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0650000", 9) == 0) // TS-590S version { sscanf(buf, "EX0650000%d", &usb_af); } else if (strcmp(buf, "EX0710000;") == 0) // TS-590SG version { SNPRINTF(buf, sizeof(buf), "EX0710000%d;", usb_af_input); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0710000", 9) == 0) // TS-590SG version { sscanf(buf, "EX0710000%d", &usb_af_input); } else if (strcmp(buf, "EX0720000;") == 0) // TS-590SG version { SNPRINTF(buf, sizeof(buf), "EX0720000%d;", usb_af); // TS-590SG version WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0720000", 9) == 0) // TS-590S version { sscanf(buf, "EX0720000%d", &usb_af); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); WRITE(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA + '0' : modeB + '0'); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; if (buf[2] == '0') { modeA = tmpmode - '0'; } else { modeB = tmpmode - '0'; } printf("modeA=%c, modeB=%c\n", modeA, modeB); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "SH", 2) == 0 && strlen(buf) > 4) { } else if (strncmp(buf, "SH", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SH%02d;", width_high); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL", 2) == 0 && strlen(buf) > 4) { sscanf(buf, "SL%d", &width_low); printf("width_main=%d, width_sub=%d\n", width_high, width_low); } else if (strncmp(buf, "SL", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SL%02d;", width_low); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "KY;") == 0) { SNPRINTF(buf, sizeof(buf), "KY0;"); WRITE(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simic275.c0000664000175000017500000003271615056640443012375 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0, n; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } if (frame[5] == 0xfd) { frame[5] = split; printf("get split %d\n", 1); frame[6] = 0xfd; n = write(fd, frame, 7); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); printf("x25/x26 command rejected\n"); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simftdx3000.c0000664000175000017500000001551215056640443013007 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { int val = ft; if (ft == 2) { val = 0; } else if (ft == 3) { val = 1; } SNPRINTF(buf, sizeof(buf), "FT%d;", val); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &ft); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 3) == 0) { sscanf(buf, "MD0%d", &md); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simft736.c0000664000175000017500000000553015056640443012407 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); continue; } switch (buf[4]) { case 0x00: printf("CAT On\n"); break; case 0x80: printf("CAT Off\n"); break; case 0x01: printf("FREQ_SET\n"); break; case 0x07: printf("MODE_SET\n"); break; case 0x0e: printf("Full Duplex On\n"); break; case 0x8e: printf("Full Duplex Off\n"); break; case 0x08: printf("Tx\n"); break; case 0x88: printf("Rx\n"); break; case 0x17: printf("Full Duplex Rx Mode\n"); break; case 0x27: printf("Full Duplex Tx Mode\n"); break; case 0x1e: printf("Full Duplex Rx Freq\n"); break; case 0x2e: printf("Full Duplex Tx Freq\n"); break; default: printf("Unknown cmd=%02x\n", buf[4]); } fflush(stdout); } return 0; } hamlib-4.6.5/simulators/simft991.c0000664000175000017500000002177215056640443012420 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '1'; char rx_vfo = '1'; char modeA = '0'; char modeB = '0'; int keyspd = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); } else if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "MR118;") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("MR118"); } } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%09.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%09.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", buf, tx_vfo); n = write(fd, buf, strlen(buf)); printf(" FT response#2=%s\n", buf); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simtrusdx.c0000664000175000017500000002166415056640443013075 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int tomode = 0; int keyspd = 25; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 1, modeB = 2; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d0001000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "ID%03d;", 20); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI", 2) == 0) { // nothing to do yet } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); WRITE(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA + '0' : modeB + '0'); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; if (buf[2] == '0') { modeA = tmpmode - '0'; } else { modeB = tmpmode - '0'; } printf("modeA=%c, modeB=%c\n", modeA, modeB); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); } else if (strncmp(buf, "TO;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simic2730.c0000664000175000017500000003310715056640443012446 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 1; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0, n; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: printf("Here#1\n"); //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } if (frame[5] == 0xfd) { frame[5] = split; printf("get split %d\n", 1); frame[6] = 0xfd; dump_hex(frame, 7); n = write(fd, frame, 7); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; dump_hex(frame, 6); n = write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); printf("x25/x26 command rejected\n"); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic905.c0000664000175000017500000003633315056640443012374 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup double freqA = 145123456; double freqB = 1407450; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 1; int filterB = 2; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 25; int datamode = 0; int filter = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); int freq_len = 5; if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { if (freqA > 5.85e9) { freq_len = 6; } printf("get_freqA len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqA, freq_len * 2); } else { if (freqB > 5.85e9) { freq_len = 6; } printf("get_freqB len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqB, freq_len * 2); } frame[5 + freq_len] = 0xfd; if (powerstat) { WRITE(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: freqB = freqA; modeB = modeA; break; case 0xb0: current_vfo = RIG_VFO_SUB; exit(1); break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; WRITE(fd, frame, 7); } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; WRITE(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; WRITE(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x06: // datamode if (frame[5] == 0xfd) { frame[6] = datamode; frame[7] = filter; frame[8] = 0xfd; WRITE(fd, frame, 9); } else { datamode = frame[6]; filter = frame[7]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { freq_len = 5; if (frame[5] == 0x00) { if (freqA > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqA, freq_len * 2); printf("X25 get_freqA=%.0f\n", freqA); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } else { if (freqB > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqB, freq_len * 2); printf("X25 get_freqB=%.0f\n", freqB); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } //unsigned char frame2[12]; #if 0 frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0x00; frame2[11] = 0xfd; WRITE(fd, frame2, 12); #endif } else { freq_len = 5; if (frame[11] != 0xfd) { freq_len = 6; } freq = from_bcd(&frame[6], freq_len * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); #if 0 // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; WRITE(fd, frame, 11); #endif } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simelecraft.c0000664000175000017500000002721315056640443013325 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int afgain = 180; int rfgain = 190; int micgain = 30; int noiseblanker = 0; int bandwidthA = 2200; int bandwidthB = 2400; int ifshift = 0; int preampA = 0; int preampB = 0; int rxattenuatorA = 0; int rxattenuatorB = 0; int keyspd = 20; int ai = 0; int dt = 0; int modea = 2; int modeb = 2; int ptt = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 14073500; while (1) { buf[0] = 0; if ((n = getmyline(fd, buf)) > 0) { if (strstr(buf, "BW")) printf("Cmd:%s, len=%d\n", buf, n); } else {continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF059014200000+000000700000;"; pbuf = strdup("IF00007230000 -000000 00?1000001 ;") ; pbuf[28] = ptt == 0 ? '0' : '1'; WRITE(fd, pbuf, strlen(pbuf)); free(pbuf); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "BW$;") == 0) { fprintf(stderr, "***** %d\n", __LINE__); SNPRINTF(buf, sizeof(buf), "BW$%04d;", bandwidthB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW$", 3) == 0) { sscanf(buf, "BW$%d", &bandwidthB); } else if (strcmp(buf, "BW;") == 0) { SNPRINTF(buf, sizeof(buf), "BW%04d;", bandwidthA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW", 2) == 0) { sscanf(buf, "BW%d", &bandwidthA); } else if (strcmp(buf, "DT;") == 0) { SNPRINTF(buf, sizeof(buf), "DT%d;", dt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT", 2) == 0) { sscanf(buf, "DT%d", &dt); } else if (strcmp(buf, "BN;") == 0) { SNPRINTF(buf, sizeof(buf), "BN03;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "SM;") == 0) { static int meter = 0; SNPRINTF(buf, sizeof(buf), "SM%04d;", meter++); if (meter > 15) { meter = 0; } WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG;") == 0) { SNPRINTF(buf, sizeof(buf), "RG%03d;", rfgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rfgain); } else if (strcmp(buf, "MG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", micgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &micgain); } else if (strcmp(buf, "AG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &afgain); } else if (strcmp(buf, "NB;") == 0) { SNPRINTF(buf, sizeof(buf), "NB%d;", noiseblanker); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "NB", 2) == 0) { sscanf(buf, "NB%d", &noiseblanker); } else if (strcmp(buf, "IS;") == 0) { SNPRINTF(buf, sizeof(buf), "IS %04d;", ifshift); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS %d", &ifshift); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "OM;") == 0) { // KPA3 SNPRINTF(buf, sizeof(buf), "OM AP----L-----;"); // K4+KPA3 SNPRINTF(buf, sizeof(buf), "OM AP-S----4---;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "K2;") == 0) { WRITE(fd, "K20;", 4); } else if (strcmp(buf, "K3;") == 0) { WRITE(fd, "K30;", 4); } else if (strcmp(buf, "RVD;") == 0) { WRITE(fd, "RVD02.36;", 9); } else if (strcmp(buf, "RVM;") == 0) { WRITE(fd, "RVM02.37;", 9); } else if (strcmp(buf, "MD;") == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modea); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD$;") == 0) { SNPRINTF(buf, sizeof(buf), "MD$%d;", modeb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { if (buf[2] == '$') { sscanf(buf, "MD$%d;", &modeb); } else { sscanf(buf, "MD%d;", &modea); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "FR;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FR0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { // we ignore FR for the K3 } else if (strncmp(buf, "FT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FT0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "TQ;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TQ0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC0980;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PA%d;", preampA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "PA$%d;", preampB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d;", &preampA); } else if (strncmp(buf, "PA$", 3) == 0) { sscanf(buf, "PA$%d;", &preampB); } else if (strncmp(buf, "RA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "RA%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "RA$%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d;", &rxattenuatorB); } else if (strncmp(buf, "RA$", 3) == 0) { sscanf(buf, "RA$%d;", &rxattenuatorB); } else if (strncmp(buf, "KY;", 3) == 0) { int status = 0; printf("KY query\n"); SNPRINTF(buf, sizeof(buf), "KY%d;", status); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KY", 2) == 0) { printf("Morse: %s\n", buf); } else if (strncmp(buf, "TX", 2) == 0) { ptt = 1; } else if (strncmp(buf, "RX", 2) == 0) { ptt = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simyaesu.c0000664000175000017500000002766015056640443012674 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; vfo_t curr_vfo = RIG_VFO_A; char modeA = '1'; char modeB = '1'; int ptt; int power = 1; int roofing_filter_main = 1; int roofing_filter_sub = 6; int width_main = 0; int width_sub = 0; int ex039 = 0; int lk = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX3000DM = 462, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char resp[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } //else { return 0; } if (buf[0] == 0x0a) { continue; } if (power == 0 && strcmp(buf, "PS1;") != 0) { continue; } if (strcmp(buf, "PS;") == 0) { sprintf(resp, "PS%d;", power); n = write(fd, resp, strlen(resp)); if (n <= 0) { perror("PS"); } } else if (strncmp(buf, "PS", 2) == 0) { sscanf(buf, "PS%d", &power); } else if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM8;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM8197000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM8"); } } else if (strcmp(buf, "RM9;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM9089000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM9"); } } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "FA;") == 0) { //SNPRINTF(resp, sizeof(resp), "FA%010.0f;", freqA); SNPRINTF(resp, sizeof(resp), "FA%08.0f;", freqA); freqA += 10; n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { //SNPRINTF(resp, sizeof(resp), "FB%0010.0f;", freqB); SNPRINTF(resp, sizeof(resp), "FB%08.0f;", freqB); n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF00107041000+000000200000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FT991; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "AB;") == 0) { freqB = freqA; modeB = modeA; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS") == 0 && strlen(buf) > 3) { curr_vfo = buf[3] == '1' ? RIG_VFO_B : RIG_VFO_A; hl_usleep(50 * 1000); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; if (curr_vfo == RIG_VFO_B || curr_vfo == RIG_VFO_SUB) { pbuf = "VS1"; } n = write(fd, pbuf, strlen(pbuf)); printf("%s\n", pbuf); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", resp, tx_vfo); n = write(fd, resp, strlen(resp)); printf(" FT response#2=%s\n", resp); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD0%c;", modeA); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD1%c;", modeB); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "SM0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "SM0111;"); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("SM"); } } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "TX%d;", ptt); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { hl_usleep(50 * 1000); ptt = buf[2] == '0' ? 0 : 1; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA00;"); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); //printf("%s n=%d\n", buf, n); } else if (strcmp(buf, "RF0;") == 0) { SNPRINTF(buf, sizeof(buf), "RF0%d;", roofing_filter_main); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "RF1;") == 0) { SNPRINTF(buf, sizeof(buf), "RF1%d;", roofing_filter_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "RF%c%d;", buf[2], buf[2] == 0 ? roofing_filter_main : roofing_filter_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], width_main); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "SH1;") == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], width_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH", 2) == 0 && strlen(buf) > 4) { int vfo, twidth; sscanf(buf, "SH%1d%d", &vfo, &twidth); if (vfo == 0) { width_main = twidth; } else { width_sub = twidth; } printf("width_main=%d, width_sub=%d\n", width_main, width_sub); } else if (strncmp(buf, "SH", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], buf[2] == 0 ? width_main : width_sub); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "LK;") == 0) { SNPRINTF(buf, sizeof(buf), "LK%d;", lk); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "LK", 3) == 0) { sscanf(buf, "LK%d", &lk); } else if (strncmp(buf, "DT0;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT020221022;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT1;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT1222100;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT2;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT2+0500;"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: '%s'\n", buf); } } return 0; } hamlib-4.6.5/simulators/simic9700.c0000664000175000017500000003424215056640443012453 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int dualwatch = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 90; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { WRITE(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } case 0x0c: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x0c\n"); } else { frame[6] = 0; frame[7] = keyspd; frame[8] = 0xfd; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x0c\n"); } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; WRITE(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x59: if (frame[6] == 0xfe) { dualwatch = frame[6]; } else { frame[6] = dualwatch; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; WRITE(fd, frame2, 11); WRITE(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; WRITE(fd, frame, 11); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simkenwood.c0000664000175000017500000002365015056640443013207 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 0; // , modeB = 0; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM5100000;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d0001000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "IS", 2) == 0) { continue; } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "FW", 2) == 0) { continue; } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); continue; } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); continue; } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); write(fd, buf, strlen(buf)); continue; } if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } continue; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simts450.c0000664000175000017500000002166415056640443012423 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int tomode = 0; int keyspd = 25; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 1, modeB = 2; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d0001000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "ID%03d;", 10); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI", 2) == 0) { // nothing to do yet } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); WRITE(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011.0f%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA + '0' : modeB + '0'); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; if (buf[2] == '0') { modeA = tmpmode - '0'; } else { modeB = tmpmode - '0'; } printf("modeA=%c, modeB=%c\n", modeA, modeB); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); } else if (strncmp(buf, "TO;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } else if (strncmp(buf, "TX", 2) == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': ptt = 1; case '0': ptt_mic = 1; case '1': ptt_data = 1; case '2': ptt_tune = 1; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simicr8600.c0000664000175000017500000002427415056640443012637 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include "sim.h" #define BUFSIZE 256 //#define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_CW; mode_t modeB = RIG_MODE_USB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; WRITE(fd, frame, 11); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_VFO; break; case 0x01: current_vfo = RIG_VFO_MEM; break; printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("n=WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // IC7200 data mode frame[6] = 0; frame[7] = 0; frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x07: // satmode frame[6] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; WRITE(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.5/simulators/simpowersdr.c0000664000175000017500000003172615056640443013411 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 20; double alc = 0; int tx; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 0; // , modeB = 0; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } // else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); // printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); // printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d0001000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; n = write(fd, ifbuf, strlen(ifbuf)); // printf("n=%d\n", n); if (n <= 0) { perror("IF"); } continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(50 * 1000); pbuf = "FV1.2;"; n = write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FW;") == 0) { hl_usleep(50 * 1000); pbuf = "FW2400;"; n = write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); // printf("n=%d\n", n); if (n <= 0) { perror("ID"); } continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; n = write(fd, pbuf, strlen(pbuf)); // printf("n=%d\n", n); if (n < 0) { perror("VS"); } continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); // printf("n=%d\n", n); if (n < 0) { perror("EX032"); } continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); n = write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); continue; } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); continue; } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); continue; } if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "ZZMD;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMD%d;", modeA); // not worried about modeB yet for simulator n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "ZZMD", 4) == 0) { sscanf(buf, "ZZMD%d", &modeA); // not worried about modeB yet for simulator continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "ZZFL;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFL+%04d;", 100); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "ZZFH;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFH+%04d;", 3500); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo_tx); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &vfo_tx); } else if (strncmp(buf, "DA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "DA%d;", datamode); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strncmp(buf, "ZZMN", 4) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMN01 5.0k 5100 100 4.4k 4500 100 3.8k 3900 100 3.3k 3400 100 2.9k 3000 100 2.7k 2800 100 2.4k 2500 100 2.1k 2200 100 1.8k 1900 100 1.0k 1100 100Var 1 3150 100Var 2 2800 100;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSQ000;", 5) == 0) { continue; } else if (strncmp(buf, "ZZAR;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZAR+068;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "NT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "NT0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "AG0;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "AG0000;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSQ;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSQ000;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZMG;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMG+00;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNA;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNA0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNR;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNR0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNS;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNS0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSM0;", 6) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSM0%d;", 140); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSP;", 6) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSP0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZFI;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFI%d;", 10); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTU;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZTU%d;", 0); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTX;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZTX%d;", ptt); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTX", 4) == 0) { printf("******** ZZTX[%c]\n", buf[4]); switch (buf[4]) { case '1': ptt = 1; break; case '0': ptt = 0; break; } continue; } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "ZZRM4", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZRM4%2.0f dB;", alc); n = write(fd, buf, strlen(buf)); alc += 1; if (alc > 40) { alc = -20; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simflex.c0000664000175000017500000001762715056640443012506 #include #include #include #include #if defined(WIN32) || defined(_WIN32) #include #include #else #include #endif #define PORT 4992 #define BUFFER_SIZE 1024 /* S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_level=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB */ char *msg1 = "V1.4.0.0\n"; char *msg2 = "H2FFEDF06.M10000001|Client connected from IP 10.1.10.102\n"; char *msg3 = "S2FFEDF06|radio slices=0 panadapters=0 lineout_gain=54 lineout_mute=0 headphone_gain=56 headphone_mute=0 remote_on_enabled=0 pll_done=0 freq_error_ppb=0 cal_freq=15.000000 tnf_enabled=0 nickname=FaradayII callsign=WQ6Q binaural_rx=1 full_duplex_enabled=0 band_persistence_enabled=1 rtty_mark_default=2125 enforce_private_ip_connections=1 backlight=50 mute_local_audio_when_remote=1 daxiq_capacity=16 daxiq_available=16 alpha=1 low_latency_digital_modes=1 mf_enable=1.S2FFEDF06|radio filter_sharpness VOICE level=2 auto_level=1\n"; char *msg4 = "S2FFEDF06|radio filter_sharpness CW level=2 auto_level=1\n"; char *msg5 = "S2FFEDF06|radio filter_sharpness DIGITAL level=2 auto_level=1\n"; char *msg6 = "S2FFEDF06|radio static_net_params ip= gateway= netmask=\n"; char *msg7 = "S2FFEDF06|radio front_speaker_mute=1\n"; char *msg8 = "S2FFEDF06|radio oscillator state=gpsdo setting=auto locked=1 ext_present=0 gpsdo_present=1 tcxo_present=1\n"; char *msg9 = "S2FFEDF06|interlock acc_txreq_enable=0 rca_txreq_enable=0 acc_tx_enabled=0 tx1_enabled=1 tx2_enabled=0 tx3_enabled=0 tx_delay=40 acc_tx_delay=0 tx1_delay=0 tx2_delay=0 tx3_delay=0 acc_txreq_polarity=0 rca_txreq_polarity=0 time out=0\n"; char *msg10 = "S2FFEDF06|eq rx mode=0 63Hz=10 125Hz=10 250Hz=10 500Hz=10 1000Hz=10 2000Hz=10 4000Hz=10 8000Hz=10\n"; char *msg11 = "S2FFEDF06|eq rxsc mode=0 63Hz=0 125Hz=0 250Hz=0 500Hz=0 1000Hz=0 2000Hz=0 4000Hz=0 8000Hz=0\n"; char *slicetxt = "S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_level=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB"; int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); #if defined(WIN32) || defined(_WIN32) WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); exit(EXIT_FAILURE); } #endif // Create socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } // Set socket options #if defined(WIN32) || defined(_WIN32) if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))) { #else if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { #endif perror("setsockopt"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // Bind the socket to the network address and port if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } // Start listening for incoming connections if (listen(server_fd, 3) < 0) { perror("listen"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } printf("Server is listening on port %d\n", PORT); while (1) { // Accept incoming connection if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { perror("accept"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } printf("Connection accepted\n"); send(new_socket, msg1, strlen(msg1), 0); send(new_socket, msg2, strlen(msg2), 0); send(new_socket, msg3, strlen(msg3), 0); send(new_socket, msg4, strlen(msg4), 0); send(new_socket, msg5, strlen(msg5), 0); send(new_socket, msg6, strlen(msg6), 0); send(new_socket, msg7, strlen(msg7), 0); send(new_socket, msg8, strlen(msg8), 0); send(new_socket, msg9, strlen(msg9), 0); send(new_socket, msg10, strlen(msg10), 0); send(new_socket, msg11, strlen(msg11), 0); while (1) { char buffer[BUFFER_SIZE] = {0}; char reply[BUFFER_SIZE] = {0}; int seqnum = -1; int valread = read(new_socket, buffer, BUFFER_SIZE); if (valread < 0) { perror("read"); break; } if (valread == 0) { // Connection closed printf("Connection closed by client\n"); break; } buffer[valread] = '\0'; printf("Received: %s", buffer); sscanf(buffer, "C%d", &seqnum); sprintf(reply, "R%d|0%c", seqnum, 0x0a); if (strstr(buffer, "sub slice")) { char buf[8192]; sprintf(buf, "%s%c", slicetxt, 0x0a); if (send(new_socket, buf, strlen(buf), 0) != strlen(buf)) { perror("send"); break; } } // Echo back the received message if (send(new_socket, reply, valread, 0) != valread) { perror("send"); break; } } close(new_socket); } close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif return 0; } hamlib-4.6.5/simulators/simic7000.c0000664000175000017500000003415315056640443012443 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0, n; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; printf("i=%d, c=0x%02x\n", i, c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); printf("\n"); // echo //n = write(fd, buf, i); //if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: if (frame[5] == 0xfd) { //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); dump_hex(frame, 11); } } else { if (current_vfo == RIG_VFO_A) { freqA = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } else { freqB = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); printf("x25/x26 command rejected\n"); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simpstrotator.c0000664000175000017500000000645215056640443013763 #include #include #include #include #include #define SERVER_PORT 12001 #define REPLY_PORT 12002 #define BUFFER_SIZE 1024 void handle_receive(int recv_sockfd, struct sockaddr_in *client_addr, socklen_t addr_len, char *buffer) { ssize_t recv_len; recv_len = recvfrom(recv_sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)client_addr, &addr_len); if (recv_len < 0) { perror("recvfrom"); close(recv_sockfd); exit(EXIT_FAILURE); } buffer[recv_len] = '\0'; // Null-terminate the received string printf("Received packet from %s:%d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); printf("Data: %s\n", buffer); } void handle_send(int send_sockfd, struct sockaddr_in *client_addr, socklen_t addr_len, const char *message) { ssize_t sent_len; sent_len = sendto(send_sockfd, message, strlen(message), 0, (struct sockaddr *)client_addr, addr_len); if (sent_len < 0) { perror("sendto"); close(send_sockfd); exit(EXIT_FAILURE); } printf("Sent reply to %s:%d from port %d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), REPLY_PORT); } int main() { int recv_sockfd, reply_sockfd; struct sockaddr_in server_addr, reply_addr, client_addr; char buffer[BUFFER_SIZE]; socklen_t addr_len = sizeof(client_addr); // Create a UDP socket for receiving on SERVER_PORT if ((recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } // Configure the server address for receiving memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(SERVER_PORT); // Bind the receiving socket to the server address if (bind(recv_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind"); close(recv_sockfd); exit(EXIT_FAILURE); } // Create a UDP socket for replying on REPLY_PORT if ((reply_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); close(recv_sockfd); exit(EXIT_FAILURE); } // Configure the reply address for sending memset(&reply_addr, 0, sizeof(reply_addr)); reply_addr.sin_family = AF_INET; reply_addr.sin_addr.s_addr = INADDR_ANY; reply_addr.sin_port = htons(REPLY_PORT); // Bind the reply socket to the reply address if (bind(reply_sockfd, (struct sockaddr *)&reply_addr, sizeof(reply_addr)) < 0) { perror("bind"); close(recv_sockfd); close(reply_sockfd); exit(EXIT_FAILURE); } printf("UDP server is listening on port %d for incoming packets and on port %d for replies\n", SERVER_PORT, REPLY_PORT); while (1) { // Handle incoming packets on SERVER_PORT handle_receive(recv_sockfd, &client_addr, addr_len, buffer); // Send "OK" reply to the client from REPLY_PORT handle_send(reply_sockfd, &client_addr, addr_len, "OK"); } // Close the sockets close(recv_sockfd); close(reply_sockfd); return 0; } hamlib-4.6.5/simulators/Makefile.in0000664000175000017500000021222415056640454012730 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = check_PROGRAMS = simelecraft$(EXEEXT) simicgeneric$(EXEEXT) \ simkenwood$(EXEEXT) simyaesu$(EXEEXT) simic9100$(EXEEXT) \ simic9700$(EXEEXT) simft991$(EXEEXT) simftdx1200$(EXEEXT) \ simftdx3000$(EXEEXT) simjupiter$(EXEEXT) simpowersdr$(EXEEXT) \ simid5100$(EXEEXT) simft736$(EXEEXT) simftdx5000$(EXEEXT) \ simtmd700$(EXEEXT) simrotorez$(EXEEXT) simspid$(EXEEXT) \ simft817$(EXEEXT) simts590$(EXEEXT) simft847$(EXEEXT) \ simic7300$(EXEEXT) simic7000$(EXEEXT) simic7100$(EXEEXT) \ simic7200$(EXEEXT) simatd578$(EXEEXT) simic905$(EXEEXT) \ simts450$(EXEEXT) simic7600$(EXEEXT) simic7610$(EXEEXT) \ simic705$(EXEEXT) simts950$(EXEEXT) simts990$(EXEEXT) \ simic7851$(EXEEXT) simftdx101$(EXEEXT) simxiegug90$(EXEEXT) \ simqrplabs$(EXEEXT) simft818$(EXEEXT) simic275$(EXEEXT) \ simtrusdx$(EXEEXT) simft1000$(EXEEXT) simtmd710$(EXEEXT) \ simts890$(EXEEXT) simxiegux108g$(EXEEXT) \ simxiegux6100$(EXEEXT) simic910$(EXEEXT) simft450$(EXEEXT) \ simelecraftk4$(EXEEXT) simmicom$(EXEEXT) simflex$(EXEEXT) \ simft710$(EXEEXT) simic2730$(EXEEXT) simorion$(EXEEXT) \ simpmr171$(EXEEXT) simic7700$(EXEEXT) simft990$(EXEEXT) \ simpstrotator$(EXEEXT) simeasycomm$(EXEEXT) \ simicr8600$(EXEEXT) subdir = simulators ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) simatd578_SOURCES = simatd578.c simatd578_OBJECTS = simatd578.$(OBJEXT) simatd578_LDADD = $(LDADD) am__DEPENDENCIES_1 = simatd578_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = simeasycomm_SOURCES = simeasycomm.c simeasycomm_OBJECTS = simeasycomm.$(OBJEXT) simeasycomm_LDADD = $(LDADD) simeasycomm_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simelecraft_OBJECTS = simelecraft-simelecraft.$(OBJEXT) simelecraft_OBJECTS = $(am_simelecraft_OBJECTS) am__DEPENDENCIES_2 = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simelecraft_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) simelecraft_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simelecraft_CFLAGS) \ $(CFLAGS) $(simelecraft_LDFLAGS) $(LDFLAGS) -o $@ simelecraftk4_SOURCES = simelecraftk4.c simelecraftk4_OBJECTS = simelecraftk4.$(OBJEXT) simelecraftk4_LDADD = $(LDADD) simelecraftk4_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simflex_SOURCES = simflex.c simflex_OBJECTS = simflex.$(OBJEXT) simflex_LDADD = $(LDADD) simflex_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft1000_SOURCES = simft1000.c simft1000_OBJECTS = simft1000.$(OBJEXT) simft1000_LDADD = $(LDADD) simft1000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft450_SOURCES = simft450.c simft450_OBJECTS = simft450.$(OBJEXT) simft450_LDADD = $(LDADD) simft450_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft710_SOURCES = simft710.c simft710_OBJECTS = simft710.$(OBJEXT) simft710_LDADD = $(LDADD) simft710_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft736_SOURCES = simft736.c simft736_OBJECTS = simft736.$(OBJEXT) simft736_LDADD = $(LDADD) simft736_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft817_SOURCES = simft817.c simft817_OBJECTS = simft817.$(OBJEXT) simft817_LDADD = $(LDADD) simft817_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft818_SOURCES = simft818.c simft818_OBJECTS = simft818.$(OBJEXT) simft818_LDADD = $(LDADD) simft818_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft847_SOURCES = simft847.c simft847_OBJECTS = simft847.$(OBJEXT) simft847_LDADD = $(LDADD) simft847_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft990_SOURCES = simft990.c simft990_OBJECTS = simft990.$(OBJEXT) simft990_LDADD = $(LDADD) simft990_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft991_SOURCES = simft991.c simft991_OBJECTS = simft991.$(OBJEXT) simft991_LDADD = $(LDADD) simft991_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx101_SOURCES = simftdx101.c simftdx101_OBJECTS = simftdx101.$(OBJEXT) simftdx101_LDADD = $(LDADD) simftdx101_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx1200_SOURCES = simftdx1200.c simftdx1200_OBJECTS = simftdx1200.$(OBJEXT) simftdx1200_LDADD = $(LDADD) simftdx1200_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx3000_SOURCES = simftdx3000.c simftdx3000_OBJECTS = simftdx3000.$(OBJEXT) simftdx3000_LDADD = $(LDADD) simftdx3000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx5000_SOURCES = simftdx5000.c simftdx5000_OBJECTS = simftdx5000.$(OBJEXT) simftdx5000_LDADD = $(LDADD) simftdx5000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic2730_SOURCES = simic2730.c simic2730_OBJECTS = simic2730.$(OBJEXT) simic2730_LDADD = $(LDADD) simic2730_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic275_SOURCES = simic275.c simic275_OBJECTS = simic275.$(OBJEXT) simic275_LDADD = $(LDADD) simic275_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7000_SOURCES = simic7000.c simic7000_OBJECTS = simic7000.$(OBJEXT) simic7000_LDADD = $(LDADD) simic7000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic705_SOURCES = simic705.c simic705_OBJECTS = simic705.$(OBJEXT) simic705_LDADD = $(LDADD) simic705_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7100_SOURCES = simic7100.c simic7100_OBJECTS = simic7100.$(OBJEXT) simic7100_LDADD = $(LDADD) simic7100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7200_SOURCES = simic7200.c simic7200_OBJECTS = simic7200.$(OBJEXT) simic7200_LDADD = $(LDADD) simic7200_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7300_SOURCES = simic7300.c simic7300_OBJECTS = simic7300.$(OBJEXT) simic7300_LDADD = $(LDADD) simic7300_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7600_SOURCES = simic7600.c simic7600_OBJECTS = simic7600.$(OBJEXT) simic7600_LDADD = $(LDADD) simic7600_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7610_SOURCES = simic7610.c simic7610_OBJECTS = simic7610.$(OBJEXT) simic7610_LDADD = $(LDADD) simic7610_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7700_SOURCES = simic7700.c simic7700_OBJECTS = simic7700.$(OBJEXT) simic7700_LDADD = $(LDADD) simic7700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7851_SOURCES = simic7851.c simic7851_OBJECTS = simic7851.$(OBJEXT) simic7851_LDADD = $(LDADD) simic7851_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic905_SOURCES = simic905.c simic905_OBJECTS = simic905.$(OBJEXT) simic905_LDADD = $(LDADD) simic905_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic910_SOURCES = simic910.c simic910_OBJECTS = simic910.$(OBJEXT) simic910_LDADD = $(LDADD) simic910_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic9100_SOURCES = simic9100.c simic9100_OBJECTS = simic9100.$(OBJEXT) simic9100_LDADD = $(LDADD) simic9100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic9700_SOURCES = simic9700.c simic9700_OBJECTS = simic9700.$(OBJEXT) simic9700_LDADD = $(LDADD) simic9700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simicgeneric_SOURCES = simicgeneric.c simicgeneric_OBJECTS = simicgeneric.$(OBJEXT) simicgeneric_LDADD = $(LDADD) simicgeneric_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simicr8600_SOURCES = simicr8600.c simicr8600_OBJECTS = simicr8600.$(OBJEXT) simicr8600_LDADD = $(LDADD) simicr8600_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simid5100_OBJECTS = simid5100-simid5100.$(OBJEXT) simid5100_OBJECTS = $(am_simid5100_OBJECTS) simid5100_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) simid5100_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simid5100_CFLAGS) \ $(CFLAGS) $(simid5100_LDFLAGS) $(LDFLAGS) -o $@ simjupiter_SOURCES = simjupiter.c simjupiter_OBJECTS = simjupiter.$(OBJEXT) simjupiter_LDADD = $(LDADD) simjupiter_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simkenwood_OBJECTS = simkenwood-simkenwood.$(OBJEXT) simkenwood_OBJECTS = $(am_simkenwood_OBJECTS) simkenwood_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) simkenwood_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simkenwood_CFLAGS) \ $(CFLAGS) $(simkenwood_LDFLAGS) $(LDFLAGS) -o $@ simmicom_SOURCES = simmicom.c simmicom_OBJECTS = simmicom.$(OBJEXT) simmicom_LDADD = $(LDADD) simmicom_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simorion_SOURCES = simorion.c simorion_OBJECTS = simorion.$(OBJEXT) simorion_LDADD = $(LDADD) simorion_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpmr171_SOURCES = simpmr171.c simpmr171_OBJECTS = simpmr171.$(OBJEXT) simpmr171_LDADD = $(LDADD) simpmr171_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpowersdr_SOURCES = simpowersdr.c simpowersdr_OBJECTS = simpowersdr.$(OBJEXT) simpowersdr_LDADD = $(LDADD) simpowersdr_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpstrotator_SOURCES = simpstrotator.c simpstrotator_OBJECTS = simpstrotator.$(OBJEXT) simpstrotator_LDADD = $(LDADD) simpstrotator_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simqrplabs_SOURCES = simqrplabs.c simqrplabs_OBJECTS = simqrplabs.$(OBJEXT) simqrplabs_LDADD = $(LDADD) simqrplabs_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simrotorez_SOURCES = simrotorez.c simrotorez_OBJECTS = simrotorez.$(OBJEXT) simrotorez_LDADD = $(LDADD) simrotorez_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simspid_SOURCES = simspid.c simspid_OBJECTS = simspid.$(OBJEXT) simspid_LDADD = $(LDADD) simspid_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtmd700_SOURCES = simtmd700.c simtmd700_OBJECTS = simtmd700.$(OBJEXT) simtmd700_LDADD = $(LDADD) simtmd700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtmd710_SOURCES = simtmd710.c simtmd710_OBJECTS = simtmd710.$(OBJEXT) simtmd710_LDADD = $(LDADD) simtmd710_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtrusdx_SOURCES = simtrusdx.c simtrusdx_OBJECTS = simtrusdx.$(OBJEXT) simtrusdx_LDADD = $(LDADD) simtrusdx_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts450_SOURCES = simts450.c simts450_OBJECTS = simts450.$(OBJEXT) simts450_LDADD = $(LDADD) simts450_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts590_SOURCES = simts590.c simts590_OBJECTS = simts590.$(OBJEXT) simts590_LDADD = $(LDADD) simts590_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts890_SOURCES = simts890.c simts890_OBJECTS = simts890.$(OBJEXT) simts890_LDADD = $(LDADD) simts890_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts950_SOURCES = simts950.c simts950_OBJECTS = simts950.$(OBJEXT) simts950_LDADD = $(LDADD) simts950_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts990_SOURCES = simts990.c simts990_OBJECTS = simts990.$(OBJEXT) simts990_LDADD = $(LDADD) simts990_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegug90_SOURCES = simxiegug90.c simxiegug90_OBJECTS = simxiegug90.$(OBJEXT) simxiegug90_LDADD = $(LDADD) simxiegug90_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegux108g_SOURCES = simxiegux108g.c simxiegux108g_OBJECTS = simxiegux108g.$(OBJEXT) simxiegux108g_LDADD = $(LDADD) simxiegux108g_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegux6100_SOURCES = simxiegux6100.c simxiegux6100_OBJECTS = simxiegux6100.$(OBJEXT) simxiegux6100_LDADD = $(LDADD) simxiegux6100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simyaesu_OBJECTS = simyaesu-simyaesu.$(OBJEXT) simyaesu_OBJECTS = $(am_simyaesu_OBJECTS) simyaesu_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) simyaesu_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simyaesu_CFLAGS) \ $(CFLAGS) $(simyaesu_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/simatd578.Po \ ./$(DEPDIR)/simeasycomm.Po \ ./$(DEPDIR)/simelecraft-simelecraft.Po \ ./$(DEPDIR)/simelecraftk4.Po ./$(DEPDIR)/simflex.Po \ ./$(DEPDIR)/simft1000.Po ./$(DEPDIR)/simft450.Po \ ./$(DEPDIR)/simft710.Po ./$(DEPDIR)/simft736.Po \ ./$(DEPDIR)/simft817.Po ./$(DEPDIR)/simft818.Po \ ./$(DEPDIR)/simft847.Po ./$(DEPDIR)/simft990.Po \ ./$(DEPDIR)/simft991.Po ./$(DEPDIR)/simftdx101.Po \ ./$(DEPDIR)/simftdx1200.Po ./$(DEPDIR)/simftdx3000.Po \ ./$(DEPDIR)/simftdx5000.Po ./$(DEPDIR)/simic2730.Po \ ./$(DEPDIR)/simic275.Po ./$(DEPDIR)/simic7000.Po \ ./$(DEPDIR)/simic705.Po ./$(DEPDIR)/simic7100.Po \ ./$(DEPDIR)/simic7200.Po ./$(DEPDIR)/simic7300.Po \ ./$(DEPDIR)/simic7600.Po ./$(DEPDIR)/simic7610.Po \ ./$(DEPDIR)/simic7700.Po ./$(DEPDIR)/simic7851.Po \ ./$(DEPDIR)/simic905.Po ./$(DEPDIR)/simic910.Po \ ./$(DEPDIR)/simic9100.Po ./$(DEPDIR)/simic9700.Po \ ./$(DEPDIR)/simicgeneric.Po ./$(DEPDIR)/simicr8600.Po \ ./$(DEPDIR)/simid5100-simid5100.Po ./$(DEPDIR)/simjupiter.Po \ ./$(DEPDIR)/simkenwood-simkenwood.Po ./$(DEPDIR)/simmicom.Po \ ./$(DEPDIR)/simorion.Po ./$(DEPDIR)/simpmr171.Po \ ./$(DEPDIR)/simpowersdr.Po ./$(DEPDIR)/simpstrotator.Po \ ./$(DEPDIR)/simqrplabs.Po ./$(DEPDIR)/simrotorez.Po \ ./$(DEPDIR)/simspid.Po ./$(DEPDIR)/simtmd700.Po \ ./$(DEPDIR)/simtmd710.Po ./$(DEPDIR)/simtrusdx.Po \ ./$(DEPDIR)/simts450.Po ./$(DEPDIR)/simts590.Po \ ./$(DEPDIR)/simts890.Po ./$(DEPDIR)/simts950.Po \ ./$(DEPDIR)/simts990.Po ./$(DEPDIR)/simxiegug90.Po \ ./$(DEPDIR)/simxiegux108g.Po ./$(DEPDIR)/simxiegux6100.Po \ ./$(DEPDIR)/simyaesu-simyaesu.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = simatd578.c simeasycomm.c $(simelecraft_SOURCES) \ simelecraftk4.c simflex.c simft1000.c simft450.c simft710.c \ simft736.c simft817.c simft818.c simft847.c simft990.c \ simft991.c simftdx101.c simftdx1200.c simftdx3000.c \ simftdx5000.c simic2730.c simic275.c simic7000.c simic705.c \ simic7100.c simic7200.c simic7300.c simic7600.c simic7610.c \ simic7700.c simic7851.c simic905.c simic910.c simic9100.c \ simic9700.c simicgeneric.c simicr8600.c $(simid5100_SOURCES) \ simjupiter.c $(simkenwood_SOURCES) simmicom.c simorion.c \ simpmr171.c simpowersdr.c simpstrotator.c simqrplabs.c \ simrotorez.c simspid.c simtmd700.c simtmd710.c simtrusdx.c \ simts450.c simts590.c simts890.c simts950.c simts990.c \ simxiegug90.c simxiegux108g.c simxiegux6100.c \ $(simyaesu_SOURCES) DIST_SOURCES = simatd578.c simeasycomm.c $(simelecraft_SOURCES) \ simelecraftk4.c simflex.c simft1000.c simft450.c simft710.c \ simft736.c simft817.c simft818.c simft847.c simft990.c \ simft991.c simftdx101.c simftdx1200.c simftdx3000.c \ simftdx5000.c simic2730.c simic275.c simic7000.c simic705.c \ simic7100.c simic7200.c simic7300.c simic7600.c simic7610.c \ simic7700.c simic7851.c simic905.c simic910.c simic9100.c \ simic9700.c simicgeneric.c simicr8600.c $(simid5100_SOURCES) \ simjupiter.c $(simkenwood_SOURCES) simmicom.c simorion.c \ simpmr171.c simpowersdr.c simpstrotator.c simqrplabs.c \ simrotorez.c simspid.c simtmd700.c simtmd710.c simtrusdx.c \ simts450.c simts590.c simts890.c simts950.c simts990.c \ simxiegug90.c simxiegux108g.c simxiegux6100.c \ $(simyaesu_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DISTCLEANFILES = simelecraft_SOURCES = simelecraft.c simkenwood_SOURCES = simkenwood.c simyaesu_SOURCES = simyaesu.c simid5100_SOURCES = simid5100.c # include generated include files ahead of any in sources #rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) simelecraft_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src simkenwood_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simyaesu_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simid5100_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simelecraft_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) simkenwood_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simyaesu_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simid5100_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) # Linker options simelecraft_LDFLAGS = $(WINEXELDFLAGS) simkenwood_LDFLAGS = $(WINEXELDFLAGS) simyaesu_LDFLAGS = $(WINEXELDFLAGS) simid5100_LDFLAGS = $(WINEXELDFLAGS) EXTRA_DIST = CLEANFILES = simelelecraft simicgeneric simkenwood simyaesu all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu simulators/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu simulators/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: $(am__rm_f) $(bin_PROGRAMS) test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) clean-checkPROGRAMS: $(am__rm_f) $(check_PROGRAMS) test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=) simatd578$(EXEEXT): $(simatd578_OBJECTS) $(simatd578_DEPENDENCIES) $(EXTRA_simatd578_DEPENDENCIES) @rm -f simatd578$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simatd578_OBJECTS) $(simatd578_LDADD) $(LIBS) simeasycomm$(EXEEXT): $(simeasycomm_OBJECTS) $(simeasycomm_DEPENDENCIES) $(EXTRA_simeasycomm_DEPENDENCIES) @rm -f simeasycomm$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simeasycomm_OBJECTS) $(simeasycomm_LDADD) $(LIBS) simelecraft$(EXEEXT): $(simelecraft_OBJECTS) $(simelecraft_DEPENDENCIES) $(EXTRA_simelecraft_DEPENDENCIES) @rm -f simelecraft$(EXEEXT) $(AM_V_CCLD)$(simelecraft_LINK) $(simelecraft_OBJECTS) $(simelecraft_LDADD) $(LIBS) simelecraftk4$(EXEEXT): $(simelecraftk4_OBJECTS) $(simelecraftk4_DEPENDENCIES) $(EXTRA_simelecraftk4_DEPENDENCIES) @rm -f simelecraftk4$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simelecraftk4_OBJECTS) $(simelecraftk4_LDADD) $(LIBS) simflex$(EXEEXT): $(simflex_OBJECTS) $(simflex_DEPENDENCIES) $(EXTRA_simflex_DEPENDENCIES) @rm -f simflex$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simflex_OBJECTS) $(simflex_LDADD) $(LIBS) simft1000$(EXEEXT): $(simft1000_OBJECTS) $(simft1000_DEPENDENCIES) $(EXTRA_simft1000_DEPENDENCIES) @rm -f simft1000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft1000_OBJECTS) $(simft1000_LDADD) $(LIBS) simft450$(EXEEXT): $(simft450_OBJECTS) $(simft450_DEPENDENCIES) $(EXTRA_simft450_DEPENDENCIES) @rm -f simft450$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft450_OBJECTS) $(simft450_LDADD) $(LIBS) simft710$(EXEEXT): $(simft710_OBJECTS) $(simft710_DEPENDENCIES) $(EXTRA_simft710_DEPENDENCIES) @rm -f simft710$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft710_OBJECTS) $(simft710_LDADD) $(LIBS) simft736$(EXEEXT): $(simft736_OBJECTS) $(simft736_DEPENDENCIES) $(EXTRA_simft736_DEPENDENCIES) @rm -f simft736$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft736_OBJECTS) $(simft736_LDADD) $(LIBS) simft817$(EXEEXT): $(simft817_OBJECTS) $(simft817_DEPENDENCIES) $(EXTRA_simft817_DEPENDENCIES) @rm -f simft817$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft817_OBJECTS) $(simft817_LDADD) $(LIBS) simft818$(EXEEXT): $(simft818_OBJECTS) $(simft818_DEPENDENCIES) $(EXTRA_simft818_DEPENDENCIES) @rm -f simft818$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft818_OBJECTS) $(simft818_LDADD) $(LIBS) simft847$(EXEEXT): $(simft847_OBJECTS) $(simft847_DEPENDENCIES) $(EXTRA_simft847_DEPENDENCIES) @rm -f simft847$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft847_OBJECTS) $(simft847_LDADD) $(LIBS) simft990$(EXEEXT): $(simft990_OBJECTS) $(simft990_DEPENDENCIES) $(EXTRA_simft990_DEPENDENCIES) @rm -f simft990$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft990_OBJECTS) $(simft990_LDADD) $(LIBS) simft991$(EXEEXT): $(simft991_OBJECTS) $(simft991_DEPENDENCIES) $(EXTRA_simft991_DEPENDENCIES) @rm -f simft991$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft991_OBJECTS) $(simft991_LDADD) $(LIBS) simftdx101$(EXEEXT): $(simftdx101_OBJECTS) $(simftdx101_DEPENDENCIES) $(EXTRA_simftdx101_DEPENDENCIES) @rm -f simftdx101$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx101_OBJECTS) $(simftdx101_LDADD) $(LIBS) simftdx1200$(EXEEXT): $(simftdx1200_OBJECTS) $(simftdx1200_DEPENDENCIES) $(EXTRA_simftdx1200_DEPENDENCIES) @rm -f simftdx1200$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx1200_OBJECTS) $(simftdx1200_LDADD) $(LIBS) simftdx3000$(EXEEXT): $(simftdx3000_OBJECTS) $(simftdx3000_DEPENDENCIES) $(EXTRA_simftdx3000_DEPENDENCIES) @rm -f simftdx3000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx3000_OBJECTS) $(simftdx3000_LDADD) $(LIBS) simftdx5000$(EXEEXT): $(simftdx5000_OBJECTS) $(simftdx5000_DEPENDENCIES) $(EXTRA_simftdx5000_DEPENDENCIES) @rm -f simftdx5000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx5000_OBJECTS) $(simftdx5000_LDADD) $(LIBS) simic2730$(EXEEXT): $(simic2730_OBJECTS) $(simic2730_DEPENDENCIES) $(EXTRA_simic2730_DEPENDENCIES) @rm -f simic2730$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic2730_OBJECTS) $(simic2730_LDADD) $(LIBS) simic275$(EXEEXT): $(simic275_OBJECTS) $(simic275_DEPENDENCIES) $(EXTRA_simic275_DEPENDENCIES) @rm -f simic275$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic275_OBJECTS) $(simic275_LDADD) $(LIBS) simic7000$(EXEEXT): $(simic7000_OBJECTS) $(simic7000_DEPENDENCIES) $(EXTRA_simic7000_DEPENDENCIES) @rm -f simic7000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7000_OBJECTS) $(simic7000_LDADD) $(LIBS) simic705$(EXEEXT): $(simic705_OBJECTS) $(simic705_DEPENDENCIES) $(EXTRA_simic705_DEPENDENCIES) @rm -f simic705$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic705_OBJECTS) $(simic705_LDADD) $(LIBS) simic7100$(EXEEXT): $(simic7100_OBJECTS) $(simic7100_DEPENDENCIES) $(EXTRA_simic7100_DEPENDENCIES) @rm -f simic7100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7100_OBJECTS) $(simic7100_LDADD) $(LIBS) simic7200$(EXEEXT): $(simic7200_OBJECTS) $(simic7200_DEPENDENCIES) $(EXTRA_simic7200_DEPENDENCIES) @rm -f simic7200$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7200_OBJECTS) $(simic7200_LDADD) $(LIBS) simic7300$(EXEEXT): $(simic7300_OBJECTS) $(simic7300_DEPENDENCIES) $(EXTRA_simic7300_DEPENDENCIES) @rm -f simic7300$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7300_OBJECTS) $(simic7300_LDADD) $(LIBS) simic7600$(EXEEXT): $(simic7600_OBJECTS) $(simic7600_DEPENDENCIES) $(EXTRA_simic7600_DEPENDENCIES) @rm -f simic7600$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7600_OBJECTS) $(simic7600_LDADD) $(LIBS) simic7610$(EXEEXT): $(simic7610_OBJECTS) $(simic7610_DEPENDENCIES) $(EXTRA_simic7610_DEPENDENCIES) @rm -f simic7610$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7610_OBJECTS) $(simic7610_LDADD) $(LIBS) simic7700$(EXEEXT): $(simic7700_OBJECTS) $(simic7700_DEPENDENCIES) $(EXTRA_simic7700_DEPENDENCIES) @rm -f simic7700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7700_OBJECTS) $(simic7700_LDADD) $(LIBS) simic7851$(EXEEXT): $(simic7851_OBJECTS) $(simic7851_DEPENDENCIES) $(EXTRA_simic7851_DEPENDENCIES) @rm -f simic7851$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7851_OBJECTS) $(simic7851_LDADD) $(LIBS) simic905$(EXEEXT): $(simic905_OBJECTS) $(simic905_DEPENDENCIES) $(EXTRA_simic905_DEPENDENCIES) @rm -f simic905$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic905_OBJECTS) $(simic905_LDADD) $(LIBS) simic910$(EXEEXT): $(simic910_OBJECTS) $(simic910_DEPENDENCIES) $(EXTRA_simic910_DEPENDENCIES) @rm -f simic910$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic910_OBJECTS) $(simic910_LDADD) $(LIBS) simic9100$(EXEEXT): $(simic9100_OBJECTS) $(simic9100_DEPENDENCIES) $(EXTRA_simic9100_DEPENDENCIES) @rm -f simic9100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic9100_OBJECTS) $(simic9100_LDADD) $(LIBS) simic9700$(EXEEXT): $(simic9700_OBJECTS) $(simic9700_DEPENDENCIES) $(EXTRA_simic9700_DEPENDENCIES) @rm -f simic9700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic9700_OBJECTS) $(simic9700_LDADD) $(LIBS) simicgeneric$(EXEEXT): $(simicgeneric_OBJECTS) $(simicgeneric_DEPENDENCIES) $(EXTRA_simicgeneric_DEPENDENCIES) @rm -f simicgeneric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simicgeneric_OBJECTS) $(simicgeneric_LDADD) $(LIBS) simicr8600$(EXEEXT): $(simicr8600_OBJECTS) $(simicr8600_DEPENDENCIES) $(EXTRA_simicr8600_DEPENDENCIES) @rm -f simicr8600$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simicr8600_OBJECTS) $(simicr8600_LDADD) $(LIBS) simid5100$(EXEEXT): $(simid5100_OBJECTS) $(simid5100_DEPENDENCIES) $(EXTRA_simid5100_DEPENDENCIES) @rm -f simid5100$(EXEEXT) $(AM_V_CCLD)$(simid5100_LINK) $(simid5100_OBJECTS) $(simid5100_LDADD) $(LIBS) simjupiter$(EXEEXT): $(simjupiter_OBJECTS) $(simjupiter_DEPENDENCIES) $(EXTRA_simjupiter_DEPENDENCIES) @rm -f simjupiter$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simjupiter_OBJECTS) $(simjupiter_LDADD) $(LIBS) simkenwood$(EXEEXT): $(simkenwood_OBJECTS) $(simkenwood_DEPENDENCIES) $(EXTRA_simkenwood_DEPENDENCIES) @rm -f simkenwood$(EXEEXT) $(AM_V_CCLD)$(simkenwood_LINK) $(simkenwood_OBJECTS) $(simkenwood_LDADD) $(LIBS) simmicom$(EXEEXT): $(simmicom_OBJECTS) $(simmicom_DEPENDENCIES) $(EXTRA_simmicom_DEPENDENCIES) @rm -f simmicom$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simmicom_OBJECTS) $(simmicom_LDADD) $(LIBS) simorion$(EXEEXT): $(simorion_OBJECTS) $(simorion_DEPENDENCIES) $(EXTRA_simorion_DEPENDENCIES) @rm -f simorion$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simorion_OBJECTS) $(simorion_LDADD) $(LIBS) simpmr171$(EXEEXT): $(simpmr171_OBJECTS) $(simpmr171_DEPENDENCIES) $(EXTRA_simpmr171_DEPENDENCIES) @rm -f simpmr171$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpmr171_OBJECTS) $(simpmr171_LDADD) $(LIBS) simpowersdr$(EXEEXT): $(simpowersdr_OBJECTS) $(simpowersdr_DEPENDENCIES) $(EXTRA_simpowersdr_DEPENDENCIES) @rm -f simpowersdr$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpowersdr_OBJECTS) $(simpowersdr_LDADD) $(LIBS) simpstrotator$(EXEEXT): $(simpstrotator_OBJECTS) $(simpstrotator_DEPENDENCIES) $(EXTRA_simpstrotator_DEPENDENCIES) @rm -f simpstrotator$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpstrotator_OBJECTS) $(simpstrotator_LDADD) $(LIBS) simqrplabs$(EXEEXT): $(simqrplabs_OBJECTS) $(simqrplabs_DEPENDENCIES) $(EXTRA_simqrplabs_DEPENDENCIES) @rm -f simqrplabs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simqrplabs_OBJECTS) $(simqrplabs_LDADD) $(LIBS) simrotorez$(EXEEXT): $(simrotorez_OBJECTS) $(simrotorez_DEPENDENCIES) $(EXTRA_simrotorez_DEPENDENCIES) @rm -f simrotorez$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simrotorez_OBJECTS) $(simrotorez_LDADD) $(LIBS) simspid$(EXEEXT): $(simspid_OBJECTS) $(simspid_DEPENDENCIES) $(EXTRA_simspid_DEPENDENCIES) @rm -f simspid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simspid_OBJECTS) $(simspid_LDADD) $(LIBS) simtmd700$(EXEEXT): $(simtmd700_OBJECTS) $(simtmd700_DEPENDENCIES) $(EXTRA_simtmd700_DEPENDENCIES) @rm -f simtmd700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtmd700_OBJECTS) $(simtmd700_LDADD) $(LIBS) simtmd710$(EXEEXT): $(simtmd710_OBJECTS) $(simtmd710_DEPENDENCIES) $(EXTRA_simtmd710_DEPENDENCIES) @rm -f simtmd710$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtmd710_OBJECTS) $(simtmd710_LDADD) $(LIBS) simtrusdx$(EXEEXT): $(simtrusdx_OBJECTS) $(simtrusdx_DEPENDENCIES) $(EXTRA_simtrusdx_DEPENDENCIES) @rm -f simtrusdx$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtrusdx_OBJECTS) $(simtrusdx_LDADD) $(LIBS) simts450$(EXEEXT): $(simts450_OBJECTS) $(simts450_DEPENDENCIES) $(EXTRA_simts450_DEPENDENCIES) @rm -f simts450$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts450_OBJECTS) $(simts450_LDADD) $(LIBS) simts590$(EXEEXT): $(simts590_OBJECTS) $(simts590_DEPENDENCIES) $(EXTRA_simts590_DEPENDENCIES) @rm -f simts590$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts590_OBJECTS) $(simts590_LDADD) $(LIBS) simts890$(EXEEXT): $(simts890_OBJECTS) $(simts890_DEPENDENCIES) $(EXTRA_simts890_DEPENDENCIES) @rm -f simts890$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts890_OBJECTS) $(simts890_LDADD) $(LIBS) simts950$(EXEEXT): $(simts950_OBJECTS) $(simts950_DEPENDENCIES) $(EXTRA_simts950_DEPENDENCIES) @rm -f simts950$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts950_OBJECTS) $(simts950_LDADD) $(LIBS) simts990$(EXEEXT): $(simts990_OBJECTS) $(simts990_DEPENDENCIES) $(EXTRA_simts990_DEPENDENCIES) @rm -f simts990$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts990_OBJECTS) $(simts990_LDADD) $(LIBS) simxiegug90$(EXEEXT): $(simxiegug90_OBJECTS) $(simxiegug90_DEPENDENCIES) $(EXTRA_simxiegug90_DEPENDENCIES) @rm -f simxiegug90$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegug90_OBJECTS) $(simxiegug90_LDADD) $(LIBS) simxiegux108g$(EXEEXT): $(simxiegux108g_OBJECTS) $(simxiegux108g_DEPENDENCIES) $(EXTRA_simxiegux108g_DEPENDENCIES) @rm -f simxiegux108g$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegux108g_OBJECTS) $(simxiegux108g_LDADD) $(LIBS) simxiegux6100$(EXEEXT): $(simxiegux6100_OBJECTS) $(simxiegux6100_DEPENDENCIES) $(EXTRA_simxiegux6100_DEPENDENCIES) @rm -f simxiegux6100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegux6100_OBJECTS) $(simxiegux6100_LDADD) $(LIBS) simyaesu$(EXEEXT): $(simyaesu_OBJECTS) $(simyaesu_DEPENDENCIES) $(EXTRA_simyaesu_DEPENDENCIES) @rm -f simyaesu$(EXEEXT) $(AM_V_CCLD)$(simyaesu_LINK) $(simyaesu_OBJECTS) $(simyaesu_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simatd578.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simeasycomm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simelecraft-simelecraft.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simelecraftk4.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simflex.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft1000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft450.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft710.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft736.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft817.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft818.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft847.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft990.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft991.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx101.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx1200.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx3000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx5000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic2730.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic275.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic705.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7200.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7300.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7600.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7610.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7851.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic905.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic910.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic9100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic9700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simicgeneric.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simicr8600.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simid5100-simid5100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simjupiter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simkenwood-simkenwood.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simmicom.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simorion.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpmr171.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpowersdr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpstrotator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simqrplabs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simrotorez.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simspid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtmd700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtmd710.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtrusdx.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts450.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts590.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts890.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts950.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts990.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegug90.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegux108g.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegux6100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simyaesu-simyaesu.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< simelecraft-simelecraft.o: simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -MT simelecraft-simelecraft.o -MD -MP -MF $(DEPDIR)/simelecraft-simelecraft.Tpo -c -o simelecraft-simelecraft.o `test -f 'simelecraft.c' || echo '$(srcdir)/'`simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simelecraft-simelecraft.Tpo $(DEPDIR)/simelecraft-simelecraft.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simelecraft.c' object='simelecraft-simelecraft.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -c -o simelecraft-simelecraft.o `test -f 'simelecraft.c' || echo '$(srcdir)/'`simelecraft.c simelecraft-simelecraft.obj: simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -MT simelecraft-simelecraft.obj -MD -MP -MF $(DEPDIR)/simelecraft-simelecraft.Tpo -c -o simelecraft-simelecraft.obj `if test -f 'simelecraft.c'; then $(CYGPATH_W) 'simelecraft.c'; else $(CYGPATH_W) '$(srcdir)/simelecraft.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simelecraft-simelecraft.Tpo $(DEPDIR)/simelecraft-simelecraft.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simelecraft.c' object='simelecraft-simelecraft.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -c -o simelecraft-simelecraft.obj `if test -f 'simelecraft.c'; then $(CYGPATH_W) 'simelecraft.c'; else $(CYGPATH_W) '$(srcdir)/simelecraft.c'; fi` simid5100-simid5100.o: simid5100.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -MT simid5100-simid5100.o -MD -MP -MF $(DEPDIR)/simid5100-simid5100.Tpo -c -o simid5100-simid5100.o `test -f 'simid5100.c' || echo '$(srcdir)/'`simid5100.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simid5100-simid5100.Tpo $(DEPDIR)/simid5100-simid5100.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simid5100.c' object='simid5100-simid5100.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -c -o simid5100-simid5100.o `test -f 'simid5100.c' || echo '$(srcdir)/'`simid5100.c simid5100-simid5100.obj: simid5100.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -MT simid5100-simid5100.obj -MD -MP -MF $(DEPDIR)/simid5100-simid5100.Tpo -c -o simid5100-simid5100.obj `if test -f 'simid5100.c'; then $(CYGPATH_W) 'simid5100.c'; else $(CYGPATH_W) '$(srcdir)/simid5100.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simid5100-simid5100.Tpo $(DEPDIR)/simid5100-simid5100.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simid5100.c' object='simid5100-simid5100.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -c -o simid5100-simid5100.obj `if test -f 'simid5100.c'; then $(CYGPATH_W) 'simid5100.c'; else $(CYGPATH_W) '$(srcdir)/simid5100.c'; fi` simkenwood-simkenwood.o: simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -MT simkenwood-simkenwood.o -MD -MP -MF $(DEPDIR)/simkenwood-simkenwood.Tpo -c -o simkenwood-simkenwood.o `test -f 'simkenwood.c' || echo '$(srcdir)/'`simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simkenwood-simkenwood.Tpo $(DEPDIR)/simkenwood-simkenwood.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simkenwood.c' object='simkenwood-simkenwood.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -c -o simkenwood-simkenwood.o `test -f 'simkenwood.c' || echo '$(srcdir)/'`simkenwood.c simkenwood-simkenwood.obj: simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -MT simkenwood-simkenwood.obj -MD -MP -MF $(DEPDIR)/simkenwood-simkenwood.Tpo -c -o simkenwood-simkenwood.obj `if test -f 'simkenwood.c'; then $(CYGPATH_W) 'simkenwood.c'; else $(CYGPATH_W) '$(srcdir)/simkenwood.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simkenwood-simkenwood.Tpo $(DEPDIR)/simkenwood-simkenwood.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simkenwood.c' object='simkenwood-simkenwood.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -c -o simkenwood-simkenwood.obj `if test -f 'simkenwood.c'; then $(CYGPATH_W) 'simkenwood.c'; else $(CYGPATH_W) '$(srcdir)/simkenwood.c'; fi` simyaesu-simyaesu.o: simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -MT simyaesu-simyaesu.o -MD -MP -MF $(DEPDIR)/simyaesu-simyaesu.Tpo -c -o simyaesu-simyaesu.o `test -f 'simyaesu.c' || echo '$(srcdir)/'`simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simyaesu-simyaesu.Tpo $(DEPDIR)/simyaesu-simyaesu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simyaesu.c' object='simyaesu-simyaesu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -c -o simyaesu-simyaesu.o `test -f 'simyaesu.c' || echo '$(srcdir)/'`simyaesu.c simyaesu-simyaesu.obj: simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -MT simyaesu-simyaesu.obj -MD -MP -MF $(DEPDIR)/simyaesu-simyaesu.Tpo -c -o simyaesu-simyaesu.obj `if test -f 'simyaesu.c'; then $(CYGPATH_W) 'simyaesu.c'; else $(CYGPATH_W) '$(srcdir)/simyaesu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simyaesu-simyaesu.Tpo $(DEPDIR)/simyaesu-simyaesu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simyaesu.c' object='simyaesu-simyaesu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -c -o simyaesu-simyaesu.obj `if test -f 'simyaesu.c'; then $(CYGPATH_W) 'simyaesu.c'; else $(CYGPATH_W) '$(srcdir)/simyaesu.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -$(am__rm_f) $(CLEANFILES) distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/simatd578.Po -rm -f ./$(DEPDIR)/simeasycomm.Po -rm -f ./$(DEPDIR)/simelecraft-simelecraft.Po -rm -f ./$(DEPDIR)/simelecraftk4.Po -rm -f ./$(DEPDIR)/simflex.Po -rm -f ./$(DEPDIR)/simft1000.Po -rm -f ./$(DEPDIR)/simft450.Po -rm -f ./$(DEPDIR)/simft710.Po -rm -f ./$(DEPDIR)/simft736.Po -rm -f ./$(DEPDIR)/simft817.Po -rm -f ./$(DEPDIR)/simft818.Po -rm -f ./$(DEPDIR)/simft847.Po -rm -f ./$(DEPDIR)/simft990.Po -rm -f ./$(DEPDIR)/simft991.Po -rm -f ./$(DEPDIR)/simftdx101.Po -rm -f ./$(DEPDIR)/simftdx1200.Po -rm -f ./$(DEPDIR)/simftdx3000.Po -rm -f ./$(DEPDIR)/simftdx5000.Po -rm -f ./$(DEPDIR)/simic2730.Po -rm -f ./$(DEPDIR)/simic275.Po -rm -f ./$(DEPDIR)/simic7000.Po -rm -f ./$(DEPDIR)/simic705.Po -rm -f ./$(DEPDIR)/simic7100.Po -rm -f ./$(DEPDIR)/simic7200.Po -rm -f ./$(DEPDIR)/simic7300.Po -rm -f ./$(DEPDIR)/simic7600.Po -rm -f ./$(DEPDIR)/simic7610.Po -rm -f ./$(DEPDIR)/simic7700.Po -rm -f ./$(DEPDIR)/simic7851.Po -rm -f ./$(DEPDIR)/simic905.Po -rm -f ./$(DEPDIR)/simic910.Po -rm -f ./$(DEPDIR)/simic9100.Po -rm -f ./$(DEPDIR)/simic9700.Po -rm -f ./$(DEPDIR)/simicgeneric.Po -rm -f ./$(DEPDIR)/simicr8600.Po -rm -f ./$(DEPDIR)/simid5100-simid5100.Po -rm -f ./$(DEPDIR)/simjupiter.Po -rm -f ./$(DEPDIR)/simkenwood-simkenwood.Po -rm -f ./$(DEPDIR)/simmicom.Po -rm -f ./$(DEPDIR)/simorion.Po -rm -f ./$(DEPDIR)/simpmr171.Po -rm -f ./$(DEPDIR)/simpowersdr.Po -rm -f ./$(DEPDIR)/simpstrotator.Po -rm -f ./$(DEPDIR)/simqrplabs.Po -rm -f ./$(DEPDIR)/simrotorez.Po -rm -f ./$(DEPDIR)/simspid.Po -rm -f ./$(DEPDIR)/simtmd700.Po -rm -f ./$(DEPDIR)/simtmd710.Po -rm -f ./$(DEPDIR)/simtrusdx.Po -rm -f ./$(DEPDIR)/simts450.Po -rm -f ./$(DEPDIR)/simts590.Po -rm -f ./$(DEPDIR)/simts890.Po -rm -f ./$(DEPDIR)/simts950.Po -rm -f ./$(DEPDIR)/simts990.Po -rm -f ./$(DEPDIR)/simxiegug90.Po -rm -f ./$(DEPDIR)/simxiegux108g.Po -rm -f ./$(DEPDIR)/simxiegux6100.Po -rm -f ./$(DEPDIR)/simyaesu-simyaesu.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/simatd578.Po -rm -f ./$(DEPDIR)/simeasycomm.Po -rm -f ./$(DEPDIR)/simelecraft-simelecraft.Po -rm -f ./$(DEPDIR)/simelecraftk4.Po -rm -f ./$(DEPDIR)/simflex.Po -rm -f ./$(DEPDIR)/simft1000.Po -rm -f ./$(DEPDIR)/simft450.Po -rm -f ./$(DEPDIR)/simft710.Po -rm -f ./$(DEPDIR)/simft736.Po -rm -f ./$(DEPDIR)/simft817.Po -rm -f ./$(DEPDIR)/simft818.Po -rm -f ./$(DEPDIR)/simft847.Po -rm -f ./$(DEPDIR)/simft990.Po -rm -f ./$(DEPDIR)/simft991.Po -rm -f ./$(DEPDIR)/simftdx101.Po -rm -f ./$(DEPDIR)/simftdx1200.Po -rm -f ./$(DEPDIR)/simftdx3000.Po -rm -f ./$(DEPDIR)/simftdx5000.Po -rm -f ./$(DEPDIR)/simic2730.Po -rm -f ./$(DEPDIR)/simic275.Po -rm -f ./$(DEPDIR)/simic7000.Po -rm -f ./$(DEPDIR)/simic705.Po -rm -f ./$(DEPDIR)/simic7100.Po -rm -f ./$(DEPDIR)/simic7200.Po -rm -f ./$(DEPDIR)/simic7300.Po -rm -f ./$(DEPDIR)/simic7600.Po -rm -f ./$(DEPDIR)/simic7610.Po -rm -f ./$(DEPDIR)/simic7700.Po -rm -f ./$(DEPDIR)/simic7851.Po -rm -f ./$(DEPDIR)/simic905.Po -rm -f ./$(DEPDIR)/simic910.Po -rm -f ./$(DEPDIR)/simic9100.Po -rm -f ./$(DEPDIR)/simic9700.Po -rm -f ./$(DEPDIR)/simicgeneric.Po -rm -f ./$(DEPDIR)/simicr8600.Po -rm -f ./$(DEPDIR)/simid5100-simid5100.Po -rm -f ./$(DEPDIR)/simjupiter.Po -rm -f ./$(DEPDIR)/simkenwood-simkenwood.Po -rm -f ./$(DEPDIR)/simmicom.Po -rm -f ./$(DEPDIR)/simorion.Po -rm -f ./$(DEPDIR)/simpmr171.Po -rm -f ./$(DEPDIR)/simpowersdr.Po -rm -f ./$(DEPDIR)/simpstrotator.Po -rm -f ./$(DEPDIR)/simqrplabs.Po -rm -f ./$(DEPDIR)/simrotorez.Po -rm -f ./$(DEPDIR)/simspid.Po -rm -f ./$(DEPDIR)/simtmd700.Po -rm -f ./$(DEPDIR)/simtmd710.Po -rm -f ./$(DEPDIR)/simtrusdx.Po -rm -f ./$(DEPDIR)/simts450.Po -rm -f ./$(DEPDIR)/simts590.Po -rm -f ./$(DEPDIR)/simts890.Po -rm -f ./$(DEPDIR)/simts950.Po -rm -f ./$(DEPDIR)/simts990.Po -rm -f ./$(DEPDIR)/simxiegug90.Po -rm -f ./$(DEPDIR)/simxiegux108g.Po -rm -f ./$(DEPDIR)/simxiegux6100.Po -rm -f ./$(DEPDIR)/simyaesu-simyaesu.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Support 'make check' target for simple tests #check_SCRIPTS = #TESTS = $(check_SCRIPTS) $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/simulators/simjupiter.c0000664000175000017500000000400115056640443013210 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.5/simulators/simic7100.c0000664000175000017500000003045115056640443012441 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #undef ECHO #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 20; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); #ifdef ECHO // echo n = write(fd, buf, i); #endif return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { unsigned char frame2[11]; memcpy(frame2, frame, 11); frame2[2] = 0xe1; frame2[3] = 0x88; dump_hex(frame2, 11); n = write(fd, frame2, 11); dump_hex(frame, 11); n = write(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; hl_usleep(20 * 1000); n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); printf("x25/x26 command rejected\n"); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simid5100.c0000664000175000017500000002354315056640443012444 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 145000000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 0; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x00: freq = from_bcd(&frame[5], 5 * 2); freqA = freq; printf("freq=%lf\n", freqA); break; case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA / 10000, 3 * 2); dump_hex(frame, 11); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB / 10000, 3 * 2); } frame[8] = 0xfd; dump_hex(frame, 9); write(fd, frame, 9); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = filterA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = filterA; } frame[7] = 0xfd; write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; write(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; write(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = filterA; } frame[7] = 0xfd; write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d filter=%d freq=%.0f\n", vfoa, modeA, filterA, freqA); printf("%cVFOB: mode=%d filter=%d freq=%.0f\n", vfob, modeB, filterA, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic7600.c0000664000175000017500000004276015056640443012454 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 //#define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int datamode = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 // async frame unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic705.c0000664000175000017500000003473615056640443012377 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; int keyspd = 85; // 85=20WPM // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_FM; mode_t modeB = RIG_MODE_FM; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } printf("Here#1\n"); dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; case 0x14: printf("cmd=0x14\n"); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x00; frame2[6] = 0x35; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); #else n = write(fd, frame, 12); #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); #if 0 // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); #endif } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0x01; frame[9] = 0xfd; n = write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simft847.c0000664000175000017500000000617615056640443012421 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; int n; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[4]) { case 0x00: printf("LOCK ON\n"); break; case 0x80: printf("LOCK OFF\n"); break; case 0x08: printf("PTT ON\n"); break; case 0x88: printf("PTT OFF\n"); break; case 0x07: printf("MODE\n"); break; case 0x05: printf("CLAR ON\n"); break; case 0x85: printf("CLAR OFF\n"); break; case 0xF5: printf("FREQ\n"); break; case 0x81: printf("VFO TOGGLE\n"); break; case 0x02: printf("SPLIT ON\n"); break; case 0x82: printf("SPLIT OFF\n"); break; case 0x09: printf("REPEATER SHIFT\n"); break; case 0xF9: printf("REPEATER FREQ\n"); break; case 0x0A: printf("CTCSS/DCS MODE\n"); break; case 0x0B: printf("CTCSS TONE\n"); break; case 0x0C: printf("DCS CODE\n"); break; case 0xE7: printf("READ RX STATUS\n"); break; case 0xF7: printf("READ TX STATUS\n"); break; case 0x03: printf("READ RX STATUS\n"); buf[0] = 0x01; buf[1] = 0x40; buf[2] = 0x74; buf[3] = 0x00; buf[4] = 0x03; n = write(fd, buf, 5); break; case 0xbb: buf[0] = buf[1] = 0; printf("READ EPROM\n"); n = write(fd, buf, 2); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.5/simulators/simpmr171.c0000664000175000017500000000425315056640443012566 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n1=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); i = buf[4]; // length of packet n = read(fd, &buf[5], i); printf("read %d bytes\n", n); if (n == 0) { return 0; } n += 5; printf("n2=%d", n); for (i = 0; i < n; ++i) { printf(" x%02x", buf[i]); } printf("\n"); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } switch (buf[5]) { case 0x07: printf("PTT=%d\n", buf[6]); write(fd, buf, 9); break; case 0x0c: printf("Power=%d\n", buf[6]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.5/simulators/simeasycomm.c0000664000175000017500000000764415056640443013363 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 static void *rotorez_thread(void *arg); int getmyline(int fd, char *buf) { unsigned char c = 0; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); //printf("fd=%d\n", fd); while (read(fd, &c, 1) > 0 && c != 0xa) { buf[i++] = c; n++; for (int j = 0; j < strlen(buf); ++j) { printf("%02x ", buf[j]); } printf("\n"); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int thread_args[2]; int main(int argc, char *argv[]) { int fd = openPort(argv[1]); //int fd2 = openPort(argv[2]); pthread_t threads[2]; thread_args[0] = fd; //thread_args[1] = fd2; pthread_create(&threads[0], NULL, rotorez_thread, (void *)&thread_args[0]); //pthread_create(&threads[1], NULL, rotorez_thread, (void *)&thread_args[1]); pthread_exit(NULL); return 0; /* again: int flag = 0; while (1) { int bytes; if (!flag) bytes = getmyline(fd, buf); else bytes = getmyline(fd2, buf); flag = !flag; if (bytes == 0) { //close(fd); printf("again\n"); goto again; } printf("line=%s\n", buf); if (strncmp(buf,"BI1",3) == 0) { sprintf(buf,"%3.1f;", az); n = write(flag?fd:fd2, buf, strlen(buf)); printf("n=%d\n", n); } else if (strncmp(buf,"AP1",3) == 0) { sscanf(buf,"AP1%f", &az); } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } return 0; */ } static void *rotorez_thread(void *arg) { int n = 0; char buf[256]; int fd = *(int *)arg; float az = 123; float el = 45; again: while (1) { int bytes; bytes = getmyline(fd, buf); if (bytes == 0) { //close(fd); hl_usleep(100 * 1000); //printf("again\n"); goto again; } printf("line[%d]=%s\n", fd, buf); if (sscanf(buf, "AZ%g EL%g", &az, &el) == 2) { //n = write(fd, buf, strlen(buf)); printf("n=%d fd=%d\n", n, fd); } else if (strcmp(buf,"AZ")==0) { sprintf(buf,"AZ%.1f\n", az); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf,"EL")==0) { sprintf(buf,"EL%.1f\n", el); n = write(fd, buf, strlen(buf)); } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } pthread_exit(NULL); } hamlib-4.6.5/simulators/simft1000.c0000664000175000017500000000535715056640443012457 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); continue; } switch (buf[4]) { case 0x01: printf("Split\n"); break; case 0x05: printf("Select VFO\n"); break; case 0x0a: printf("Set Main freq\n"); break; case 0x10: printf("Info\n"); break; case 0x0c: printf("Set mode\n"); break; case 0x0e: printf("Pacing\n"); break; case 0x0f: printf("Tx\n"); break; case 0x83: printf("Full Duplex Rx Mode\n"); break; case 0x8a: printf("Set Sub freq\n"); break; case 0x8b: printf("Bandwidth\n"); break; case 0xf7: printf("Read meter\n"); break; default: printf("Unknown cmd=%02x\n", buf[4]); } fflush(stdout); } return 0; } hamlib-4.6.5/simulators/simrotorez.c0000664000175000017500000001021515056640443013236 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 static void *rotorez_thread(void *arg); int getmyline(int fd, char *buf) { unsigned char c = 0; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); //printf("fd=%d\n", fd); while (read(fd, &c, 1) > 0 && c != ';') { buf[i++] = c; n++; for (int j = 0; j < strlen(buf); ++j) { printf("%02x ", buf[j]); } printf("\n"); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int thread_args[2]; int main(int argc, char *argv[]) { int fd = openPort(argv[1]); int fd2 = openPort(argv[2]); pthread_t threads[2]; thread_args[0] = fd; thread_args[1] = fd2; pthread_create(&threads[0], NULL, rotorez_thread, (void *)&thread_args[0]); pthread_create(&threads[1], NULL, rotorez_thread, (void *)&thread_args[1]); pthread_exit(NULL); return 0; /* again: int flag = 0; while (1) { int bytes; if (!flag) bytes = getmyline(fd, buf); else bytes = getmyline(fd2, buf); flag = !flag; if (bytes == 0) { //close(fd); printf("again\n"); goto again; } printf("line=%s\n", buf); if (strncmp(buf,"BI1",3) == 0) { sprintf(buf,"%3.1f;", az); n = write(flag?fd:fd2, buf, strlen(buf)); printf("n=%d\n", n); } else if (strncmp(buf,"AP1",3) == 0) { sscanf(buf,"AP1%f", &az); } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } return 0; */ } static void *rotorez_thread(void *arg) { int n = 0; char buf[256]; int fd = *(int *)arg; float az = 123; float el = 45; again: while (1) { int bytes; bytes = getmyline(fd, buf); if (bytes == 0) { //close(fd); hl_usleep(100 * 1000); //printf("again\n"); goto again; } printf("line[%d]=%s\n", fd, buf); if (strncmp(buf, "BI1", 3) == 0) { if (fd == thread_args[0]) { sprintf(buf, "%3.1f;", az); printf("az=%f\n", az); } else { sprintf(buf, "%3.1f;", el); printf("el=%f\n", el); } n = write(fd, buf, strlen(buf)); printf("n=%d fd=%d\n", n, fd); } else if (strncmp(buf, "AP1", 3) == 0) { if (fd == thread_args[0]) { sscanf(buf, "AP1%f", &az); } else { sscanf(buf, "AP1%f", &el); } } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } pthread_exit(NULL); } hamlib-4.6.5/simulators/simic7300.c0000664000175000017500000004664615056640443012460 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; int keyspd = 85; // 85=20WPM int band = 8; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 1; pbwidth_t widthB = 2; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyertype = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; printf("i=%d, c=0x%02x\n", i, c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); printf("\n"); // echo //n = write(fd, buf, i); //if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: if (frame[5] == 0xfd) { //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { dump_hex(frame, 11); n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } } else { if (current_vfo == RIG_VFO_A) { freqA = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } else { freqB = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("cmd=0x14\n"); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x01: // band if (frame[6] == 0xfd) { frame[6] = band; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { band = frame[6]; printf("Band select=%d\n", band); frame[4] = 0xfb; frame[5] = 0xfe; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x05: { int item = frame[6] * 256 + frame[7]; printf("0x05 *************************** item=%04x\n", item); if (frame[8] != 0xfd) // then we're setting it { switch (item) { case 164: keyertype = frame[8]; break; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else // we're reading it { switch (item) case 164: frame[8] = keyertype; frame[9] = 0xfb; break; } n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("X25 get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; #if 0 unsigned char frame2[11]; frame2[0] = 0xfe; frame2[1] = 0xfe; frame2[2] = 0x00; // send transceive frame frame2[3] = frame[3]; // send transceive frame frame2[4] = 0x00; frame2[5] = 0x70; frame2[6] = 0x28; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #if 0 // send async frame frame[2] = 0x00; // async freq frame[3] = 0xa2; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x10; frame[7] = 0x01; frame[8] = 0x96; frame[9] = 0x12; frame[10] = 0xfd; n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simic7200.c0000664000175000017500000005535115056640443012450 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 85; int filter_width = 38; int preamp = 0; int attenuator = 0; int autonotch = 0; int aflevel = 128; int noiseblanker = 0; int manualnotch = 0; int mnf = 0; int noisereduction = 0; int speechcompressor = 0; int agc = 0; int vox = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s: %s ", mytime, __func__); dumphex(buf, i); #if 0 // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } #endif return i; } if (i > 2 && c == 0xfe) { printf("Turning power on due to 0xfe string\n"); powerstat = 1; int j; for (j = i; j < 175; ++j) { if (read(fd, &c, 1) < 0) { break; } } i = 0; goto again; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } // reverse the addressing frame[3] = frame[2]; frame[2] = 0xe0; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; if (powerstat) { n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0) { split = 0; } else if (frame[5] == 1) { split = 1; } else { frame[6] = split; } if (frame[5] == 0xfd) { printf("get split %d\n", 1); frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x11: if (frame[6] == 0xfd) { frame[6] = attenuator; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { attenuator = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x01: if (frame[6] == 0xfd) { frame[6] = aflevel; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { aflevel = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[4] = 0xfb; frame[5] = 0xfd; dumphex(frame, 6); hl_usleep(10 * 1000); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfd; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x0d: if (frame[6] == 0xfd) { frame[6] = mnf; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { mnf = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } ovf_status = ovf_status == 0 ? 1 : 0; break; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x02: if (frame[6] == 0xfd) { frame[6] = preamp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { preamp = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: if (frame[6] == 0xfd) { frame[6] = agc; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { agc = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x22: if (frame[6] == 0xfd) { frame[6] = noiseblanker; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { noiseblanker = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x40: if (frame[6] == 0xfd) { frame[6] = noisereduction; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { noisereduction = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x41: if (frame[6] == 0xfd) { frame[6] = autonotch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { autonotch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x44: if (frame[6] == 0xfd) { frame[6] = speechcompressor; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { speechcompressor = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x46: if (frame[6] == 0xfd) { frame[6] = vox; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { vox = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x48: if (frame[6] == 0xfd) { frame[6] = manualnotch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { manualnotch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x02: // filter width printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = filter_width; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("FILTER_WIDTH RESPONSE******************************"); filter_width = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x04: // AGC TIME printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = agc_time; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; default: printf("cmd 0x%02x unknown\n", frame[4]); } if (n == 0) { printf("Write failed=%s\n", strerror(errno)); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); printf("x25/x26 command rejected\n"); #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.5/simulators/simft710.c0000664000175000017500000003712615056640443012405 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int ks = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; int vs = 0; int vx = 0; int pa = 0; int ra = 0; int ag = 0; int pc = 100; int is = 0; int bp_on = 0; int bp_pos = 0; int rl = 0; int nb = 0; int nr = 0; int tx = 0; int mg = 0; int rg = 100; int vg = 0; int kr = 0; int bi = 0; int gt = 0; int ex016 = 0; int ex020 = 0; int st = 0; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682, NC_RIGID_FT710 = 800 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { // printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM4;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM4"); } } else if (strcmp(buf, "RM5;") == 0) { static int power = 0; power += 5; if (power > 255) { power = 0; } hl_usleep(50 * 1000); snprintf(buf, sizeof(buf), "RM5%03d000;", power); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM6;") == 0) { hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(50 * 1000); int id = NC_RIGID_FT710; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; } else if (strcmp(buf, "MD0;") == 0) { printf("MD=%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VS"); } } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "KR;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "KR%d;", kr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("KR"); } } else if (strncmp(buf, "KR", 2) == 0) { sscanf(buf, "KR%d", &kr); } else if (strcmp(buf, "BI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BI%d;", bi); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BI"); } } else if (strncmp(buf, "BI", 2) == 0) { sscanf(buf, "BI%d", &bi); } else if (strcmp(buf, "VX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VX%d;", vx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VX"); } } else if (strncmp(buf, "VX", 2) == 0) { sscanf(buf, "VX%d", &vx); } else if (strcmp(buf, "PA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PA%d;", pa); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PA"); } } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &vs); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RA%d;", ra); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RA"); } } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AG%d;", ag); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("AG"); } } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "PC;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PC"); } } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "VG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VG%03d;", vg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VG"); } } else if (strncmp(buf, "VG", 2) == 0) { sscanf(buf, "VG%d", &vg); } else if (strcmp(buf, "RG0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RG0%03d;", rg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RG"); } } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG0%d", &rg); } else if (strcmp(buf, "GT0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "GT0%0d;", gt); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("GT"); } } else if (strncmp(buf, "GT", 2) == 0) { sscanf(buf, "GT0%d", >); } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "TX+%04d;", tx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "IS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "IS+%04d;", is); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("IS"); } } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strcmp(buf, "RL0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RL0%d;", rl); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RL"); } } else if (strncmp(buf, "RL", 2) == 0) { sscanf(buf, "RL0%02d", &rl); } else if (strcmp(buf, "BP00;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_on); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP00", 4) == 0) { sscanf(buf, "BP00%d", &bp_on); } else if (strcmp(buf, "BP01;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_pos); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP01", 4) == 0) { sscanf(buf, "BP01%d", &bp_pos); } else if (strcmp(buf, "NB0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NB0%d;", nb); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NB"); } } else if (strncmp(buf, "NB0", 3) == 0) { sscanf(buf, "NB0%d", &nb); } else if (strcmp(buf, "NR0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NR0%d;", nr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NR"); } } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "EX016;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX016%04d;", ex016); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strcmp(buf, "EX020;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX020%04d;", ex020); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strncmp(buf, "EX020", 5) == 0) { sscanf(buf, "EX020%d\n", &ex020); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", ks); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &ks); } else if (strncmp(buf, "MG;", 3) == 0) { sprintf(buf, "MG%03d;", mg); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%03d", &mg); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strncmp(buf, "ST1", 3) == 0) { sscanf(buf, "ST1%3d", &st); } else if (strncmp(buf, "ST;", 3) == 0) { sprintf(buf, "ST%d;", st); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simicgeneric.c0000664000175000017500000002445215056640443013472 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include "sim.h" #define BUFSIZE 256 //#define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_CW; mode_t modeB = RIG_MODE_USB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; WRITE(fd, frame, 11); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xd0: current_vfo = RIG_VFO_MAIN; break; case 0xd1: current_vfo = RIG_VFO_SUB; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("n=WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; WRITE(fd, frame, 8); break; case 0x04: // IC7200 data mode frame[6] = 0; frame[7] = 0; frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x07: // satmode frame[6] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; WRITE(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; WRITE(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.5/simulators/simspid.c0000664000175000017500000000400215056640443012466 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.5/simulators/simmicom.c0000664000175000017500000000466315056640443012650 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #include "../src/misc.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { int i = 0; int n = 0; memset(buf, 0, BUFSIZE); n = read(fd, buf, 4); if (n <= 0) { sleep(1); return 0;} int bytesToRead = buf[1] + 2; //; len does not include cksum, or eom n += read(fd, &buf[4], bytesToRead); printf("n=%d:", n); for (i = 0; i < n; ++i) { printf(" %02x", buf[i]); } printf("\n"); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } switch (buf[3]) { case 0x06: printf("Report receiver freq\n"); unsigned char cmd[11] = { 0x24, 0x06, 0x18, 0x05, 0x01, 0x00, 0x38, 0xea, 0x50, 0xba, 0x03}; dump_hex(cmd, 11); int n = write(fd, cmd, sizeof(cmd)); printf("%d bytes sent\n", n); break; case 0x13: printf("PTT On\n"); break; case 0x14: printf("PTT Off\n"); break; case 0x36: printf("Key request\n"); break; default: printf("Unknown cmd=%02x\n", buf[3]); } } return 0; } hamlib-4.6.5/simulators/simatd578.c0000664000175000017500000000722015056640443012550 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int ptt = 0; int curr_vfo = 0; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); // seems the anytone only gives 8-byte commands and 1-byte responses do { int bytes = read(fd, &c, 1); if (bytes > 0) { buf[i++] = c; } n++; } while (c != 0x0a); printf("n=%d \n", n); for (i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { unsigned char buf[256], buf2[256]; int n; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 8) { printf("Not 8 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case 0x41: if (buf[4] == 0x00) // set ptt { if (buf[1] == 1) { ptt = 1; printf("PTT ON\n"); } else { ptt = 0; printf("PTT OFF\n"); } buf[0] = 0x06; n = write(fd, buf, 1); } if (buf[4] == 0x20) // get vfo { printf("Get VFO curr_vfo=%d\n", curr_vfo); if (curr_vfo == 1) { curr_vfo = 0; } else { curr_vfo = 1; } printf("Get VFO curr_vfo=%d\n", curr_vfo); buf2[0] = 0xaa; buf2[1] = 0x53; buf2[2] = 0x00; buf2[3] = 0x00; buf2[4] = 0x00; buf2[5] = 0x01; buf2[6] = 0x01; buf2[7] = 0x00; buf2[8] = curr_vfo; buf2[9] = 0x00; buf2[10] = 0x10; buf2[11] = 0x00; buf2[12] = 0x00; buf2[13] = 0x00; buf2[14] = 0x00; buf2[15] = 0x00; buf2[16] = 0x06; n = write(fd, buf2, 17); } break; case 0x06: buf[0] = 0x06; n = write(fd, buf, 1); break; default: printf("Unknown cmd=%02x\n", buf[0]); continue; } printf("%d bytes returned\n", n); } return 0; } hamlib-4.6.5/simulators/simxiegug90.c0000664000175000017500000002511515056640443013200 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_CW; mode_t modeB = RIG_MODE_USB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int keyspd = 20; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } } //printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; write(fd, frame, 11); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xb0: freq = freqA; freqA = freqB; freqB = freq; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; #if 0 case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("n=write 8 bytes\n"); dump_hex(frame, 8); write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; write(fd, frame, 9); break; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; write(fd, frame, 7); break; #endif case 0x19: frame[6] = 0x00; frame[7] = 0x80; frame[8] = 0xfd; write(fd, frame, 9); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; write(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; write(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.5/simulators/simts890.c0000664000175000017500000013531515056640443012432 //#define TRACE /* Full traffic trace if enabled */ // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include "config.h" #include #include #include #include #include #include #include #include //#include /* Definitions */ /* The TS-890S has some undocumented commands, left over from older * Kenwood models. They have newer counterparts with more functionality, * but are still around for legacy software. If you want to see if your * app is only using the latest-and-greatest, comment out the next define. */ #define LEGACY // Size of command buffer #define BUFSIZE 256 // Number of selectable bands #define NBANDS 11 /* Type we're emulating - K=The Americas(default), E=Europe */ #if !defined(TYPE) #define TYPE K #endif /* Define a macro for sending response back to the app * This will allow us to reroute output to a buffering routine * Needed to handle multiple commands in a single message * Also makes it easy to trace */ #if defined(TRACE) #define OUTPUT(s) {printf("Resp:\"%s\"\n", s); write(fd, s, strlen(s)); } #else #define OUTPUT(s) write(fd, s, strlen(s)) #endif int mysleep = 20; int filternum1 = 7; int filternum2 = 8; int ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 20; int sl = 3, sh = 3; int nr = 0; int pa = 0; int pc = 25; int sm = 35; int nt = 0; int ag = 100; int ac = 0; int nb[2] = {0, 0}; // NB1/NB2 OFF/ON int sq = 0; int rg = 0; int mg = 0; int ra = 0; int rl = 0; int is = 0; int sp = 0; // Split OFF/ON int split_op = 0; // Split frequency setting operation in progress int rit = 0, xit = 0, rxit = 0; // RIT off/on, XIT off/on, Offset freq(-9999<=rxit<=+9999) int fine = 0; // Fine tuning - step size off=10hz, on=1hz // Clock data int autoset = 1; int tzs[2] = {36, 56}; // 0=primary(EST), 1=auxiliary(UTC) char auxtzc = 'U'; // Auxiliary clock identifier (UTC) // Antenna connections char antnum = '1', recant = '0', driveout = '0', antout = '0'; // Multiple meter functions struct meter_data { int enabled; int value; // # of pips lit, range 0-70 }; struct meter_data meter[6] = { { 0, 5}, // ALC { 0, 1}, // SWR { 0, 10}, // COMP { 0, 30}, // ID (amps) { 0, 60}, // Vd (Volts) { 0, 20} // Temp (Unknown units) }; int tfset = 0; typedef struct kvfo { int freq; int mode; short band, vfo; // Redundant, but useful for relative movement } *kvfop_t; int nummems = 3; // Default - values = 1, 3, 5 int bandslot[2][NBANDS]; // 0-based band memory: ((bandslot[i] + 1) % nummems) (+1 for display) /* Storage and default data for band memories * vfoA freq and mode initialized here, vfoB and other items set at startup * 1, 3(default), or 5 memories per band can be used. One is always active on * each band. Manually they are selected by multiple band button pushes; CAT * selection is by BD/BU command */ struct kvfo band_mem[2][NBANDS][5] = { { #if TYPE==K /* 160M */ { { 1800000, 3}, { 1810000, 3}, { 1820000, 3}, { 1830000, 3}, { 1840000, 3} }, /* 80M */ { { 3500000, 1}, { 3600000, 1}, { 3700000, 1}, { 3800000, 1}, { 3900000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { { 135700, 3}, { 472000, 3}, { 1000000, 5}, { 5305500, 2}, { 5403500, 2} } #else // TYPE==E /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1810000, 3}, { 1820000, 3} }, /* 80M */ { { 3500000, 1}, { 3550000, 1}, { 3600000, 1}, { 3650000, 1}, { 3700000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { {70100000, 2}, { 135700, 3}, { 472000, 5}, { 999000, 5}, { 5258500, 2} } #endif } }; /* Band definitions * differ by model */ struct band_def { int low; int high; }; const struct band_def band_limits[NBANDS] = { #if TYPE == K { 1800000, 2000000}, { 3500000, 4000000}, { 7000000, 7300000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, {50000000, 54000000}, { 30000, 60000000} #else { 1810000, 2000000}, { 3500000, 3800000}, { 7000000, 7200000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, {50000000, 52000000}, { 30000, 74800000} #endif }; /* Table for mode<->emission class conversion * Claas 0 = SSB * 1 = CW/FSK/PSK * 2 = FM * 3 = AM */ const int mode2classtab[16] = { -1, 0, 0, 1, 2, 3, 1, 1, -1, 1, 1, 1, 0, 0, 2, 3}; const int stepvalues[4][10] = // Step sizes in Hz { /* SSB */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* CW/FSK/PSK */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* FM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000}, /* AM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000} }; int stepsize[4] = { 1000, 500, 10000, 5000}; // Defaults by modeclass /* Function prototypes */ int freq2band(int freq); kvfop_t newvfo(kvfop_t ovfo, int band); void swapvfos(kvfop_t *vfoset[]); // Extracted from rig.h int hl_usleep(unsigned long usec); // Until it's replaced #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); int retval; while ((retval = read(fd, &c, 1)) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (retval != 0) { perror("read failed:"); close(fd); fd = openPort(""); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int cmd_err = 0; char *err_txt[] = { "?;", "E;", "O;" }; struct kvfo *vfoA = &band_mem[0][4][0], *vfoB = &band_mem[1][6][0]; kvfop_t *const vfoAB[2] = {&vfoA, &vfoB}; // 0=A, 1=B, fixed kvfop_t *vfoLR[2] = {&vfoA, &vfoB}; // 0=Left, 1=Right, can change #if defined(LEGACY) /* The IF command is not documented for the TS-890S, and is supposed * to be supplanted by SF. However, it is still there for legacy S/W. * This description is taken from the TS-590S/SG manual, with values * reflecting a real TS-890S. */ const char IFformat[] = "IF" // Output only "%011d" // P1 freq(Hz) " " // P2 ?? "% 05d" // P3 RIT/XIT freq(Hz) "%1d" // P4 RIT on/off "%1d" // P5 XIT on/off "000" // P6,P7 mem channel "%1d" // P8 RX/TX "%1X" // P9 Operating mode (See OM command) "0" // P10 Function? "0" // P11 Scan status? "%1d" // P12 Simplex=0/Split=1 "0" // P13 Tone/CTCSS (not on TS-890S) "00" // P14 Tone/CTCSS freq (not on TS-890S) "0;"; // P15 Always zero #endif const char SFformat[] = "SF" // Input/Output "%1d" // P1 VFOA/VFOB "%011d" // P2 Freq(Hz) "%1X;"; // P3 Mode /* Initialization */ for (int i = 0; i < NBANDS; i++) { for (int j = 0; j < 5; j++) { band_mem[1][i][j] = band_mem[0][i][j]; band_mem[1][i][j].vfo = 1; band_mem[0][i][j].band = band_mem[1][i][j].band = i; } } while (1) { hl_usleep(10); buf[0] = 0; /* Clean up from last continue - pass along any errors found */ if (cmd_err != 0) { OUTPUT(err_txt[cmd_err - 1]); cmd_err = 0; } if (getmyline(fd, buf) > 0) { #if defined(TRACE) printf("Cmd:\"%s\"\n", buf); #endif } // else { return 0; } buf[0] = toupper(buf[0]); buf[1] = toupper(buf[1]); if (strcmp(buf, "IF;") == 0) { // Reads the transceiver status #if defined(LEGACY) char ifbuf[256]; hl_usleep(mysleep * 1000); sprintf(ifbuf, IFformat, (*vfoLR[0])->freq, rxit, rit, xit, (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, (*vfoLR[0])->mode, sp); OUTPUT(ifbuf); #else cmd_err = 1; #endif } else if (strncmp(buf, "AN", 2) == 0) { // Antenna connection handling hl_usleep(mysleep * 1000); if (buf[2] == ';') { buf[2] = antnum; buf[3] = recant; buf[4] = driveout; buf[5] = antout; buf[6] = ';'; buf[7] = '\0'; OUTPUT(buf); } else { if (buf[2] != '9') { antnum = buf[2]; } if (buf[3] != '9') { recant = buf[3]; } if (buf[4] != '9') { driveout = buf[4]; } if (buf[5] != '9') { antout = buf[5]; } } } else if (strncmp(buf, "NB", 2) == 0) { // Noise Blanker settings int idx; switch (toupper(buf[2])) { case '1': // Noise Blanker 1 case '2': // Noise Blanker 2 idx = buf[2] - '1'; if (buf[3] == ';') { // Read hl_usleep(mysleep * 20); sprintf(buf, "NB%d%d;", idx + 1, nb[idx]); OUTPUT(buf); } else { // Set nb[idx] = buf[3] - '0'; } break; case 'D': // Noise Blanker 2, type B Depth case 'T': // Noise Blanker 2 Type case 'W': // Noise Blanker 2, type B Width break; default: cmd_err = 1; } } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 200); sprintf(buf, "RA%d;", ra); OUTPUT(buf); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 000); pbuf = "RG255;"; OUTPUT(pbuf); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; OUTPUT(pbuf); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; OUTPUT(pbuf); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.05;"; OUTPUT(pbuf); } else if (strncmp(buf, "IS;", 3) == 0) { snprintf(buf, sizeof(buf), "IS%+04d;", is); OUTPUT(buf); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strncmp(buf, "SM;", 3) == 0) { pbuf = "SM0035;"; OUTPUT(pbuf); } else if (strncmp(buf, "PC;", 3) == 0) { snprintf(buf, sizeof(buf), "PC%03d;", pc); OUTPUT(buf); } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(mysleep * 1000); int id = 24; snprintf(buf, sizeof(buf), "ID%03d;", id); OUTPUT(buf); } else if (strncmp(buf, "EX", 2) == 0) { // Menu Setting if (strcmp(buf + 2, "00011;") == 0) { // S-Meter Scale pbuf = "EX00011 001;"; OUTPUT(pbuf); } else if (strncmp(buf + 2, "00311", 5) == 0) { // Number of Band Memories if (buf[7] == ';') { snprintf(buf, sizeof buf, "EX00311 %03d;", nummems / 2); // Rounds down OUTPUT(buf); } else { int temp = -1; sscanf(buf + 8, "%3d", &temp); if (temp <= 2 && temp >= 0) { nummems = temp * 2 + 1; } else { cmd_err = 1; } } } else if (strncmp(buf + 2, "00301", 5) >= 0 && strncmp(buf + 2, "00304", 5) <= 0) { // [SSB|CW/FSK/PSK|FM|AM] Mode Frequency Step Size (Multi/Channel Control) int class = buf[6] - '1'; int i, tmpstep = -1; if (buf[7] == ';') { // Read for (i = 0; i < 10 && stepvalues[class][i] != 0; i++) { if (stepsize[class] == stepvalues[class][i]) { tmpstep = i; break; } } if (tmpstep < 0) {cmd_err = 3; continue;} // Shouldn't happen snprintf(buf + 7, sizeof(buf) - 7, " %03d;", tmpstep); OUTPUT(buf); } else { // Set tmpstep = atoi(buf + 8); if (tmpstep < 0 || tmpstep > 9 || stepvalues[class][tmpstep] == 0) {cmd_err = 1; continue;} stepsize[class] = stepvalues[class][tmpstep]; } } } else if (buf[0] == 'F' && (buf[1] == 'A' || buf[1] == 'B')) // FA/FB { // VFO {A|B} Frequency int idx = buf[1] - 'A'; if (buf[2] == ';') { snprintf(buf + 2, sizeof(buf) - 2, "%011d;", (*vfoAB[idx])->freq); OUTPUT(buf); } else { int tmpfreq, newband; kvfop_t ovfo, nvfo; sscanf(buf + 2, "%d", &tmpfreq); newband = freq2band(tmpfreq); if (newband < 0) {cmd_err = 1; continue; } ovfo = *vfoAB[idx]; nvfo = newvfo(ovfo, newband); nvfo->freq = tmpfreq; *vfoAB[idx] = nvfo; } } else if (strncmp(buf, "AI;", 3) == 0) { pbuf = "AI0;"; OUTPUT(pbuf); } else if (strncmp(buf, "PS;", 3) == 0) { snprintf(buf, sizeof(buf), "PS1;"); OUTPUT(buf); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { int tmpvfo = buf[2] - '0'; if (tmpvfo < 0 || tmpvfo > 1) { cmd_err = 1; continue; } snprintf(buf, sizeof(buf), SFformat, tmpvfo, (*vfoAB[tmpvfo])->freq, (*vfoAB[tmpvfo])->mode); //printf("SF buf=%s\n", buf); OUTPUT(buf); } else if (strncmp(buf, "SF", 2) == 0) { // Sets and Reads the VFO (Frequency and Mode) int tmpvfo, tmpfreq, tmpmode, newband; kvfop_t ovfo, nvfo; if (sscanf(buf, SFformat, &tmpvfo, &tmpfreq, &tmpmode) != 3 || tmpvfo < 0 || tmpvfo > 1) { printf("Error decoding SF:%s\n", buf); cmd_err = 1; continue; } //printf("tmpvfo=%d, tmpfreq=%d, tmpmode=%d\n", tmpvfo, tmpfreq, tmpmode); ovfo = *vfoAB[tmpvfo]; newband = freq2band(tmpfreq); if (newband < 0) {cmd_err = 1; continue; } nvfo = newvfo(ovfo, newband); nvfo->mode = tmpmode; nvfo->freq = tmpfreq; *vfoAB[tmpvfo] = nvfo; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } else if (strncmp(buf, "FR", 2) == 0) { // Receiver Function (VFO A / VFO B / Memory channel) int idx; if (buf[2] == ';') { // Read idx = sp && tfset; snprintf(buf, sizeof(buf), "FR%d;", (*vfoLR[idx])->vfo); OUTPUT(buf); } else { // Set idx = buf[2] - '0'; if (idx == 3) { //TODO: Memory channels are a long way off puts("Memory channels not implemented.\n"); cmd_err = 3; continue; } if (idx < 0 || idx > 1) {cmd_err = 1; continue; } sp = 0; // Turn off split if ((*vfoLR[0])->vfo != idx) // If the selected vfo is not the operational one { swapvfos(vfoLR); // Make it so } } } else if (strncmp(buf, "FT", 2) == 0) { // Transmitter Function ( VFO A / VFO B ) int idx; if (buf[2] == ';') { // Read idx = sp && !tfset; snprintf(buf, sizeof(buf), "FT%d;", (*vfoLR[idx])->vfo); OUTPUT(buf); } else { // Set idx = buf[2] - '0'; if (idx < 0 || idx > 1) {cmd_err = 1; continue; } sp = idx != (*vfoLR[0])->vfo; // Turn split on if vfos differ, else off } } else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD { // Frequency Band Selection(Setting 1)/[UP}/{DOWN] Operating(Setting 2) int band, idx, newfreq; int dir = buf[1] == 'D' ? -1 : +1; kvfop_t ovfo = *vfoLR[0]; // Current operating VFO if (buf[2] == ';') { // Setting 2 /* The TS-890S doesn't have a real BAND_UP/BAND_DOWN command * This one just does a simple UP/DOWN. As the manual says, just * like pushing the UP/DOWN button on the mic */ int class = mode2classtab[ovfo->mode]; if (class < 0 || class > 3) {cmd_err = 3; continue;} // Shouldn't happen newfreq = ovfo->freq + (dir * stepsize[class]); //TODO: Checking for band edges needs to go here ovfo->freq = newfreq; } else if (buf[3] == ';') { // Read idx = buf[2] - '0'; if (idx < 0 || idx > 1) {cmd_err = 1; continue;} snprintf(buf + 3, sizeof(buf) - 3, "%d;", bandslot[idx][ovfo->band] + 1); OUTPUT(buf); } else if (buf[5] == ';') { // Setting 1 band = atoi(buf + 3); if (band < 0 || band >= NBANDS) {cmd_err = 1; continue;} if (band == ovfo->band) { // Same band, cycle the band memory # bandslot[ovfo->vfo][band] = (bandslot[ovfo->vfo][band] + 1) % nummems; } *vfoLR[0] = newvfo(ovfo, band); } else { cmd_err = 1; } } else if ((strncmp(buf, "DN", 2) == 0) || (strncmp(buf, "UP", 2) == 0)) { // Microphone UP/DOWN Switch Operation int dir = buf[0] == 'D' ? -1 : +1; int steps = -1; kvfop_t ovfo = *vfoLR[0]; // Modify the current operational VFO if (buf[2] == ';') { steps = 1; } else if (buf[4] == ';') { steps = atoi(buf + 2); } if (steps < 0 || steps > 99) {cmd_err = 1; continue;} ovfo->freq += dir * steps * stepsize[mode2classtab[ovfo->mode]]; } else if (strncmp(buf, "FC", 2) == 0) { // Change the Frequency (Tuning Control) static const int fc_steps[6] = { 1, 2, 5, 10, 50, 100}; int dir = buf[2] == '0' ? +1 : -1; int stepidx = buf[3] - '0'; int delta; kvfop_t ovfo = *vfoLR[0]; if (stepidx < 0 || stepidx > 5) {cmd_err = 1; continue;} delta = dir * fc_steps[stepidx] * stepsize[mode2classtab[ovfo->mode]]; //TODO: This really needs a sanity check here ovfo->freq += delta; } else if (strncmp(buf, "UD", 2) == 0) { // VFO Frequency UP/DOWN int idx = buf[2] - '0'; int dir = buf[3] == '0' ? +1 : -1; int steps = -1; kvfop_t nvfo; if (idx < 0 || idx > 1 || tfset != 0) {cmd_err = 1; continue;} nvfo = *vfoAB[idx]; if (buf[4] == ';') { steps = 1; } else if (buf[6] == ';') { steps = atoi(buf + 4); } if (steps < 0 || steps > 99) {cmd_err = 1; continue; } nvfo->freq += dir * steps * stepsize[mode2classtab[nvfo->mode]]; } else if (strcmp(buf, "RX;") == 0) { // Receive Function State ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strncmp(buf, "TX", 2) == 0) { // Transmission Mode ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': case '0': ptt = ptt_mic = 1; break; case '1': ptt_data = 1; break; case '2': ptt_tune = 1; break; } } else if (strncmp(buf, "SP", 2) == 0) { // Split Operation Frequency Setting if (buf[2] == ';') { // Read snprintf(buf + 2, sizeof(buf) - 2, "%1d;", split_op); OUTPUT(buf); } else if (buf[3] == ';') { // Set 1 /* This section needs a lot of work, and a lot * of cooperation from other commands. * AFAICT the split freq can be set by spinning * the big knob, or by other means. When oper=0 * is sent, the current freq is used as the split * value. See page 5-1 of the IM, blinking SPLIT */ switch (buf[2]) { case '0': // Operation complete if (split_op) // If a split setup was in progress, { sp = 1; // split operation is enabled } //TODO: Set split freq VFO split_op = 0; break; case '1': // Start split frequency setup split_op = 1; break; case '2': // Cancel op split_op = 0; break; default: cmd_err = 1; } } else { // Set 2 int dir, split, spfreq, band; kvfop_t ovfo, svfo; sscanf(buf, "SP%1d%1d%1d", &sp, &dir, &split); dir = dir == 0 ? +1 : -1; split = dir * 1000 * split; // Convert kHz to +/- Hz ovfo = *vfoLR[0]; // Operational VFO spfreq = ovfo->freq + split; band = freq2band(spfreq); svfo = newvfo(*vfoLR[1], band); // Other VFO svfo->freq = spfreq; *vfoLR[1] = svfo; sp = 1; // Turn On Split } } else if (strncmp(buf, "TB;", 3) == 0) { // Split sprintf(buf, "TB%d;", sp); OUTPUT(buf); } else if (strncmp(buf, "TB", 2) == 0) { sscanf(buf, "TB%d", &sp); } else if (strncmp(buf, "TS", 2) == 0) { // TF-SET if (buf[2] == ';') { snprintf(buf, sizeof buf, "TS%d;", tfset); OUTPUT(buf); } else if (buf[2] >= '0' && buf[2] < '2') { if (sp && (tfset != buf[2] - '0')) { // Split is set and we're changing state of TF-SET swapvfos(vfoLR); // Reverse vfo functions } tfset = buf[2] - '0'; } else { cmd_err = 1; } } else if (strcmp(buf, "EC;") == 0) { // VFO A and VFO B Frequency Information Exchange /* No matter what the title says above, the TS-890S does not * have a frequency swap command. It does, however, have a VFO * function exchange - just by swapping the left and right displays. * This command is the same as the "A/B" button on the front panel. */ swapvfos(vfoLR); } else if (strcmp(buf, "VV;") == 0) { // VFO A to VFO B Copy ([A=B] Operation) /* Akin to the EC command above, this isn't really a "VFO A to VFO B" * copy, but an "Operational VFO to Secondary VFO" copy. It also * mimics the front panel [A=B] action. */ kvfop_t ovfo, svfo; ovfo = *vfoLR[0]; svfo = newvfo(*vfoLR[1], ovfo->band); // Get appropriate vfo for new freq svfo->freq = ovfo->freq; svfo->mode = ovfo->mode; *vfoLR[1] = svfo; } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); OUTPUT(buf); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "KY", 2) == 0) { // CW Keying if (buf[2] == ';') { // Checking status - we always have room OUTPUT("KY0;"); } else if (buf[3] == ';') { // Stop sending(?) if (buf[2] != '0') {cmd_err = 1; } } else { // Send the message //printf("CW mesg: %s\n", buf + 2); } } else if (strncmp(buf, "OM", 2) == 0) { // Operating Mode /* The TS-890S displays two frequencies and modes - left and right, * along with arrows that show which is VFO A and which is VFO B. * In almost all cases, the left VFO is the receive freq. The right * VFO is only used in split operation, as the transmit frequency. */ if (buf[3] == ';') { int tmpvfo = buf[2] - '0'; if (tmpvfo < 0 || tmpvfo > 1) { cmd_err = 1; } else { sprintf(buf, "OM%d%X;", tmpvfo, (*vfoLR[tmpvfo])->mode); OUTPUT(buf); } } else { /* Setting - Only sets the active function(RX/TX), * which is always the left VFO unless split is active and * we are transmitting. */ int idx = sp && ((ptt + ptt_mic + ptt_data + ptt_tune) > 0); sscanf(&buf[3], "%1X", &(*vfoLR[idx])->mode); } } else if (strncmp(buf, "MD", 2) == 0) { // Sets and reads the operating mode status #if defined(LEGACY) if (buf[2] == ';') { snprintf(buf, sizeof(buf), "MD%X;", (*vfoLR[0])->mode); OUTPUT(buf); } else { sscanf(buf, "MD%1X", &(*vfoLR[0])->mode); } #else cmd_err = 1; #endif } else if (strncmp(buf, "RM", 2) == 0) { // Meter if (buf[2] == ';') { // Read all enabled meters char tbuf[8]; buf[0] = '\0'; pbuf = buf; for (int i = 0; i < 6; i++) { if (meter[i].enabled) { snprintf(tbuf, sizeof tbuf, "RM%d%03d;", i + 1, meter[i].value); pbuf = stpcpy(pbuf, tbuf); } } if (buf[0] != '\0') { OUTPUT(buf); } } else { // Enable/disable one meter int target = buf[2] - '1'; int status = buf[3] - '0'; if (target < 0 || target > 5 || status < 0 || status > 1) { cmd_err = 2; continue; } meter[target].enabled = status; } } else if (strcmp(buf, "SL0;") == 0) { sprintf(buf, "SL0%02d;", sl); printf("R: %s\n", buf); OUTPUT(buf); } else if (strcmp(buf, "SH0;") == 0) { sprintf(buf, "SH0%03d;", sh); printf("R: %s\n", buf); OUTPUT(buf); } else if (strncmp(buf, "SL0", 3) == 0) { printf("Cmd: %s\n", buf); sscanf(buf, "SL0%3d", &sl); } else if (strncmp(buf, "SH0", 3) == 0) { printf("Cmd: %s\n", buf); sscanf("SH0%3d", "%d", &sh); } else if (strcmp(buf, "NR;") == 0) { sprintf(buf, "NR%d;", nr); OUTPUT(buf); } else if (strncmp(buf, "NR", 2) == 0) { puts(buf); sscanf(buf, "NR%d", &nr); } else if (strcmp(buf, "PA;") == 0) { sprintf(buf, "PA%d;", pa); OUTPUT(buf); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &pa); } else if (strcmp(buf, "SM;") == 0) { sprintf(buf, "SM%04d;", sm); OUTPUT(buf); } else if (strcmp(buf, "PC;") == 0) { sprintf(buf, "PC%03d;", sm); OUTPUT(buf); } else if (strcmp(buf, "NT;") == 0) { sprintf(buf, "NT%d;", nt); OUTPUT(buf); } else if (strncmp(buf, "NT", 2) == 0) { sscanf(buf, "NT%d", &nt); } else if (strcmp(buf, "AG;") == 0) { sprintf(buf, "AG%03d;", ag); OUTPUT(buf); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "AC;") == 0) { sprintf(buf, "AC%03d;", ac); OUTPUT(buf); } else if (strncmp(buf, "AC", 2) == 0) { sscanf(buf, "AC%d", &ac); } else if (strcmp(buf, "SQ;") == 0) { sprintf(buf, "SQ%03d;", sq); OUTPUT(buf); } else if (strncmp(buf, "SQ", 2) == 0) { sscanf(buf, "SQ%d", &sq); } else if (strcmp(buf, "RG;") == 0) { sprintf(buf, "RG%03d;", rg); OUTPUT(buf); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rg); } else if (strcmp(buf, "MG;") == 0) { sprintf(buf, "MG%03d;", mg); OUTPUT(buf); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mg); } else if (strncmp(buf, "RL1;", 3) == 0) { snprintf(buf, sizeof(buf), "RL%02d;", rl); OUTPUT(buf); } else if (strncmp(buf, "RL1", 2) == 0) { puts(buf); sscanf(buf, "RL1%d", &rl); } else if (strncmp(buf, "FS", 2) == 0) { // FINE Function if (buf[2] == ';') { snprintf(buf, sizeof buf, "FS%d%d;", fine, fine); // For now OUTPUT(buf); } else { if (buf[2] == '0' || buf[2] == '1') { fine = buf[2] - '0'; } else { cmd_err = 1; } } } else if (strcmp(buf, "RC;") == 0) { // RIT/XIT Frequency Clear rxit = 0; } else if (buf[0] == 'R' && (buf[1] == 'D' || buf[1] == 'U')) // RD/RU { // RIT/XIT Frequency Up/Down int dir = buf[1] == 'D' ? -1 : +1; int tempit; if (buf[2] == ';') { tempit = rxit + (dir * (fine ? 1 : 10)); } else { tempit = rxit + dir * atoi(buf + 2); } if (abs(tempit) > 9999) {cmd_err = 1; continue;} /* Some weird rounding going on here - TBD */ rxit = tempit; } else if (strcmp(buf, "RF;") == 0) { // RIT/XIT Frequency snprintf(buf, sizeof buf, "RF%1d%04d;", rxit < 0 ? 1 : 0, abs(rxit)); OUTPUT(buf); } else if (strncmp(buf, "RT", 2) == 0) { // RIT Function State, RIT Shift switch (buf[2]) { case ';': // Read snprintf(buf, sizeof buf, "RT%d;", rit); OUTPUT(buf); break; case '0': // Set case '1': rit = buf[2] - '0'; break; case '2': // Shift //TODO: set recv freq to vfo+rxit, clear rxit and rit break; default: cmd_err = 1; } } else if (strncmp(buf, "XT", 2) == 0) { // XIT Function State, XIT Shift switch (buf[2]) { case '0': // Set case '1': xit = buf[2] - '0'; break; case '2': // Shift //TODO: set xmit freq to vfo+rxit(Which vfo?), set split, clear rxit and xit break; default: cmd_err = 1; } } else if (strncmp(buf, "CK", 2) == 0) { // All the clock functions switch (buf[2]) { case '0': // Get/Set Local clock { time_t t; struct tm *localtm; if (buf[3] == ';') { t = time(NULL); localtm = localtime(&t); strftime(&buf[3], BUFSIZ - 3, "%y%m%d%H%M%S;", localtm); OUTPUT(buf); } else { printf("Clock not set. cmd = %s\n", buf); } break; } case '1': // Setting status buf[3] = '1'; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); break; case '2': // Local clock time zone case '3': // Auxiliary clock time zone { int idx = buf[2] - '2'; if (buf[3] == ';') { sprintf(&buf[3], "%03d;", tzs[idx]); OUTPUT(buf); } else { sscanf(&buf[3], "%3d;", &tzs[idx]); } break; } case '4': // ID character for auxiliary clock if (buf[3] == ';') { buf[3] = auxtzc; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); } else { auxtzc = buf[3]; } break; case '5': // Date display format break; case '6': // Automatic date/time retrieval (NTP) //TODO: Fix this when we can set the clock if (buf[3] == ';') { buf[3] = autoset + '0'; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); } else { autoset = buf[3] - '0'; } break; case '7': // NTP server address case '8': // Force time update via NTP case '9': // Clock display (primary/secondary/both) default: printf("Bad clock command - %s\n", buf); } } else if (strncmp(buf, "BS", 2) == 0) { // All the Bandscope commands switch (toupper(buf[2])) { case '0': // Scope Display ON/OFF case '1': // Scope Display Type case '2': // Bandscpoe Operation Mode case '3': // Bandscope Span case '4': // Bandscope Span case '5': // Bandscope Scope Range (Fixed Mode) case '6': // Bandscope Display Pause case '7': // Bandscope Marker case '8': // Bandscope Attenuator case '9': // Bandscope Max Hold case 'A': // Bandscope Averaging case 'B': // Bandscope Waterfall Display Speed case 'C': // Bandscope Reference Level case 'D': // Bandscope Waterfall Display Clear case 'E': // Bandscope Marker Shift / Marker Center case 'G': // Audio Scope Attenuator case 'H': // Audio Scope Span case 'I': // Oscilloscope Level case 'J': // Oscilloscpoe Sweep Time case 'K': // Bandscope Shift Position case 'L': // Bandscope Receive Circuit State case 'M': // Bandscope Scope Range Lower/Upper Frequency Limit case 'N': // Audio Scope Display Pause case 'O': // Expands Spectrum Analysis Range break; default: // Unknown cmd_err = 1; } } else if (strncmp(buf, "CD", 2) == 0) { // CW Communications switch (buf[2]) { case '0': // CW Communication Screen Display case '1': // CW Morse Decoding Threshold Level case '2': // Decoded CW Morse Character Output case '3': // CW Communication Screen (Decode Filter) case '4': // CW Communication Screen (Quick Mode) case '5': // CW Decode break; default: cmd_err = 1; } } else if (strncmp(buf, "CM", 2) == 0) { // CW Message Memory switch (buf[2]) { case '0': // Registration of CW Message (Paddle Input) case '1': // Play/Stop the CW Message case '2': // Register State of CW Message (Paddle Input) case '3': // Clear the CW Message (Paddle Input) case '4': // CW Message Memory Name (Paddle Input) case '5': // Registering the CW Message Memory (Text Input) case '6': // CW Message Channel Repeat case '7': // Contest Number break; default: cmd_err = 1; // Unknown command } } else if (strncmp(buf, "FL", 2) == 0) { switch (buf[2]) { case '0': // Select the Receive Filter case '1': // Roofing Filter case '2': // IF Filter Shape case '3': // AF Filter Type continue; // For now default: cmd_err = 1; } } else if (strncmp(buf, "FM", 2) == 0) { // Frequency Markers switch (buf[2]) { case '0': // Frequency Marker Function case '1': // Frequency Marker List Registration case '2': // Total Number Registered of Frequency Marker List case '3': // Frequency Marker List Readout case '4': // Frequency Marker List Delete break; default: cmd_err = 1; } } else if (strncmp(buf, "IP", 2) == 0) { // Network Config switch (buf[2]) { case '0': // DHCP case '1': // IP Address (Manual Configuration) case '2': // MAC Address break; default: cmd_err = 1; } } else if (strncmp(buf, "LA", 2) == 0) { // Linear Amplifier Configuration switch (buf[2]) { case '0': // Target Band of Linear Amplifier Menu case '1': // Linear Amplifier ON/OFF case '2': // Linear Amplifier Transmission Control case '3': // Linear Amplifier Transmission Delay ON/OFF case '4': // Linear Amplifier Transmission Delay Time case '5': // Linear Amplifier Relay Control case '6': // Linear Amplifier External ALC Voltage break; default: cmd_err = 1; } } else if (strncmp(buf, "MA", 2) == 0) { // Memory Channel Functions switch (buf[2]) { case '0': // Memory Channel Configuration case '1': // Memort Channel (Direct Write) case '2': // Memory Channel (Channel Name) case '3': // Memory Channel (Scan Lockout) case '4': // Memory Channel (Channel Copy) case '5': // Memory Channel (Channel Deletion) case '6': // Programmable VFO End Frequency case '7': // Memory Channel (Temporary Change Frequency) break; default: cmd_err = 1; } } else if (strncmp(buf, "PB", 2) == 0) { // Voice Messages switch (buf[2]) { case '0': // Voice Message List Display case '1': // Voice Message Playback, etc. case '2': // Voice Message Channel Registration State case '3': // Voice Message Channel Repeat case '4': // Voice Message Channel Name case '5': // Voice Message Recording Sound Source case '6': // Voice Message Recording Total Remaining Time break; default: cmd_err = 1; } } else if (strncmp(buf, "SC", 2) == 0) { // Scan functions switch (buf[2]) { case '0': // Scan case '1': // Scan Speed case '2': // Tone Scan/CTCSS Scan case '3': // Program Scan/VFO Scan Selection break; default: cmd_err = 1; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } /* Convert freq to TS-890S band # * * Input freq in Hz * * Returns band # or negative if invalid input */ int freq2band(int freq) { int i, retval = -1; // Assume the worst for (i = 0; i < NBANDS; i++) { if (freq >= band_limits[i].low && freq <= band_limits[i].high) { retval = i; break; } } //printf("%dHz is in band # %d\n", freq, retval); return retval; } /* Get appropriate vfo for new frequency * * Input: current vfo * new band * Return: new vfo pointer */ kvfop_t newvfo(kvfop_t ovfo, int band) { int vfonum, slot; vfonum = ovfo->vfo; slot = bandslot[vfonum][band]; return &band_mem[vfonum][band][slot]; } /* Reverse the function of vfoA and vfoB * No status returned */ void swapvfos(kvfop_t *vfoset[]) { kvfop_t *temp; temp = vfoset[0]; vfoset[0] = vfoset[1]; vfoset[1] = temp; return; } hamlib-4.6.5/simulators/simorion.c0000664000175000017500000000667115056640443012673 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 int freqA = 14074000; int freqB = 14074500; int modeA = 0; int width = 3010; int ptt = 0; int keyspd = 20; int getmyline(int fd, char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { if (c == 0x0d) { break; } buf[i++] = c; n++; } return n; } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256], reply[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (strncmp(buf, "?V", 2) == 0) { char *s = "Version 3.032x7"; write(fd, s, strlen(s)); } else if (strncmp(buf, "?AF", 3) == 0) { sprintf(reply, "@AF%8d\r", freqA); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?BF", 3) == 0) { sprintf(reply, "@BF%8d\r", freqB); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "*AF", 3) == 0) { sscanf(buf, "*AF%d", &freqA); } else if (strncmp(buf, "*BF", 3) == 0) { sscanf(buf, "*BF%d", &freqB); } else if (strncmp(buf, "?KV", 3) == 0) { sprintf(reply, "@KVANA\r"); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?RMM", 4) == 0) { sprintf(reply, "@RMM%d\r", modeA); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?RMF", 4) == 0) { sprintf(reply, "@RMF%d\r", width); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?S", 2) == 0) { if (ptt) { sprintf(reply, "@STWF002R000S256\r"); } else { sprintf(reply, "@SRM055S000\r"); } write(fd, reply, strlen(reply)); } else if (strncmp(buf, "*TK", 3) == 0) { ptt = 1; } else if (strncmp(buf, "*TU", 3) == 0) { ptt = 0; } else if (strncmp(buf, "?CS", 3) == 0) { sprintf(reply, "@CS%d\r", keyspd); } else if (strncmp(buf, "*CS", 3) == 0) { sscanf(buf, "*CS%d\r", &keyspd); } else { printf("Unknown cmd=%s\n", buf); } } //flush(fd); return 0; } hamlib-4.6.5/simulators/Makefile.am0000664000175000017500000000425615056640443012721 # Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl DISTCLEANFILES = bin_PROGRAMS = check_PROGRAMS = simelecraft simicgeneric simkenwood simyaesu simic9100 simic9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simic7300 simic7000 simic7100 simic7200 simatd578 simic905 simts450 simic7600 simic7610 simic705 simts950 simts990 simic7851 simftdx101 simxiegug90 simqrplabs simft818 simic275 simtrusdx simft1000 simtmd710 simts890 simxiegux108g simxiegux6100 simic910 simft450 simelecraftk4 simmicom simflex simft710 simic2730 simorion simpmr171 simic7700 simft990 simpstrotator simeasycomm simicr8600 simelecraft_SOURCES = simelecraft.c simkenwood_SOURCES = simkenwood.c simyaesu_SOURCES = simyaesu.c simid5100_SOURCES = simid5100.c # include generated include files ahead of any in sources #rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) simelecraft_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src simkenwood_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simyaesu_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simid5100_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simelecraft_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) simkenwood_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simyaesu_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simid5100_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) # Linker options simelecraft_LDFLAGS = $(WINEXELDFLAGS) simkenwood_LDFLAGS = $(WINEXELDFLAGS) simyaesu_LDFLAGS = $(WINEXELDFLAGS) simid5100_LDFLAGS = $(WINEXELDFLAGS) EXTRA_DIST = # Support 'make check' target for simple tests #check_SCRIPTS = #TESTS = $(check_SCRIPTS) $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la CLEANFILES = simelelecraft simicgeneric simkenwood simyaesu hamlib-4.6.5/simulators/simftdx1200.c0000664000175000017500000001622415056640443013010 // can run this using rigctl/rigctld and socat pty devices #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; int keyspd = 20; // ID 0310 == 310, Must drop leading zero typedef enum nc_rigid_e { NC_RIGID_NONE = 0, NC_RIGID_FT450 = 241, NC_RIGID_FT450D = 244, NC_RIGID_FT950 = 310, NC_RIGID_FT891 = 135, NC_RIGID_FT991 = 135, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%c;", vfo == 0 ? '0' : '1'); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.5/simulators/simxiegux6100.c0000664000175000017500000002544215056640443013362 // simicom will show the pts port to use for rigctl on Unix // using virtual serial ports on Windows is to be developed yet // Needs a lot of improvement to work on all Icoms #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #define BUFSIZE 256 #define X25 int civ_731_mode = 0; vfo_t current_vfo = RIG_VFO_A; int split = 0; // we make B different from A to ensure we see a difference at startup float freqA = 14074000; float freqB = 14074500; mode_t modeA = RIG_MODE_CW; mode_t modeB = RIG_MODE_USB; int datamodeA = 0; int datamodeB = 0; pbwidth_t widthA = 0; pbwidth_t widthB = 1; ant_t ant_curr = 0; int ant_option = 0; int ptt = 0; int keyspd = 20; void dumphex(const unsigned char *buf, int n) { for (int i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); } int frameGet(int fd, unsigned char *buf) { int i = 0; memset(buf, 0, BUFSIZE); unsigned char c; while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { dumphex(buf, i); return i; } } //printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n=0; dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_freqA\n"); to_bcd(&frame[5], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); } frame[10] = 0xfd; n = write(fd, frame, 11); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = widthA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; case 0x05: freq = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x06: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { modeA = frame[6]; } else { modeB = frame[6]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xb0: freq = freqA; freqA = freqB; freqB = freq; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; #if 0 case 0x12: // we're simulating the 3-byte version -- not the 2-byte if (frame[5] != 0xfd) { printf("Set ant %d\n", -1); ant_curr = frame[5]; ant_option = frame[6]; dump_hex(frame, 8); } else { printf("Get ant\n"); } frame[5] = ant_curr; frame[6] = ant_option; frame[7] = 0xfd; printf("n=n = write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0a: printf("Using power level %d\n", power_level); power_level += 10; if (power_level > 250) { power_level = 0; } to_bcd(&frame[6], (long long)power_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x11: printf("Using meter level %d\n", meter_level); meter_level += 10; if (meter_level > 250) { meter_level = 0; } to_bcd(&frame[6], (long long)meter_level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); break; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); break; #endif case 0x19: frame[6] = 0x61; frame[7] = 0x00; frame[8] = 0xfd; n = write(fd, frame, 9); break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x03: // width if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { frame[6] = widthA; } else { frame[6] = widthB; } frame[7] = 0xfd; n = write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { if (frame[5] == 0x00) { to_bcd(&frame[6], (long long)freqA, (civ_731_mode ? 4 : 5) * 2); printf("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; n = write(fd, frame, 12); } else { freq = from_bcd(&frame[6], (civ_731_mode ? 4 : 5) * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; case 0x26: for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { for (int i = 0; i < 6; ++i) { printf("%02x:", frame[i]); } frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = 0xfb; frame[9] = 0xfd; n = write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet if (n == 0) printf("write failed?\n"); } #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { int fd; fd = open(comport, O_RDWR); if (fd < 0) { perror(comport); } return fd; } #else int openPort(char *comport) // doesn't matter for using pts devices { int fd = posix_openpt(O_RDWR); char *name = ptsname(fd); if (name == NULL) { perror("ptsname"); return -1; } printf("name=%s\n", name); if (fd == -1 || grantpt(fd) == -1 || unlockpt(fd) == -1) { perror("posix_openpt"); return -1; } return fd; } #endif void rigStatus() { char vfoa = current_vfo == RIG_VFO_A ? '*' : ' '; char vfob = current_vfo == RIG_VFO_B ? '*' : ' '; printf("%cVFOA: mode=%d datamode=%d width=%ld freq=%.0f\n", vfoa, modeA, datamodeA, widthA, freqA); printf("%cVFOB: mode=%d datamode=%d width=%ld freq=%.0f\n", vfob, modeB, datamodeB, widthB, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #ifdef X25 printf("x25/x26 command recognized\n"); #else printf("x25/x26 command rejected\n"); #endif #if defined(WIN32) || defined(_WIN32) if (argc != 2) { printf("Missing comport argument\n"); printf("%s [comport]\n", argv[0]); exit(1); } #endif while (1) { int len = frameGet(fd, buf); if (len <= 0) { close(fd); fd = openPort(argv[1]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.5/bindings/0000775000175000017500000000000015056640475010336 5hamlib-4.6.5/bindings/tcltest.tcl.in0000664000175000017500000000335415056640442013050 #!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" # Edit the path below to reflect installed Hamlib extension lappend ::auto_path @tcldir@ ## Brute force loading #load "@tcldir@/hamlibtcl.so" Hamlib ## Preferred package loading package require hamlib set tclver [info tclversion] puts "Tcl $tclver test, $hamlib_version\n" #rig_set_debug $RIG_DEBUG_TRACE rig_set_debug $RIG_DEBUG_NONE # Init RIG_MODEL_DUMMY Rig my_rig $RIG_MODEL_DUMMY my_rig open my_rig set_freq $RIG_VFO_A 145550000 puts "status:\t\t[my_rig cget -error_status]" # get_mode returns a tuple set moderes [my_rig get_mode] set mode [rig_strrmode [lindex $moderes 0]] puts "mode:\t\t$mode\nbandwidth:\t[lindex $moderes 1]Hz" set state [my_rig cget -state] # The following works well also set rigcaps [my_rig cget -caps] #set model [$rigcaps cget -model_name] puts "Model:\t\t[$rigcaps cget -model_name]" puts "Manufacturer:\t\t[$rigcaps cget -mfg_name]" puts "Backend version:\t[$rigcaps cget -version]" puts "Backend license:\t[$rigcaps cget -copyright]" puts "Attenuators:\t[$rigcaps cget -attenuator]" puts "getinfo:\t[my_rig get_info]" my_rig set_level "VOXDELAY" 1 puts "status:\t\t[my_rig cget -error_status]" puts "VOX delay:\t[my_rig get_level_i 'VOXDELAY']" puts "status:\t\t[my_rig cget -error_status]" my_rig set_level $RIG_LEVEL_VOXDELAY 5 puts "status:\t\t[my_rig cget -error_status]" puts "VOX delay:\t[my_rig get_level_i $RIG_LEVEL_VOXDELAY]" puts "status:\t\t[my_rig cget -error_status]" puts "strength:\t[my_rig get_level_i $RIG_LEVEL_STRENGTH]" puts "status:\t\t[my_rig cget -error_status]" puts "status(str):\t[rigerror [my_rig cget -error_status]]" puts "\nSending Morse, '73'" my_rig send_morse $RIG_VFO_A "73" my_rig close #my_rig cleanup exit 0 hamlib-4.6.5/bindings/pytest.py0000775000175000017500000000774615056640442012173 #!/usr/bin/env python2 # -*- coding: utf-8 -*- import sys ## Uncomment to run this script from an in-tree build (or adjust to the ## build directory) without installing the bindings. #sys.path.append ('.') #sys.path.append ('.libs') import Hamlib def StartUp(verbose): """Simple script to test the Hamlib.py module with Python2.""" print "%s: Python %s; %s\n" \ % (sys.argv[0], sys.version.split()[0], Hamlib.cvar.hamlib_version) Hamlib.rig_set_debug([Hamlib.RIG_DEBUG_NONE, Hamlib.RIG_DEBUG_VERBOSE][verbose]) # Init RIG_MODEL_DUMMY my_rig = Hamlib.Rig(Hamlib.RIG_MODEL_DUMMY) my_rig.set_conf("rig_pathname", "/dev/Rig") my_rig.set_conf("retry", "5") my_rig.open() rpath = my_rig.get_conf("rig_pathname") retry = my_rig.get_conf("retry") print "status(str):\t\t", Hamlib.rigerror(my_rig.error_status) print "get_conf:\t\tpath = %s, retry = %s" \ % (rpath, retry) my_rig.set_freq(Hamlib.RIG_VFO_B, 5700000000) my_rig.set_vfo(Hamlib.RIG_VFO_B) print "freq:\t\t\t", my_rig.get_freq() my_rig.set_freq(Hamlib.RIG_VFO_A, 145550000) (mode, width) = my_rig.get_mode() print "mode:\t\t\t", Hamlib.rig_strrmode(mode), "\nbandwidth:\t\t", width my_rig.set_mode(Hamlib.RIG_MODE_CW) (mode, width) = my_rig.get_mode() print "mode:\t\t\t", Hamlib.rig_strrmode(mode), "\nbandwidth:\t\t", width print "Backend copyright:\t", my_rig.caps.copyright print "Model:\t\t\t", my_rig.caps.model_name print "Manufacturer:\t\t", my_rig.caps.mfg_name print "Backend version:\t", my_rig.caps.version print "Backend status:\t\t", Hamlib.rig_strstatus(my_rig.caps.status) print "Rig info:\t\t", my_rig.get_info() my_rig.set_level("VOXDELAY", 1) print "VOX delay:\t\t", my_rig.get_level_i("VOXDELAY") my_rig.set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5) print "VOX delay:\t\t", my_rig.get_level_i(Hamlib.RIG_LEVEL_VOXDELAY) af = 12.34 print "Setting AF to %0.2f...." % (af) my_rig.set_level("AF", af) print "status:\t\t\t%s - %s" % (my_rig.error_status, Hamlib.rigerror(my_rig.error_status)) print "AF level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_AF) print "strength:\t\t", my_rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH) print "status:\t\t\t", my_rig.error_status print "status(str):\t\t", Hamlib.rigerror(my_rig.error_status) chan = Hamlib.channel(Hamlib.RIG_VFO_B) my_rig.get_channel(chan,1) print "get_channel status:\t", my_rig.error_status print "VFO:\t\t\t", Hamlib.rig_strvfo(chan.vfo), ", ", chan.freq print "Attenuators:\t\t", my_rig.caps.attenuator print "\nSending Morse, '73'" my_rig.send_morse(Hamlib.RIG_VFO_A, "73") my_rig.close () print "\nSome static functions:" err, lon1, lat1 = Hamlib.locator2longlat("IN98XC") err, lon2, lat2 = Hamlib.locator2longlat("DM33DX") err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3) err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3) print "Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s" % (lon1, lat1, loc1) print "Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s" % (lon2, lat2, loc2) err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2) longpath = Hamlib.distance_long_path(dist) print "Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km" \ % (dist, az, longpath) # dec2dms expects values from 180 to -180 # sw is 1 when deg is negative (west or south) as 0 cannot be signed err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1) err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1) lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1) lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2) print 'Longitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ % (lon1, deg1, mins1, sec1, ('W' if sw1 else 'E'), lon3) print 'Latitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ % (lat1, deg2, mins2, sec2, ('S' if sw2 else 'N'), lat3) if __name__ == '__main__': StartUp([0,1]["-v" in sys.argv]) hamlib-4.6.5/bindings/rotator.swg0000664000175000017500000000737615056640442012501 /* * Hamlib bindings - Rotator interface * Copyright (c) 2001,2002 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ %inline %{ typedef struct Rot { ROT *rot; struct rot_caps *caps; /* shortcut to ROT->caps */ struct rot_state *state; /* shortcut to ROT->state */ int error_status; int do_exception; } Rot; %} /* * declare wrapper method with 0,1,2 arguments besides ROT* */ #define ROTMETHOD0(f) void f () \ { self->error_status = rot_##f(self->rot); } #define ROTMETHOD1(f, t1) void f (t1 _##t1) \ { self->error_status = rot_##f(self->rot, _##t1); } #define ROTMETHOD2(f, t1, t2) void f (t1 _##t1##_1, t2 _##t2##_2) \ { self->error_status = rot_##f(self->rot, _##t1##_1, _##t2##_2); } %extend Rot { Rot(rot_model_t rot_model) { Rot *r; r = (Rot*)malloc(sizeof(Rot)); if (!r) return NULL; r->rot = rot_init(rot_model); if (!r->rot) { free(r); return NULL; } /* install shortcuts */ r->caps = r->rot->caps; r->state = &r->rot->state; r->do_exception = 0; /* default is disabled */ r->error_status = RIG_OK; return r; } ~Rot () { rot_cleanup(self->rot); free(self); } /* * return code checking */ %exception { arg1->error_status = RIG_OK; $action if (arg1->error_status != RIG_OK && arg1->do_exception) SWIG_exception(SWIG_UnknownError, rigerror(arg1->error_status)); } ROTMETHOD0(open) ROTMETHOD0(close) ROTMETHOD2(set_position, azimuth_t, elevation_t) extern void get_position(azimuth_t *OUTPUT, elevation_t *OUTPUT); ROTMETHOD0(stop) ROTMETHOD0(park) ROTMETHOD1(reset, rot_reset_t) ROTMETHOD2(move, int, int) ROTMETHOD1(token_lookup, const_char_string) /* conf */ void set_conf(const char *name, const char *val) { hamlib_token_t tok = rot_token_lookup(self->rot, name); if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = rot_set_conf(self->rot, tok, val); } ROTMETHOD2(set_conf, hamlib_token_t, const_char_string) const char *get_conf(hamlib_token_t tok) { static char s[128] = ""; self->error_status = rot_get_conf(self->rot, tok, s); return s; } const char *get_conf(const char *name) { hamlib_token_t tok = rot_token_lookup(self->rot, name); static char s[128] = ""; if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = rot_get_conf(self->rot, tok, s); return s; } const char * get_info(void) { const char *s; s = rot_get_info(self->rot); self->error_status = s ? RIG_OK : -RIG_EINVAL; return s; } /* TODO: get_conf_list, .. */ }; %{ /* * this one returns 2 values, here is a perl example: * ($az, $elevation) = $rig->get_position(); */ void Rot_get_position(Rot *self, azimuth_t *azimuth, elevation_t *elevation) { self->error_status = rot_get_position(self->rot, azimuth, elevation); } %} hamlib-4.6.5/bindings/rig.swg0000664000175000017500000004547015056640442011565 /* * Hamlib bindings - Rig interface * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ %inline %{ #pragma SWIG nowarn=451 typedef struct Rig { RIG *rig; struct rig_caps *caps; /* shortcut to RIG->caps */ struct rig_state *state; /* shortcut to RIG->state */ int error_status; int do_exception; } Rig; typedef char * char_string; typedef channel_t * channel_t_p; typedef channel_t * const_channel_t_p; %} %extend channel { channel(vfo_t vfo = RIG_VFO_CURR, int ch = 0) { channel_t *chan; chan = (channel_t*)malloc(sizeof(channel_t)); if (!chan) return NULL; memset(chan, 0, sizeof(channel_t)); chan->vfo = vfo; chan->channel_num = ch; return chan; } ~channel (void) { /* TODO: free ext_levels */ free(self); } } %include "carrays.i" %array_class(struct channel, channelArray); %array_class(tone_t, toneArray); /* * declare wrapper method with one argument besides RIG* and optional no target vfo */ #define METHOD1(f, t1) void f (t1 _##t1 _VFO_DECL) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1); } #define METHOD2(f, t1, t2) void f (t1 _##t1##_1, t2 _##t2##_2 _VFO_DECL) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1##_1, _##t2##_2); } #define METHOD2_INIT(f, t1, t2, i2) void f (t1 _##t1##_1, t2 _##t2##_2 = i2 _VFO_DECL) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1##_1, _##t2##_2); } #define METHOD3(f, t1) void f ( vfo_t vfo, t1 _##t1) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1); } #define METHOD3_INIT(f, t1, t2, t3, i3) void f (t1 _##t1##_1, t2 _##t2##_2, t3 _##t3##_3 = i3 _VFO_DECL) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1##_1, _##t2##_2, _##t3##_3); } #define METHOD4(f, t1) void f ( vfo_t vfo, t1 _##t1) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1); } #define METHOD4_INIT(f, t1, t2, t3, t4, i4) void f (t1 _##t1##_1, t2 _##t2##_2, t3 _##t3##_3, ##t4##_4 = i4 _VFO_DECL) \ { self->error_status = rig_##f(self->rig _VFO_ARG, _##t1##_1, _##t2##_2, _##t3##_3 _##t4##_4); } /* * declare wrapper method with one output argument besides RIG* (no target vfo) */ #define METHOD1GET(f, t1) t1 f (void) \ { t1 _##t1; self->error_status = rig_##f(self->rig, &_##t1); return _##t1; } #define METHOD1SET(f, t1) t1 f (void) \ { t1 _##t1; self->error_status = rig_##f(self->rig, _##t1); return _##t1; } /* * declare wrapper method with one output argument besides RIG* and vfo */ #define METHOD1VGET(f, t1) t1 f (vfo_t vfo = RIG_VFO_CURR) \ { t1 _##t1; self->error_status = rig_##f(self->rig, vfo, &_##t1); return _##t1; } #ifndef SWIGLUA #define METHODSIMPLESET(f, t1, fld, chk) void set_##f (setting_t stg, t1 fld _VFO_DECL) \ { value_t val = {0}; if (chk) { \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return; \ } \ val.fld = fld; \ self->error_status = rig_set_##f(self->rig _VFO_ARG , stg, val); \ } #else #define METHODSIMPLESET(f, t1, fld, chk) void set_##f (setting_t stg, t1 fld _VFO_DECL) \ { value_t val = {0}; \ if (chk) { \ int ival = (int)fld; \ val.i = fld; \ } \ else { \ val.fld = fld; \ } \ self->error_status = rig_set_##f(self->rig _VFO_ARG , stg, val); \ } #endif /* * RIG_CONF_ extparm's type: * NUMERIC: val.f * COMBO: val.i, starting from 0 * STRING: val.s * CHECKBUTTON: val.i 0/1 */ #ifndef SWIGLUA #define METHODSUPERSET(f, t1, fld, chk) void set_##f (const char *name, t1 fld _VFO_DECL) \ { setting_t stg; value_t val = {0}; \ stg = rig_parse_##f(name); \ if (!rig_has_set_##f(self->rig, stg)) { \ const struct confparams *cfp; \ cfp = rig_ext_lookup(self->rig, name); \ if (!cfp) { \ self->error_status = -RIG_EINVAL; /* no such parameter */ \ return; \ } \ switch (cfp->type) { \ case RIG_CONF_NUMERIC: \ val.fld = fld; \ break; \ case RIG_CONF_CHECKBUTTON: \ case RIG_CONF_COMBO: \ val.i = (int)fld; \ break; \ case RIG_CONF_STRING: \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return; \ default: \ self->error_status = -RIG_ECONF; \ return; \ } \ self->error_status = rig_set_ext_##f(self->rig _VFO_ARG, cfp->token, val); \ return; \ } \ if (chk) { \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return; \ } \ val.fld = fld; \ self->error_status = rig_set_##f(self->rig _VFO_ARG , stg, val); \ } #else #define METHODSUPERSET(f, t1, fld, chk) void set_##f (const char *name, t1 fld _VFO_DECL) \ { setting_t stg; value_t val = {0}; \ stg = rig_parse_##f(name); \ if (!rig_has_set_##f(self->rig, stg)) { \ const struct confparams *cfp; \ cfp = rig_ext_lookup(self->rig, name); \ if (!cfp) { \ self->error_status = -RIG_EINVAL; /* no such parameter */ \ return; \ } \ switch (cfp->type) { \ case RIG_CONF_NUMERIC: \ val.fld = fld; \ break; \ case RIG_CONF_CHECKBUTTON: \ case RIG_CONF_COMBO: \ val.i = (int)fld; \ break; \ case RIG_CONF_STRING: \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return; \ default: \ self->error_status = -RIG_ECONF; \ return; \ } \ self->error_status = rig_set_ext_##f(self->rig _VFO_ARG, cfp->token, val); \ return; \ } \ if (chk) { \ int ival = (int)fld; \ val.i = ival; \ } \ else { \ val.fld = fld; \ } \ self->error_status = rig_set_##f(self->rig _VFO_ARG , stg, val); \ } #endif #define METHODSTRSET(f) void set_##f (const char *name, const char *s _VFO_DECL) \ { value_t val = {0}; /* only ext_level/parm's can have string values */ \ const struct confparams *cfp; \ cfp = rig_ext_lookup(self->rig, name); \ if (!cfp) { \ self->error_status = -RIG_EINVAL; /* no such parameter */ \ return; \ } \ if (cfp->type != RIG_CONF_STRING) { \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return; \ } \ val.cs = s; \ self->error_status = rig_set_ext_##f(self->rig _VFO_ARG, cfp->token, val); \ } #define METHODSIMPLEGET(f, t1, fld, chk) t1 get_##f##_##fld (setting_t stg _VFO_DECL) \ { value_t val = {0}; if (chk) { \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return val.fld; /* undefined value */ \ } \ self->error_status = rig_get_##f(self->rig _VFO_ARG , stg, &val); \ return val.fld; \ } #define METHODSUPERGET(fct, t1, fld, chk) t1 get_##fct##_##fld(const char *name _VFO_DECL) \ { setting_t stg; value_t val = {0}; \ stg = rig_parse_##fct(name); \ if (!rig_has_get_##fct(self->rig, stg)) { \ const struct confparams *cfp; \ cfp = rig_ext_lookup(self->rig, name); \ if (!cfp) { \ self->error_status = -RIG_EINVAL; /* no such parameter */ \ return val.fld; /* undefined */ \ } \ if (cfp->type == RIG_CONF_STRING) { \ self->error_status = -RIG_EINVAL; \ return val.fld; /* undefined */ \ } \ self->error_status = rig_get_ext_##fct(self->rig _VFO_ARG, cfp->token, &val); \ switch (cfp->type) { \ case RIG_CONF_NUMERIC: \ return (t1)val.f; \ case RIG_CONF_CHECKBUTTON: \ case RIG_CONF_COMBO: \ return (t1)val.i; \ default: \ self->error_status = -RIG_ECONF; \ return val.fld; /* undefined */ \ } \ } \ if (chk) { \ self->error_status = -RIG_EINVAL; /* invalid type */ \ return val.fld; /* undefined */ \ } \ self->error_status = rig_get_##fct(self->rig _VFO_ARG , stg, &val); \ return val.fld; \ } #define METHODSTRGET(f) void get_##f (const char *name, char *returnstr _VFO_DECL) \ { value_t val = {0}; /* only ext_level/parm's can have string values */ \ const struct confparams *cfp; \ returnstr[0] = '\0'; \ cfp = rig_ext_lookup(self->rig, name); \ if (!cfp || cfp->type != RIG_CONF_STRING) { \ self->error_status = -RIG_EINVAL; /* no such parameter/invalid type */ \ return; \ } \ val.s = returnstr; \ self->error_status = rig_get_ext_##f(self->rig _VFO_ARG, cfp->token, &val); \ } /* * string as return value * NB: The %apply has to be outside the %extend, * but the %cstring_bounded_output must be inside. */ %ignore MAX_RETURNSTR; #define MAX_RETURNSTR 256 #ifndef SWIGJAVA %apply char *OUTPUT { char *returnstr }; #endif /* * Rig class alike */ %extend Rig { #ifndef SWIGLUA #ifndef SWIG_CSTRING_UNIMPL #ifndef SWIGJAVA %cstring_bounded_output(char *returnstr, MAX_RETURNSTR); #endif #endif #endif Rig(int rig_model) { Rig *r; r = (Rig*)malloc(sizeof(Rig)); if (!r) return NULL; r->rig = rig_init(rig_model); if (!r->rig) { free(r); return NULL; } /* install shortcuts */ r->caps = r->rig->caps; r->state = &r->rig->state; r->do_exception = 0; /* default is disabled */ r->error_status = RIG_OK; return r; } ~Rig () { rig_cleanup(self->rig); free(self); } /* * return code checking */ %exception { arg1->error_status = RIG_OK; $action if (arg1->error_status != RIG_OK && arg1->do_exception) SWIG_exception(SWIG_UnknownError, rigerror(arg1->error_status)); } void open () { self->error_status = rig_open(self->rig); } void close () { self->error_status = rig_close(self->rig); } /* * group all vfo, and non vfo apart */ #define _VFO_ARG ,vfo #define _VFO_DECL ,vfo_t vfo = RIG_VFO_CURR METHOD3(set_freq, freq_t) METHOD2_INIT(set_mode, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL) METHOD3(set_ptt, ptt_t) METHOD3(set_rptr_shift, rptr_shift_t) METHOD3(set_rptr_offs, shortfreq_t) METHOD3(set_ctcss_tone, tone_t) METHOD3(set_dcs_code, tone_t) METHOD3(set_ctcss_sql, tone_t) METHOD1(set_dcs_sql, tone_t) METHOD3(set_split_freq, freq_t) METHOD2_INIT(set_split_mode, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL) METHOD3_INIT(set_split_freq_mode, freq_t, rmode_t, pbwidth_t, RIG_PASSBAND_NORMAL) METHOD2(set_split_vfo, split_t, vfo_t) METHOD3(set_rit, shortfreq_t) METHOD3(set_xit, shortfreq_t) METHOD3(set_ts, shortfreq_t) METHOD2(set_ant, ant_t, value_t) METHOD2(set_func, setting_t, int) METHOD2(set_ext_func, hamlib_token_t, int) METHOD3(set_bank, int) METHOD3(set_mem, int) METHOD3(send_dtmf, const_char_string) METHOD3(send_morse, const_char_string) METHOD3(vfo_op, vfo_op_t) METHOD2(scan, scan_t, int) METHODSIMPLESET(level, int, i, RIG_LEVEL_IS_FLOAT(stg)) METHODSIMPLESET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg)) METHODSUPERSET(level, int, i, RIG_LEVEL_IS_FLOAT(stg)) METHODSUPERSET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg)) METHODSTRSET(level) METHOD2(set_ext_level, hamlib_token_t, value_t) METHODSIMPLEGET(level, int, i, RIG_LEVEL_IS_FLOAT(stg)) METHODSIMPLEGET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg)) METHODSUPERGET(level, int, i, RIG_LEVEL_IS_FLOAT(stg)) METHODSUPERGET(level, float, f, !RIG_LEVEL_IS_FLOAT(stg)) METHODSTRGET(level) /* * these ones take no vfo arg */ #undef _VFO_ARG #undef _VFO_DECL #define _VFO_ARG #define _VFO_DECL METHOD1(set_vfo, vfo_t) /* particular case */ METHOD1(set_powerstat, powerstat_t) METHOD1(set_trn, int) METHOD1(has_get_level, setting_t) METHOD1(has_set_parm, setting_t) METHOD1(has_set_func, setting_t) METHOD1(reset, reset_t) METHOD1(has_scan, scan_t) METHOD1(has_vfo_op, vfo_op_t) METHOD1(passband_normal, rmode_t) METHOD1(passband_narrow, rmode_t) METHOD1(passband_wide, rmode_t) METHOD1(set_vfo_opt, int) METHOD1(ext_token_lookup, const_char_string) /* level & parm */ METHOD1(token_lookup, const_char_string) /* conf */ METHOD2(set_conf, hamlib_token_t, const_char_string) METHOD2(set_ext_parm, hamlib_token_t, value_t) METHODSIMPLESET(parm, int, i, RIG_PARM_IS_FLOAT(stg)) METHODSIMPLESET(parm, float, f, !RIG_PARM_IS_FLOAT(stg)) METHODSUPERSET(parm, int, i, RIG_PARM_IS_FLOAT(stg)) METHODSUPERSET(parm, float, f, !RIG_PARM_IS_FLOAT(stg)) METHODSTRSET(parm) METHODSIMPLEGET(parm, int, i, RIG_PARM_IS_FLOAT(stg)) METHODSIMPLEGET(parm, float, f, !RIG_PARM_IS_FLOAT(stg)) METHODSUPERGET(parm, int, i, RIG_PARM_IS_FLOAT(stg)) METHODSUPERGET(parm, float, f, !RIG_PARM_IS_FLOAT(stg)) METHODSTRGET(parm) void set_conf(const char *name, const char *val) { hamlib_token_t tok = rig_token_lookup(self->rig, name); if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = rig_set_conf(self->rig, tok, val); } /* TODO: get_ext_parm_list, level, conf, .. */ /* get functions */ METHOD1VGET(get_freq, freq_t) extern void get_mode(rmode_t * OUTPUT, pbwidth_t * OUTPUT, vfo_t vfo = RIG_VFO_CURR); extern void get_split_mode(rmode_t * OUTPUT, pbwidth_t * OUTPUT, vfo_t vfo = RIG_VFO_CURR); METHOD1GET(get_vfo, vfo_t) METHOD1VGET(get_ptt, ptt_t) METHOD1VGET(get_rptr_shift, rptr_shift_t) METHOD1VGET(get_rptr_offs, shortfreq_t) METHOD1VGET(get_ctcss_tone, tone_t) METHOD1VGET(get_dcs_code, tone_t) METHOD1VGET(get_ctcss_sql, tone_t) METHOD1VGET(get_dcs_sql, tone_t) METHOD1VGET(get_split_freq, freq_t) void get_split_vfo(split_t *split, vfo_t *tx_vfo, vfo_t vfo = RIG_VFO_CURR) { self->error_status = rig_get_split_vfo(self->rig, vfo, split, tx_vfo); } METHOD1VGET(get_rit, shortfreq_t) METHOD1VGET(get_xit, shortfreq_t) METHOD1VGET(get_ts, shortfreq_t) extern void get_ant(ant_t *ant_rx, ant_t *ant_tx, ant_t *ant_curr, value_t * OUTPUT, ant_t ant, vfo_t vfo = RIG_VFO_CURR); extern void get_vfo_info (int *satmode, split_t *split, pbwidth_t *width, rmode_t *mode, freq_t *freq, vfo_t vfo = RIG_VFO_CURR); METHOD1VGET(get_mem, int) METHOD1GET(get_powerstat, powerstat_t) METHOD1GET(get_trn, int) METHOD1VGET(get_dcd, dcd_t) int mem_count(void) { return rig_mem_count(self->rig); } const chan_t *lookup_mem_caps(int channel_num = RIG_MEM_CAPS_ALL) { return rig_lookup_mem_caps(self->rig, channel_num); } void set_channel(const struct channel *chan) { self->error_status = rig_set_channel(self->rig, RIG_VFO_NONE, chan); } void get_channel(struct channel *chan, int read_only) { self->error_status = rig_get_channel(self->rig, RIG_VFO_NONE, chan, read_only); /* TODO: handle ext_level's */ } void chan_clear(struct channel *chans, int nb_chans = 1) { memset(chans, 0, sizeof(struct channel)*nb_chans); } void get_chan_all(struct channel *chans) { self->error_status = rig_get_chan_all(self->rig, RIG_VFO_NONE, chans); /* TODO: handle ext_level's */ } /* * Rem: does swig has to be told that returned object need to be handled by gc? */ struct channel *get_chan_all(void); /* get_channel() returns current VFO data * get_channel(10) returns content of memory #10 * get_channel(0, RIG_VFO_A) returns VFO A data * Rem: does swig has to be told that returned object need to be handled by gc? */ struct channel *get_channel(int read_only, int channel_num = INT_MAX, vfo_t vfo = RIG_VFO_MEM) { struct channel *chan; chan = new_channel(channel_num != INT_MAX ? vfo : RIG_VFO_CURR, channel_num); if (!chan) { self->error_status = -RIG_ENOMEM; return NULL; } self->error_status = rig_get_channel(self->rig, RIG_VFO_NONE, chan, read_only); /* TODO: copy ext_level's */ return chan; } void get_conf(hamlib_token_t tok, char *returnstr) { returnstr[0] = '\0'; self->error_status = rig_get_conf(self->rig, tok, returnstr); } void get_conf(const char *name, char *returnstr) { returnstr[0] = '\0'; hamlib_token_t tok = rig_token_lookup(self->rig, name); if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = rig_get_conf(self->rig, tok, returnstr); } void recv_dtmf(char *returnstr, vfo_t vfo = RIG_VFO_CURR) { int len = MAX_RETURNSTR; self->error_status = rig_recv_dtmf(self->rig, vfo, returnstr, &len); returnstr[len] = '\0'; } const char * get_info(void) { const char *s; s = rig_get_info(self->rig); self->error_status = s ? RIG_OK : -RIG_EINVAL; return s; } int get_func(setting_t func, vfo_t vfo = RIG_VFO_CURR) { int status; self->error_status = rig_get_func(self->rig, vfo, func, &status); return status; } int get_ext_func(hamlib_token_t func, vfo_t vfo = RIG_VFO_CURR) { int status; self->error_status = rig_get_ext_func(self->rig, vfo, func, &status); return status; } //#ifndef SWIGJAVA /* TODO */ void get_level(setting_t level, vfo_t vfo = RIG_VFO_CURR) { value_t val = {0}; self->error_status = rig_get_level(self->rig, vfo, level, &val); //if (RIG_LEVEL_IS_FLOAT(level)) /* TODO: dynamic casting */ } void get_ext_level(hamlib_token_t token, vfo_t vfo = RIG_VFO_CURR) { value_t val = {0}; self->error_status = rig_get_level(self->rig, vfo, token, &val); //if (RIG_LEVEL_IS_FLOAT(level)) /* TODO: dynamic casting */ } void get_parm(setting_t parm) { value_t val = {0}; self->error_status = rig_get_parm(self->rig, parm, &val); //if (RIG_LEVEL_IS_FLOAT(parm)) /* TODO: dynamic casting */ } void get_ext_parm(hamlib_token_t parm) { value_t val = {0}; self->error_status = rig_get_parm(self->rig, parm, &val); //if (RIG_LEVEL_IS_FLOAT(parm)) /* TODO: dynamic casting */ } //#endif }; %{ /* * these ones return 2 values, here is a perl example: * ($mode, $width) = $rig->get_mode(); */ void Rig_get_mode(Rig *self, rmode_t *mode, pbwidth_t *width, vfo_t vfo) { self->error_status = rig_get_mode(self->rig, vfo, mode, width); } void Rig_get_split_mode(Rig *self, rmode_t *mode, pbwidth_t *width, vfo_t vfo) { self->error_status = rig_get_split_mode(self->rig, vfo, mode, width); } /* * these ones return 3 values */ void Rig_get_split_freq_mode(Rig *self, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width) { self->error_status = rig_get_split_freq_mode(self->rig, vfo, tx_freq, tx_mode, tx_width); } /* * these ones return 4 values */ void Rig_get_ant(Rig *self, ant_t *ant_rx, ant_t *ant_tx, ant_t *ant_curr, value_t *option, ant_t ant, vfo_t vfo) { self->error_status = rig_get_ant(self->rig, vfo, ant, option, ant_curr, ant_tx, ant_rx); } void Rig_get_vfo_info (Rig *self, int *satmode, split_t *split, pbwidth_t *width, rmode_t *mode, freq_t *freq, vfo_t vfo) { self->error_status = rig_get_vfo_info(self->rig, vfo, freq, mode, width, split, satmode); } struct channel *Rig_get_chan_all(Rig *self) { struct channel *chans; int nb_chans = rig_mem_count(self->rig); /* TODO: memleak: typemap to release that memory */ chans = calloc(sizeof (struct channel), nb_chans); if (!chans) { self->error_status = -RIG_ENOMEM; return NULL; } self->error_status = rig_get_chan_all(self->rig, RIG_VFO_NONE, chans); /* TODO: copy ext_level's */ return chans; } %} hamlib-4.6.5/bindings/Makefile.PL0000664000175000017500000000075215056640442012226 # Builds Hamlib-pl.mk and is invoked from Makefile use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Hamlib', # Add these new keywords supported since 5.005 ($] >= 5.005 ? ( #ABSTRACT_FROM => 'Hamlib.pm', # retrieve abstract from module AUTHOR => 'Stephane Fillod and the Hamlib Group') : ()), # should use libtool somehow. Otherwise try -Wl,--rpath #'LIBS' => ['-lhamlib'], #'DEFINE' => '', #'INC' => '', #'OBJECT' => 'hamlibperl_wrap.o', # link all the C files too ); hamlib-4.6.5/bindings/README.python0000664000175000017500000002061615056640442012455 For several years the Python world has been in a state of transition from version 2.x to 3.x. Much code still exists for Python2 in the form of applications, modules, and packages and will likely be supported for some time to come. Python3 is gaining acceptance, especially with new development and many modules and packages are now available for Python3. The Python developers have taken care to ensure that Python2 and Python3 and their respective modules and packages can be installed concurrently. The steps below take advantage of this feature to install Hamlib.py modules for both Python versions. Complete installation of each Python version including their respective development files are required for successful generation of the bindings by SWIG. At this time the GNU Autotools do not offer a clean method of building SWIG bindings for multiple versions of Python. Some hacks can be found on the Web but until a clean native solution is offered the steps in this document should prove adequate. With the wealth of Python2 programs, modules, and packages still in use, it isn't likely to disappear from distributions anytime soon. Python3 is becoming more popular for new development with a complete standard library and many modules and packages being ported over and available. It's time that we offer a means to generate bindings for either version. This document will provide the steps for doing so. NOTE: Developers and testers building from a Git clone/checkout will need to bootstrap the build system by running the (appropriately named) 'bootstrap' script. Source releases and source daily snapshots already have this step completed. NOTE: The commands assume an out of tree build in a sibling directory to the main source directory. Adjust your paths accordingly. Adjust your --prefix option as needed (installation to the user's home directory is shown to avoid root privileges). Assuming that Python2 is the default installed Python interpreter, build its bindings first: ../hamlib/configure --with-python-binding --prefix=$HOME/local make make install NOTE: Over time Python3 will become the default Python interpreter on most distributions and the extra step will be needed for Python2 as detailed below. At this point the Hamlib binaries, development files, and Python2 bindings will be installed to their customary locations under $HOME/local. Examination of the configure script's output will confirm that Python2 is found and used as this extract shows: checking whether to build python binding and demo... yes checking for python... /usr/bin/python checking for a version of Python >= '2.1.0'... yes checking for the distutils Python package... yes checking for Python include path... -I/usr/include/python2.7 checking for Python library path... -L/usr/lib64 -lpython2.7 checking for Python site-packages path... /usr/lib64/python2.7/site-packages checking python extra libraries... -lpthread -ldl -lutil -lm checking python extra linking flags... -Xlinker -export-dynamic checking consistency of all components of python development environment... yes checking whether /usr/bin/python version is >= 2.1... yes checking for /usr/bin/python version... 2.7 checking for /usr/bin/python platform... linux2 checking for /usr/bin/python script directory... ${prefix}/lib64/python2.7/site-packages checking for /usr/bin/python extension module directory... ${exec_prefix}/lib64/python2.7/site-packages At this point the file pytest.py in the source bindings directory may be run as a test. If an error is given that the Hamlib module cannot be found, see below. The next step is to configure and build for Python3: ../hamlib/configure --with-python-binding PYTHON_VERSION='3.6' --prefix=$HOME/local If that doesn't work try: ../hamlib/configure --with-python-binding PYTHON=$(which python3) --prefix=$HOME/local then do the build: cd bindings make NOTE: By changing the current directory to 'bindings', only the new Python3 module will be compiled, which speeds things up considerably. Here the PYTHON_VERSION environment variable is set to the Major.minor version of Python we wish to build against. The build system should be able to set everything correctly from this environment variable. If not, try the second example line which sets the PYTHON environment variable to the first python3 executable found in the path (python3 may be a symbolic link, which is fine). This may be unwanted behavior if multiple versions of Python are installed so a specific version with the full path may also be provided. Python3 was found as shown in this configure output extract: checking whether to build python binding and demo... yes checking for python3.6... /usr/bin/python3.6 checking for a version of Python >= '2.1.0'... yes checking for the distutils Python package... yes checking for Python include path... -I/usr/include/python3.6m checking for Python library path... -L/usr/lib64 -lpython3.6m checking for Python site-packages path... /usr/lib64/python3.6/site-packages checking python extra libraries... -lpthread -ldl -lutil -lm checking python extra linking flags... -Xlinker -export-dynamic checking consistency of all components of python development environment... yes checking whether /usr/bin/python3.6 version is >= 2.1... yes checking for /usr/bin/python3.6 version... 3.6 checking for /usr/bin/python3.6 platform... linux checking for /usr/bin/python3.6 script directory... ${prefix}/lib64/python3.6/site-packages checking for /usr/bin/python3.6 extension module directory... ${exec_prefix}/lib64/python3.6/site-packages Since all the Makefiles were regenerated by the second run of configure, hamlib will be compiled again. Next install only the Python3 bindings (still in 'bindings' as the current directory): make install In this case, only the generated files in 'bindings' will be installed which will be the new Python3 bindings. Test that the Hamlib Python3 bindings are found by running the bindings/py3test.py script. At this point working bindings are installed and have been tested. Running 'make uninstall' will only remove the version of the bindings that was last configured. To uninstall the other version the respective options will need to be passed to 'configure' and 'make uninstall' run again. What to do if Python complains the module cannot be found. There are various ways that a specific path can be provided to Python. Perhaps the easiest is to provide an environment variable to your script. Since Python will not have $HOME/local/... in its search path, here is an example: $ py3test.py Traceback (most recent call last): File "./py3test.py", line 9, in import Hamlib ModuleNotFoundError: No module named 'Hamlib' This isn't good! Let's set an environment variable for the running script: PYTHONPATH=$HOME/local/lib64/python3.6/site-packages:$PYTHONPATH ./py3test.py Success! Like the standard PATH environment variable PYTHONPATH can contain multiple paths separated by colons. In this case, if PYTHONPATH was already set the new path is prepended to its prior setting. While setting the environment variable is good for a one-off run, a more permanent solution can be achieved by placing a file that ends in .pth in a directory that Python will process when starting. The special place is: ~/.local/lib64/python3.6/site-packages A .pth file must be set for each major.minor version of Python. Here is an example for Python 2.7: $HOME/.local/lib64/python2.7/site-packages/home.pth Its content is simple: /home/username/local/lib64/python2.7/site-packages (These examples are from a Slackware box which installs Python modules into the 'lib64' directory. Other distributions may simply use 'lib' or another name.) To verify the path, start the Python interpreter in interactive mode, import the sys module, and check the value of sys.path. It will show a number of paths in the list including the ones above and the directory the interpreter was started from and various system directories. Far more information than this is available in the relevant Python documentation, but this should get your scripts working. Removing (uninstalling) the bindings can be done from the 'bindings' directory. Just be sure that 'configure' is run with the options for either Python2 or Python3 first so that 'bindings/Makefile' will generated for the version to be removed. As always, feedback is welcome: Hamlib Developers 73, Nate, N0NB hamlib-4.6.5/bindings/luatest.lua0000775000175000017500000001232515056640442012442 #!/usr/bin/lua Hamlib = require("Hamliblua") -- you can see the Hamlib properties: -- for key,value in pairs(Hamlib) do print(key,value) end function version() ver = string.sub(_VERSION,4) -- should only get one match to this for ver2 in string.gmatch(ver,"%d.%d") do ver = tonumber(ver2) end return ver end function doStartup() print(string.format("%s test, %s\n", _VERSION, Hamlib.hamlib_version)) -- Hamlib.rig_set_debug (Hamlib.RIG_DEBUG_TRACE) Hamlib.rig_set_debug (Hamlib.RIG_DEBUG_NONE) -- Init RIG_MODEL_DUMMY my_rig = Hamlib.Rig (Hamlib.RIG_MODEL_DUMMY) -- you can see the Rig properties: -- for key,value in pairs(my_rig) do print(key,value) end my_rig:set_conf("rig_pathname", "/dev/Rig") my_rig:set_conf("retry", "5") my_rig:open() tpath = my_rig:get_conf("rig_pathname") retry = my_rig:get_conf("retry") print (string.format("status(str):\t\t%s", Hamlib.rigerror(my_rig.error_status))) print (string.format("get_conf:\t\tpath = %s, retry = %s", tpath, retry)) my_rig:set_freq(Hamlib.RIG_VFO_B, 5700000000) my_rig:set_vfo(Hamlib.RIG_VFO_B) print(string.format("freq:\t\t\t%d", my_rig:get_freq())) my_rig:set_freq(Hamlib.RIG_VFO_A, 145550000) my_rig:set_vfo(Hamlib.RIG_VFO_A) mode, width = my_rig:get_mode() print(string.format("mode:\t\t\t%s\nbandwidth:\t\t%s", Hamlib.rig_strrmode(mode), width)) my_rig:set_mode(Hamlib.RIG_MODE_CW) mode, width = my_rig:get_mode() print(string.format("mode:\t\t\t%s\nbandwidth:\t\t%d", Hamlib.rig_strrmode(mode), width)) print(string.format("Backend copyright:\t%s",my_rig.caps.copyright)) print(string.format("Model:\t\t\t%s", my_rig.caps.model_name)) print(string.format("Manufacturer:\t\t%s", my_rig.caps.mfg_name)) print(string.format("Backend version:\t%s", my_rig.caps.version)) print(string.format("Backend license:\t%s", my_rig.caps.copyright)) print(string.format("Rig info:\t\t%s", my_rig:get_info())) my_rig:set_level("VOXDELAY", 1) print(string.format("status:\t\t\t%s - %s", my_rig.error_status, Hamlib.rigerror(my_rig.error_status))) print(string.format("VOX delay:\t\t%d", my_rig:get_level_i("VOXDELAY"))) my_rig:set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5) print(string.format("status:\t\t\t%s - %s", my_rig.error_status, Hamlib.rigerror(my_rig.error_status))) -- see the func name (get_level_i) and format (%d) print(string.format("VOX delay:\t\t%d", my_rig:get_level_i(Hamlib.RIG_LEVEL_VOXDELAY))) af = 12.34 print(string.format("Setting AF to %f...", af)) my_rig:set_level(Hamlib.RIG_LEVEL_AF, af) print(string.format("status:\t\t\t%s - %s", my_rig.error_status, Hamlib.rigerror(my_rig.error_status))) -- see the different of func name and format related to RIG_LEVEL_VOXDELAY! print(string.format("AF level:\t\t%f", my_rig:get_level_f("AF"))) print(string.format("strength:\t\t%d", my_rig:get_level_i(Hamlib.RIG_LEVEL_STRENGTH))) print(string.format("status:\t\t\t%s", my_rig.error_status)) print(string.format("status(str):\t\t%s", Hamlib.rigerror(my_rig.error_status))) chan = Hamlib.channel(Hamlib.RIG_VFO_B) my_rig:get_channel(chan,1) print(string.format("get_channel status:\t%d", my_rig.error_status)) print(string.format("VFO:\t\t\t%s, %s", Hamlib.rig_strvfo(chan.vfo), chan.freq)) print(string.format("Attenuators:\t\t%s", table.concat(my_rig.caps.attenuator, ", "))) print("\nSending Morse, '73'") my_rig:send_morse(Hamlib.RIG_VFO_A, "73") my_rig:close () print("\nSome static functions:") err, lon1, lat1 = Hamlib.locator2longlat("IN98XC") err, lon2, lat2 = Hamlib.locator2longlat("DM33DX") err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3) err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3) print(string.format("Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s", lon1, lat1, loc1)) print(string.format("Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s", lon2, lat2, loc2)) err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2) longpath = Hamlib.distance_long_path(dist) print(string.format("Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km", dist, az, longpath)) -- dec2dms expects values from 180 to -180 -- sw is 1 when deg is negative (west or south) as 0 cannot be signed err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1) err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1) lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1) lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2) if sw1 > 0 then D = 'W' else D = 'E' end print(string.format("Longitude:\t%4.4f, %4.0f° %.0f' %2.0f\" %1s\trecoded: %9.4f", lon1, deg1, mins1, sec1, D, lon3)) if sw2 > 0 then D = 'S' else D = 'N' end print(string.format("Latitude:\t%4.4f, %4.0f° %.0f' %2.0f\" %1s\trecoded: %9.4f", lat1, deg2, mins2, sec2, D, lat3)) if (version() >= 5.4) then -- older version may not handle 64-bit values -- not sure when this was fixed...might have been 5.3 somewhere print(string.format("The next two lines should show 0x8000000000000000")); print(string.format("RIG_MODE_TESTS_MAX: 0x%08x", Hamlib.RIG_MODE_TESTS_MAX)); print(string.format("RIG_FUNC_BIT63: 0x%08x", Hamlib.RIG_FUNC_BIT63)); end end doStartup() hamlib-4.6.5/bindings/amplifier.swg0000664000175000017500000001014015056640442012736 /* * Hamlib bindings - Amplifier interface * Copyright (c) 2001,2002 by Stephane Fillod * Copyright (c) 2020 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ %inline %{ typedef struct Amp { AMP *amp; struct amp_caps *caps; /* shortcut to AMP->caps */ struct amp_state *state; /* shortcut to AMP->state */ int error_status; int do_exception; } Amp; %} /* * declare wrapper method with 0,1,2 arguments besides AMP* */ #define AMPMETHOD0(f) void f () \ { self->error_status = amp_##f(self->amp); } #define AMPMETHOD1(f, t1) void f (t1 _##t1) \ { self->error_status = amp_##f(self->amp, _##t1); } #define AMPMETHOD2(f, t1, t2) void f (t1 _##t1##_1, t2 _##t2##_2) \ { self->error_status = amp_##f(self->amp, _##t1##_1, _##t2##_2); } #define AMPMETHOD3(f, t1, t2, t3) void f (t1 _##t1##_1, t2 _##t2##_2, t3 _##t3##_3) \ { self->error_status = amp_##f(self->amp, _##t1##_1, _##t2##_2, t3 _##t3##_3); } #define AMPMETHOD4(f, t1, t2, t3, t4) void f (t1 _##t1##_1, t2 _##t2##_3, t3 _##t3##_3, ##t4##_4) \ { self->error_status = amp_##f(self->amp, _##t1##_1, _##t2##_3, t3 _##t3##_3, ##t4##_4); } %extend Amp { Amp(amp_model_t amp_model) { Amp *r; r = (Amp*)malloc(sizeof(Amp)); if (!r) return NULL; r->amp = amp_init(amp_model); if (!r->amp) { free(r); return NULL; } /* install shortcuts */ r->caps = r->amp->caps; r->state = &r->amp->state; r->do_exception = 0; /* default is disabled */ r->error_status = RIG_OK; return r; } ~Amp () { amp_cleanup(self->amp); free(self); } /* * return code checking */ %exception { arg1->error_status = RIG_OK; $action if (arg1->error_status != RIG_OK && arg1->do_exception) SWIG_exception(SWIG_UnknownError, rigerror(arg1->error_status)); } AMPMETHOD0(open) AMPMETHOD0(close) AMPMETHOD1(reset, amp_reset_t) AMPMETHOD1(token_lookup, const_char_string) /* conf */ /* set functions */ AMPMETHOD1(set_freq, freq_t) AMPMETHOD1(set_powerstat, powerstat_t) void set_conf(const char *name, const char *val) { hamlib_token_t tok = amp_token_lookup(self->amp, name); if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = amp_set_conf(self->amp, tok, val); } AMPMETHOD2(set_conf, hamlib_token_t, const_char_string) /* * declare wrapper method with one output argument besides AMP* */ #define AMPMETHOD1VGET(f, t1) t1 f \ { t1 _##t1; self->error_status = amp_##f(self->amp, &_##t1); return _##t1; } /* get functions */ const char *get_conf(hamlib_token_t tok) { static char s[128] = ""; self->error_status = amp_get_conf(self->amp, tok, s); return s; } const char *get_conf(const char *name) { hamlib_token_t tok = amp_token_lookup(self->amp, name); static char s[128] = ""; if (tok == RIG_CONF_END) self->error_status = -RIG_EINVAL; else self->error_status = amp_get_conf(self->amp, tok, s); return s; } const char * get_info(void) { const char *s; s = amp_get_info(self->amp); self->error_status = s ? RIG_OK : -RIG_EINVAL; return s; } }; %{ void Amp_get_freq(Amp *self, freq_t *freq) { self->error_status = amp_get_freq(self->amp, freq); } void Amp_get_powerstat(Amp *self, powerstat_t *status) { self->error_status = amp_get_powerstat(self->amp, status); } %} hamlib-4.6.5/bindings/Makefile.in0000664000175000017500000013022615056640452012322 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Hamlib bindings using SWIG # more information on swig at http://www.swig.org # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ ########################################## # Perl binding @ENABLE_PERL_TRUE@am__append_1 = hamlibperl_wrap.c @ENABLE_PERL_TRUE@am__append_2 = hamlibperl_wrap.c Hamlib.pm Hamlib.bs Hamlib-pl.mk.old @ENABLE_PERL_TRUE@am__append_3 = perltest.pl @ENABLE_PYTHON_TRUE@am__append_4 = hamlibpy_wrap.c Hamlib.py *.pyc @ENABLE_PYTHON_TRUE@am__append_5 = hamlibpy_wrap.c Hamlib.py # PYVER_3 @ENABLE_PYTHON_TRUE@am__append_6 = $(pytest) # Python ########################################## # Tcl binding @ENABLE_TCL_TRUE@am__append_7 = hamlibtcl_wrap.c @ENABLE_TCL_TRUE@am__append_8 = hamlibtcl_wrap.c pkgIndex.tcl tcltest.tcl @ENABLE_TCL_TRUE@am__append_9 = tcltest.tcl @ENABLE_LUA_TRUE@am__append_10 = hamliblua_wrap.c @ENABLE_LUA_TRUE@am__append_11 = hamliblua_wrap.c @ENABLE_LUA_TRUE@am__append_12 = luatest.lua subdir = bindings ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(Hamliblua_ladir)" \ "$(DESTDIR)$(_Hamlib_ladir)" "$(DESTDIR)$(hamlibtcl_ladir)" \ "$(DESTDIR)$(pyexecdir)" "$(DESTDIR)$(exampledir)" \ "$(DESTDIR)$(hamlibtcl_ladir)" LTLIBRARIES = $(Hamliblua_la_LTLIBRARIES) $(_Hamlib_la_LTLIBRARIES) \ $(hamlibtcl_la_LTLIBRARIES) @ENABLE_LUA_TRUE@Hamliblua_la_DEPENDENCIES = \ @ENABLE_LUA_TRUE@ $(top_builddir)/src/libhamlib.la @ENABLE_LUA_TRUE@nodist_Hamliblua_la_OBJECTS = \ @ENABLE_LUA_TRUE@ Hamliblua_la-hamliblua_wrap.lo Hamliblua_la_OBJECTS = $(nodist_Hamliblua_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = Hamliblua_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(Hamliblua_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_LUA_TRUE@am_Hamliblua_la_rpath = -rpath $(Hamliblua_ladir) am__DEPENDENCIES_1 = @ENABLE_PYTHON_TRUE@_Hamlib_la_DEPENDENCIES = \ @ENABLE_PYTHON_TRUE@ $(top_builddir)/src/libhamlib.la \ @ENABLE_PYTHON_TRUE@ $(am__DEPENDENCIES_1) @ENABLE_PYTHON_TRUE@nodist__Hamlib_la_OBJECTS = hamlibpy_wrap.lo _Hamlib_la_OBJECTS = $(nodist__Hamlib_la_OBJECTS) _Hamlib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(_Hamlib_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_PYTHON_TRUE@am__Hamlib_la_rpath = -rpath $(_Hamlib_ladir) @ENABLE_TCL_TRUE@hamlibtcl_la_DEPENDENCIES = \ @ENABLE_TCL_TRUE@ $(top_builddir)/src/libhamlib.la \ @ENABLE_TCL_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @ENABLE_TCL_TRUE@nodist_hamlibtcl_la_OBJECTS = \ @ENABLE_TCL_TRUE@ hamlibtcl_la-hamlibtcl_wrap.lo hamlibtcl_la_OBJECTS = $(nodist_hamlibtcl_la_OBJECTS) hamlibtcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hamlibtcl_la_CFLAGS) \ $(CFLAGS) $(hamlibtcl_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_TCL_TRUE@am_hamlibtcl_la_rpath = -rpath $(hamlibtcl_ladir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/Hamliblua_la-hamliblua_wrap.Plo \ ./$(DEPDIR)/hamlibpy_wrap.Plo \ ./$(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(nodist_Hamliblua_la_SOURCES) $(nodist__Hamlib_la_SOURCES) \ $(nodist_hamlibtcl_la_SOURCES) DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile) am__pep3147_tweak = \ sed -e 's|\.py$$||' -e 's|[^/]*$$|__pycache__/&.*.pyc __pycache__/&.*.pyo|' py_compile = $(top_srcdir)/build-aux/py-compile DATA = $(example_DATA) $(hamlibtcl_la_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/py-compile DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CPPFLAGS@ -fno-strict-aliasing AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/include -I$(top_srcdir)/bindings \ $(TCL_INCLUDE_SPEC) $(PYTHON_CPPFLAGS) AM_CXXFLAGS = -O2 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SWGFILES = hamlib.swg ignore.swg rig.swg rotator.swg amplifier.swg SWGDEP = \ $(top_srcdir)/include/hamlib/rig.h \ $(top_srcdir)/include/hamlib/riglist.h \ $(top_srcdir)/include/hamlib/rotator.h \ $(top_srcdir)/include/hamlib/rotlist.h \ $(top_srcdir)/include/hamlib/amplifier.h \ $(top_srcdir)/include/hamlib/amplist.h \ $(SWGFILES) EXTRA_DIST = $(SWGFILES) \ Makefile.PL perltest.pl tcltest.tcl.in pytest.py py3test.py \ luatest.lua README.python exampledir = $(docdir)/examples example_DATA = $(am__append_3) $(am__append_6) $(am__append_9) \ $(am__append_12) BUILT_SOURCES = $(am__append_1) $(am__append_5) $(am__append_7) \ $(am__append_11) MOSTLYCLEANFILES = $(am__append_2) $(am__append_4) $(am__append_8) \ $(am__append_10) # Perl ########################################## # Python binding @ENABLE_PYTHON_TRUE@pyexec_ltlib = _Hamlib.la @ENABLE_PYTHON_TRUE@@PYVER_3_FALSE@pytest = pytest.py # Set by AM_CONDITIONAL in configure.ac @ENABLE_PYTHON_TRUE@@PYVER_3_TRUE@pytest = py3test.py @ENABLE_PYTHON_TRUE@nodist_pyexec_PYTHON = Hamlib.py @ENABLE_PYTHON_TRUE@nodist__Hamlib_la_SOURCES = hamlibpy_wrap.c @ENABLE_PYTHON_TRUE@_Hamlib_la_LDFLAGS = -no-undefined -module -avoid-version @ENABLE_PYTHON_TRUE@_Hamlib_la_LIBADD = $(top_builddir)/src/libhamlib.la $(PYTHON_LIBS) @ENABLE_PYTHON_TRUE@_Hamlib_ladir = $(pyexecdir) @ENABLE_PYTHON_TRUE@_Hamlib_la_LTLIBRARIES = $(pyexec_ltlib) @ENABLE_TCL_TRUE@tcl_ltlib = hamlibtcl.la @ENABLE_TCL_TRUE@tcldir = $(libdir)/tcl$(TCL_VERSION)/Hamlib @ENABLE_TCL_TRUE@PKG_VER = $(ABI_VERSION).$(ABI_REVISION) @ENABLE_TCL_TRUE@DLL = hamlibtcl-$(PKG_VER)$(TCL_SHLIB_SUFFIX) @ENABLE_TCL_TRUE@nodist_hamlibtcl_la_SOURCES = hamlibtcl_wrap.c @ENABLE_TCL_TRUE@hamlibtcl_la_CFLAGS = $(TCL_CFLAGS) @ENABLE_TCL_TRUE@hamlibtcl_la_LDFLAGS = -no-undefined -module -release $(PKG_VER) -avoid-version @ENABLE_TCL_TRUE@hamlibtcl_la_LIBADD = $(top_builddir)/src/libhamlib.la $(TCL_LIB_SPEC) $(TCL_LIBS) @ENABLE_TCL_TRUE@hamlibtcl_ladir = $(tcldir) @ENABLE_TCL_TRUE@hamlibtcl_la_DATA = pkgIndex.tcl # Install hamlibtcl.la into the $(tcldir)/Hamlib directory # set by $(hamlibtcl_ladir) @ENABLE_TCL_TRUE@hamlibtcl_la_LTLIBRARIES = $(tcl_ltlib) @ENABLE_TCL_TRUE@do_subst = sed -e 's,[@]tcldir[@],$(tcldir),g' # TCL ########################################## # Lua binding @ENABLE_LUA_TRUE@luaexec_ltlib = Hamliblua.la @ENABLE_LUA_TRUE@nodist_luaexec_LUA = Hamlib.lua @ENABLE_LUA_TRUE@nodist_Hamliblua_la_SOURCES = hamliblua_wrap.c @ENABLE_LUA_TRUE@Hamliblua_la_CPPFLAGS = $(LUA_INCLUDE) -I$(top_srcdir)/include -I$(top_srcdir)/src @ENABLE_LUA_TRUE@Hamliblua_la_LDFLAGS = -no-undefined -module -avoid-version @ENABLE_LUA_TRUE@Hamliblua_la_LIBADD = $(top_builddir)/src/libhamlib.la @ENABLE_LUA_TRUE@Hamliblua_ladir = $(luaexecdir) @ENABLE_LUA_TRUE@Hamliblua_la_LTLIBRARIES = $(luaexec_ltlib) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bindings/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu bindings/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-Hamliblua_laLTLIBRARIES: $(Hamliblua_la_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(Hamliblua_la_LTLIBRARIES)'; test -n "$(Hamliblua_ladir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(Hamliblua_ladir)'"; \ $(MKDIR_P) "$(DESTDIR)$(Hamliblua_ladir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(Hamliblua_ladir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(Hamliblua_ladir)"; \ } uninstall-Hamliblua_laLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(Hamliblua_la_LTLIBRARIES)'; test -n "$(Hamliblua_ladir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(Hamliblua_ladir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(Hamliblua_ladir)/$$f"; \ done clean-Hamliblua_laLTLIBRARIES: -$(am__rm_f) $(Hamliblua_la_LTLIBRARIES) @list='$(Hamliblua_la_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} install-_Hamlib_laLTLIBRARIES: $(_Hamlib_la_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(_Hamlib_la_LTLIBRARIES)'; test -n "$(_Hamlib_ladir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(_Hamlib_ladir)'"; \ $(MKDIR_P) "$(DESTDIR)$(_Hamlib_ladir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(_Hamlib_ladir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(_Hamlib_ladir)"; \ } uninstall-_Hamlib_laLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(_Hamlib_la_LTLIBRARIES)'; test -n "$(_Hamlib_ladir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(_Hamlib_ladir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(_Hamlib_ladir)/$$f"; \ done clean-_Hamlib_laLTLIBRARIES: -$(am__rm_f) $(_Hamlib_la_LTLIBRARIES) @list='$(_Hamlib_la_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} install-hamlibtcl_laLTLIBRARIES: $(hamlibtcl_la_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(hamlibtcl_la_LTLIBRARIES)'; test -n "$(hamlibtcl_ladir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(hamlibtcl_ladir)'"; \ $(MKDIR_P) "$(DESTDIR)$(hamlibtcl_ladir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(hamlibtcl_ladir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(hamlibtcl_ladir)"; \ } uninstall-hamlibtcl_laLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(hamlibtcl_la_LTLIBRARIES)'; test -n "$(hamlibtcl_ladir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(hamlibtcl_ladir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(hamlibtcl_ladir)/$$f"; \ done clean-hamlibtcl_laLTLIBRARIES: -$(am__rm_f) $(hamlibtcl_la_LTLIBRARIES) @list='$(hamlibtcl_la_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} Hamliblua.la: $(Hamliblua_la_OBJECTS) $(Hamliblua_la_DEPENDENCIES) $(EXTRA_Hamliblua_la_DEPENDENCIES) $(AM_V_CCLD)$(Hamliblua_la_LINK) $(am_Hamliblua_la_rpath) $(Hamliblua_la_OBJECTS) $(Hamliblua_la_LIBADD) $(LIBS) _Hamlib.la: $(_Hamlib_la_OBJECTS) $(_Hamlib_la_DEPENDENCIES) $(EXTRA__Hamlib_la_DEPENDENCIES) $(AM_V_CCLD)$(_Hamlib_la_LINK) $(am__Hamlib_la_rpath) $(_Hamlib_la_OBJECTS) $(_Hamlib_la_LIBADD) $(LIBS) hamlibtcl.la: $(hamlibtcl_la_OBJECTS) $(hamlibtcl_la_DEPENDENCIES) $(EXTRA_hamlibtcl_la_DEPENDENCIES) $(AM_V_CCLD)$(hamlibtcl_la_LINK) $(am_hamlibtcl_la_rpath) $(hamlibtcl_la_OBJECTS) $(hamlibtcl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Hamliblua_la-hamliblua_wrap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hamlibpy_wrap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< Hamliblua_la-hamliblua_wrap.lo: hamliblua_wrap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Hamliblua_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT Hamliblua_la-hamliblua_wrap.lo -MD -MP -MF $(DEPDIR)/Hamliblua_la-hamliblua_wrap.Tpo -c -o Hamliblua_la-hamliblua_wrap.lo `test -f 'hamliblua_wrap.c' || echo '$(srcdir)/'`hamliblua_wrap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/Hamliblua_la-hamliblua_wrap.Tpo $(DEPDIR)/Hamliblua_la-hamliblua_wrap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hamliblua_wrap.c' object='Hamliblua_la-hamliblua_wrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Hamliblua_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o Hamliblua_la-hamliblua_wrap.lo `test -f 'hamliblua_wrap.c' || echo '$(srcdir)/'`hamliblua_wrap.c hamlibtcl_la-hamlibtcl_wrap.lo: hamlibtcl_wrap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hamlibtcl_la_CFLAGS) $(CFLAGS) -MT hamlibtcl_la-hamlibtcl_wrap.lo -MD -MP -MF $(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Tpo -c -o hamlibtcl_la-hamlibtcl_wrap.lo `test -f 'hamlibtcl_wrap.c' || echo '$(srcdir)/'`hamlibtcl_wrap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Tpo $(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hamlibtcl_wrap.c' object='hamlibtcl_la-hamlibtcl_wrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hamlibtcl_la_CFLAGS) $(CFLAGS) -c -o hamlibtcl_la-hamlibtcl_wrap.lo `test -f 'hamlibtcl_wrap.c' || echo '$(srcdir)/'`hamlibtcl_wrap.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-nodist_pyexecPYTHON: $(nodist_pyexec_PYTHON) @$(NORMAL_INSTALL) @list='$(nodist_pyexec_PYTHON)'; dlist=; list2=; test -n "$(pyexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pyexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pyexecdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ if test -f $$b$$p; then \ $(am__strip_dir) \ dlist="$$dlist $$f"; \ list2="$$list2 $$b$$p"; \ else :; fi; \ done; \ for file in $$list2; do echo $$file; done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pyexecdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pyexecdir)" || exit $$?; \ done || exit $$?; \ if test -n "$$dlist"; then \ $(am__py_compile) --destdir "$(DESTDIR)" \ --basedir "$(pyexecdir)" $$dlist; \ else :; fi uninstall-nodist_pyexecPYTHON: @$(NORMAL_UNINSTALL) @list='$(nodist_pyexec_PYTHON)'; test -n "$(pyexecdir)" || list=; \ py_files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$py_files" || exit 0; \ dir='$(DESTDIR)$(pyexecdir)'; \ pyc_files=`echo "$$py_files" | sed 's|$$|c|'`; \ pyo_files=`echo "$$py_files" | sed 's|$$|o|'`; \ st=0; \ for files in "$$py_files" "$$pyc_files" "$$pyo_files"; do \ $(am__uninstall_files_from_dir) || st=$$?; \ done; \ dir='$(DESTDIR)$(pyexecdir)'; \ files=`echo "$$py_files" | $(am__pep3147_tweak)`; \ $(am__uninstall_files_from_dir) || st=$$?; \ exit $$st install-exampleDATA: $(example_DATA) @$(NORMAL_INSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(exampledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(exampledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(exampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(exampledir)" || exit $$?; \ done uninstall-exampleDATA: @$(NORMAL_UNINSTALL) @list='$(example_DATA)'; test -n "$(exampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(exampledir)'; $(am__uninstall_files_from_dir) install-hamlibtcl_laDATA: $(hamlibtcl_la_DATA) @$(NORMAL_INSTALL) @list='$(hamlibtcl_la_DATA)'; test -n "$(hamlibtcl_ladir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(hamlibtcl_ladir)'"; \ $(MKDIR_P) "$(DESTDIR)$(hamlibtcl_ladir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(hamlibtcl_ladir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(hamlibtcl_ladir)" || exit $$?; \ done uninstall-hamlibtcl_laDATA: @$(NORMAL_UNINSTALL) @list='$(hamlibtcl_la_DATA)'; test -n "$(hamlibtcl_ladir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(hamlibtcl_ladir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(DATA) all-local installdirs: for dir in "$(DESTDIR)$(Hamliblua_ladir)" "$(DESTDIR)$(_Hamlib_ladir)" "$(DESTDIR)$(hamlibtcl_ladir)" "$(DESTDIR)$(pyexecdir)" "$(DESTDIR)$(exampledir)" "$(DESTDIR)$(hamlibtcl_ladir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -$(am__rm_f) $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-Hamliblua_laLTLIBRARIES clean-_Hamlib_laLTLIBRARIES \ clean-generic clean-hamlibtcl_laLTLIBRARIES clean-libtool \ clean-local mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/Hamliblua_la-hamliblua_wrap.Plo -rm -f ./$(DEPDIR)/hamlibpy_wrap.Plo -rm -f ./$(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-local distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-Hamliblua_laLTLIBRARIES \ install-_Hamlib_laLTLIBRARIES install-exampleDATA \ install-hamlibtcl_laDATA install-hamlibtcl_laLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-exec-local install-nodist_pyexecPYTHON install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/Hamliblua_la-hamliblua_wrap.Plo -rm -f ./$(DEPDIR)/hamlibpy_wrap.Plo -rm -f ./$(DEPDIR)/hamlibtcl_la-hamlibtcl_wrap.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-Hamliblua_laLTLIBRARIES \ uninstall-_Hamlib_laLTLIBRARIES uninstall-exampleDATA \ uninstall-hamlibtcl_laDATA uninstall-hamlibtcl_laLTLIBRARIES \ uninstall-local uninstall-nodist_pyexecPYTHON .MAKE: all check check-am install install-am install-exec \ install-strip .PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles check \ check-am check-local clean clean-Hamliblua_laLTLIBRARIES \ clean-_Hamlib_laLTLIBRARIES clean-generic \ clean-hamlibtcl_laLTLIBRARIES clean-libtool clean-local \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-local \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-Hamliblua_laLTLIBRARIES \ install-_Hamlib_laLTLIBRARIES install-am install-data \ install-data-am install-dvi install-dvi-am install-exampleDATA \ install-exec install-exec-am install-exec-local \ install-hamlibtcl_laDATA install-hamlibtcl_laLTLIBRARIES \ install-html install-html-am install-info install-info-am \ install-man install-nodist_pyexecPYTHON install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-Hamliblua_laLTLIBRARIES \ uninstall-_Hamlib_laLTLIBRARIES uninstall-am \ uninstall-exampleDATA uninstall-hamlibtcl_laDATA \ uninstall-hamlibtcl_laLTLIBRARIES uninstall-local \ uninstall-nodist_pyexecPYTHON .PRECIOUS: Makefile $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la @ENABLE_PERL_TRUE@hamlibperl_wrap.c: $(SWIGDEP) @ENABLE_PERL_TRUE@ $(AM_V_GEN)$(SWIG) -perl5 -shadow $(AM_CPPFLAGS) -I$(top_srcdir)/bindings \ @ENABLE_PERL_TRUE@ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg @ENABLE_PERL_TRUE@Hamlib-pl.mk: $(srcdir)/Makefile.PL @ENABLE_PERL_TRUE@ $(AM_V_at)test -f Makefile.PL || $(LN_S) $(srcdir)/Makefile.PL Makefile.PL @ENABLE_PERL_TRUE@ $(AM_V_at)perl $$(test -f Makefile.PL || echo '$(srcdir)/')Makefile.PL \ @ENABLE_PERL_TRUE@ MAKEFILE="Hamlib-pl.mk" \ @ENABLE_PERL_TRUE@ PREFIX="$(prefix)" \ @ENABLE_PERL_TRUE@ INC="$(AM_CPPFLAGS)" \ @ENABLE_PERL_TRUE@ CC="$(CC)" \ @ENABLE_PERL_TRUE@ OBJECT="hamlibperl_wrap.o" \ @ENABLE_PERL_TRUE@ VERSION="$(PACKAGE_VERSION)" \ @ENABLE_PERL_TRUE@ LIBS="-L$(top_builddir)/src/.libs -lhamlib" @ENABLE_PERL_TRUE@ $(AM_V_at)sed -e 's/^LD_RUN_PATH.*/LD_RUN_PATH =/' Hamlib-pl.mk > Hamlib-pl-norpath.mk @ENABLE_PERL_TRUE@ $(AM_V_at)mv Hamlib-pl-norpath.mk Hamlib-pl.mk @ENABLE_PERL_TRUE@all-perl: Hamlib-pl.mk hamlibperl_wrap.c @ENABLE_PERL_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk all @ENABLE_PERL_TRUE@check-perl: all-perl @ENABLE_PERL_TRUE@ $(AM_V_at)LD_LIBRARY_PATH=$(top_builddir)/src/.libs perl $(top_srcdir)/bindings/perltest.pl @ENABLE_PERL_TRUE@clean-perl: Hamlib-pl.mk @ENABLE_PERL_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk clean @ENABLE_PERL_TRUE@distclean-perl: ## Hamlib-pl.mk @ENABLE_PERL_TRUE@distcheck-perl: Hamlib-pl.mk @ENABLE_PERL_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk distcheck @ENABLE_PERL_TRUE@install-perl: Hamlib-pl.mk @ENABLE_PERL_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk install_site @ENABLE_PERL_TRUE@uninstall-perl: ## Hamlib-pl.mk @ENABLE_PYTHON_TRUE@all-py: $(pyexec_ltlib) @ENABLE_PYTHON_TRUE@check-py: all-py @ENABLE_PYTHON_TRUE@ $(AM_V_at)PYTHONPATH=$(builddir):$(builddir)/.libs \ @ENABLE_PYTHON_TRUE@ $(PYTHON) $(srcdir)/$(pytest) \ @ENABLE_PYTHON_TRUE@ || echo "Python test failed" 1>&2 @ENABLE_PYTHON_TRUE@Hamlib.py: hamlibpy_wrap.c @ENABLE_PYTHON_TRUE@hamlibpy_wrap.c: $(SWGDEP) @ENABLE_PYTHON_TRUE@ $(AM_V_GEN)$(SWIG) -python $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) -I$(top_srcdir)/bindings \ @ENABLE_PYTHON_TRUE@ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg @ENABLE_PYTHON_TRUE@install-py: @ENABLE_PYTHON_TRUE@clean-py: @ENABLE_PYTHON_TRUE@ $(AM_V_at)rm -rf $(builddir)/__pycache__ @ENABLE_PYTHON_TRUE@distclean-py: @ENABLE_PYTHON_TRUE@uninstall-py: # Having the first occurrence of 'hamlib' capitalized seemed to cause confusion # for the TCL interpreter loading the Hamlib module. @ENABLE_TCL_TRUE@pkgIndex.tcl: Makefile @ENABLE_TCL_TRUE@ $(AM_V_at)echo 'package ifneeded hamlib $(PKG_VER) [list load [file join $$dir $(DLL)] Hamlib]' > pkgIndex.tcl @ENABLE_TCL_TRUE@hamlibtcl_wrap.c: $(SWGDEP) @ENABLE_TCL_TRUE@ $(AM_V_GEN)$(SWIG) -tcl -pkgversion $(PKG_VER) $(AM_CPPFLAGS) \ @ENABLE_TCL_TRUE@ -I$(top_srcdir)/bindings \ @ENABLE_TCL_TRUE@ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg @ENABLE_TCL_TRUE@tcltest.tcl: tcltest.tcl.in Makefile @ENABLE_TCL_TRUE@ $(AM_V_GEN)$(do_subst) < $(srcdir)/tcltest.tcl.in > tcltest.tcl @ENABLE_TCL_TRUE@all-tcl: pkgIndex.tcl $(tcl_ltlib) tcltest.tcl @ENABLE_TCL_TRUE@check-tcl: all-tcl @ENABLE_TCL_TRUE@ $(AM_V_at)cp $(builddir)/pkgIndex.tcl $(builddir)/.libs @ENABLE_TCL_TRUE@ $(AM_V_at)TCLLIBPATH=$(builddir)/.libs tclsh $(builddir)/tcltest.tcl \ @ENABLE_TCL_TRUE@ || echo "Tcl test failed" 1>&2 @ENABLE_TCL_TRUE@ $(AM_V_at)rm -f $(builddir)/.libs/pkgIndex.tcl @ENABLE_TCL_TRUE@install-tcl: @ENABLE_TCL_TRUE@clean-tcl: @ENABLE_TCL_TRUE@distclean-tcl: clean-tcl @ENABLE_TCL_TRUE@uninstall-tcl: @ENABLE_LUA_TRUE@all-lua: $(luaexec_ltlib) @ENABLE_LUA_TRUE@check-lua: all-lua @ENABLE_LUA_TRUE@ $(AM_V_at)LUA_CPATH="$(abs_builddir)/.libs/?.so" $(LUA) $(srcdir)/luatest.lua \ @ENABLE_LUA_TRUE@ || echo "Lua test failed" 1>&2 @ENABLE_LUA_TRUE@Hamlib.lua: hamliblua_wrap.c @ENABLE_LUA_TRUE@hamliblua_wrap.c: $(SWGDEP) @ENABLE_LUA_TRUE@ $(AM_V_GEN)$(SWIG) -lua $(AM_CPPFLAGS) -I$(top_srcdir)/bindings \ @ENABLE_LUA_TRUE@ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg @ENABLE_LUA_TRUE@install-lua: @ENABLE_LUA_TRUE@clean-lua: @ENABLE_LUA_TRUE@distclean-lua: @ENABLE_LUA_TRUE@uninstall-lua: # Lua all-local: @BINDING_ALL@ check-local: @BINDING_CHECK@ clean-local: @BINDING_CLEAN@ distclean-local: @BINDING_DISTCLEAN@ distcheck-local: @BINDING_DISTCHECK@ install-exec-local: @BINDING_INSTALL_EXEC@ uninstall-local: @BINDING_UNINSTALL@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/bindings/perltest.pl0000775000175000017500000000614615056640442012461 #!/usr/bin/perl -Iblib/arch -Iblib/lib use Hamlib; print "Perl $] test, version: $Hamlib::hamlib_version\n\n"; #Hamlib::rig_set_debug($Hamlib::RIG_DEBUG_TRACE); Hamlib::rig_set_debug($Hamlib::RIG_DEBUG_NONE); $rig = new Hamlib::Rig($Hamlib::RIG_MODEL_DUMMY); # replace "/dev/Rig" with your path to serial port $rig->set_conf("retry","50"); $rig->set_conf("rig_pathname","/dev/Rig"); $rig->open(); $rpath = $rig->get_conf("rig_pathname"); $retry = $rig->get_conf("retry"); print "get_conf:\t\tpath = \"$rpath\", retry = $retry\n"; $rig->set_freq($Hamlib::RIG_VFO_A, 14266000); $f = $rig->get_freq(); print "freq:\t\t\t$f\n"; ($mode, $width) = $rig->get_mode(); print "get_mode:\t\t".Hamlib::rig_strrmode($mode)."\nwidth:\t\t\t$width\n"; $vfo = $rig->get_vfo(); print "get_vfo:\t\t".Hamlib::rig_strvfo($vfo)."\n"; $rig->set_vfo($Hamlib::RIG_VFO_B); #$rig->set_vfo("VFOA"); $rig->set_mode($Hamlib::RIG_MODE_CW, $Hamlib::RIG_PASSBAND_NORMAL); print "Backend copyright:\t$rig->{caps}->{copyright}\n"; print "Model:\t\t\t$rig->{caps}->{model_name}\n"; print "Manufacturer:\t\t$rig->{caps}->{mfg_name}\n"; print "Backend version:\t$rig->{caps}->{version}\n"; $inf = $rig->get_info(); print "get_info:\t\t$inf\n"; $rig->set_level("VOX", 1); $lvl = $rig->get_level_i("VOX"); print "VOX delay:\t\t$lvl\n"; $rig->set_level($Hamlib::RIG_LEVEL_VOXDELAY, 5); $lvl = $rig->get_level_i($Hamlib::RIG_LEVEL_VOXDELAY); print "VOX delay:\t\t$lvl\n"; $lvl = $rig->get_level_i($Hamlib::RIG_LEVEL_STRENGTH); print "strength:\t\t$lvl\n"; $chan = new Hamlib::channel($Hamlib::RIG_VFO_A); $rig->get_channel($chan,1); @tokens = split("\n",Hamlib::rigerror($rig->{error_status})); print "get_channel status:\t$rig->{error_status} = ".$tokens[0]."\n"; print "VFO:\t\t\t".Hamlib::rig_strvfo($chan->{vfo}).", $chan->{freq}\n"; $att = $rig->{caps}->{attenuator}; print "Attenuators:\t\t@$att\n"; print "\nSending Morse, '73'\n"; $rig->send_morse($Hamlib::RIG_VFO_A, "73"); $rig->close(); print "\nSome static functions:\n"; ($err, $lon1, $lat1, $sw1) = Hamlib::locator2longlat("IN98XC"); ($err, $lon2, $lat2, $sw1) = Hamlib::locator2longlat("DM33DX"); $loc1 = Hamlib::longlat2locator($lon1, $lat1, 3); $loc2 = Hamlib::longlat2locator($lon2, $lat2, 3); printf("Loc1:\t\tIN98XC -> %9.4f, %9.4f-> %s\n", $lon1, $lat1, $loc1); printf("Loc1:\t\tDM33DX -> %9.4f, %9.4f-> %s\n", $lon2, $lat2, $loc2); ($err, $dist, $az) = Hamlib::qrb($lon1, $lat1, $lon2, $lat2); $longpath = Hamlib::distance_long_path($dist); printf("Distance:\t%.3f km, azimuth %.2f, long path: %.3f km\n", $dist, $az, $longpath); # dec2dms expects values from 180 to -180 # sw is 1 when deg is negative (west or south) as 0 cannot be signed ($err, $deg1, $min1, $sec1, $sw1) = Hamlib::dec2dms($lon1); ($err, $deg2, $min2, $sec2, $sw2) = Hamlib::dec2dms($lat1); $lon3 = Hamlib::dms2dec($deg1, $min1, $sec1, $sw1); $lat3 = Hamlib::dms2dec($deg2, $min2, $sec2, $sw2); printf("Longitude:\t%9.4f, %4d° %2d' %2d\" %1s\trecoded: %9.4f\n", $lon1, $deg1, $min1, $sec1, $sw1 ? 'W' : 'E', $lon3); printf("Latitude:\t%9.4f, %4d° %2d' %2d\" %1s\trecoded: %9.4f\n", $lat1, $deg2, $min2, $sec2, $sw2 ? 'S' : 'N', $lat3); hamlib-4.6.5/bindings/py3test.py0000775000175000017500000001106515056640442012243 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys # Change this path to match your "make install" path sys.path.append('/usr/local/lib/python3.10/site-packages') ## Uncomment to run this script from an in-tree build (or adjust to the ## build directory) without installing the bindings. #sys.path.append ('.') #sys.path.append ('.libs') import Hamlib def StartUp(): """Simple script to test the Hamlib.py module with Python3.""" print("%s: Python %s; %s\n" \ % (sys.argv[0], sys.version.split()[0], Hamlib.cvar.hamlib_version)) Hamlib.rig_set_debug(Hamlib.RIG_DEBUG_NONE) # Init RIG_MODEL_DUMMY my_rig = Hamlib.Rig(Hamlib.RIG_MODEL_DUMMY) my_rig.set_conf("rig_pathname", "/dev/Rig") my_rig.set_conf("retry", "5") my_rig.open () rpath = my_rig.get_conf("rig_pathname") retry = my_rig.get_conf("retry") print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status)) print("get_conf:\t\tpath = %s, retry = %s" \ % (rpath, retry)) my_rig.set_freq(Hamlib.RIG_VFO_B, 5700000000) my_rig.set_vfo(Hamlib.RIG_VFO_B) print("freq:\t\t\t%s" % my_rig.get_freq()) my_rig.set_freq(Hamlib.RIG_VFO_A, 145550000) (mode, width) = my_rig.get_mode(Hamlib.RIG_VFO_A) print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width)) my_rig.set_mode(Hamlib.RIG_MODE_CW) (mode, width) = my_rig.get_mode() print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width)) print("Backend copyright:\t%s" % my_rig.caps.copyright) print("Model:\t\t\t%s" % my_rig.caps.model_name) print("Manufacturer:\t\t%s" % my_rig.caps.mfg_name) print("Backend version:\t%s" % my_rig.caps.version) print("Backend status:\t\t%s" % Hamlib.rig_strstatus(my_rig.caps.status)) print("Rig info:\t\t%s" % my_rig.get_info()) my_rig.set_level("VOXDELAY", 1) print("VOX delay:\t\t%s" % my_rig.get_level_i("VOXDELAY")) my_rig.set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5) print("VOX delay:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_VOXDELAY)) af = 12.34 print("Setting AF to %0.2f...." % (af)) my_rig.set_level("AF", af) print("status:\t\t\t%s - %s" % (my_rig.error_status, Hamlib.rigerror(my_rig.error_status))) print("AF level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_AF)) print("Power level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_RFPOWER_METER)) print("Power level Watts:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_RFPOWER_METER_WATTS)) print("strength:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH)) print("status:\t\t\t%s" % my_rig.error_status) print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status)) chan = Hamlib.channel(Hamlib.RIG_VFO_B) my_rig.get_channel(chan,1) print("get_channel status:\t%s" % my_rig.error_status) print("VFO:\t\t\t%s, %s" % (Hamlib.rig_strvfo(chan.vfo), chan.freq)) print("Attenuators:\t\t%s" % my_rig.caps.attenuator) # Can't seem to get get_vfo_info to work #(freq, width, mode, split) = my_rig.get_vfo_info(Hamlib.RIG_VFO_A,freq,width,mode,split) #print("Rig vfo_info:\t\tfreq=%s, mode=%s, width=%s, split=%s" % (freq, mode, width, split)) print("\nSending Morse, '73'") my_rig.send_morse(Hamlib.RIG_VFO_A, "73") my_rig.close() print("\nSome static functions:") err, lon1, lat1 = Hamlib.locator2longlat("IN98XC") err, lon2, lat2 = Hamlib.locator2longlat("DM33DX") err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3) err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3) print("Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s" % (lon1, lat1, loc1)) print("Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s" % (lon2, lat2, loc2)) err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2) longpath = Hamlib.distance_long_path(dist) print("Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km" \ % (dist, az, longpath)) # dec2dms expects values from 180 to -180 # sw is 1 when deg is negative (west or south) as 0 cannot be signed err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1) err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1) lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1) lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2) print('Longitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ % (lon1, deg1, mins1, sec1, ('W' if sw1 else 'E'), lon3)) print('Latitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \ % (lat1, deg2, mins2, sec2, ('S' if sw2 else 'N'), lat3)) my_rig.set_vfo_opt(0); if __name__ == '__main__': StartUp() hamlib-4.6.5/bindings/hamlib.swg0000664000175000017500000001261015056640442012226 #ifndef SWIGLUA %module Hamlib #else %module Hamliblua #endif %{ /* * Hamlib bindings - swig interface file * Copyright (c) 2001-2008 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include //mdblack98 -- Commented this out -- is anybody using the functions in misc.h? //If so, then those functions should be moved to rig.h //#include "misc.h" #include %} /* * symbols that won't be wrapped */ %include "ignore.swg" %include typemaps.i %include stdint.i %include exception.i #ifndef SWIGLUA #ifndef SWIGJAVA %include cstring.i #endif #endif #ifdef SWIGPYTHON %include python/file.i %typemap(out) int [ANY] { int len,i; len = $1_dim0; $result = PyList_New(len); for (i = 0; i < len; i++) { PyList_SetItem($result,i,PyInt_FromLong((long)$1[i])); } } %typemap(varout) int [ANY] { int len,i; len = $1_dim0; $result = PyList_New(len); for (i = 0; i < len; i++) { PyList_SetItem($result,i,PyInt_FromLong((long)$1[i])); } } #endif #ifdef SWIGPERL %typemap(out) int [ANY] { AV * av = newAV(); int i = 0,len = 0; len = $1_dim0; for (i = 0; i < len ; i++) { SV* perlval = newSV(0); sv_setiv(perlval, (IV)$1[i]); av_push(av, perlval); } $result = newRV_noinc((SV *)av); sv_2mortal( $result ); argvi++; } %typemap(argout) int [ANY] { AV * av = newAV(); int i = 0,len = 0; len = $1_dim0; for (i = 0; i < len ; i++) { SV* perlval = newSV(0); sv_setiv(perlval, (IV)$1[i]); av_push(av, perlval); } $result = newRV_noinc((SV *)av); sv_2mortal( $result ); argvi++; } #endif #ifdef SWIGTCL %typemap(out) int [ANY] { int i, len, l; len = $1_dim0; Tcl_Obj * list = Tcl_NewListObj(len, NULL); for(i=0; i < len; i++) { Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj($1[i])); } Tcl_SetObjResult(interp, list); } %typemap(varout) int [ANY] { int i, len, l; len = $1_dim0; Tcl_Obj * list = Tcl_NewListObj(len, NULL); for(i=0; i < len; i++) { Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj($1[i])); } $result = list; } #endif #ifdef SWIGLUA %typemap(out) int [ANY] { int len,i; len = $1_dim0; lua_createtable (L, len, 0); for(i=0; i %include %include %include %include %inline { typedef const char * const_char_string; } /* * The Rig "class" */ %include "rig.swg" /* * The Rot "class" */ %include "rotator.swg" /* * The Amp "class" */ %include "amplifier.swg" /* * Put binding specific code in separate files * %include "perl.i" %include "tcl.i" %include "python.i" %include "whatever.i" */ hamlib-4.6.5/bindings/Makefile.am0000664000175000017500000001515115056640442012307 # Hamlib bindings using SWIG # more information on swig at http://www.swig.org # AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/include -I$(top_srcdir)/bindings \ $(TCL_INCLUDE_SPEC) $(PYTHON_CPPFLAGS) AM_CFLAGS = @AM_CPPFLAGS@ -fno-strict-aliasing AM_CXXFLAGS = -O2 SWGFILES = hamlib.swg ignore.swg rig.swg rotator.swg amplifier.swg SWGDEP = \ $(top_srcdir)/include/hamlib/rig.h \ $(top_srcdir)/include/hamlib/riglist.h \ $(top_srcdir)/include/hamlib/rotator.h \ $(top_srcdir)/include/hamlib/rotlist.h \ $(top_srcdir)/include/hamlib/amplifier.h \ $(top_srcdir)/include/hamlib/amplist.h \ $(SWGFILES) EXTRA_DIST = $(SWGFILES) \ Makefile.PL perltest.pl tcltest.tcl.in pytest.py py3test.py \ luatest.lua README.python exampledir = $(docdir)/examples example_DATA = BUILT_SOURCES = MOSTLYCLEANFILES = $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la if ENABLE_PERL ########################################## # Perl binding BUILT_SOURCES += hamlibperl_wrap.c MOSTLYCLEANFILES += hamlibperl_wrap.c Hamlib.pm Hamlib.bs Hamlib-pl.mk.old example_DATA += perltest.pl hamlibperl_wrap.c: $(SWIGDEP) $(AM_V_GEN)$(SWIG) -perl5 -shadow $(AM_CPPFLAGS) -I$(top_srcdir)/bindings \ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg Hamlib-pl.mk: $(srcdir)/Makefile.PL $(AM_V_at)test -f Makefile.PL || $(LN_S) $(srcdir)/Makefile.PL Makefile.PL $(AM_V_at)perl $$(test -f Makefile.PL || echo '$(srcdir)/')Makefile.PL \ MAKEFILE="Hamlib-pl.mk" \ PREFIX="$(prefix)" \ INC="$(AM_CPPFLAGS)" \ CC="$(CC)" \ OBJECT="hamlibperl_wrap.o" \ VERSION="$(PACKAGE_VERSION)" \ LIBS="-L$(top_builddir)/src/.libs -lhamlib" $(AM_V_at)sed -e 's/^LD_RUN_PATH.*/LD_RUN_PATH =/' Hamlib-pl.mk > Hamlib-pl-norpath.mk $(AM_V_at)mv Hamlib-pl-norpath.mk Hamlib-pl.mk all-perl: Hamlib-pl.mk hamlibperl_wrap.c $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk all check-perl: all-perl $(AM_V_at)LD_LIBRARY_PATH=$(top_builddir)/src/.libs perl $(top_srcdir)/bindings/perltest.pl clean-perl: Hamlib-pl.mk $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk clean ## 'distclean' target is a NOOP in Hamlib-pl.mk distclean-perl: ## Hamlib-pl.mk ## $(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk distclean distcheck-perl: Hamlib-pl.mk $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk distcheck install-perl: Hamlib-pl.mk $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk install_site ## ExtUtils::MakeMaker says uninstall is deprecated and won't remove the files ## anyway, so we'll have to figure out another way to remove the installed files. uninstall-perl: ## Hamlib-pl.mk ## $(MAKE) $(AM_MAKEFLAGS) -f Hamlib-pl.mk uninstall endif # Perl if ENABLE_PYTHON ########################################## # Python binding pyexec_ltlib = _Hamlib.la MOSTLYCLEANFILES += hamlibpy_wrap.c Hamlib.py *.pyc BUILT_SOURCES += hamlibpy_wrap.c Hamlib.py # Set by AM_CONDITIONAL in configure.ac if PYVER_3 pytest = py3test.py else !PYVER_3 pytest = pytest.py endif # PYVER_3 example_DATA += $(pytest) nodist_pyexec_PYTHON = Hamlib.py nodist__Hamlib_la_SOURCES = hamlibpy_wrap.c _Hamlib_la_LDFLAGS = -no-undefined -module -avoid-version _Hamlib_la_LIBADD = $(top_builddir)/src/libhamlib.la $(PYTHON_LIBS) _Hamlib_ladir = $(pyexecdir) _Hamlib_la_LTLIBRARIES = $(pyexec_ltlib) all-py: $(pyexec_ltlib) check-py: all-py $(AM_V_at)PYTHONPATH=$(builddir):$(builddir)/.libs \ $(PYTHON) $(srcdir)/$(pytest) \ || echo "Python test failed" 1>&2 Hamlib.py: hamlibpy_wrap.c hamlibpy_wrap.c: $(SWGDEP) $(AM_V_GEN)$(SWIG) -python $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) -I$(top_srcdir)/bindings \ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg install-py: clean-py: $(AM_V_at)rm -rf $(builddir)/__pycache__ distclean-py: uninstall-py: endif # Python if ENABLE_TCL ########################################## # Tcl binding BUILT_SOURCES += hamlibtcl_wrap.c MOSTLYCLEANFILES += hamlibtcl_wrap.c pkgIndex.tcl tcltest.tcl example_DATA += tcltest.tcl tcl_ltlib = hamlibtcl.la tcldir = $(libdir)/tcl$(TCL_VERSION)/Hamlib PKG_VER = $(ABI_VERSION).$(ABI_REVISION) DLL = hamlibtcl-$(PKG_VER)$(TCL_SHLIB_SUFFIX) nodist_hamlibtcl_la_SOURCES = hamlibtcl_wrap.c hamlibtcl_la_CFLAGS = $(TCL_CFLAGS) hamlibtcl_la_LDFLAGS = -no-undefined -module -release $(PKG_VER) -avoid-version hamlibtcl_la_LIBADD = $(top_builddir)/src/libhamlib.la $(TCL_LIB_SPEC) $(TCL_LIBS) hamlibtcl_ladir = $(tcldir) hamlibtcl_la_DATA = pkgIndex.tcl # Install hamlibtcl.la into the $(tcldir)/Hamlib directory # set by $(hamlibtcl_ladir) hamlibtcl_la_LTLIBRARIES = $(tcl_ltlib) # Having the first occurrence of 'hamlib' capitalized seemed to cause confusion # for the TCL interpreter loading the Hamlib module. pkgIndex.tcl: Makefile $(AM_V_at)echo 'package ifneeded hamlib $(PKG_VER) [list load [file join $$dir $(DLL)] Hamlib]' > pkgIndex.tcl hamlibtcl_wrap.c: $(SWGDEP) $(AM_V_GEN)$(SWIG) -tcl -pkgversion $(PKG_VER) $(AM_CPPFLAGS) \ -I$(top_srcdir)/bindings \ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg do_subst = sed -e 's,[@]tcldir[@],$(tcldir),g' tcltest.tcl: tcltest.tcl.in Makefile $(AM_V_GEN)$(do_subst) < $(srcdir)/tcltest.tcl.in > tcltest.tcl all-tcl: pkgIndex.tcl $(tcl_ltlib) tcltest.tcl check-tcl: all-tcl $(AM_V_at)cp $(builddir)/pkgIndex.tcl $(builddir)/.libs $(AM_V_at)TCLLIBPATH=$(builddir)/.libs tclsh $(builddir)/tcltest.tcl \ || echo "Tcl test failed" 1>&2 $(AM_V_at)rm -f $(builddir)/.libs/pkgIndex.tcl install-tcl: clean-tcl: distclean-tcl: clean-tcl uninstall-tcl: endif # TCL if ENABLE_LUA ########################################## # Lua binding luaexec_ltlib = Hamliblua.la MOSTLYCLEANFILES += hamliblua_wrap.c BUILT_SOURCES += hamliblua_wrap.c example_DATA += luatest.lua nodist_luaexec_LUA = Hamlib.lua nodist_Hamliblua_la_SOURCES = hamliblua_wrap.c Hamliblua_la_CPPFLAGS = $(LUA_INCLUDE) -I$(top_srcdir)/include -I$(top_srcdir)/src Hamliblua_la_LDFLAGS = -no-undefined -module -avoid-version Hamliblua_la_LIBADD = $(top_builddir)/src/libhamlib.la Hamliblua_ladir = $(luaexecdir) Hamliblua_la_LTLIBRARIES = $(luaexec_ltlib) all-lua: $(luaexec_ltlib) check-lua: all-lua $(AM_V_at)LUA_CPATH="$(abs_builddir)/.libs/?.so" $(LUA) $(srcdir)/luatest.lua \ || echo "Lua test failed" 1>&2 Hamlib.lua: hamliblua_wrap.c hamliblua_wrap.c: $(SWGDEP) $(AM_V_GEN)$(SWIG) -lua $(AM_CPPFLAGS) -I$(top_srcdir)/bindings \ -o $@ $$(test -f hamlib.swg || echo '$(srcdir)/')hamlib.swg install-lua: clean-lua: distclean-lua: uninstall-lua: endif # Lua all-local: @BINDING_ALL@ check-local: @BINDING_CHECK@ clean-local: @BINDING_CLEAN@ distclean-local: @BINDING_DISTCLEAN@ distcheck-local: @BINDING_DISTCHECK@ install-exec-local: @BINDING_INSTALL_EXEC@ uninstall-local: @BINDING_UNINSTALL@ hamlib-4.6.5/bindings/ignore.swg0000664000175000017500000001216715056640442012264 /* unsupported Hamlib's calls */ /* useless macros */ %ignore _RIG_H; %ignore _RIGLIST_H; %ignore _ROTLIST_H; %ignore _ROTATOR_H; %ignore RIG_DUMMY; %ignore RIG_BACKEND_DUMMY; %ignore RIG_YAESU; %ignore RIG_BACKEND_YAESU; %ignore RIG_KENWOOD; %ignore RIG_BACKEND_KENWOOD; %ignore RIG_ICOM; %ignore RIG_BACKEND_ICOM; %ignore RIG_PCR; %ignore RIG_BACKEND_PCR; %ignore RIG_AOR; %ignore RIG_BACKEND_AOR; %ignore RIG_JRC; %ignore RIG_BACKEND_JRC; %ignore RIG_RADIOSHACK; %ignore RIG_BACKEND_RADIOSHACK; %ignore RIG_UNIDEN; %ignore RIG_BACKEND_UNIDEN; %ignore RIG_DRAKE; %ignore RIG_BACKEND_DRAKE; %ignore RIG_LOWE; %ignore RIG_BACKEND_LOWE; %ignore RIG_RACAL; %ignore RIG_BACKEND_RACAL; %ignore RIG_WJ; %ignore RIG_BACKEND_WJ; %ignore RIG_EK; %ignore RIG_BACKEND_EK; %ignore RIG_SKANTI; %ignore RIG_BACKEND_SKANTI; %ignore RIG_PRM80; %ignore RIG_BACKEND_PRM80; %ignore RIG_WINRADIO; %ignore RIG_BACKEND_WINRADIO; %ignore RIG_TENTEC; %ignore RIG_BACKEND_TENTEC; %ignore RIG_ALINCO; %ignore RIG_BACKEND_ALINCO; %ignore RIG_KACHINA; %ignore RIG_BACKEND_KACHINA; %ignore RIG_RPC; %ignore RIG_BACKEND_RPC; %ignore RIG_GNURADIO; %ignore RIG_BACKEND_GNURADIO; %ignore RIG_MICROTUNE; %ignore RIG_BACKEND_MICROTUNE; %ignore RIG_TAPR; %ignore RIG_BACKEND_TAPR; %ignore RIG_FLEXRADIO; %ignore RIG_BACKEND_FLEXRADIO; %ignore RIG_RFT; %ignore RIG_BACKEND_RFT; %ignore RIG_KIT; %ignore RIG_BACKEND_KIT; %ignore RIG_TUNER; %ignore RIG_BACKEND_TUNER; %ignore RIG_RS; %ignore RIG_BACKEND_RS; %ignore RIG_ADAT; %ignore RIG_BACKEND_ADAT; %ignore RIG_ICMARINE; %ignore RIG_BACKEND_ICMARINE; %ignore ROT_DUMMY; %ignore ROT_BACKEND_DUMMY; %ignore ROT_RPC; %ignore ROT_BACKEND_RPC; %ignore ROT_EASYCOMM; %ignore ROT_BACKEND_EASYCOMM; %ignore ROT_FODTRACK; %ignore ROT_BACKEND_FODTRACK; %ignore ROT_ROTOREZ; %ignore ROT_BACKEND_ROTOREZ; %ignore ROT_SARTEK; %ignore ROT_BACKEND_SARTEK; %ignore ROT_GS232A; %ignore ROT_BACKEND_GS232A; %ignore ROT_KIT; %ignore ROT_BACKEND_KIT; %ignore ROT_HEATHKIT; %ignore ROT_BACKEND_HEATHKIT; %ignore ROT_SPID; %ignore ROT_BACKEND_SPID; %ignore ROT_M2; %ignore ROT_BACKEND_M2; %ignore ROT_ARS; %ignore ROT_BACKEND_ARS; %ignore ROT_AMSAT; %ignore ROT_BACKEND_AMSAT; %ignore ROT_TS7400; %ignore ROT_BACKEND_TS7400; %ignore ROT_CELESTRON; %ignore ROT_BACKEND_CELESTRON; %ignore PRIfreq; %ignore SCNfreq; %ignore FREQFMT; %ignore rig_open; %ignore rig_set_freq; %ignore rig_get_freq; %ignore rig_set_mode; %ignore rig_get_mode; %ignore rig_set_vfo; %ignore rig_get_vfo; %ignore rig_set_ptt; %ignore rig_get_ptt; %ignore rig_get_dcd; %ignore rig_set_rptr_shift; %ignore rig_get_rptr_shift; %ignore rig_set_rptr_offs; %ignore rig_get_rptr_offs; %ignore rig_set_ctcss_tone; %ignore rig_get_ctcss_tone; %ignore rig_set_dcs_code; %ignore rig_get_dcs_code; %ignore rig_set_ctcss_sql; %ignore rig_get_ctcss_sql; %ignore rig_set_dcs_sql; %ignore rig_get_dcs_sql; %ignore rig_set_split_freq; %ignore rig_get_split_freq; %ignore rig_set_split_mode; %ignore rig_get_split_mode; %ignore rig_set_split; %ignore rig_get_split; %ignore rig_set_rit; %ignore rig_get_rit; %ignore rig_set_xit; %ignore rig_get_xit; %ignore rig_set_ts; %ignore rig_get_ts; %ignore rig_power2mW; %ignore rig_mW2power; %ignore rig_get_resolution; %ignore rig_set_level; %ignore rig_get_level; %ignore rig_set_parm; %ignore rig_get_parm; %ignore rig_set_conf; %ignore rig_get_conf; %ignore rig_set_powerstat; %ignore rig_get_powerstat; %ignore rig_reset; %ignore rig_set_ext_level; %ignore rig_get_ext_level; %ignore rig_set_ext_parm; %ignore rig_get_ext_parm; %ignore rig_ext_level_foreach; %ignore rig_ext_parm_foreach; %ignore rig_token_lookup; %ignore rig_close; %ignore rig_cleanup; %ignore rig_probe; %ignore rig_set_ant; %ignore rig_get_ant; %ignore rig_has_get_level; %ignore rig_has_set_level; %ignore rig_has_get_parm; %ignore rig_has_set_parm; %ignore rig_has_get_func; %ignore rig_has_set_func; %ignore rig_set_func; %ignore rig_get_func; %ignore rig_send_dtmf; %ignore rig_recv_dtmf; %ignore rig_send_morse; %ignore rig_set_bank; %ignore rig_set_mem; %ignore rig_get_mem; %ignore rig_vfo_op; %ignore rig_has_vfo_op; %ignore rig_scan; %ignore rig_has_scan; %ignore rig_set_channel; %ignore rig_get_channel; %ignore rig_set_trn; %ignore rig_get_trn; %ignore rig_set_freq_callback; %ignore rig_set_mode_callback; %ignore rig_set_vfo_callback; %ignore rig_set_ptt_callback; %ignore rig_set_dcd_callback; %ignore rig_set_pltune_callback; %ignore rig_get_info; %ignore rig_passband_normal; %ignore rig_passband_narrow; %ignore rig_passband_wide; %ignore rig_get_vfo_info; %ignore rot_open; %ignore rot_close; %ignore rot_cleanup; %ignore rot_set_conf; %ignore rot_get_conf; %ignore rot_set_position; %ignore rot_get_position; %ignore rot_stop; %ignore rot_park; %ignore rot_reset; %ignore rot_move; %ignore rot_get_info; %ignore hamlib_copyright2; %ignore hamlib_version2; %ignore macro_name; %ignore fd_sync_write; %ignore fd_sync_read; %ignore fd_sync_error_write; %ignore fd_sync_error_read; %ignore FIFO_RIG; #ifdef SWIGLUA %ignore Rig::set_level(setting_t,int,vfo_t); %ignore Rig::set_ext_level(setting_t,value_t,vfo_t); %ignore Rig::set_level(char const *,int,vfo_t); %ignore Rig::set_parm(setting_t,int); %ignore Rig::set_parm(char const *,int); #endif hamlib-4.6.5/lib/0000775000175000017500000000000015056640474007306 5hamlib-4.6.5/lib/asyncpipe.h0000664000175000017500000000144115056640442011365 #ifndef _ASYNC_PIPE_H #define _ASYNC_PIPE_H 1 #include "hamlib/config.h" #if defined(WIN32) && defined(HAVE_WINDOWS_H) #include #include #define PIPE_BUFFER_SIZE_DEFAULT 65536 struct hamlib_async_pipe { HANDLE write; HANDLE read; OVERLAPPED write_overlapped; OVERLAPPED read_overlapped; }; int async_pipe_create(hamlib_async_pipe_t **pipe_out, unsigned long pipe_buffer_size, unsigned long pipe_connect_timeout_millis); void async_pipe_close(hamlib_async_pipe_t *pipe); ssize_t async_pipe_read(hamlib_async_pipe_t *pipe, void *buf, size_t count, int timeout); int async_pipe_wait_for_data(hamlib_async_pipe_t *pipe, int timeout); ssize_t async_pipe_write(hamlib_async_pipe_t *pipe, const unsigned char *buf, size_t count, int timeout); #endif #endif hamlib-4.6.5/lib/termios.c0000664000175000017500000026550215056640442011061 #include #include #include "misc.h" #if defined(WIN32) && !defined(HAVE_TERMIOS_H) #undef DEBUG //#undef TRACE #ifdef DEBUG #define DEBUG_VERBOSE #define DEBUG_ERRORS static char message[256]; static char datestr[64]; #define report(a) fprintf(stderr, "%s: %s", date_strget(datestr, sizeof(datestr), 0), a) #define report_warning(a) fprintf(stderr, "%s: %s", date_strget(datestr, sizeof(datestr), 0), a) #define report_error(a) fprintf(stderr, "%s: %s", date_strget(datestr, sizeof(datestr), 0), a) #else #define report(a) do {} while (0) #define report_warning(a) do {} while (0) #define report_error(a) do {} while (0) #endif /* DEBUG */ /*------------------------------------------------------------------------- | rxtx is a native interface to serial ports in java. | Copyright 1997-2002 by Trent Jarvi taj@www.linux.org.uk. | Copyright 1997-2006 by Trent Jarvi taj@www.linux.org.uk. | | 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.1 of the License, or (at your option) any later version. | | If you compile this program with cygwin32 tools this package falls | under the GPL. See COPYING.CYGNUS for details. | | 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 | Lesser General Public License for more details. | | 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | | This file was taken from rxtx-2.1-7 and adapted for Hamlib. --------------------------------------------------------------------------*/ #include #include #include #include #include #include "win32termios.h" /* * odd malloc.h error with lcc compiler * winsock has FIONREAD with lcc */ #ifdef __LCC__ # include #else # include #endif /* __LCC__ */ #define SIGIO 0 int my_errno; #if 0 extern int errno; #endif struct termios_list *first_tl = NULL; /*---------------------------------------------------------- serial_test accept: filename to test perform: return: 1 on success 0 on failure exceptions: win32api: CreateFile CloseHandle comments: if the file opens it should be ok. ----------------------------------------------------------*/ int win32_serial_test(char *filename) { unsigned long *hcomm; int ret; hcomm = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hcomm == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_ACCESS_DENIED) { ret = 1; } else { ret = 0; } } else { ret = 1; } CloseHandle(hcomm); return (ret); } static void termios_setflags(int fd, int termios_flags[]) { struct termios_list *index = win32_serial_find_port(fd); int i, result; int windows_flags[11] = { 0, EV_RXCHAR, EV_TXEMPTY, EV_CTS, EV_DSR, EV_RING | 0x2000, EV_RLSD, EV_ERR, EV_ERR, EV_ERR, EV_BREAK }; if (!index) { LEAVE("termios_setflags"); return; } index->event_flag = 0; for (i = 0; i < 11; i++) if (termios_flags[i]) { index->event_flag |= windows_flags[i]; } result = SetCommMask(index->hComm, index->event_flag); /* This is rank. 0x2000 was used to detect the trailing edge of ring. The leading edge is detedted by EV_RING. The trailing edge is reliable. The leading edge is not. Softie no longer allows the trailing edge to be detected in NTsp2 and beyond. So... Try the reliable option above and if it fails, use the less reliable means. The screams for a giveio solution that bypasses the kernel. */ if (index->event_flag & 0x2000 && result == 0) { index->event_flag &= ~0x2000; SetCommMask(index->hComm, index->event_flag); } } #if 0 /*---------------------------------------------------------- get_fd() accept: filename perform: find the file descriptor associated with the filename return: fd exceptions: win32api: None comments: This is not currently called by anything ----------------------------------------------------------*/ int get_fd(char *filename) { struct termios_list *index = first_tl; ENTER("get_fd"); if (!index) { return -1; } while (strcmp(index->filename, filename)) { index = index->next; if (!index->next) { return (-1); } } LEAVE("get_fd"); return (index->fd); } /*---------------------------------------------------------- get_filename() accept: file descriptor perform: find the filename associated with the file descriptor return: the filename associated with the fd exceptions: None win32api: None comments: This is not currently called by anything ----------------------------------------------------------*/ char *get_filename(int fd) { struct termios_list *index = first_tl; ENTER("get_filename"); if (!index) { return ("bad"); } while (index->fd != fd) { if (index->next == NULL) { return ("bad"); } index = index->next; } LEAVE("get_filename"); return (index->filename); } /*---------------------------------------------------------- dump_termios_list() accept: string to print out. perform: return: exceptions: win32api: None comments: used only for debugging eg serial_close() ----------------------------------------------------------*/ void dump_termios_list(char *foo) { #ifdef DEBUG struct termios_list *index = first_tl; printf("============== %s start ===============\n", foo); if (index) { printf("%i filename | %s\n", index->fd, index->filename); } /* if ( index->next ) { printf( "%i filename | %s\n", index->fd, index->filename ); } */ printf("============== %s end ===============\n", foo); #endif } #endif /*---------------------------------------------------------- set_errno() accept: perform: return: exceptions: win32api: None comments: FIXME ----------------------------------------------------------*/ static void set_errno(int error) { my_errno = error; } #if 0 /*---------------------------------------------------------- usleep() accept: perform: return: exceptions: win32api: Sleep() comments: ----------------------------------------------------------*/ static void usleep(unsigned long usec) { Sleep(usec / 1000); } #endif /*---------------------------------------------------------- CBR_toB() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int CBR_to_B(int Baud) { ENTER("CBR_to_B"); switch (Baud) { case 0: return (B0); case 50: return (B50); case 75: return (B75); case CBR_110: return (B110); case 134: return (B134); case 150: return (B150); case 200: return (B200); case CBR_300: return (B300); case CBR_600: return (B600); case CBR_1200: return (B1200); case 1800: return (B1800); case CBR_2400: return (B2400); case CBR_4800: return (B4800); case CBR_9600: return (B9600); case CBR_14400: return (B14400); case CBR_19200: return (B19200); case CBR_28800: return (B28800); case CBR_38400: return (B38400); case CBR_57600: return (B57600); case CBR_115200: return (B115200); case CBR_128000: return (B128000); case CBR_230400: return (B230400); case CBR_256000: return (B256000); case CBR_460800: return (B460800); case CBR_500000: return (B500000); case CBR_576000: return (B576000); case CBR_921600: return (B921600); case CBR_1000000: return (B1000000); case CBR_1152000: return (B1152000); case CBR_1500000: return (B1500000); case CBR_2000000: return (B2000000); case CBR_2500000: return (B2500000); case CBR_3000000: return (B3000000); case CBR_3500000: return (B3500000); case CBR_4000000: return (B4000000); default: /* assume custom baudrate */ return (Baud); } } /*---------------------------------------------------------- B_to_CBR() accept: perform: return: exceptions: win32api: comments: None ----------------------------------------------------------*/ static int B_to_CBR(int Baud) { int ret; ENTER("B_to_CBR"); switch (Baud) { case 0: ret = 0; break; case B50: ret = 50; break; case B75: ret = 75; break; case B110: ret = CBR_110; break; case B134: ret = 134; break; case B150: ret = 150; break; case B200: ret = 200; break; case B300: ret = CBR_300; break; case B600: ret = CBR_600; break; case B1200: ret = CBR_1200; break; case B1800: ret = 1800; break; case B2400: ret = CBR_2400; break; case B4800: ret = CBR_4800; break; case B9600: ret = CBR_9600; break; case B14400: ret = CBR_14400; break; case B19200: ret = CBR_19200; break; case B28800: ret = CBR_28800; break; case B38400: ret = CBR_38400; break; case B57600: ret = CBR_57600; break; case B115200: ret = CBR_115200; break; case B128000: ret = CBR_128000; break; case B230400: ret = CBR_230400; break; case B256000: ret = CBR_256000; break; case B460800: ret = CBR_460800; break; case B500000: ret = CBR_500000; break; case B576000: ret = CBR_576000; break; case B921600: ret = CBR_921600; break; case B1000000: ret = CBR_1000000; break; case B1152000: ret = CBR_1152000; break; case B1500000: ret = CBR_1500000; break; case B2000000: ret = CBR_2000000; break; case B2500000: ret = CBR_2500000; break; case B3000000: ret = CBR_3000000; break; case B3500000: ret = CBR_3500000; break; case B4000000: ret = CBR_4000000; break; default: /* assume custom baudrate */ return Baud; } LEAVE("B_to_CBR"); return ret; } /*---------------------------------------------------------- bytesize_to_termios() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int bytesize_to_termios(int ByteSize) { ENTER("bytesize_to_termios"); switch (ByteSize) { case 5: return (CS5); case 6: return (CS6); case 7: return (CS7); case 8: default: return (CS8); } } /*---------------------------------------------------------- termios_to_bytesize() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int termios_to_bytesize(int cflag) { ENTER("termios_to_bytesize"); switch (cflag & CSIZE) { case CS5: return (5); case CS6: return (6); case CS7: return (7); case CS8: default: return (8); } } #if 0 /*---------------------------------------------------------- get_dos_port() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static const char *get_dos_port(char const *name) { ENTER("get_dos_port"); if (!strcmp(name, "/dev/cua0")) { return ("COM1"); } if (!strcmp(name, "/dev/cua1")) { return ("COM2"); } if (!strcmp(name, "/dev/cua2")) { return ("COM3"); } if (!strcmp(name, "/dev/cua3")) { return ("COM4"); } LEAVE("get_dos_port"); return ((const char *) name); } #endif /*---------------------------------------------------------- ClearErrors() accept: perform: keep track of errors for the eventLoop() (SerialImp.c) return: the return value of ClearCommError() exceptions: win32api: ClearCommError() comments: ----------------------------------------------------------*/ static int ClearErrors(struct termios_list *index, COMSTAT *Stat) { unsigned long ErrCode; int ret; ret = ClearCommError(index->hComm, &ErrCode, Stat); if (ret == 0) { YACK(); return (ret); } #ifdef DEBUG_ERRORS if (ErrCode) { printf("%i frame %i %i overrun %li %i parity %u %i brk %i %i\n", (int) ErrCode, (int) ErrCode & CE_FRAME, index->sis->frame, (int)(ErrCode & CE_OVERRUN) | (ErrCode & CE_RXOVER), index->sis->overrun, (int) ErrCode & CE_RXPARITY, index->sis->parity, (int) ErrCode & CE_BREAK, index->sis->brk ); } #endif /* DEBUG_ERRORS */ if (ErrCode & CE_FRAME) { index->sis->frame++; ErrCode &= ~CE_FRAME; } #ifdef LIFE_IS_GOOD FIXME OVERRUN is spewing if (ErrCode & CE_OVERRUN) { index->sis->overrun++; ErrCode &= ~CE_OVERRUN; } /* should this be here? */ else if (ErrCode & CE_RXOVER) { index->sis->overrun++; ErrCode &= ~CE_OVERRUN; } #endif /* LIFE_IS_GOOD */ if (ErrCode & CE_RXPARITY) { index->sis->parity++; ErrCode &= ~CE_RXPARITY; } if (ErrCode & CE_BREAK) { index->sis->brk++; ErrCode &= ~CE_BREAK; } return (ret); } #if 0 /*---------------------------------------------------------- FillDCB() accept: perform: return: exceptions: win32api: GetCommState(), SetCommState(), SetCommTimeouts() comments: ----------------------------------------------------------*/ static BOOL FillDCB(DCB *dcb, unsigned long *hCommPort, COMMTIMEOUTS Timeout) { ENTER("FillDCB"); dcb->DCBlength = sizeof(dcb); if (!GetCommState(hCommPort, dcb)) { report("GetCommState\n"); return (-1); } dcb->BaudRate = CBR_9600 ; dcb->ByteSize = 8; dcb->Parity = NOPARITY; dcb->StopBits = ONESTOPBIT; dcb->fDtrControl = DTR_CONTROL_ENABLE; dcb->fRtsControl = RTS_CONTROL_ENABLE; dcb->fOutxCtsFlow = FALSE; dcb->fOutxDsrFlow = FALSE; dcb->fDsrSensitivity = FALSE; dcb->fOutX = FALSE; dcb->fInX = FALSE; dcb->fTXContinueOnXoff = FALSE; dcb->XonChar = 0x11; dcb->XoffChar = 0x13; dcb->XonLim = 0; dcb->XoffLim = 0; dcb->fParity = TRUE; if (EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | (EV_RLSD & EV_RXFLAG)) { dcb->EvtChar = '\n'; } else { dcb->EvtChar = '\0'; } if (!SetCommState(hCommPort, dcb)) { report("SetCommState\n"); YACK(); return (-1); } if (!SetCommTimeouts(hCommPort, &Timeout)) { YACK(); report("SetCommTimeouts\n"); return (-1); } LEAVE("FillDCB"); return (TRUE) ; } #endif /*---------------------------------------------------------- serial_close() accept: perform: return: exceptions: win32api: SetCommMask(), CloseHandle() comments: ----------------------------------------------------------*/ int win32_serial_close(int fd) { struct termios_list *index; /* char message[80]; */ ENTER("serial_close"); if (!first_tl || !first_tl->hComm) { report("gotit!"); return (0); } index = win32_serial_find_port(fd); if (!index) { LEAVE("serial_close"); return -1; } /* WaitForSingleObject( index->wol.hEvent, INFINITE ); */ /* if ( index->hComm != INVALID_HANDLE_VALUE ) { if ( !SetCommMask( index->hComm, EV_RXCHAR ) ) { YACK(); report( "eventLoop hung\n" ); } CloseHandle( index->hComm ); } else { SNPRINTF( message, sizeof(message), sizeof(message), "serial_ close(): Invalid Port Reference for %s\n", index->filename ); report( message ); } */ if (index->next && index->prev) { index->next->prev = index->prev; index->prev->next = index->next; } else if (index->prev) { index->prev->next = NULL; } else if (index->next) { index->next->prev = NULL; first_tl = index->next; } else { first_tl = NULL; } if (index->rol.hEvent) { CloseHandle(index->rol.hEvent); } if (index->wol.hEvent) { CloseHandle(index->wol.hEvent); } if (index->sol.hEvent) { CloseHandle(index->sol.hEvent); } if (index->hComm) { CloseHandle(index->hComm); } if (index->ttyset) { free(index->ttyset); } if (index->astruct) { free(index->astruct); } if (index->sstruct) { free(index->sstruct); } if (index->sis) { free(index->sis); } /* had problems with strdup if ( index->filename ) free( index->filename ); */ free(index); LEAVE("serial_close"); return 0; } /*---------------------------------------------------------- cfmakeraw() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ void cfmakeraw(struct termios *s_termios) { ENTER("cfmakeraw"); s_termios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); s_termios->c_oflag &= ~OPOST; s_termios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); s_termios->c_cflag &= ~(CSIZE | PARENB); s_termios->c_cflag |= CS8; LEAVE("cfmakeraw"); } /*---------------------------------------------------------- init_serial_struct() accept: perform: return: exceptions: win32api: comments: ----------------------------------------------------------*/ static BOOL init_serial_struct(struct serial_struct *sstruct) { ENTER("init_serial_struct"); /* FIXME This needs to use inb() to read the actual baud_base and divisor from the UART registers. Question is how far do we take this? */ sstruct->custom_divisor = 0; sstruct->baud_base = 115200; /* not currently used check values before using */ /* unsigned short */ sstruct->close_delay = 0; sstruct->closing_wait = 0; sstruct->iomem_reg_shift = 0; /* int */ sstruct->type = 0; sstruct->line = 0; sstruct->irq = 0; sstruct->flags = 0; sstruct->xmit_fifo_size = 0; sstruct->hub6 = 0; /* unsigned int */ sstruct->port = 0; sstruct->port_high = 0; /* char */ sstruct->io_type = 0; /* unsigned char * */ sstruct->iomem_base = NULL; LEAVE("init_serial_struct"); return TRUE; } /*---------------------------------------------------------- init_termios() accept: perform: return: exceptions: win32api: comments: ----------------------------------------------------------*/ static BOOL init_termios(struct termios *ttyset) { ENTER("init_termios"); if (!ttyset) { return FALSE; } memset(ttyset, 0, sizeof(struct termios)); cfsetospeed(ttyset, B9600); cfmakeraw(ttyset); ttyset->c_cc[VINTR] = 0x03; /* 0: C-c */ ttyset->c_cc[VQUIT] = 0x1c; /* 1: C-\ */ ttyset->c_cc[VERASE] = 0x7f; /* 2: */ ttyset->c_cc[VKILL] = 0x15; /* 3: C-u */ ttyset->c_cc[VEOF] = 0x04; /* 4: C-d */ ttyset->c_cc[VTIME] = 0; /* 5: read timeout */ ttyset->c_cc[VMIN] = 1; /* 6: read returns after this many bytes */ ttyset->c_cc[VSUSP] = 0x1a; /* 10: C-z */ ttyset->c_cc[VEOL] = '\r'; /* 11: */ ttyset->c_cc[VREPRINT] = 0x12; /* 12: C-r */ /* ttyset->c_cc[VDISCARD] = 0x; 13: IEXTEN only */ ttyset->c_cc[VWERASE] = 0x17; /* 14: C-w */ ttyset->c_cc[VLNEXT] = 0x16; /* 15: C-w */ ttyset->c_cc[VEOL2] = '\n'; /* 16: */ LEAVE("init_termios"); return TRUE; /* default VTIME = 0, VMIN = 1: read blocks forever until one byte */ } /*---------------------------------------------------------- port_opened() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int port_opened(const char *filename) { struct termios_list *index = first_tl; ENTER("port_opened"); if (! index) { return 0; } if (!strcmp(index->filename, filename)) { return index->fd; } while (index->next) { index = index->next; if (!strcmp(index->filename, filename)) { return index->fd; } } LEAVE("port_opened"); return 0; } /*---------------------------------------------------------- open_port() accept: perform: return: exceptions: win32api: CreateFile(), SetupComm(), CreateEvent() comments: FILE_FLAG_OVERLAPPED allows one to break out the select() so RXTXPort.close() does not hang. The setDTR() and setDSR() are the functions that noticed to be blocked in the java close. Basically ioctl(TIOCM[GS]ET) are where it hangs. FILE_FLAG_OVERLAPPED also means we need to create valid OVERLAPPED structure in Serial_select. ----------------------------------------------------------*/ static int open_port(struct termios_list *port) { ENTER("open_port"); port->hComm = CreateFile(port->filename, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); if (port->hComm == INVALID_HANDLE_VALUE) { YACK(); set_errno(EINVAL); /* printf( "serial_open failed %s\n", port->filename ); */ return -1; } if (!SetupComm(port->hComm, 2048, 1024)) { YACK(); return -1; } memset(&port->rol, 0, sizeof(OVERLAPPED)); memset(&port->wol, 0, sizeof(OVERLAPPED)); memset(&port->sol, 0, sizeof(OVERLAPPED)); port->rol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!port->rol.hEvent) { YACK(); report("Could not create read overlapped\n"); goto fail; } port->sol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!port->sol.hEvent) { YACK(); report("Could not create select overlapped\n"); goto fail; } port->wol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!port->wol.hEvent) { YACK(); report("Could not create write overlapped\n"); goto fail; } LEAVE("open_port"); return (0); fail: return (-1); } /*---------------------------------------------------------- termios_list() accept: fd which is a fake # for the port assigned when the port is opened perform: walk through a double linked list to see if the given fd is in any of the termios_list members. return: the termios_list if it is found. NULL if no matches are found. exceptions: None win32api: None comments: ----------------------------------------------------------*/ struct termios_list *win32_serial_find_port(int fd) { char message[80]; struct termios_list *index = first_tl; ENTER("find_port"); if (fd <= 0 || !first_tl) { goto fail; } while (index->fd) { if (index->fd == fd) { LEAVE("find_port"); return index; } if (!index->next) { break; } index = index->next; } fail: SNPRINTF(message, sizeof(message), "No info known about the port. %i\n", fd); report(message); set_errno(EBADF); LEAVE("find_port"); return NULL; } /*---------------------------------------------------------- get_free_fd() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int get_free_fd() { int next, last; struct termios_list *index = first_tl; ENTER("get_free_fd"); if (!index) { return (1); } if (!index->fd) { report("!index->fd\n"); return (1); } if (index->fd > 1) { first_tl = index; return (1); } last = index->fd; while (index->next) { next = index->next->fd; if (next != last + 1) { return (last + 1); } index = index->next; last = next; } LEAVE("get_free_fd"); return (index->fd + 1); } /*---------------------------------------------------------- add_port() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static struct termios_list *add_port(const char *filename) { struct termios_list *index = first_tl; struct termios_list *port; ENTER("add_port"); port = calloc(1, sizeof(struct termios_list)); if (!port) { goto fail; } memset(port, 0, sizeof(struct termios_list)); port->ttyset = calloc(1, sizeof(struct termios)); if (! port->ttyset) { goto fail; } memset(port->ttyset, 0, sizeof(struct termios)); port->sstruct = calloc(1, sizeof(struct serial_struct)); if (! port->sstruct) { goto fail; } memset(port->sstruct, 0, sizeof(struct serial_struct)); port->sis = calloc(1, sizeof(struct serial_icounter_struct)); if (! port->sis) { goto fail; } memset(port->sis, 0, sizeof(struct serial_icounter_struct)); /* FIXME the async_struct is being defined by mingw32 headers? port->astruct = calloc(1, sizeof( struct async_struct ) ); if( ! port->astruct ) goto fail; memset( port->astruct, 0, sizeof( struct async_struct ) ); */ port->MSR = 0; strncpy(port->filename, filename, sizeof(port->filename) - 1); port->fd = get_free_fd(); if (!first_tl) { port->prev = NULL; first_tl = port; } else { while (index->next) { index = index->next; } if (port == first_tl) { port->prev = NULL; port->next = first_tl; first_tl->prev = port; first_tl = port; } else { port->prev = index; index->next = port; } } port->next = NULL; LEAVE("add_port"); return port; fail: report("add_port: Out Of Memory\n"); if (port->ttyset) { free(port->ttyset); } if (port->astruct) { free(port->astruct); } if (port->sstruct) { free(port->sstruct); } if (port->sis) { free(port->sis); } if (port) { free(port); } return NULL; } /*---------------------------------------------------------- check_port_capabilities() accept: perform: return: exceptions: win32api: GetCommProperties(), GetCommState() comments: ----------------------------------------------------------*/ static int check_port_capabilities(struct termios_list *index) { COMMPROP cp; DCB dcb; char message[80]; ENTER("check_port_capabilities"); /* check for capabilities */ GetCommProperties(index->hComm, &cp); if (!(cp.dwProvCapabilities & PCF_DTRDSR)) { SNPRINTF(message, sizeof(message), "%s: no DTR & DSR support\n", __func__); report(message); } if (!(cp.dwProvCapabilities & PCF_RLSD)) { SNPRINTF(message, sizeof(message), "%s: no carrier detect (RLSD) support\n", __func__); report(message); } if (!(cp.dwProvCapabilities & PCF_RTSCTS)) { SNPRINTF(message, sizeof(message), "%s: no RTS & CTS support\n", __func__); report(message); } if (!(cp.dwProvCapabilities & PCF_TOTALTIMEOUTS)) { SNPRINTF(message, sizeof(message), "%s: no timeout support\n", __func__); report(message); } if (!GetCommState(index->hComm, &dcb)) { YACK(); report("GetCommState\n"); return -1; } LEAVE("check_port_capabilities"); return 0; } /*---------------------------------------------------------- serial_open() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int win32_serial_open(const char *filename, int flags, ...) { struct termios_list *index; char message[756]; char fullfilename[256]; ENTER("serial_open"); fullfilename[sizeof(fullfilename) - 1] = '\0'; /* according to http://support.microsoft.com/kb/115831 * this is necessary for COM ports larger than COM9 */ if (memcmp(filename, "\\\\.\\", 4) != 0) { SNPRINTF(fullfilename, sizeof(fullfilename) - 1, "\\\\.\\%s", filename); } else { strncpy(fullfilename, filename, sizeof(fullfilename) - 1); } if (port_opened(fullfilename)) { report("Port is already opened\n"); return (-1); } index = add_port(fullfilename); if (!index) { report("serial_open !index\n"); return (-1); } index->interrupt = 0; index->tx_happened = 0; if (open_port(index)) { SNPRINTF(message, sizeof(message), "serial_open(): Invalid Port Reference for %s\n", fullfilename); report(message); win32_serial_close(index->fd); return -1; } if (check_port_capabilities(index)) { report("check_port_capabilities!"); win32_serial_close(index->fd); return -1; } init_termios(index->ttyset); init_serial_struct(index->sstruct); /* set default condition */ tcsetattr(index->fd, 0, index->ttyset); /* if opened with non-blocking, then operating non-blocking */ if (flags & O_NONBLOCK) { index->open_flags = O_NONBLOCK; } else { index->open_flags = 0; } if (!first_tl->hComm) { SNPRINTF(message, sizeof(message), "open(): Invalid Port Reference for %s\n", index->filename); report(message); } if (first_tl->hComm == INVALID_HANDLE_VALUE) { report("serial_open: test\n"); } LEAVE("serial_open"); return (index->fd); } /*---------------------------------------------------------- serial_write() accept: perform: return: exceptions: win32api: WriteFile(), GetLastError(), WaitForSingleObject(), GetOverlappedResult(), FlushFileBuffers(), Sleep() comments: ----------------------------------------------------------*/ int win32_serial_write(int fd, const char *Str, int length) { unsigned long nBytes; struct termios_list *index; /* COMSTAT Stat; */ int old_flag; ENTER("serial_write"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("serial_write"); return -1; } old_flag = index->event_flag; /* index->event_flag &= ~EV_TXEMPTY; SetCommMask( index->hComm, index->event_flag ); index->tx_happened = 1; */ index->wol.Offset = index->wol.OffsetHigh = 0; ResetEvent(index->wol.hEvent); if (!WriteFile(index->hComm, Str, length, &nBytes, &index->wol)) { WaitForSingleObject(index->wol.hEvent, 100); if (GetLastError() != ERROR_IO_PENDING) { /* ClearErrors( index, &Stat ); */ report("serial_write error\n"); /* report("Condition 1 Detected in write()\n"); */ YACK(); errno = EIO; nBytes = -1; goto end; } /* This is breaking on Win2K, WinXP for some reason */ else while (!GetOverlappedResult(index->hComm, &index->wol, &nBytes, TRUE)) { if (GetLastError() != ERROR_IO_INCOMPLETE) { /* report("Condition 2 Detected in write()\n"); */ YACK(); errno = EIO; nBytes = -1; goto end; /* ClearErrors( index, &Stat ); */ } } } else { /* Write finished synchronously. That is ok! * I have seen this with USB to Serial * devices like TI's. */ } end: /* FlushFileBuffers( index->hComm ); */ index->event_flag |= EV_TXEMPTY; /* ClearErrors( index, &Stat ); */ SetCommMask(index->hComm, index->event_flag); /* ClearErrors( index, &Stat ); */ index->event_flag = old_flag; index->tx_happened = 1; LEAVE("serial_write"); return nBytes; } /*---------------------------------------------------------- serial_read() accept: perform: return: exceptions: win32api: ReadFile(), GetLastError(), WaitForSingleObject() GetOverLappedResult() comments: If setting errno make sure not to use EWOULDBLOCK In that case use EAGAIN. See SerialImp.c:testRead() ----------------------------------------------------------*/ int win32_serial_read(int fd, void *vb, int size) { long start, now; unsigned long nBytes = 0, total = 0; /* unsigned long waiting = 0; */ int err; struct termios_list *index; // char message[80]; COMSTAT stat; clock_t c; unsigned char *dest = vb; start = GetTickCount(); ENTER("serial_read"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("serial_read"); return -1; } /* FIXME: CREAD: without this, data cannot be read FIXME: PARMRK: mark framing & parity errors FIXME: IGNCR: ignore \r FIXME: ICRNL: convert \r to \n FIXME: INLCR: convert \n to \r */ if (index->open_flags & O_NONBLOCK) { /* pull mucho-cpu here? */ do { #ifdef DEBUG_VERBOSE report("vmin=0\n"); #endif /* DEBUG_VERBOSE */ ClearErrors(index, &stat); if (stat.cbInQue < index->ttyset->c_cc[VMIN]) { /* hl_usleep(50); */ hl_usleep(100); /* don't hog the CPU while waiting */ /* we should use -1 instead of 0 for disabled timeout */ now = GetTickCount(); if (index->ttyset->c_cc[VTIME] && now - start >= (index->ttyset->c_cc[VTIME] * 100)) { /* SNPRINTF( message, sizeof(message), "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total); report( message ); */ return total; /* read timeout */ } } } while (size > 1 && stat.cbInQue < index->ttyset->c_cc[VMIN]); } else { /* VTIME is in units of 0.1 seconds */ #ifdef DEBUG_VERBOSE report("vmin!=0\n"); #endif /* DEBUG_VERBOSE */ /* vmin = index->ttyset->c_cc[VMIN]; */ c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10; do { ClearErrors(index, &stat); hl_usleep(100); } while (stat.cbInQue < index->ttyset->c_cc[VMIN] && c > clock()); } total = 0; while (size > 0) { nBytes = 0; /* ClearErrors( index, &stat); */ index->rol.Offset = index->rol.OffsetHigh = 0; ResetEvent(index->rol.hEvent); err = ReadFile(index->hComm, dest + total, size, &nBytes, &index->rol); #ifdef DEBUG_VERBOSE /* warning Roy Rogers! */ SNPRINTF(message, sizeof(message), " ========== ReadFile = %i 0x%x\n", (int) nBytes, *((char *) dest + total)); report(message); #endif /* DEBUG_VERBOSE */ if (!err) { switch (GetLastError()) { case ERROR_BROKEN_PIPE: report("ERROR_BROKEN_PIPE\n "); nBytes = 0; break; case ERROR_MORE_DATA: /* hl_usleep(1000); */ report("ERROR_MORE_DATA\n"); break; case ERROR_IO_PENDING: while (! GetOverlappedResult( index->hComm, &index->rol, &nBytes, TRUE)) { if (GetLastError() != ERROR_IO_INCOMPLETE) { ClearErrors( index, &stat); return (total); } } size -= nBytes; total += nBytes; return (total); #if 0 if (size > 0) { now = GetTickCount(); SNPRINTF(message, sizeof(message), "size > 0: spent=%ld have=%d\n", now - start, index->ttyset->c_cc[VTIME] * 100); report(message); /* we should use -1 for disabled timouts */ if (index->ttyset->c_cc[VTIME] && now - start >= (index->ttyset->c_cc[VTIME] * 100)) { report("TO "); /* read timeout */ return total; } } SNPRINTF(message, sizeof(message), "end nBytes=%lu] ", nBytes); report(message); /* hl_usleep(1000); */ report("ERROR_IO_PENDING\n"); break; #endif default: /* hl_usleep(1000); */ YACK(); return -1; } } else { size -= nBytes; total += nBytes; /* hl_usleep(1000); */ ClearErrors(index, &stat); return (total); } } LEAVE("serial_read"); return total; } #ifdef asdf int win32_serial_read(int fd, void *vb, int size) { long start, now; unsigned long nBytes = 0, total = 0, error; /* unsigned long waiting = 0; */ int err, vmin; struct termios_list *index; char message[80]; COMSTAT Stat; clock_t c; unsigned char *dest = vb; start = GetTickCount(); ENTER("serial_read"); if (fd <= 0) { printf("1\n"); return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("serial_read 7"); errno = EIO; printf("2\n"); return -1; } /* FIXME: CREAD: without this, data cannot be read FIXME: PARMRK: mark framing & parity errors FIXME: IGNCR: ignore \r FIXME: ICRNL: convert \r to \n FIXME: INLCR: convert \n to \r */ ClearErrors(index, &Stat); if (index->open_flags & O_NONBLOCK) { vmin = 0; /* pull mucho-cpu here? */ do { #ifdef DEBUG_VERBOSE report("vmin=0\n"); #endif /* DEBUG_VERBOSE */ ClearErrors(index, &Stat); /* hl_usleep(1000); hl_usleep(50); */ /* we should use -1 instead of 0 for disabled timeout */ now = GetTickCount(); if (index->ttyset->c_cc[VTIME] && now - start >= (index->ttyset->c_cc[VTIME] * 100)) { /* SNPRINTF( message, sizeof(message), "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total); report( message ); */ errno = EAGAIN; printf("3\n"); return -1; /* read timeout */ } } while (Stat.cbInQue < size && size > 1); } else { /* VTIME is in units of 0.1 seconds */ #ifdef DEBUG_VERBOSE report("vmin!=0\n"); #endif /* DEBUG_VERBOSE */ vmin = index->ttyset->c_cc[VMIN]; c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10; do { error = ClearErrors(index, &Stat); hl_usleep(1000); } while (c > clock()); } total = 0; while (size > 0) { nBytes = 0; /* ClearErrors( index, &Stat); */ index->rol.Offset = index->rol.OffsetHigh = 0; ResetEvent(index->rol.hEvent); err = ReadFile(index->hComm, dest + total, size, &nBytes, &index->rol); #ifdef DEBUG_VERBOSE /* warning Roy Rogers! */ SNPRINTF(message, sizeof(message), " ========== ReadFile = %i %s\n", (int) nBytes, (char *) dest + total); report(message); #endif /* DEBUG_VERBOSE */ if (!err) { switch (GetLastError()) { case ERROR_BROKEN_PIPE: report("ERROR_BROKEN_PIPE\n "); nBytes = 0; break; case ERROR_MORE_DATA: /* hl_usleep(1000); */ report("ERROR_MORE_DATA\n"); break; case ERROR_IO_PENDING: while (! GetOverlappedResult( index->hComm, &index->rol, &nBytes, TRUE)) { if (GetLastError() != ERROR_IO_INCOMPLETE) { ClearErrors( index, &Stat); printf("4\n"); return (total); } } size -= nBytes; total += nBytes; return (total); #if 0 if (size > 0) { now = GetTickCount(); SNPRINTF(message, sizeof(message), "size > 0: spent=%ld have=%d\n", now - start, index->ttyset->c_cc[VTIME] * 100); report(message); /* we should use -1 for disabled timouts */ if (index->ttyset->c_cc[VTIME] && now - start >= (index->ttyset->c_cc[VTIME] * 100)) { report("TO "); /* read timeout */ printf("5\n"); return total; } } SNPRINTF(message, sizeof(message), "end nBytes=%ld] ", nBytes); report(message); /* hl_usleep(1000); */ report("ERROR_IO_PENDING\n"); break; #endif default: /* hl_usleep(1000); */ YACK(); errno = EIO; printf("6\n"); return -1; } } else { size -= nBytes; total += nBytes; /* hl_usleep(1000); */ ClearErrors(index, &Stat); printf("7\n"); return (total); } } LEAVE("serial_read"); ClearErrors(index, &Stat); return total; } #endif /* asdf */ /*---------------------------------------------------------- cfsetospeed() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int cfsetospeed(struct termios *s_termios, speed_t speed) { char message[80]; ENTER("cfsetospeed"); /* clear baudrate */ s_termios->c_cflag &= ~CBAUD; if (speed & ~CBAUD) { SNPRINTF(message, sizeof(message), "cfsetospeed: not speed: %#o\n", speed); report(message); /* continue assuming its a custom baudrate */ s_termios->c_cflag |= B38400; /* use 38400 during custom */ s_termios->c_cflag |= CBAUDEX; /* use CBAUDEX for custom */ } else if (speed) { s_termios->c_cflag |= speed; } else { /* PC blows up with speed 0 handled in Java */ s_termios->c_cflag |= B9600; } s_termios->c_ispeed = s_termios->c_ospeed = speed; LEAVE("cfsetospeed"); return 1; } /*---------------------------------------------------------- cfsetispeed() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int cfsetispeed(struct termios *s_termios, speed_t speed) { return cfsetospeed(s_termios, speed); } /*---------------------------------------------------------- cfsetspeed() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int cfsetspeed(struct termios *s_termios, speed_t speed) { return cfsetospeed(s_termios, speed); } /*---------------------------------------------------------- cfgetospeed() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ speed_t cfgetospeed(struct termios *s_termios) { ENTER("cfgetospeed"); return s_termios->c_ospeed; } /*---------------------------------------------------------- cfgetispeed() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ speed_t cfgetispeed(struct termios *s_termios) { ENTER("cfgetospeed"); return s_termios->c_ispeed; } /*---------------------------------------------------------- serial_struct_to_DCB() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int serial_struct_to_DCB(struct serial_struct *sstruct, DCB *dcb) { /* 5 Baud rate fix sstruct.baud_base sstruct.custom_divisor = ( sstruct.baud_base/cspeed ); */ return (0); } /*---------------------------------------------------------- termios_to_DCB() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static int termios_to_DCB(struct termios *s_termios, DCB *dcb) { ENTER("termios_to_DCB"); if (!(s_termios->c_cflag & CBAUDEX)) { s_termios->c_ispeed = s_termios->c_ospeed = s_termios->c_cflag & CBAUD; } dcb->BaudRate = B_to_CBR(s_termios->c_ispeed); dcb->ByteSize = termios_to_bytesize(s_termios->c_cflag); if (s_termios->c_cflag & PARENB) { if (s_termios->c_cflag & PARODD && s_termios->c_cflag & CMSPAR) { dcb->Parity = MARKPARITY; } else if (s_termios->c_cflag & PARODD) { dcb->Parity = ODDPARITY; } else if (s_termios->c_cflag & CMSPAR) { dcb->Parity = SPACEPARITY; } else { dcb->Parity = EVENPARITY; } } else { dcb->Parity = NOPARITY; } if (s_termios->c_cflag & CSTOPB) { dcb->StopBits = TWOSTOPBITS; } else { dcb->StopBits = ONESTOPBIT; } if (s_termios->c_cflag & HARDWARE_FLOW_CONTROL) { dcb->fRtsControl = RTS_CONTROL_HANDSHAKE; dcb->fOutxCtsFlow = TRUE; } else { dcb->fRtsControl = RTS_CONTROL_DISABLE; dcb->fOutxCtsFlow = FALSE; } LEAVE("termios_to_DCB"); return 0; } /*---------------------------------------------------------- DCB_to_serial_struct() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ int DCB_to_serial_struct(DCB *dcb, struct serial_struct *sstruct) { return (0); } /*---------------------------------------------------------- DCB_to_termios() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static void DCB_to_termios(DCB *dcb, struct termios *s_termios) { ENTER("DCB_to_termios"); s_termios->c_ispeed = CBR_to_B(dcb->BaudRate); s_termios->c_ospeed = s_termios->c_ispeed; s_termios->c_cflag |= s_termios->c_ispeed & CBAUD; LEAVE("DCB_to_termios"); } /*---------------------------------------------------------- show_DCB() accept: perform: return: exceptions: win32api: None comments: ----------------------------------------------------------*/ static void show_DCB(DCB myDCB) { #ifdef DEBUG_HOSED char message[80]; SNPRINTF(message, sizeof(message), "DCBlength: %ld\n", myDCB.DCBlength); report(message); SNPRINTF(message, sizeof(message), "BaudRate: %ld\n", myDCB.BaudRate); report(message); if (myDCB.fBinary) { report("fBinary\n"); } if (myDCB.fParity) { report("fParity: "); if (myDCB.fErrorChar) { SNPRINTF(message, sizeof(message), "fErrorChar: %#x\n", myDCB.ErrorChar); report(message); } else { report("fErrorChar == false\n"); } } if (myDCB.fOutxCtsFlow) { report("fOutxCtsFlow\n"); } if (myDCB.fOutxDsrFlow) { report("fOutxDsrFlow\n"); } if (myDCB.fDtrControl & DTR_CONTROL_HANDSHAKE) { report("DTR_CONTROL_HANDSHAKE\n"); } if (myDCB.fDtrControl & DTR_CONTROL_ENABLE) { report("DTR_CONTROL_ENABLE\n"); } if (myDCB.fDtrControl & DTR_CONTROL_DISABLE) { report("DTR_CONTROL_DISABLE\n"); } if (myDCB.fDsrSensitivity) { report("fDsrSensitivity\n"); } if (myDCB.fTXContinueOnXoff) { report("fTXContinueOnXoff\n"); } if (myDCB.fOutX) { report("fOutX\n"); } if (myDCB.fInX) { report("fInX\n"); } if (myDCB.fNull) { report("fNull\n"); } if (myDCB.fRtsControl & RTS_CONTROL_TOGGLE) { report("RTS_CONTROL_TOGGLE\n"); } if (myDCB.fRtsControl == 0) { report("RTS_CONTROL_HANDSHAKE ( fRtsControl==0 )\n"); } if (myDCB.fRtsControl & RTS_CONTROL_HANDSHAKE) { report("RTS_CONTROL_HANDSHAKE\n"); } if (myDCB.fRtsControl & RTS_CONTROL_ENABLE) { report("RTS_CONTROL_ENABLE\n"); } if (myDCB.fRtsControl & RTS_CONTROL_DISABLE) { report("RTS_CONTROL_DISABLE\n"); } if (myDCB.fAbortOnError) { report("fAbortOnError\n"); } SNPRINTF(message, sizeof(message), "XonLim: %d\n", myDCB.XonLim); report(message); SNPRINTF(message, sizeof(message), "XoffLim: %d\n", myDCB.XoffLim); report(message); SNPRINTF(message, sizeof(message), "ByteSize: %d\n", myDCB.ByteSize); report(message); switch (myDCB.Parity) { case EVENPARITY: report("EVENPARITY"); break; case MARKPARITY: report("MARKPARITY"); break; case NOPARITY: report("NOPARITY"); break; case ODDPARITY: report("ODDPARITY"); break; default: SNPRINTF(message, sizeof(message), "unknown Parity (%#x ):", myDCB.Parity); report(message); break; } report("\n"); switch (myDCB.StopBits) { case ONESTOPBIT: report("ONESTOPBIT"); break; case ONE5STOPBITS: report("ONE5STOPBITS"); break; case TWOSTOPBITS: report("TWOSTOPBITS"); break; default: report("unknown StopBits (%#x ):", myDCB.StopBits); break; } report("\n"); SNPRINTF(message, sizeof(message), "XonChar: %#x\n", myDCB.XonChar); report(message); SNPRINTF(message, sizeof(message), "XoffChar: %#x\n", myDCB.XoffChar); report(message); SNPRINTF(message, sizeof(message), "EofChar: %#x\n", myDCB.EofChar); report(message); SNPRINTF(message, sizeof(message), "EvtChar: %#x\n", myDCB.EvtChar); report(message); report("\n"); #endif /* DEBUG_HOSED */ } /*---------------------------------------------------------- tcgetattr() accept: perform: return: exceptions: win32api: GetCommState(), GetCommTimeouts() comments: ----------------------------------------------------------*/ int tcgetattr(int fd, struct termios *s_termios) { DCB myDCB; COMMTIMEOUTS timeouts; struct termios_list *index; char message[80]; ENTER("tcgetattr"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("tcgetattr"); return -1; } if (!GetCommState(index->hComm, &myDCB)) { SNPRINTF(message, sizeof(message), "GetCommState failed\n"); report(message); return -1; } memcpy(s_termios, index->ttyset, sizeof(struct termios)); show_DCB(myDCB); /***** input mode flags (c_iflag ) ****/ /* parity check enable */ if (myDCB.fParity) { s_termios->c_iflag |= INPCK; s_termios->c_iflag &= ~IGNPAR; } else { s_termios->c_iflag &= ~INPCK; s_termios->c_iflag |= IGNPAR; } /* FIXME: IGNBRK: ignore break */ /* FIXME: BRKINT: interrupt on break */ if (myDCB.fOutX) { s_termios->c_iflag |= IXON; } else { /* IXON: output start/stop control */ s_termios->c_iflag &= ~IXON; } if (myDCB.fInX) { s_termios->c_iflag |= IXOFF; } else { /* IXOFF: input start/stop control */ s_termios->c_iflag &= ~IXOFF; } if (myDCB.fTXContinueOnXoff) { s_termios->c_iflag |= IXANY; } else { /* IXANY: any char restarts output */ s_termios->c_iflag &= ~IXANY; } /* FIXME: IMAXBEL: if input buffer full, send bell */ /***** control mode flags (c_cflag ) *****/ /* FIXME: CLOCAL: DONT send SIGHUP on modem disconnect */ /* FIXME: HUPCL: generate modem disconnect when all has closed or exited */ /* CSTOPB two stop bits ( otherwise one) */ if (myDCB.StopBits == TWOSTOPBITS) { s_termios->c_cflag |= CSTOPB; } if (myDCB.StopBits == ONESTOPBIT) { s_termios->c_cflag &= ~CSTOPB; } /* PARENB enable parity bit */ s_termios->c_cflag &= ~(PARENB | PARODD | CMSPAR); myDCB.fParity = 1; #if 0 // redundant if (myDCB.fParity) { #endif report("tcgetattr getting parity\n"); s_termios->c_cflag |= PARENB; if (myDCB.Parity == MARKPARITY) { s_termios->c_cflag |= (PARODD | CMSPAR); } else if (myDCB.Parity == SPACEPARITY) { s_termios->c_cflag |= CMSPAR; } else if (myDCB.Parity == ODDPARITY) { report("ODDPARITY\n"); s_termios->c_cflag |= PARODD; } else if (myDCB.Parity == EVENPARITY) { report("EVENPARITY\n"); s_termios->c_cflag &= ~PARODD; } else if (myDCB.Parity == NOPARITY) { s_termios->c_cflag &= ~(PARODD | CMSPAR | PARENB); } #if 0 // see redundant above } else { s_termios->c_cflag &= ~PARENB; } #endif /* CSIZE */ s_termios->c_cflag |= bytesize_to_termios(myDCB.ByteSize); /* HARDWARE_FLOW_CONTROL: hardware flow control */ if ((myDCB.fOutxCtsFlow == TRUE) || (myDCB.fRtsControl == RTS_CONTROL_HANDSHAKE)) { s_termios->c_cflag |= HARDWARE_FLOW_CONTROL; } else { s_termios->c_cflag &= ~HARDWARE_FLOW_CONTROL; } /* MDMBUF: carrier based flow control of output */ /* CIGNORE: tcsetattr will ignore control modes & baudrate */ /***** NOT SUPPORTED: local mode flags (c_lflag) *****/ /* ICANON: canonical (not raw) mode */ /* ECHO: echo back to terminal */ /* ECHOE: echo erase */ /* ECHOPRT: hardcopy echo erase */ /* ECHOK: show KILL char */ /* ECHOKE: BSD ECHOK */ /* ECHONL: ICANON only: echo newline even with no ECHO */ /* ECHOCTL: if ECHO, then control-A are printed as '^A' */ /* ISIG: recognize INTR, QUIT & SUSP */ /* IEXTEN: implementation defined */ /* NOFLSH: dont clear i/o queues on INTR, QUIT or SUSP */ /* TOSTOP: background process generate SIGTTOU */ /* ALTWERASE: alt-w erase distance */ /* FLUSHO: user DISCARD char */ /* NOKERNINFO: disable STATUS char */ /* PENDIN: input line needsd reprinting, set by REPRINT char */ /***** END - NOT SUPPORTED *****/ /***** control characters (c_cc[NCCS] ) *****/ if (!GetCommTimeouts(index->hComm, &timeouts)) { YACK(); report("GetCommTimeouts\n"); return -1; } s_termios->c_cc[VTIME] = timeouts.ReadTotalTimeoutConstant / 100; /* handled in SerialImp.c? s_termios->c_cc[VMIN] = ? */ s_termios->c_cc[VSTART] = myDCB.XonChar; s_termios->c_cc[VSTOP] = myDCB.XoffChar; s_termios->c_cc[VEOF] = myDCB.EofChar; #ifdef DEBUG_VERBOSE SNPRINTF(message, sizeof(message), "tcgetattr: VTIME:%d, VMIN:%d\n", s_termios->c_cc[VTIME], s_termios->c_cc[VMIN]); report(message); #endif /* DEBUG_VERBOSE */ /***** line discipline ( c_line ) ( == c_cc[33] ) *****/ DCB_to_termios(&myDCB, s_termios); /* baudrate */ LEAVE("tcgetattr"); return 0; } /* `TCSANOW' Make the change immediately. `TCSADRAIN' Make the change after waiting until all queued output has been written. You should usually use this option when changing parameters that affect output. `TCSAFLUSH' This is like `TCSADRAIN', but also discards any queued input. `TCSASOFT' This is a flag bit that you can add to any of the above alternatives. Its meaning is to inhibit alteration of the state of the terminal hardware. It is a BSD extension; it is only supported on BSD systems and the GNU system. Using `TCSASOFT' is exactly the same as setting the `CIGNORE' bit in the `c_cflag' member of the structure TERMIOS-P points to. *Note Control Modes::, for a description of `CIGNORE'. */ /*---------------------------------------------------------- tcsetattr() accept: perform: return: exceptions: win32api: GetCommState(), GetCommTimeouts(), SetCommState(), SetCommTimeouts() comments: ----------------------------------------------------------*/ int tcsetattr(int fd, int when, struct termios *s_termios) { int vtime; DCB dcb; COMMTIMEOUTS timeouts; struct termios_list *index; ENTER("tcsetattr"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("tcsetattr"); return -1; } fflush(stdout); if (s_termios->c_lflag & ICANON) { report("tcsetattr: no canonical mode support\n"); /* and all other c_lflags too */ return -1; } if (!GetCommState(index->hComm, &dcb)) { YACK(); report("tcsetattr:GetCommState\n"); return -1; } if (!GetCommTimeouts(index->hComm, &timeouts)) { YACK(); report("tcsetattr:GetCommTimeouts\n"); return -1; } /*** control flags, c_cflag **/ if (!(s_termios->c_cflag & CIGNORE)) { dcb.fParity = 1; /* CIGNORE: ignore control modes and baudrate */ /* baudrate */ if (termios_to_DCB(s_termios, &dcb) < 0) { return -1; } } else { } /*** input flags, c_iflag **/ /* This is wrong. It disables Parity FIXME if( ( s_termios->c_iflag & INPCK ) && !( s_termios->c_iflag & IGNPAR ) ) { dcb.fParity = TRUE; } else { dcb.fParity = FALSE; } */ /* not in win95? Some years later... eww.. FIXME This is used for changing the Parity error character I think this code is hosed. See VEOF below Trent */ if (s_termios->c_iflag & ISTRIP) { dcb.fBinary = FALSE; } /* ISTRIP: strip to seven bits */ else { dcb.fBinary = TRUE; } /* FIXME: IGNBRK: ignore break */ /* FIXME: BRKINT: interrupt on break */ if (s_termios->c_iflag & IXON) { dcb.fOutX = TRUE; } else { dcb.fOutX = FALSE; } if (s_termios->c_iflag & IXOFF) { dcb.fInX = TRUE; } else { dcb.fInX = FALSE; } dcb.fTXContinueOnXoff = (s_termios->c_iflag & IXANY) ? TRUE : FALSE; /* FIXME: IMAXBEL: if input buffer full, send bell */ /* no DTR control in termios? */ dcb.fDtrControl = DTR_CONTROL_DISABLE; /* no DSR control in termios? */ dcb.fOutxDsrFlow = FALSE; /* DONT ignore rx bytes when DSR is OFF */ dcb.fDsrSensitivity = FALSE; dcb.XonChar = s_termios->c_cc[VSTART]; dcb.XoffChar = s_termios->c_cc[VSTOP]; dcb.XonLim = 0; /* ? */ dcb.XoffLim = 0; /* ? */ dcb.EofChar = s_termios->c_cc[VEOF]; if (dcb.EofChar != '\0') { dcb.fBinary = FALSE; } else { dcb.fBinary = TRUE; } if (EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | (EV_RLSD & EV_RXFLAG)) { dcb.EvtChar = '\n'; } else { dcb.EvtChar = '\0'; } if (!SetCommState(index->hComm, &dcb)) { report("SetCommState error\n"); YACK(); return -1; } #ifdef DEBUG_VERBOSE { char message[32]; SNPRINTF(message, sizeof(message), "VTIME:%d, VMIN:%d\n", s_termios->c_cc[VTIME], s_termios->c_cc[VMIN]); report(message); } #endif /* DEBUG_VERBOSE */ vtime = s_termios->c_cc[VTIME] * 100; timeouts.ReadTotalTimeoutConstant = vtime; timeouts.ReadIntervalTimeout = 0; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = vtime; timeouts.WriteTotalTimeoutMultiplier = 0; /* max between bytes */ if (s_termios->c_cc[VMIN] > 0 && vtime > 0) { /* read blocks forever on VMIN chars */ } else if (s_termios->c_cc[VMIN] == 0 && vtime == 0) { /* read returns immediately */ timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; } #ifdef DEBUG_VERBOSE { char message[64]; SNPRINTF(message, sizeof(message), "ReadIntervalTimeout=%ld\n", timeouts.ReadIntervalTimeout); report(message); SNPRINTF(message, sizeof(message), "c_cc[VTIME] = %d, c_cc[VMIN] = %d\n", s_termios->c_cc[VTIME], s_termios->c_cc[VMIN]); report(message); SNPRINTF(message, sizeof(message), "ReadTotalTimeoutConstant: %ld\n", timeouts.ReadTotalTimeoutConstant); report(message); SNPRINTF(message, sizeof(message), "ReadIntervalTimeout : %ld\n", timeouts.ReadIntervalTimeout); report(message); SNPRINTF(message, sizeof(message), "ReadTotalTimeoutMultiplier: %ld\n", timeouts.ReadTotalTimeoutMultiplier); report(message); } #endif /* DEBUG_VERBOSE */ if (!SetCommTimeouts(index->hComm, &timeouts)) { YACK(); report("SetCommTimeouts\n"); return -1; } memcpy(index->ttyset, s_termios, sizeof(struct termios)); LEAVE("tcsetattr"); return 0; } /*---------------------------------------------------------- tcsendbreak() accept: perform: return: exceptions: win32api: None comments: break for duration*0.25 seconds or 0.25 seconds if duration = 0. ----------------------------------------------------------*/ int tcsendbreak(int fd, int duration) { struct termios_list *index; COMSTAT Stat; ENTER("tcsendbreak"); index = win32_serial_find_port(fd); if (!index) { LEAVE("tcdrain"); return -1; } if (duration <= 0) { duration = 1; } if (!SetCommBreak(index->hComm)) { ClearErrors(index, &Stat); } /* 0.25 seconds == 250000 usec */ hl_usleep(duration * 250000); if (!ClearCommBreak(index->hComm)) { ClearErrors(index, &Stat); } LEAVE("tcsendbreak"); return 1; } /*---------------------------------------------------------- tcdrain() accept: file descriptor perform: wait for output to be written. return: 0 on success, -1 otherwise exceptions: None win32api: FlushFileBuffers comments: ----------------------------------------------------------*/ int tcdrain(int fd) { struct termios_list *index; char message[80]; int old_flag; ENTER("tcdrain"); index = win32_serial_find_port(fd); if (!index) { LEAVE("tcdrain"); return -1; } old_flag = index->event_flag; /* index->event_flag &= ~EV_TXEMPTY; SetCommMask( index->hComm, index->event_flag ); index->tx_happened = 1; */ if (!FlushFileBuffers(index->hComm)) { /* FIXME Need to figure out what the various errors are in windows. YACK() should report them and we can handle them as we find them Something funky is happening on NT. GetLastError = 0. */ SNPRINTF(message, sizeof(message), "FlushFileBuffers() %i\n", (int) GetLastError()); report(message); if (GetLastError() == 0) { set_errno(0); return (0); } set_errno(EAGAIN); YACK(); LEAVE("tcdrain"); return -1; } /* SNPRINTF( message, sizeof(message), "FlushFileBuffers() %i\n", (int) GetLastError() ); report( message ); */ LEAVE("tcdrain success"); index->event_flag |= EV_TXEMPTY; SetCommMask(index->hComm, index->event_flag); index->event_flag = old_flag; /* index->tx_happened = 1; */ return 0; } /*---------------------------------------------------------- tcflush() accept: file descriptor, queue_selector perform: discard data not transmitted or read TCIFLUSH: flush data not read TCOFLUSH: flush data not transmitted TCIOFLUSH: flush both return: 0 on success, -1 on error exceptions: none win32api: PurgeComm comments: ----------------------------------------------------------*/ int tcflush(int fd, int queue_selector) { struct termios_list *index; int old_flag; ENTER("tcflush"); index = win32_serial_find_port(fd); if (!index) { LEAVE("tclflush"); return (-1); } old_flag = index->event_flag; /* index->event_flag &= ~EV_TXEMPTY; SetCommMask( index->hComm, index->event_flag ); index->tx_happened = 1; */ index->tx_happened = 1; switch (queue_selector) { case TCIFLUSH: if (!PurgeComm(index->hComm, PURGE_RXABORT | PURGE_RXCLEAR)) { goto fail; } break; case TCOFLUSH: if (!PurgeComm(index->hComm, PURGE_TXABORT | PURGE_TXCLEAR)) { goto fail; } break; case TCIOFLUSH: if (!PurgeComm(index->hComm, PURGE_TXABORT | PURGE_TXCLEAR)) { goto fail; } if (!PurgeComm(index->hComm, PURGE_RXABORT | PURGE_RXCLEAR)) { goto fail; } break; default: /* set_errno( ENOTSUP ); */ report("tcflush: Unknown queue_selector\n"); LEAVE("tcflush"); return -1; } index->event_flag |= EV_TXEMPTY; SetCommMask(index->hComm, index->event_flag); index->event_flag = old_flag; index->tx_happened = 1; LEAVE("tcflush"); return (0); /* FIXME Need to figure out what the various errors are in windows. YACK() should report them and we can handle them as we find them */ fail: LEAVE("tcflush"); set_errno(EAGAIN); YACK(); return -1; } /*---------------------------------------------------------- tcflow() accept: perform: return: exceptions: win32api: None comments: FIXME ----------------------------------------------------------*/ int tcflow(int fd, int action) { ENTER("tcflow"); switch (action) { /* Suspend transmission of output */ case TCOOFF: break; /* Restart transmission of output */ case TCOON: break; /* Transmit a STOP character */ case TCIOFF: break; /* Transmit a START character */ case TCION: break; default: return -1; } LEAVE("tcflow"); return 1; } /*---------------------------------------------------------- fstat() accept: perform: return: exceptions: win32api: comments: this is just to keep the eventLoop happy. ----------------------------------------------------------*/ #if 0 int fstat(int fd, ...) { return (0); } #endif /*---------------------------------------------------------- ioctl() accept: perform: return: exceptions: win32api: GetCommError(), GetCommModemStatus, EscapeCommFunction() comments: FIXME the DCB struct is: typedef struct _DCB { unsigned long DCBlength, BaudRate, fBinary:1, fParity:1; unsigned long fOutxCtsFlow:1, fOutxDsrFlow:1, fDtrControl:2; unsigned long fDsrSensitivity:1, fTXContinueOnXoff:1; unsigned long fOutX:1, fInX:1, fErrorChar:1, fNull:1; unsigned long fRtsControl:2, fAbortOnError:1, fDummy2:17; WORD wReserved, XonLim, XoffLim; BYTE ByteSize, Parity, StopBits; char XonChar, XoffChar, ErrorChar, EofChar, EvtChar; WORD wReserved1; } DCB; ----------------------------------------------------------*/ int win32_serial_ioctl(int fd, int request, ...) { unsigned long dwStatus = 0; va_list ap; int *arg, ret, old_flag; char message[80]; #ifdef TIOCGSERIAL DCB *dcb; struct serial_struct *sstruct; #endif /* TIOCGSERIAL */ COMSTAT Stat; struct termios_list *index; #ifdef TIOCGICOUNT struct serial_icounter_struct *sistruct; #endif /* TIOCGICOUNT */ ENTER("ioctl"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("ioctl"); return -1; } va_start(ap, request); ret = ClearErrors(index, &Stat); if (ret == 0) { set_errno(EBADFD); YACK(); report("ClearError Failed! ernno EBADFD"); arg = va_arg(ap, int *); va_end(ap); return -1; } switch (request) { case TCSBRK: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; case TCSBRKP: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; case TIOCGSOFTCAR: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; case TIOCSSOFTCAR: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; case TIOCCBRK: case TIOCSBRK: arg = va_arg(ap, int *); if (EscapeCommFunction(index->hComm, (request == TIOCSBRK) ? SETBREAK : CLRBREAK)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } break; case TIOCMGET: arg = va_arg(ap, int *); /* DORITOS */ if (!GetCommModemStatus(index->hComm, &dwStatus)) { report_error("GetCommMOdemStatus failed!\n"); } if (dwStatus & MS_RLSD_ON) { *arg |= TIOCM_CAR; } else { *arg &= ~TIOCM_CAR; } if (dwStatus & MS_RING_ON) { *arg |= TIOCM_RNG; } else { *arg &= ~TIOCM_RNG; } if (dwStatus & MS_DSR_ON) { *arg |= TIOCM_DSR; } else { *arg &= ~TIOCM_DSR; } if (dwStatus & MS_CTS_ON) { *arg |= TIOCM_CTS; } else { *arg &= ~TIOCM_CTS; } /* I'm not seeing a way to read the MSR directly we store the state using TIOCM_* Trent */ if (index->MSR & TIOCM_DTR) { *arg |= TIOCM_DTR; } else { *arg &= ~TIOCM_DTR; } if (index->MSR & TIOCM_RTS) { *arg |= TIOCM_RTS; } else { *arg &= ~TIOCM_RTS; } /* TIOCM_LE TIOCM_ST TIOCM_SR */ va_end(ap); return (0); case TIOCMBIS: arg = va_arg(ap, int *); if (*arg & TIOCM_DTR) { index->MSR |= TIOCM_DTR; if (EscapeCommFunction(index->hComm, SETDTR)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } } if (*arg & TIOCM_RTS) { index->MSR |= TIOCM_RTS; if (EscapeCommFunction(index->hComm, SETRTS)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } } break; case TIOCMBIC: arg = va_arg(ap, int *); if (*arg & TIOCM_DTR) { index->MSR &= ~TIOCM_DTR; if (EscapeCommFunction(index->hComm, CLRDTR)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } } if (*arg & TIOCM_RTS) { index->MSR &= ~TIOCM_RTS; if (EscapeCommFunction(index->hComm, CLRRTS)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } } break; case TIOCMSET: arg = va_arg(ap, int *); if ((*arg & TIOCM_DTR) == (index->MSR & TIOCM_DTR)) { report("DTR is unchanged\n"); } SNPRINTF(message, sizeof(message), "DTR %i %i\n", *arg & TIOCM_DTR, index->MSR & TIOCM_DTR); report(message); if (*arg & TIOCM_DTR) { index->MSR |= TIOCM_DTR; } else { index->MSR &= ~TIOCM_DTR; } if (EscapeCommFunction(index->hComm, (*arg & TIOCM_DTR) ? SETDTR : CLRDTR)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } if ((*arg & TIOCM_RTS) == (index->MSR & TIOCM_RTS)) { report("RTS is unchanged\n"); } SNPRINTF(message, sizeof(message), "RTS %i %i\n", *arg & TIOCM_RTS, index->MSR & TIOCM_RTS); report(message); if (*arg & TIOCM_RTS) { index->MSR |= TIOCM_RTS; } else { index->MSR &= ~TIOCM_RTS; } if (EscapeCommFunction(index->hComm, (*arg & TIOCM_RTS) ? SETRTS : CLRRTS)) { report("EscapeCommFunction: True\n"); } else { report("EscapeCommFunction: False\n"); } break; #ifdef TIOCGSERIAL case TIOCGSERIAL: report("TIOCGSERIAL\n"); dcb = calloc(1, sizeof(DCB)); if (!dcb) { va_end(ap); return -1; } memset(dcb, 0, sizeof(DCB)); GetCommState(index->hComm, dcb); sstruct = va_arg(ap, struct serial_struct *); if (DCB_to_serial_struct(dcb, sstruct) < 0) { va_end(ap); return -1; } index->sstruct = sstruct; report("TIOCGSERIAL\n"); free(dcb); break; #endif /* TIOCGSERIAL */ #ifdef TIOCSSERIAL case TIOCSSERIAL: report("TIOCSSERIAL\n"); dcb = calloc(1, sizeof(DCB)); if (!dcb) { va_end(ap); return -1; } memset(dcb, 0, sizeof(DCB)); GetCommState(index->hComm, dcb); index->sstruct = va_arg(ap, struct serial_struct *); if (serial_struct_to_DCB(index->sstruct, dcb) < 0) { va_end(ap); return -1; } report("TIOCSSERIAL\n"); free(dcb); break; #endif /* TIOCSSERIAL */ case TIOCSERCONFIG: case TIOCSERGETLSR: arg = va_arg(ap, int *); /* do { wait = WaitForSingleObject( index->sol.hEvent, 5000 ); } while ( wait == WAIT_TIMEOUT ); */ ret = ClearErrors(index, &Stat); if (ret == 0) { /* FIXME ? */ set_errno(EBADFD); YACK(); report("TIOCSERGETLSR EBADFD"); va_end(ap); return -1; } if ((int) Stat.cbOutQue == 0) { /* output is empty */ if (index->tx_happened == 1) { old_flag = index->event_flag; index->event_flag &= ~EV_TXEMPTY; SetCommMask(index->hComm, index->event_flag); index->event_flag = old_flag; *arg = 1; index->tx_happened = 0; report("ioctl: output empty\n"); } else { *arg = 0; } ret = 0; } else { /* still data out there */ *arg = 0; ret = 0; } va_end(ap); return (0); break; case TIOCSERGSTRUCT: case TIOCSERGETMULTI: case TIOCSERSETMULTI: va_end(ap); return -ENOIOCTLCMD; case TIOCMIWAIT: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; /* On linux this fills a struct with all the line info (data available, bytes sent, ... */ #ifdef TIOCGICOUNT case TIOCGICOUNT: sistruct = va_arg(ap, struct serial_icounter_struct *); ret = ClearErrors(index, &Stat); if (ret == 0) { /* FIXME ? */ report("TIOCGICOUNT failed\n"); set_errno(EBADFD); va_end(ap); return -1; } sistruct->frame = index->sis->frame; sistruct->overrun = index->sis->overrun; sistruct->parity = index->sis->parity; sistruct->brk = index->sis->brk; va_end(ap); return 0; /* abolete ioctls */ #endif /* TIOCGICOUNT */ case TIOCSERGWILD: case TIOCSERSWILD: report("TIOCSER[GS]WILD absolete\n"); va_end(ap); return 0; /* number of bytes available for reading */ case FIONREAD: arg = va_arg(ap, int *); ret = ClearErrors(index, &Stat); if (ret == 0) { /* FIXME ? */ report("FIONREAD failed\n"); set_errno(EBADFD); va_end(ap); return -1; } *arg = (int) Stat.cbInQue; #ifdef DEBUG_VERBOSE SNPRINTF(message, sizeof(message), "FIONREAD: %i bytes available\n", (int) Stat.cbInQue); report(message); if (*arg) { SNPRINTF(message, sizeof(message), "FIONREAD: %i\n", *arg); report(message); } #endif /* DEBUG_VERBOSE */ ret = 0; break; /* pending bytes to be sent */ case TIOCOUTQ: arg = va_arg(ap, int *); va_end(ap); return -ENOIOCTLCMD; default: SNPRINTF(message, sizeof(message), "FIXME: ioctl: unknown request: %#x\n", request); report(message); va_end(ap); return -ENOIOCTLCMD; } va_end(ap); LEAVE("ioctl"); return 0; } /*---------------------------------------------------------- fcntl() accept: perform: return: exceptions: win32api: None comments: FIXME ----------------------------------------------------------*/ int win32_serial_fcntl(int fd, int command, ...) { int arg, ret = 0; va_list ap; struct termios_list *index; char message[80]; ENTER("fcntl"); if (fd <= 0) { return 0; } index = win32_serial_find_port(fd); if (!index) { LEAVE("fcntl"); return -1; } va_start(ap, command); arg = va_arg(ap, int); switch (command) { case F_SETOWN: /* set ownership of fd */ break; case F_SETFL: /* set operating flags */ #ifdef DEBUG SNPRINTF(message, sizeof(message), "F_SETFL fd=%d flags=%d\n", fd, arg); report(message); #endif index->open_flags = arg; break; case F_GETFL: /* get operating flags */ ret = index->open_flags; break; default: SNPRINTF(message, sizeof(message), "unknown fcntl command %#x\n", command); report(message); break; } va_end(ap); LEAVE("fcntl"); return ret; } #if 0 /*---------------------------------------------------------- termios_interrupt_event_loop() accept: perform: return: let Serial_select break out so the thread can die exceptions: win32api: comments: ----------------------------------------------------------*/ static void termios_interrupt_event_loop(int fd, int flag) { struct termios_list *index = win32_serial_find_port(fd); if (!index) { LEAVE("termios_interrupt_event_loop"); return; } /* index->event_flag = 0; TRENT SetCommMask( index->hComm, index->event_flag ); hl_usleep(2000); tcdrain( index->fd ); SetEvent( index->sol.hEvent ); */ index->interrupt = flag; return; } #endif /*---------------------------------------------------------- Serial_select() accept: perform: return: number of fd's changed on success or -1 on error. exceptions: win32api: SetCommMask(), GetCommEvent(), WaitSingleObject() comments: ----------------------------------------------------------*/ #ifndef __LCC__ int win32_serial_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { unsigned long dwCommEvent, wait = WAIT_TIMEOUT; int fd = n - 1; struct termios_list *index; char message[80]; COMSTAT Stat; int ret; ENTER("serial_select"); if (fd <= 0) { /* Baby did a bad baad thing */ goto fail; } index = win32_serial_find_port(fd); if (!index) { goto fail; } #define DATA_AVAILABLE 1 //nativeSetEventFlag( fd, SerialPortEvent.DATA_AVAILABLE, enable ); if (readfds) { int eventflags[12]; memset(eventflags, 0, sizeof(eventflags)); eventflags[DATA_AVAILABLE] = 1; termios_setflags(fd, eventflags); } if (!index->event_flag) { /* still setting up the port? hold off for a Sec so things can fire up this does happen. loops ~twice on a 350 Mzh with hl_usleep(1000000) */ /* hl_usleep(10000); */ LEAVE("serial_uselect"); return (0); } ResetEvent(index->wol.hEvent); ResetEvent(index->sol.hEvent); ResetEvent(index->rol.hEvent); ret = ClearErrors(index, &Stat); #if 1 if (ret == 0) { goto fail; } /* look only after read */ if (readfds && !writefds && !exceptfds) { int timeout_usec = timeout ? timeout->tv_sec * 1000000 + timeout->tv_usec : INT_MAX; while (timeout_usec > 0) { SNPRINTF(message, sizeof(message), "wait for data in read buffer%d\n", (int)Stat.cbInQue); report(message); if (Stat.cbInQue != 0) { goto end; } hl_usleep(1000); /* FIXME: not very accurate wrt process time */ timeout_usec -= 1000; report("sleep...\n"); ret = ClearErrors(index, &Stat); if (ret == 0) { goto fail; } } goto timeout; } #endif while (wait == WAIT_TIMEOUT && index->sol.hEvent) { if (index->interrupt == 1) { goto fail; } SetCommMask(index->hComm, index->event_flag); ClearErrors(index, &Stat); if (!WaitCommEvent(index->hComm, &dwCommEvent, &index->rol)) { /* WaitCommEvent failed probably overlapped though */ if (GetLastError() != ERROR_IO_PENDING) { ClearErrors(index, &Stat); goto fail; } /* thought so... */ } /* could use the select timeout here but it should not be needed */ ClearErrors(index, &Stat); wait = WaitForSingleObject(index->rol.hEvent, 100); switch (wait) { case WAIT_OBJECT_0: goto end; case WAIT_TIMEOUT: goto timeout; case WAIT_ABANDONED: default: goto fail; } } end: /* You may want to chop this out for lower latency */ /* hl_usleep(1000); */ LEAVE("serial_select"); return (1); timeout: LEAVE("serial_select"); return (0); fail: YACK(); SNPRINTF(message, sizeof(message), "< select called error %i\n", n); report(message); errno = EBADFD; LEAVE("serial_select"); return (-1); } #ifdef asdf int win32_serial_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { unsigned long nBytes, dwCommEvent, wait = WAIT_TIMEOUT; int fd = n - 1; struct termios_list *index; char message[80]; ENTER("serial_select"); if (fd <= 0) { /* hl_usleep(1000); */ return 1; } index = win32_serial_find_port(fd); if (!index) { LEAVE("serial_select"); return -1; } if (index->interrupt == 1) { goto end; } while (!index->event_flag) { /* hl_usleep(1000); */ return -1; } while (wait == WAIT_TIMEOUT && index->sol.hEvent) { if (index->interrupt == 1) { goto end; } if (!index->sol.hEvent) { return 1; } if (!WaitCommEvent(index->hComm, &dwCommEvent, &index->sol)) { /* WaitCommEvent failed */ if (index->interrupt == 1) { goto end; } if (GetLastError() != ERROR_IO_PENDING) { SNPRINTF(message, sizeof(message), "WaitCommEvent filename = %s\n", index->filename); report(message); return (1); /* goto fail; */ } return (1); } if (index->interrupt == 1) { goto end; } wait = WaitForSingleObject(index->sol.hEvent, 1000); switch (wait) { case WAIT_OBJECT_0: if (index->interrupt == 1) { goto end; } if (!index->sol.hEvent) { return (1); } if (!GetOverlappedResult(index->hComm, &index->sol, &nBytes, TRUE)) { goto end; } else if (index->tx_happened == 1) { goto end; } else { goto end; } break; case WAIT_TIMEOUT: default: return (1); /* WaitFor error */ } } end: /* hl_usleep(1000); */ LEAVE("serial_select"); return (1); #ifdef asdf /* FIXME this needs to be cleaned up... */ fail: SNPRINTF(message, sizeof(message), "< select called error %i\n", n); YACK(); report(message); set_errno(EBADFD); LEAVE("serial_select"); return (1); #endif /* asdf */ } #endif /* asdf */ #endif /* __LCC__ */ #if 0 /*---------------------------------------------------------- termiosSetParityError() accept: fd The device opened perform: Get the Parity Error Char return: the Parity Error Char exceptions: none win32api: GetCommState() comments: No idea how to do this in Unix (handle in read?) ----------------------------------------------------------*/ static int termiosGetParityErrorChar(int fd) { struct termios_list *index; DCB dcb; ENTER("termiosGetParityErrorChar"); index = win32_serial_find_port(fd); if (!index) { LEAVE("termiosGetParityErrorChar"); return (-1); } GetCommState(index->hComm, &dcb); LEAVE("termiosGetParityErrorChar"); return (dcb.ErrorChar); } /*---------------------------------------------------------- termiosSetParityError() accept: fd The device opened, value the new Parity Error Char perform: Set the Parity Error Char return: void exceptions: none win32api: GetCommState(), SetCommState() comments: No idea how to do this in Unix (handle in read?) ----------------------------------------------------------*/ static void termiosSetParityError(int fd, char value) { DCB dcb; struct termios_list *index; ENTER("termiosSetParityErrorChar"); index = win32_serial_find_port(fd); if (!index) { LEAVE("termiosSetParityError"); return; } GetCommState(index->hComm, &dcb); dcb.ErrorChar = value; SetCommState(index->hComm, &dcb); LEAVE("termiosSetParityErrorChar"); } #endif /*----------------------- END OF LIBRARY -----------------*/ #endif /* WIN32 */ hamlib-4.6.5/lib/cJSON.h0000664000175000017500000003750115056640442010314 /* Copyright (c) 2009-2017 Dave Gamble and cJSON contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef cJSON__h #define cJSON__h #ifdef __cplusplus extern "C" { #endif #if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) #define __WINDOWS__ #endif #ifdef __WINDOWS__ /* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol For *nix builds that support visibility attribute, you can define similar behavior by setting default visibility to hidden by adding -fvisibility=hidden (for gcc) or -xldscope=hidden (for sun cc) to CFLAGS then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does */ #define CJSON_CDECL __cdecl #define CJSON_STDCALL __stdcall /* export symbols by default, this is necessary for copy pasting the C and header file */ #if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) #define CJSON_EXPORT_SYMBOLS #endif #if defined(CJSON_HIDE_SYMBOLS) #define CJSON_PUBLIC(type) type CJSON_STDCALL #elif defined(CJSON_EXPORT_SYMBOLS) #define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL #elif defined(CJSON_IMPORT_SYMBOLS) #define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL #endif #else /* !__WINDOWS__ */ #define CJSON_CDECL #define CJSON_STDCALL #if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) #define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type #else #define CJSON_PUBLIC(type) type #endif #endif /* project version */ #define CJSON_VERSION_MAJOR 1 #define CJSON_VERSION_MINOR 7 #define CJSON_VERSION_PATCH 15 #include /* cJSON Types: */ #define cJSON_Invalid (0) #define cJSON_False (1 << 0) #define cJSON_True (1 << 1) #define cJSON_NULL (1 << 2) #define cJSON_Number (1 << 3) #define cJSON_String (1 << 4) #define cJSON_Array (1 << 5) #define cJSON_Object (1 << 6) #define cJSON_Raw (1 << 7) /* raw json */ #define cJSON_IsReference 256 #define cJSON_StringIsConst 512 /* The cJSON structure: */ typedef struct cJSON { /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ struct cJSON *next; struct cJSON *prev; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ struct cJSON *child; /* The type of the item, as above. */ int type; /* The item's string, if type==cJSON_String and type == cJSON_Raw */ char *valuestring; /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ int valueint; /* The item's number, if type==cJSON_Number */ double valuedouble; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ char *string; } cJSON; typedef struct cJSON_Hooks { /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ void *(CJSON_CDECL *malloc_fn)(size_t sz); void (CJSON_CDECL *free_fn)(void *ptr); } cJSON_Hooks; typedef int cJSON_bool; /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. * This is to prevent stack overflows. */ #ifndef CJSON_NESTING_LIMIT #define CJSON_NESTING_LIMIT 1000 #endif /* returns the version of cJSON as a string */ CJSON_PUBLIC(const char*) cJSON_Version(void); /* Supply malloc, realloc and free functions to cJSON */ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); /* Render a cJSON entity to text for transfer/storage. */ CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); /* Render a cJSON entity to text for transfer/storage without any formatting. */ CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); /* Delete a cJSON entity and all subentities. */ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); /* Returns the number of items in an array (or object). */ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); /* Get item "string" from object. Case insensitive. */ CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); /* Check item type and return its value */ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); /* These functions check the type of an item */ CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); /* These calls create a cJSON item of the appropriate type. */ CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); /* raw json */ CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); /* Create a string where valuestring references a string so * it will not be freed by cJSON_Delete */ CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); /* Create an object/array that only references it's elements so * they will not be freed by cJSON_Delete */ CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); /* These utilities create an Array of count items. * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); /* Append item to the specified array/object. */ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before * writing to `item->string` */ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); /* Remove/Detach items from Arrays/Objects. */ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); /* Update array items. */ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); /* Duplicate a cJSON item */ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will * need to be released. With recurse!=0, it will duplicate any children connected to the item. * The item->next and ->prev pointers are always zero on return from Duplicate. */ /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. * The input pointer json cannot point to a read-only address area, such as a string constant, * but should point to a readable and writable address area. */ CJSON_PUBLIC(void) cJSON_Minify(char *json); /* Helper functions for creating and adding items to an object at the same time. * They return the added item or NULL on failure. */ CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) /* helper for the cJSON_SetNumberValue macro */ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); /* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/ #define cJSON_SetBoolValue(object, boolValue) ( \ (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \ (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \ cJSON_Invalid\ ) /* Macro for iterating over an array or object */ #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ CJSON_PUBLIC(void *) cJSON_malloc(size_t size); CJSON_PUBLIC(void) cJSON_free(void *object); #ifdef __cplusplus } #endif #endif hamlib-4.6.5/lib/dummy.c0000664000175000017500000000026015056640442010516 /* Dummy function to make sure libmisc never become an empty library. * Solaris linker does not like such libs. */ // cppcheck-suppress unusedFunction void dummy(void) { } hamlib-4.6.5/lib/cJSON.c0000664000175000017500000023255215056640442010312 /* Copyright (c) 2009-2017 Dave Gamble and cJSON contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* cJSON */ /* JSON parser in C. */ /* disable warnings about old C89 functions in MSVC */ #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) #define _CRT_SECURE_NO_DEPRECATE #endif #ifdef __GNUC__ #pragma GCC visibility push(default) #endif #if defined(_MSC_VER) #pragma warning (push) /* disable warning about single line comments in system headers */ #pragma warning (disable : 4001) #endif #include #include #include #include #include #include #include #ifdef ENABLE_LOCALES #include #endif #if defined(_MSC_VER) #pragma warning (pop) #endif #ifdef __GNUC__ #pragma GCC visibility pop #endif #include "cJSON.h" /* define our own boolean type */ #ifdef true #undef true #endif #define true ((cJSON_bool)1) #ifdef false #undef false #endif #define false ((cJSON_bool)0) /* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ #ifndef isinf #define isinf(d) (isnan((d - d)) && !isnan(d)) #endif #ifndef isnan #define isnan(d) (d != d) #endif #ifndef NAN #ifdef _WIN32 #define NAN sqrt(-1.0) #else #define NAN 0.0/0.0 #endif #endif typedef struct { const unsigned char *json; size_t position; } error; static error global_error = { NULL, 0 }; CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) { return (const char *)(global_error.json + global_error.position); } CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON *const item) { if (!cJSON_IsString(item)) { return NULL; } return item->valuestring; } CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON *const item) { if (!cJSON_IsNumber(item)) { return (double) NAN; } return item->valuedouble; } /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15) #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. #endif CJSON_PUBLIC(const char *) cJSON_Version(void) { static char version[15]; sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); return version; } /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) { if ((string1 == NULL) || (string2 == NULL)) { return 1; } if (string1 == string2) { return 0; } for (; tolower(*string1) == tolower(*string2); (void)string1++, string2++) { if (*string1 == '\0') { return 0; } } return tolower(*string1) - tolower(*string2); } typedef struct internal_hooks { void *(CJSON_CDECL *allocate)(size_t size); void (CJSON_CDECL *deallocate)(void *pointer); void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); } internal_hooks; #if defined(_MSC_VER) /* work around MSVC error C2322: '...' address of dllimport '...' is not static */ static void *CJSON_CDECL internal_malloc(size_t size) { return malloc(size); } static void CJSON_CDECL internal_free(void *pointer) { free(pointer); } static void *CJSON_CDECL internal_realloc(void *pointer, size_t size) { return realloc(pointer, size); } #else #define internal_malloc malloc #define internal_free free #define internal_realloc realloc #endif /* strlen of character literals resolved at compile time */ #define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; static unsigned char *cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks) { size_t length = 0; unsigned char *copy = NULL; if (string == NULL) { return NULL; } length = strlen((const char *)string) + sizeof(""); copy = (unsigned char *)hooks->allocate(length); if (copy == NULL) { return NULL; } memcpy(copy, string, length); return copy; } CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks) { if (hooks == NULL) { /* Reset hooks */ global_hooks.allocate = malloc; global_hooks.deallocate = free; global_hooks.reallocate = realloc; return; } global_hooks.allocate = malloc; if (hooks->malloc_fn != NULL) { global_hooks.allocate = hooks->malloc_fn; } global_hooks.deallocate = free; if (hooks->free_fn != NULL) { global_hooks.deallocate = hooks->free_fn; } /* use realloc only if both free and malloc are used */ global_hooks.reallocate = NULL; if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) { global_hooks.reallocate = realloc; } } /* Internal constructor. */ static cJSON *cJSON_New_Item(const internal_hooks *const hooks) { cJSON *node = (cJSON *)hooks->allocate(sizeof(cJSON)); if (node) { memset(node, '\0', sizeof(cJSON)); } return node; } /* Delete a cJSON structure. */ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) { cJSON *next = NULL; while (item != NULL) { next = item->next; if (!(item->type & cJSON_IsReference) && (item->child != NULL)) { cJSON_Delete(item->child); } if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) { global_hooks.deallocate(item->valuestring); } if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) { global_hooks.deallocate(item->string); } global_hooks.deallocate(item); item = next; } } /* get the decimal point character of the current locale */ static unsigned char get_decimal_point(void) { #ifdef ENABLE_LOCALES struct lconv *lconv = localeconv(); return (unsigned char) lconv->decimal_point[0]; #else return '.'; #endif } typedef struct { const unsigned char *content; size_t length; size_t offset; size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ internal_hooks hooks; } parse_buffer; /* check if the given size is left to read in a given parse buffer (starting with 1) */ #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) /* check if the buffer can be accessed at the given index (starting with 0) */ #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) /* get a pointer to the buffer at the position */ #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) /* Parse the input text to generate a number, and populate the result into item. */ static cJSON_bool parse_number(cJSON *const item, parse_buffer *const input_buffer) { double number = 0; unsigned char *after_end = NULL; unsigned char number_c_string[64]; unsigned char decimal_point = get_decimal_point(); size_t i = 0; if ((input_buffer == NULL) || (input_buffer->content == NULL)) { return false; } /* copy the number into a temporary buffer and replace '.' with the decimal point * of the current locale (for strtod) * This also takes care of '\0' not necessarily being available for marking the end of the input */ for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) { switch (buffer_at_offset(input_buffer)[i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '+': case '-': case 'e': case 'E': number_c_string[i] = buffer_at_offset(input_buffer)[i]; break; case '.': number_c_string[i] = decimal_point; break; default: goto loop_end; } } loop_end: number_c_string[i] = '\0'; number = strtod((const char *)number_c_string, (char **)&after_end); if (number_c_string == after_end) { return false; /* parse_error */ } item->valuedouble = number; /* use saturation in case of overflow */ if (number >= INT_MAX) { item->valueint = INT_MAX; } else if (number <= (double)INT_MIN) { item->valueint = INT_MIN; } else { item->valueint = (int)number; } item->type = cJSON_Number; input_buffer->offset += (size_t)(after_end - number_c_string); return true; } /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) { if (number >= INT_MAX) { object->valueint = INT_MAX; } else if (number <= (double)INT_MIN) { object->valueint = INT_MIN; } else { object->valueint = (int)number; } return object->valuedouble = number; } CJSON_PUBLIC(char *) cJSON_SetValuestring(cJSON *object, const char *valuestring) { char *copy = NULL; /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) { return NULL; } if (strlen(valuestring) <= strlen(object->valuestring)) { strcpy(object->valuestring, valuestring); return object->valuestring; } copy = (char *) cJSON_strdup((const unsigned char *)valuestring, &global_hooks); if (copy == NULL) { return NULL; } if (object->valuestring != NULL) { cJSON_free(object->valuestring); } object->valuestring = copy; return copy; } typedef struct { unsigned char *buffer; size_t length; size_t offset; size_t depth; /* current nesting depth (for formatted printing) */ cJSON_bool noalloc; cJSON_bool format; /* is this print a formatted print */ internal_hooks hooks; } printbuffer; /* realloc printbuffer if necessary to have at least "needed" bytes more */ static unsigned char *ensure(printbuffer *const p, size_t needed) { unsigned char *newbuffer = NULL; size_t newsize = 0; if ((p == NULL) || (p->buffer == NULL)) { return NULL; } if ((p->length > 0) && (p->offset >= p->length)) { /* make sure that offset is valid */ return NULL; } if (needed > INT_MAX) { /* sizes bigger than INT_MAX are currently not supported */ return NULL; } needed += p->offset + 1; if (needed <= p->length) { return p->buffer + p->offset; } if (p->noalloc) { return NULL; } /* calculate new buffer size */ if (needed > (INT_MAX / 2)) { /* overflow of int, use INT_MAX if possible */ if (needed <= INT_MAX) { newsize = INT_MAX; } else { return NULL; } } else { newsize = needed * 2; } if (p->hooks.reallocate != NULL) { /* reallocate with realloc if available */ newbuffer = (unsigned char *)p->hooks.reallocate(p->buffer, newsize); if (newbuffer == NULL) { p->hooks.deallocate(p->buffer); p->length = 0; p->buffer = NULL; return NULL; } } else { /* otherwise reallocate manually */ newbuffer = (unsigned char *)p->hooks.allocate(newsize); if (!newbuffer) { p->hooks.deallocate(p->buffer); p->length = 0; p->buffer = NULL; return NULL; } memcpy(newbuffer, p->buffer, p->offset + 1); p->hooks.deallocate(p->buffer); } p->length = newsize; p->buffer = newbuffer; return newbuffer + p->offset; } /* calculate the new length of the string in a printbuffer and update the offset */ static void update_offset(printbuffer *const buffer) { const unsigned char *buffer_pointer = NULL; if ((buffer == NULL) || (buffer->buffer == NULL)) { return; } buffer_pointer = buffer->buffer + buffer->offset; buffer->offset += strlen((const char *)buffer_pointer); } /* securely comparison of floating-point variables */ static cJSON_bool compare_double(double a, double b) { double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); return (fabs(a - b) <= maxVal * DBL_EPSILON); } /* Render the number nicely from the given item into a string. */ static cJSON_bool print_number(const cJSON *const item, printbuffer *const output_buffer) { unsigned char *output_pointer = NULL; double d = item->valuedouble; int length = 0; size_t i = 0; unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ unsigned char decimal_point = get_decimal_point(); double test = 0.0; if (output_buffer == NULL) { return false; } /* This checks for NaN and Infinity */ if (isnan(d) || isinf(d)) { length = sprintf((char *)number_buffer, "null"); } else if (d == (double)item->valueint) { length = sprintf((char *)number_buffer, "%d", item->valueint); } else { /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ length = sprintf((char *)number_buffer, "%1.15g", d); /* Check whether the original double can be recovered */ if ((sscanf((char *)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) { /* If not, print with 17 decimal places of precision */ length = sprintf((char *)number_buffer, "%1.17g", d); } } /* sprintf failed or buffer overrun occurred */ if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) { return false; } /* reserve appropriate space in the output */ output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); if (output_pointer == NULL) { return false; } /* copy the printed number to the output and replace locale * dependent decimal point with '.' */ for (i = 0; i < ((size_t)length); i++) { if (number_buffer[i] == decimal_point) { output_pointer[i] = '.'; continue; } output_pointer[i] = number_buffer[i]; } output_pointer[i] = '\0'; output_buffer->offset += (size_t)length; return true; } /* parse 4 digit hexadecimal number */ static unsigned parse_hex4(const unsigned char *const input) { unsigned int h = 0; size_t i = 0; for (i = 0; i < 4; i++) { /* parse digit */ if ((input[i] >= '0') && (input[i] <= '9')) { h += (unsigned int) input[i] - '0'; } else if ((input[i] >= 'A') && (input[i] <= 'F')) { h += (unsigned int) 10 + input[i] - 'A'; } else if ((input[i] >= 'a') && (input[i] <= 'f')) { h += (unsigned int) 10 + input[i] - 'a'; } else /* invalid */ { return 0; } if (i < 3) { /* shift left to make place for the next nibble */ h = h << 4; } } return h; } /* converts a UTF-16 literal to UTF-8 * A literal can be one or two sequences of the form \uXXXX */ static unsigned char utf16_literal_to_utf8(const unsigned char *const input_pointer, const unsigned char *const input_end, unsigned char **output_pointer) { long unsigned int codepoint = 0; unsigned int first_code = 0; const unsigned char *first_sequence = input_pointer; unsigned char utf8_length = 0; unsigned char utf8_position = 0; unsigned char sequence_length = 0; unsigned char first_byte_mark = 0; if ((input_end - first_sequence) < 6) { /* input ends unexpectedly */ goto fail; } /* get the first utf16 sequence */ first_code = parse_hex4(first_sequence + 2); /* check that the code is valid */ if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) { goto fail; } /* UTF16 surrogate pair */ if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) { const unsigned char *second_sequence = first_sequence + 6; unsigned int second_code = 0; sequence_length = 12; /* \uXXXX\uXXXX */ if ((input_end - second_sequence) < 6) { /* input ends unexpectedly */ goto fail; } if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) { /* missing second half of the surrogate pair */ goto fail; } /* get the second utf16 sequence */ second_code = parse_hex4(second_sequence + 2); /* check that the code is valid */ if ((second_code < 0xDC00) || (second_code > 0xDFFF)) { /* invalid second half of the surrogate pair */ goto fail; } /* calculate the unicode codepoint from the surrogate pair */ codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); } else { sequence_length = 6; /* \uXXXX */ codepoint = first_code; } /* encode as UTF-8 * takes at maximum 4 bytes to encode: * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ if (codepoint < 0x80) { /* normal ascii, encoding 0xxxxxxx */ utf8_length = 1; } else if (codepoint < 0x800) { /* two bytes, encoding 110xxxxx 10xxxxxx */ utf8_length = 2; first_byte_mark = 0xC0; /* 11000000 */ } else if (codepoint < 0x10000) { /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ utf8_length = 3; first_byte_mark = 0xE0; /* 11100000 */ } else if (codepoint <= 0x10FFFF) { /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ utf8_length = 4; first_byte_mark = 0xF0; /* 11110000 */ } else { /* invalid unicode codepoint */ goto fail; } /* encode as utf8 */ for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) { /* 10xxxxxx */ (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); codepoint >>= 6; } /* encode first byte */ if (utf8_length > 1) { (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); } else { (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); } *output_pointer += utf8_length; return sequence_length; fail: return 0; } /* Parse the input text into an unescaped cinput, and populate item. */ static cJSON_bool parse_string(cJSON *const item, parse_buffer *const input_buffer) { const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; unsigned char *output_pointer = NULL; unsigned char *output = NULL; /* not a string */ if (buffer_at_offset(input_buffer)[0] != '\"') { goto fail; } { /* calculate approximate size of the output (overestimate) */ size_t allocation_length = 0; size_t skipped_bytes = 0; while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) { /* is escape sequence */ if (input_end[0] == '\\') { if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) { /* prevent buffer overflow when last input character is a backslash */ goto fail; } skipped_bytes++; input_end++; } input_end++; } if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) { goto fail; /* string ended unexpectedly */ } /* This is at most how much we need for the output */ allocation_length = (size_t)(input_end - buffer_at_offset( input_buffer)) - skipped_bytes; output = (unsigned char *)input_buffer->hooks.allocate(allocation_length + sizeof("")); if (output == NULL) { goto fail; /* allocation failure */ } } output_pointer = output; /* loop through the string literal */ while (input_pointer < input_end) { if (*input_pointer != '\\') { *output_pointer++ = *input_pointer++; } /* escape sequence */ else { unsigned char sequence_length = 2; if ((input_end - input_pointer) < 1) { goto fail; } switch (input_pointer[1]) { case 'b': *output_pointer++ = '\b'; break; case 'f': *output_pointer++ = '\f'; break; case 'n': *output_pointer++ = '\n'; break; case 'r': *output_pointer++ = '\r'; break; case 't': *output_pointer++ = '\t'; break; case '\"': case '\\': case '/': *output_pointer++ = input_pointer[1]; break; /* UTF-16 literal */ case 'u': sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); if (sequence_length == 0) { /* failed to convert UTF16-literal to UTF-8 */ goto fail; } break; default: goto fail; } input_pointer += sequence_length; } } /* zero terminate the output */ *output_pointer = '\0'; item->type = cJSON_String; item->valuestring = (char *)output; input_buffer->offset = (size_t)(input_end - input_buffer->content); input_buffer->offset++; return true; fail: if (output != NULL) { input_buffer->hooks.deallocate(output); } if (input_pointer != NULL) { input_buffer->offset = (size_t)(input_pointer - input_buffer->content); } return false; } /* Render the cstring provided to an escaped version that can be printed. */ static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer) { const unsigned char *input_pointer = NULL; unsigned char *output = NULL; unsigned char *output_pointer = NULL; size_t output_length = 0; /* numbers of additional characters needed for escaping */ size_t escape_characters = 0; if (output_buffer == NULL) { return false; } /* empty string */ if (input == NULL) { output = ensure(output_buffer, sizeof("\"\"")); if (output == NULL) { return false; } strcpy((char *)output, "\"\""); return true; } /* set "flag" to 1 if something needs to be escaped */ for (input_pointer = input; *input_pointer; input_pointer++) { switch (*input_pointer) { case '\"': case '\\': case '\b': case '\f': case '\n': case '\r': case '\t': /* one character escape sequence */ escape_characters++; break; default: if (*input_pointer < 32) { /* UTF-16 escape sequence uXXXX */ escape_characters += 5; } break; } } output_length = (size_t)(input_pointer - input) + escape_characters; output = ensure(output_buffer, output_length + sizeof("\"\"")); if (output == NULL) { return false; } /* no characters have to be escaped */ if (escape_characters == 0) { output[0] = '\"'; memcpy(output + 1, input, output_length); output[output_length + 1] = '\"'; output[output_length + 2] = '\0'; return true; } output[0] = '\"'; output_pointer = output + 1; /* copy the string */ for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) { if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) { /* normal character, copy */ *output_pointer = *input_pointer; } else { /* character needs to be escaped */ *output_pointer++ = '\\'; switch (*input_pointer) { case '\\': *output_pointer = '\\'; break; case '\"': *output_pointer = '\"'; break; case '\b': *output_pointer = 'b'; break; case '\f': *output_pointer = 'f'; break; case '\n': *output_pointer = 'n'; break; case '\r': *output_pointer = 'r'; break; case '\t': *output_pointer = 't'; break; default: /* escape and print as unicode codepoint */ sprintf((char *)output_pointer, "u%04x", *input_pointer); output_pointer += 4; break; } } } output[output_length + 1] = '\"'; output[output_length + 2] = '\0'; return true; } /* Invoke print_string_ptr (which is useful) on an item. */ static cJSON_bool print_string(const cJSON *const item, printbuffer *const p) { return print_string_ptr((unsigned char *)item->valuestring, p); } /* Predeclare these prototypes. */ static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer); static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer); static cJSON_bool parse_array(cJSON *const item, parse_buffer *const input_buffer); static cJSON_bool print_array(const cJSON *const item, printbuffer *const output_buffer); static cJSON_bool parse_object(cJSON *const item, parse_buffer *const input_buffer); static cJSON_bool print_object(const cJSON *const item, printbuffer *const output_buffer); /* Utility to jump whitespace and cr/lf */ static parse_buffer *buffer_skip_whitespace(parse_buffer *const buffer) { if ((buffer == NULL) || (buffer->content == NULL)) { return NULL; } if (cannot_access_at_index(buffer, 0)) { return buffer; } while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) { buffer->offset++; } if (buffer->offset == buffer->length) { buffer->offset--; } return buffer; } /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ static parse_buffer *skip_utf8_bom(parse_buffer *const buffer) { if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) { return NULL; } if (can_access_at_index(buffer, 4) && (strncmp((const char *)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) { buffer->offset += 3; } return buffer; } CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) { size_t buffer_length; if (NULL == value) { return NULL; } /* Adding null character size due to require_null_terminated. */ buffer_length = strlen(value) + sizeof(""); return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); } /* Parse an object - create a new root, and populate. */ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) { parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; cJSON *item = NULL; /* reset error position */ global_error.json = NULL; global_error.position = 0; if (value == NULL || 0 == buffer_length) { goto fail; } buffer.content = (const unsigned char *)value; buffer.length = buffer_length; buffer.offset = 0; buffer.hooks = global_hooks; item = cJSON_New_Item(&global_hooks); if (item == NULL) /* memory fail */ { goto fail; } if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) { /* parse failure. ep is set. */ goto fail; } /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ if (require_null_terminated) { buffer_skip_whitespace(&buffer); if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') { goto fail; } } if (return_parse_end) { *return_parse_end = (const char *)buffer_at_offset(&buffer); } return item; fail: if (item != NULL) { cJSON_Delete(item); } if (value != NULL) { error local_error; local_error.json = (const unsigned char *)value; local_error.position = 0; if (buffer.offset < buffer.length) { local_error.position = buffer.offset; } else if (buffer.length > 0) { local_error.position = buffer.length - 1; } if (return_parse_end != NULL) { *return_parse_end = (const char *)local_error.json + local_error.position; } global_error = local_error; } return NULL; } /* Default options for cJSON_Parse */ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) { return cJSON_ParseWithOpts(value, 0, 0); } CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) { return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); } #define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) static unsigned char *print(const cJSON *const item, cJSON_bool format, const internal_hooks *const hooks) { static const size_t default_buffer_size = 256; printbuffer buffer[1]; unsigned char *printed = NULL; memset(buffer, 0, sizeof(buffer)); /* create buffer */ buffer->buffer = (unsigned char *) hooks->allocate(default_buffer_size); buffer->length = default_buffer_size; buffer->format = format; buffer->hooks = *hooks; if (buffer->buffer == NULL) { goto fail; } /* print the value */ if (!print_value(item, buffer)) { goto fail; } update_offset(buffer); /* check if reallocate is available */ if (hooks->reallocate != NULL) { printed = (unsigned char *) hooks->reallocate(buffer->buffer, buffer->offset + 1); if (printed == NULL) { goto fail; } buffer->buffer = NULL; } else /* otherwise copy the JSON over to a new buffer */ { printed = (unsigned char *) hooks->allocate(buffer->offset + 1); if (printed == NULL) { goto fail; } memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); printed[buffer->offset] = '\0'; /* just to be sure */ /* free the buffer */ hooks->deallocate(buffer->buffer); } return printed; fail: if (buffer->buffer != NULL) { hooks->deallocate(buffer->buffer); } if (printed != NULL) { hooks->deallocate(printed); } return NULL; } /* Render a cJSON item/entity/structure to text. */ CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) { return (char *)print(item, true, &global_hooks); } CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) { return (char *)print(item, false, &global_hooks); } CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) { printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; if (prebuffer < 0) { return NULL; } p.buffer = (unsigned char *)global_hooks.allocate((size_t)prebuffer); if (!p.buffer) { return NULL; } p.length = (size_t)prebuffer; p.offset = 0; p.noalloc = false; p.format = fmt; p.hooks = global_hooks; if (!print_value(item, &p)) { global_hooks.deallocate(p.buffer); return NULL; } return (char *)p.buffer; } CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) { printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; if ((length < 0) || (buffer == NULL)) { return false; } p.buffer = (unsigned char *)buffer; p.length = (size_t)length; p.offset = 0; p.noalloc = true; p.format = format; p.hooks = global_hooks; return print_value(item, &p); } /* Parser core - when encountering text, process appropriately. */ static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer) { if ((input_buffer == NULL) || (input_buffer->content == NULL)) { return false; /* no input */ } /* parse the different types of values */ /* null */ if (can_read(input_buffer, 4) && (strncmp((const char *)buffer_at_offset(input_buffer), "null", 4) == 0)) { item->type = cJSON_NULL; input_buffer->offset += 4; return true; } /* false */ if (can_read(input_buffer, 5) && (strncmp((const char *)buffer_at_offset(input_buffer), "false", 5) == 0)) { item->type = cJSON_False; input_buffer->offset += 5; return true; } /* true */ if (can_read(input_buffer, 4) && (strncmp((const char *)buffer_at_offset(input_buffer), "true", 4) == 0)) { item->type = cJSON_True; item->valueint = 1; input_buffer->offset += 4; return true; } /* string */ if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) { return parse_string(item, input_buffer); } /* number */ if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) { return parse_number(item, input_buffer); } /* array */ if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) { return parse_array(item, input_buffer); } /* object */ if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) { return parse_object(item, input_buffer); } return false; } /* Render a value to text. */ static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer) { unsigned char *output = NULL; if ((item == NULL) || (output_buffer == NULL)) { return false; } switch ((item->type) & 0xFF) { case cJSON_NULL: output = ensure(output_buffer, 5); if (output == NULL) { return false; } strcpy((char *)output, "null"); return true; case cJSON_False: output = ensure(output_buffer, 6); if (output == NULL) { return false; } strcpy((char *)output, "false"); return true; case cJSON_True: output = ensure(output_buffer, 5); if (output == NULL) { return false; } strcpy((char *)output, "true"); return true; case cJSON_Number: return print_number(item, output_buffer); case cJSON_Raw: { size_t raw_length = 0; if (item->valuestring == NULL) { return false; } raw_length = strlen(item->valuestring) + sizeof(""); output = ensure(output_buffer, raw_length); if (output == NULL) { return false; } memcpy(output, item->valuestring, raw_length); return true; } case cJSON_String: return print_string(item, output_buffer); case cJSON_Array: return print_array(item, output_buffer); case cJSON_Object: return print_object(item, output_buffer); default: return false; } } /* Build an array from input text. */ static cJSON_bool parse_array(cJSON *const item, parse_buffer *const input_buffer) { cJSON *head = NULL; /* head of the linked list */ cJSON *current_item = NULL; if (input_buffer->depth >= CJSON_NESTING_LIMIT) { return false; /* to deeply nested */ } input_buffer->depth++; if (buffer_at_offset(input_buffer)[0] != '[') { /* not an array */ goto fail; } input_buffer->offset++; buffer_skip_whitespace(input_buffer); if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) { /* empty array */ goto success; } /* check if we skipped to the end of the buffer */ if (cannot_access_at_index(input_buffer, 0)) { input_buffer->offset--; goto fail; } /* step back to character in front of the first element */ input_buffer->offset--; /* loop through the comma separated array elements */ do { /* allocate next item */ cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); if (new_item == NULL) { goto fail; /* allocation failure */ } /* attach next item to list */ if (head == NULL) { /* start the linked list */ current_item = head = new_item; } else { /* add to the end and advance */ current_item->next = new_item; new_item->prev = current_item; current_item = new_item; } /* parse next value */ input_buffer->offset++; buffer_skip_whitespace(input_buffer); if (!parse_value(current_item, input_buffer)) { goto fail; /* failed to parse value */ } buffer_skip_whitespace(input_buffer); } while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') { goto fail; /* expected end of array */ } success: input_buffer->depth--; if (head != NULL) { head->prev = current_item; } item->type = cJSON_Array; item->child = head; input_buffer->offset++; return true; fail: if (head != NULL) { cJSON_Delete(head); } return false; } /* Render an array to text */ static cJSON_bool print_array(const cJSON *const item, printbuffer *const output_buffer) { unsigned char *output_pointer = NULL; size_t length = 0; cJSON *current_element = item->child; if (output_buffer == NULL) { return false; } /* Compose the output array. */ /* opening square bracket */ output_pointer = ensure(output_buffer, 1); if (output_pointer == NULL) { return false; } *output_pointer = '['; output_buffer->offset++; output_buffer->depth++; while (current_element != NULL) { if (!print_value(current_element, output_buffer)) { return false; } update_offset(output_buffer); if (current_element->next) { length = (size_t)(output_buffer->format ? 2 : 1); output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { return false; } *output_pointer++ = ','; if (output_buffer->format) { *output_pointer++ = ' '; } *output_pointer = '\0'; output_buffer->offset += length; } current_element = current_element->next; } output_pointer = ensure(output_buffer, 2); if (output_pointer == NULL) { return false; } *output_pointer++ = ']'; *output_pointer = '\0'; output_buffer->depth--; return true; } /* Build an object from the text. */ static cJSON_bool parse_object(cJSON *const item, parse_buffer *const input_buffer) { cJSON *head = NULL; /* linked list head */ cJSON *current_item = NULL; if (input_buffer->depth >= CJSON_NESTING_LIMIT) { return false; /* to deeply nested */ } input_buffer->depth++; if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) { goto fail; /* not an object */ } input_buffer->offset++; buffer_skip_whitespace(input_buffer); if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) { goto success; /* empty object */ } /* check if we skipped to the end of the buffer */ if (cannot_access_at_index(input_buffer, 0)) { input_buffer->offset--; goto fail; } /* step back to character in front of the first element */ input_buffer->offset--; /* loop through the comma separated array elements */ do { /* allocate next item */ cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); if (new_item == NULL) { goto fail; /* allocation failure */ } /* attach next item to list */ if (head == NULL) { /* start the linked list */ current_item = head = new_item; } else { /* add to the end and advance */ current_item->next = new_item; new_item->prev = current_item; current_item = new_item; } /* parse the name of the child */ input_buffer->offset++; buffer_skip_whitespace(input_buffer); if (!parse_string(current_item, input_buffer)) { goto fail; /* failed to parse name */ } buffer_skip_whitespace(input_buffer); /* swap valuestring and string, because we parsed the name */ current_item->string = current_item->valuestring; current_item->valuestring = NULL; if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) { goto fail; /* invalid object */ } /* parse the value */ input_buffer->offset++; buffer_skip_whitespace(input_buffer); if (!parse_value(current_item, input_buffer)) { goto fail; /* failed to parse value */ } buffer_skip_whitespace(input_buffer); } while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) { goto fail; /* expected end of object */ } success: input_buffer->depth--; if (head != NULL) { head->prev = current_item; } item->type = cJSON_Object; item->child = head; input_buffer->offset++; return true; fail: if (head != NULL) { cJSON_Delete(head); } return false; } /* Render an object to text. */ static cJSON_bool print_object(const cJSON *const item, printbuffer *const output_buffer) { unsigned char *output_pointer = NULL; size_t length = 0; cJSON *current_item = item->child; if (output_buffer == NULL) { return false; } /* Compose the output: */ length = (size_t)(output_buffer->format ? 2 : 1); /* fmt: {\n */ output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { return false; } *output_pointer++ = '{'; output_buffer->depth++; if (output_buffer->format) { *output_pointer++ = '\n'; } output_buffer->offset += length; while (current_item) { if (output_buffer->format) { size_t i; output_pointer = ensure(output_buffer, output_buffer->depth); if (output_pointer == NULL) { return false; } for (i = 0; i < output_buffer->depth; i++) { *output_pointer++ = '\t'; } output_buffer->offset += output_buffer->depth; } /* print key */ if (!print_string_ptr((unsigned char *)current_item->string, output_buffer)) { return false; } update_offset(output_buffer); length = (size_t)(output_buffer->format ? 2 : 1); output_pointer = ensure(output_buffer, length); if (output_pointer == NULL) { return false; } *output_pointer++ = ':'; if (output_buffer->format) { *output_pointer++ = '\t'; } output_buffer->offset += length; /* print value */ if (!print_value(current_item, output_buffer)) { return false; } update_offset(output_buffer); /* print comma if not last */ length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)( current_item->next ? 1 : 0)); output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { return false; } if (current_item->next) { *output_pointer++ = ','; } if (output_buffer->format) { *output_pointer++ = '\n'; } *output_pointer = '\0'; output_buffer->offset += length; current_item = current_item->next; } output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); if (output_pointer == NULL) { return false; } if (output_buffer->format) { size_t i; for (i = 0; i < (output_buffer->depth - 1); i++) { *output_pointer++ = '\t'; } } *output_pointer++ = '}'; *output_pointer = '\0'; output_buffer->depth--; return true; } /* Get Array size/item / object item. */ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) { cJSON *child = NULL; size_t size = 0; if (array == NULL) { return 0; } child = array->child; while (child != NULL) { size++; child = child->next; } /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ return (int)size; } static cJSON *get_array_item(const cJSON *array, size_t index) { cJSON *current_child = NULL; if (array == NULL) { return NULL; } current_child = array->child; while ((current_child != NULL) && (index > 0)) { index--; current_child = current_child->next; } return current_child; } CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) { if (index < 0) { return NULL; } return get_array_item(array, (size_t)index); } static cJSON *get_object_item(const cJSON *const object, const char *const name, const cJSON_bool case_sensitive) { cJSON *current_element = NULL; if ((object == NULL) || (name == NULL)) { return NULL; } current_element = object->child; if (case_sensitive) { while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) { current_element = current_element->next; } } else { while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char *)name, (const unsigned char *)(current_element->string)) != 0)) { current_element = current_element->next; } } if ((current_element == NULL) || (current_element->string == NULL)) { return NULL; } return current_element; } CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON *const object, const char *const string) { return get_object_item(object, string, false); } CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON *const object, const char *const string) { return get_object_item(object, string, true); } CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) { return cJSON_GetObjectItem(object, string) ? 1 : 0; } /* Utility for array list handling. */ static void suffix_object(cJSON *prev, cJSON *item) { prev->next = item; item->prev = prev; } /* Utility for handling references. */ static cJSON *create_reference(const cJSON *item, const internal_hooks *const hooks) { cJSON *reference = NULL; if (item == NULL) { return NULL; } reference = cJSON_New_Item(hooks); if (reference == NULL) { return NULL; } memcpy(reference, item, sizeof(cJSON)); reference->string = NULL; reference->type |= cJSON_IsReference; reference->next = reference->prev = NULL; return reference; } static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) { cJSON *child = NULL; if ((item == NULL) || (array == NULL) || (array == item)) { return false; } child = array->child; /* * To find the last item in array quickly, we use prev in array */ if (child == NULL) { /* list is empty, start new one */ array->child = item; item->prev = item; item->next = NULL; } else { /* append to the end */ if (child->prev) { suffix_object(child->prev, item); array->child->prev = item; } } return true; } /* Add item to array/object. */ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) { return add_item_to_array(array, item); } #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic push #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wcast-qual" #endif /* helper function to cast away const */ static void *cast_away_const(const void *string) { return (void *)string; } #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic pop #endif static cJSON_bool add_item_to_object(cJSON *const object, const char *const string, cJSON *const item, const internal_hooks *const hooks, const cJSON_bool constant_key) { char *new_key = NULL; int new_type = cJSON_Invalid; if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) { return false; } if (constant_key) { new_key = (char *)cast_away_const(string); new_type = item->type | cJSON_StringIsConst; } else { new_key = (char *)cJSON_strdup((const unsigned char *)string, hooks); if (new_key == NULL) { return false; } new_type = item->type & ~cJSON_StringIsConst; } if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) { hooks->deallocate(item->string); } item->string = new_key; item->type = new_type; return add_item_to_array(object, item); } CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { return add_item_to_object(object, string, item, &global_hooks, false); } /* Add an item to an object with constant string as key */ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { return add_item_to_object(object, string, item, &global_hooks, true); } CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { if (array == NULL) { return false; } return add_item_to_array(array, create_reference(item, &global_hooks)); } CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) { if ((object == NULL) || (string == NULL)) { return false; } return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); } CJSON_PUBLIC(cJSON *) cJSON_AddNullToObject(cJSON *const object, const char *const name) { cJSON *null = cJSON_CreateNull(); if (add_item_to_object(object, name, null, &global_hooks, false)) { return null; } cJSON_Delete(null); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddTrueToObject(cJSON *const object, const char *const name) { cJSON *true_item = cJSON_CreateTrue(); if (add_item_to_object(object, name, true_item, &global_hooks, false)) { return true_item; } cJSON_Delete(true_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddFalseToObject(cJSON *const object, const char *const name) { cJSON *false_item = cJSON_CreateFalse(); if (add_item_to_object(object, name, false_item, &global_hooks, false)) { return false_item; } cJSON_Delete(false_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddBoolToObject(cJSON *const object, const char *const name, const cJSON_bool boolean) { cJSON *bool_item = cJSON_CreateBool(boolean); if (add_item_to_object(object, name, bool_item, &global_hooks, false)) { return bool_item; } cJSON_Delete(bool_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddNumberToObject(cJSON *const object, const char *const name, const double number) { cJSON *number_item = cJSON_CreateNumber(number); if (add_item_to_object(object, name, number_item, &global_hooks, false)) { return number_item; } cJSON_Delete(number_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddStringToObject(cJSON *const object, const char *const name, const char *const string) { cJSON *string_item = cJSON_CreateString(string); if (add_item_to_object(object, name, string_item, &global_hooks, false)) { return string_item; } cJSON_Delete(string_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddRawToObject(cJSON *const object, const char *const name, const char *const raw) { cJSON *raw_item = cJSON_CreateRaw(raw); if (add_item_to_object(object, name, raw_item, &global_hooks, false)) { return raw_item; } cJSON_Delete(raw_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddObjectToObject(cJSON *const object, const char *const name) { cJSON *object_item = cJSON_CreateObject(); if (add_item_to_object(object, name, object_item, &global_hooks, false)) { return object_item; } cJSON_Delete(object_item); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_AddArrayToObject(cJSON *const object, const char *const name) { cJSON *array = cJSON_CreateArray(); if (add_item_to_object(object, name, array, &global_hooks, false)) { return array; } cJSON_Delete(array); return NULL; } CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item) { if ((parent == NULL) || (item == NULL)) { return NULL; } if (item != parent->child) { /* not the first element */ item->prev->next = item->next; } if (item->next != NULL) { /* not the last element */ item->next->prev = item->prev; } if (item == parent->child) { /* first element */ parent->child = item->next; } else if (item->next == NULL) { /* last element */ parent->child->prev = item->prev; } /* make sure the detached item doesn't point anywhere anymore */ item->prev = NULL; item->next = NULL; return item; } CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) { if (which < 0) { return NULL; } return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); } CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) { cJSON_Delete(cJSON_DetachItemFromArray(array, which)); } CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) { cJSON *to_detach = cJSON_GetObjectItem(object, string); return cJSON_DetachItemViaPointer(object, to_detach); } CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) { cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); return cJSON_DetachItemViaPointer(object, to_detach); } CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) { cJSON_Delete(cJSON_DetachItemFromObject(object, string)); } CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) { cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); } /* Replace array/object items with new ones. */ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) { cJSON *after_inserted = NULL; if (which < 0) { return false; } after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { return add_item_to_array(array, newitem); } newitem->next = after_inserted; newitem->prev = after_inserted->prev; after_inserted->prev = newitem; if (after_inserted == array->child) { array->child = newitem; } else { newitem->prev->next = newitem; } return true; } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item, cJSON *replacement) { if ((parent == NULL) || (replacement == NULL) || (item == NULL)) { return false; } if (replacement == item) { return true; } replacement->next = item->next; replacement->prev = item->prev; if (replacement->next != NULL) { replacement->next->prev = replacement; } if (parent->child == item) { if (parent->child->prev == parent->child) { replacement->prev = replacement; } parent->child = replacement; } else { /* * To find the last item in array quickly, we use prev in array. * We can't modify the last item's next pointer where this item was the parent's child */ if (replacement->prev != NULL) { replacement->prev->next = replacement; } if (replacement->next == NULL) { parent->child->prev = replacement; } } item->next = NULL; item->prev = NULL; cJSON_Delete(item); return true; } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) { if (which < 0) { return false; } return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); } static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) { if ((replacement == NULL) || (string == NULL)) { return false; } /* replace the name in the replacement */ if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) { cJSON_free(replacement->string); } replacement->string = (char *)cJSON_strdup((const unsigned char *)string, &global_hooks); if (replacement->string == NULL) { return false; } replacement->type &= ~cJSON_StringIsConst; return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { return replace_item_in_object(object, string, newitem, false); } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) { return replace_item_in_object(object, string, newitem, true); } /* Create basic types: */ CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_NULL; } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_True; } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_False; } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = boolean ? cJSON_True : cJSON_False; } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_Number; item->valuedouble = num; /* use saturation in case of overflow */ if (num >= INT_MAX) { item->valueint = INT_MAX; } else if (num <= (double)INT_MIN) { item->valueint = INT_MIN; } else { item->valueint = (int)num; } } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_String; item->valuestring = (char *)cJSON_strdup((const unsigned char *)string, &global_hooks); if (!item->valuestring) { cJSON_Delete(item); return NULL; } } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) { cJSON *item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_String | cJSON_IsReference; item->valuestring = (char *)cast_away_const(string); } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) { cJSON *item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_Object | cJSON_IsReference; item->child = (cJSON *)cast_away_const(child); } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { cJSON *item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_Array | cJSON_IsReference; item->child = (cJSON *)cast_away_const(child); } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_Raw; item->valuestring = (char *)cJSON_strdup((const unsigned char *)raw, &global_hooks); if (!item->valuestring) { cJSON_Delete(item); return NULL; } } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_Array; } return item; } CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) { cJSON *item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_Object; } return item; } /* Create Arrays: */ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) { size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; cJSON *a = NULL; if ((count < 0) || (numbers == NULL)) { return NULL; } a = cJSON_CreateArray(); for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if (!n) { cJSON_Delete(a); return NULL; } if (!i) { a->child = n; } else { suffix_object(p, n); } p = n; } if (a && a->child) { a->child->prev = n; } return a; } CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) { size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; cJSON *a = NULL; if ((count < 0) || (numbers == NULL)) { return NULL; } a = cJSON_CreateArray(); for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber((double)numbers[i]); if (!n) { cJSON_Delete(a); return NULL; } if (!i) { a->child = n; } else { suffix_object(p, n); } p = n; } if (a && a->child) { a->child->prev = n; } return a; } CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) { size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; cJSON *a = NULL; if ((count < 0) || (numbers == NULL)) { return NULL; } a = cJSON_CreateArray(); for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if (!n) { cJSON_Delete(a); return NULL; } if (!i) { a->child = n; } else { suffix_object(p, n); } p = n; } if (a && a->child) { a->child->prev = n; } return a; } CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) { size_t i = 0; cJSON *n = NULL; cJSON *p = NULL; cJSON *a = NULL; if ((count < 0) || (strings == NULL)) { return NULL; } a = cJSON_CreateArray(); for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateString(strings[i]); if (!n) { cJSON_Delete(a); return NULL; } if (!i) { a->child = n; } else { suffix_object(p, n); } p = n; } if (a && a->child) { a->child->prev = n; } return a; } /* Duplication */ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) { cJSON *newitem = NULL; cJSON *child = NULL; cJSON *next = NULL; cJSON *newchild = NULL; /* Bail on bad ptr */ if (!item) { goto fail; } /* Create new item */ newitem = cJSON_New_Item(&global_hooks); if (!newitem) { goto fail; } /* Copy over all vars */ newitem->type = item->type & (~cJSON_IsReference); newitem->valueint = item->valueint; newitem->valuedouble = item->valuedouble; if (item->valuestring) { newitem->valuestring = (char *)cJSON_strdup((unsigned char *)item->valuestring, &global_hooks); if (!newitem->valuestring) { goto fail; } } if (item->string) { newitem->string = (item->type & cJSON_StringIsConst) ? item->string : (char *)cJSON_strdup((unsigned char *)item->string, &global_hooks); if (!newitem->string) { goto fail; } } /* If non-recursive, then we're done! */ if (!recurse) { return newitem; } /* Walk the ->next chain for the child. */ child = item->child; while (child != NULL) { newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ if (!newchild) { goto fail; } if (next != NULL) { /* If newitem->child already set, then crosswire ->prev and ->next and move on */ next->next = newchild; newchild->prev = next; next = newchild; } else { /* Set newitem->child and move to it */ newitem->child = newchild; next = newchild; } child = child->next; } if (newitem && newitem->child) { newitem->child->prev = newchild; } return newitem; fail: if (newitem != NULL) { cJSON_Delete(newitem); } return NULL; } static void skip_oneline_comment(char **input) { *input += static_strlen("//"); for (; (*input)[0] != '\0'; ++(*input)) { if ((*input)[0] == '\n') { *input += static_strlen("\n"); return; } } } static void skip_multiline_comment(char **input) { *input += static_strlen("/*"); for (; (*input)[0] != '\0'; ++(*input)) { if (((*input)[0] == '*') && ((*input)[1] == '/')) { *input += static_strlen("*/"); return; } } } static void minify_string(char **input, char **output) { (*output)[0] = (*input)[0]; *input += static_strlen("\""); *output += static_strlen("\""); for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { (*output)[0] = (*input)[0]; if ((*input)[0] == '\"') { (*output)[0] = '\"'; *input += static_strlen("\""); *output += static_strlen("\""); return; } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { (*output)[1] = (*input)[1]; *input += static_strlen("\""); *output += static_strlen("\""); } } } CJSON_PUBLIC(void) cJSON_Minify(char *json) { char *into = json; if (json == NULL) { return; } while (json[0] != '\0') { switch (json[0]) { case ' ': case '\t': case '\r': case '\n': json++; break; case '/': if (json[1] == '/') { skip_oneline_comment(&json); } else if (json[1] == '*') { skip_multiline_comment(&json); } else { json++; } break; case '\"': minify_string(&json, (char **)&into); break; default: into[0] = json[0]; json++; into++; } } /* and null-terminate. */ *into = '\0'; } CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_Invalid; } CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_False; } CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xff) == cJSON_True; } CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & (cJSON_True | cJSON_False)) != 0; } CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_NULL; } CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_Number; } CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_String; } CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_Array; } CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_Object; } CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON *const item) { if (item == NULL) { return false; } return (item->type & 0xFF) == cJSON_Raw; } CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON *const a, const cJSON *const b, const cJSON_bool case_sensitive) { if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) { return false; } /* check if type is valid */ switch (a->type & 0xFF) { case cJSON_False: case cJSON_True: case cJSON_NULL: case cJSON_Number: case cJSON_String: case cJSON_Raw: case cJSON_Array: case cJSON_Object: break; default: return false; } /* identical objects are equal */ if (a == b) { return true; } switch (a->type & 0xFF) { /* in these cases and equal type is enough */ case cJSON_False: case cJSON_True: case cJSON_NULL: return true; case cJSON_Number: if (compare_double(a->valuedouble, b->valuedouble)) { return true; } return false; case cJSON_String: case cJSON_Raw: if ((a->valuestring == NULL) || (b->valuestring == NULL)) { return false; } if (strcmp(a->valuestring, b->valuestring) == 0) { return true; } return false; case cJSON_Array: { cJSON *a_element = a->child; cJSON *b_element = b->child; for (; (a_element != NULL) && (b_element != NULL);) { if (!cJSON_Compare(a_element, b_element, case_sensitive)) { return false; } a_element = a_element->next; b_element = b_element->next; } /* one of the arrays is longer than the other */ if (a_element != b_element) { return false; } return true; } case cJSON_Object: { cJSON *a_element = NULL; cJSON *b_element = NULL; cJSON_ArrayForEach(a_element, a) { /* TODO This has O(n^2) runtime, which is horrible! */ b_element = get_object_item(b, a_element->string, case_sensitive); if (b_element == NULL) { return false; } if (!cJSON_Compare(a_element, b_element, case_sensitive)) { return false; } } /* doing this twice, once on a and b to prevent true comparison if a subset of b * TODO: Do this the proper way, this is just a fix for now */ cJSON_ArrayForEach(b_element, b) { a_element = get_object_item(a, b_element->string, case_sensitive); if (a_element == NULL) { return false; } if (!cJSON_Compare(b_element, a_element, case_sensitive)) { return false; } } return true; } default: return false; } } CJSON_PUBLIC(void *) cJSON_malloc(size_t size) { return global_hooks.allocate(size); } CJSON_PUBLIC(void) cJSON_free(void *object) { global_hooks.deallocate(object); } hamlib-4.6.5/lib/Makefile.in0000664000175000017500000005577415056640452011311 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libmisc_la_DEPENDENCIES = $(LTLIBOBJS) $(am__DEPENDENCIES_1) am_libmisc_la_OBJECTS = cJSON.lo asyncpipe.lo precise_time.lo libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = $(DEPDIR)/dummy.Plo $(DEPDIR)/getaddrinfo.Plo \ $(DEPDIR)/getopt.Plo $(DEPDIR)/getopt_long.Plo \ $(DEPDIR)/gettimeofday.Plo $(DEPDIR)/termios.Plo \ $(DEPDIR)/usleep.Plo ./$(DEPDIR)/asyncpipe.Plo \ ./$(DEPDIR)/cJSON.Plo ./$(DEPDIR)/precise_time.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libmisc_la_SOURCES) DIST_SOURCES = $(libmisc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp dummy.c getaddrinfo.c getopt.c \ getopt_long.c gettimeofday.c termios.c usleep.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = getopt.c getopt.h getopt_long.c usleep.c \ termios.c win32termios.h gettimeofday.c getaddrinfo.c noinst_LTLIBRARIES = libmisc.la libmisc_la_SOURCES = cJSON.c cJSON.h asyncpipe.c asyncpipe.h precise_time.c libmisc_la_LIBADD = $(LTLIBOBJS) $(NET_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libmisc.la: $(libmisc_la_OBJECTS) $(libmisc_la_DEPENDENCIES) $(EXTRA_libmisc_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libmisc_la_OBJECTS) $(libmisc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getopt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getopt_long.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gettimeofday.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/termios.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/usleep.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asyncpipe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cJSON.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/precise_time.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f $(DEPDIR)/dummy.Plo -rm -f $(DEPDIR)/getaddrinfo.Plo -rm -f $(DEPDIR)/getopt.Plo -rm -f $(DEPDIR)/getopt_long.Plo -rm -f $(DEPDIR)/gettimeofday.Plo -rm -f $(DEPDIR)/termios.Plo -rm -f $(DEPDIR)/usleep.Plo -rm -f ./$(DEPDIR)/asyncpipe.Plo -rm -f ./$(DEPDIR)/cJSON.Plo -rm -f ./$(DEPDIR)/precise_time.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(DEPDIR)/dummy.Plo -rm -f $(DEPDIR)/getaddrinfo.Plo -rm -f $(DEPDIR)/getopt.Plo -rm -f $(DEPDIR)/getopt_long.Plo -rm -f $(DEPDIR)/gettimeofday.Plo -rm -f $(DEPDIR)/termios.Plo -rm -f $(DEPDIR)/usleep.Plo -rm -f ./$(DEPDIR)/asyncpipe.Plo -rm -f ./$(DEPDIR)/cJSON.Plo -rm -f ./$(DEPDIR)/precise_time.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/lib/precise_time.c0000664000175000017500000001107215056640442012036 // --------------------------------------------------------------------- // precise_time.cxx // // Copyright (C) 2023 // Dave Freese, W1HKJ // // This file is part of flrig // // flrig is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // flrig 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with fldigi. If not, see . // --------------------------------------------------------------------- #include #include #include #if 0 // return current tick time in seconds double monotonic_seconds() { static struct timeval t1; gettimeofday(&t1, NULL); return t1.tv_sec + t1.tv_usec / 1e6; } #else //====================================================================== // // A cross platform monotonic timer. // Copyright 2013 Alex Reece. // #include #define NANOS_PER_SECF 1000000000.0 #define USECS_PER_SEC 1000000 #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) // If we have it, use clock_gettime and CLOCK_MONOTONIC. #include static int showme = 0; double monotonic_seconds() { if (showme) { showme = 0; } struct timespec time; // Note: Make sure to link with -lrt to define clock_gettime. clock_gettime(CLOCK_MONOTONIC, &time); return ((double) time.tv_sec) + ((double) time.tv_nsec / (NANOS_PER_SECF)); } #elif defined(__APPLE__) // If we don't have CLOCK_MONOTONIC, we might be on a Mac. There we instead // use mach_absolute_time(). #include static mach_timebase_info_data_t info; static void __attribute__((constructor)) init_info() { mach_timebase_info(&info); } double monotonic_seconds() { uint64_t time = mach_absolute_time(); double dtime = (double) time; dtime *= (double) info.numer; dtime /= (double) info.denom; return dtime / NANOS_PER_SECF; } #elif defined(__WIN32__) // On Windows, use QueryPerformanceCounter and QueryPerformanceFrequency. #include static double PCFreq = 0.0; // According to http://stackoverflow.com/q/1113409/447288, this will // make this function a constructor. // TODO(awreece) Actually attempt to compile on windows. // w1hkj - builds OK on mingw32 static void __cdecl init_pcfreq(); __declspec(allocate(".CRT$XCU")) void (__cdecl *init_pcfreq_)() = init_pcfreq; static void __cdecl init_pcfreq() { // Accoring to http://stackoverflow.com/a/1739265/447288, this will // properly initialize the QueryPerformanceCounter. LARGE_INTEGER li; int has_qpc = QueryPerformanceFrequency(&li); assert(has_qpc); PCFreq = ((double) li.QuadPart) / 1000.0; } double monotonic_seconds() { LARGE_INTEGER li; QueryPerformanceCounter(&li); return ((double) li.QuadPart) / PCFreq; } #else // Fall back to rdtsc. The reason we don't use clock() is this scary message // from the man page: // "On several other implementations, the value returned by clock() also // includes the times of any children whose status has been collected via // wait(2) (or another wait-type call)." // // Also, clock() only has microsecond accuracy. // // This whitepaper offered excellent advice on how to use rdtscp for // profiling: http://download.intel.com/embedded/software/IA/324264.pdf // // Unfortunately, we can't follow its advice exactly with our semantics, // so we're just going to use rdtscp with cpuid. // // Note that rdtscp will only be available on new processors. #include static inline uint64_t rdtsc() { uint32_t hi, lo; uint64_t hi64, lo64; asm volatile("rdtscp\n" "movl %%edx, %0\n" "movl %%eax, %1\n" "cpuid" : "=r"(hi), "=r"(lo) : : "%rax", "%rbx", "%rcx", "%rdx"); hi64 = hi; lo64 = lo; return (hi64 << 32) | lo64; } static uint64_t rdtsc_per_sec = 0; static void __attribute__((constructor)) init_rdtsc_per_sec() { uint64_t before, after; before = rdtsc(); usleep(USECS_PER_SEC); after = rdtsc(); rdtsc_per_sec = after - before; } double monotonic_seconds() { if (showme) { showme = false; } return (double) rdtsc() / (double) rdtsc_per_sec; } #endif #endif hamlib-4.6.5/lib/getopt.h0000664000175000017500000001063315056640442010677 /* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ // extern int getopt (void); // do we need this for anything? #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index); extern int getopt_long_only (int argc, char *const *argv, const char *options, const struct option *longopts, int *opt_index); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ hamlib-4.6.5/lib/getopt_long.c0000664000175000017500000001112415056640442011705 /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "getopt.h" #if !__STDC__ && !defined(const) && IN_GCC #define const #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv(); #endif #ifndef NULL #define NULL 0 #endif int getopt_long(argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal(argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only(argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal(argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main(argc, argv) int argc; char **argv; { while (1) { int c; int digit_optind = 0; int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) { break; } switch (c) { case 0: printf("option %s", long_options[option_index].name); if (optarg) { printf(" with arg %s", optarg); } printf("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) { printf("digits occur in two different argv-elements.\n"); } digit_optind = this_option_optind; printf("option %c\n", c); break; case 'a': printf("option a\n"); break; case 'b': printf("option b\n"); break; case 'c': printf("option c with value `%s'\n", optarg); break; case 'd': printf("option d with value `%s'\n", optarg); break; case '?': break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) { printf("%s ", argv[optind++]); } printf("\n"); } exit(0); } #endif /* TEST */ #include "getopt.c" hamlib-4.6.5/lib/usleep.c0000664000175000017500000000343515056640442010667 /* Copyright (C) 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. 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.1 of the License, or (at your option) any later version. 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 Lesser General Public License for more details. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #ifndef HAVE_USLEEP #include #include #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H # include #endif #ifdef apollo # include # include static time_$clock_t DomainTime100mS = { 0, 100000 / 4 }; static status_$t DomainStatus; #endif /* Sleep USECONDS microseconds, or until a previously set timer goes off. */ int usleep(unsigned long useconds) { #ifdef apollo /* The usleep function does not work under the SYS5.3 environment. Use the Domain/OS time_$wait call instead. */ time_$wait(time_$relative, DomainTime100mS, &DomainStatus); #elif defined(HAVE_SSLEEP) /* Win32 */ Sleep(useconds / 1000); #else struct timeval delay; delay.tv_sec = 0; delay.tv_usec = useconds; select(0, 0, 0, 0, &delay); #endif return 0; } #endif /* !HAVE_USLEEP */ hamlib-4.6.5/lib/getaddrinfo.c0000664000175000017500000000742215056640442011660 /* * Hamlib Interface - getaddrinfo replacement * Copyright (c) 2000-2010 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Forcing WINVER in MinGW yanks in getaddrinfo(), but locks out Win95/Win98 */ /* #define WINVER 0x0501 */ #include #include #include /* Standard input/output definitions */ #include /* UNIX standard function definitions */ #include /* File control definitions */ #include /* Error number definitions */ #include #include #ifdef HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #elif HAVE_WS2TCPIP_H #include # if defined(HAVE_WSPIAPI_H) # include # endif #endif /* * Replacement for getaddrinfo. Only one addrinfo is returned. * Weak checking. * Return 0 when success, otherwise -1. */ #ifndef HAVE_GETADDRINFO int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *p; int ai_family, ai_socktype, ai_protocol, ai_flags; /* limitation: service must be non null */ if (!service) { return -1; } if (hints == NULL) { ai_family = AF_UNSPEC; ai_socktype = 0; ai_protocol = 0; ai_flags = 0; } else { ai_family = hints->ai_family; ai_socktype = hints->ai_socktype; ai_protocol = hints->ai_protocol; ai_flags = hints->ai_flags; } /* limitation: this replacement function only for IPv4 */ if (ai_family == AF_UNSPEC) { ai_family = AF_INET; } if (ai_family != AF_INET) { return -1; } p = calloc(1, sizeof(struct addrinfo)); if (!p) { return -1; } memset(p, 0, sizeof(struct addrinfo)); p->ai_family = ai_family; p->ai_socktype = ai_socktype; p->ai_protocol = ai_protocol; p->ai_addrlen = sizeof(struct sockaddr_in); p->ai_addr = calloc(1, p->ai_addrlen); if (!p->ai_addr) { free(p); return -1; } memset((char *) p->ai_addr, 0, p->ai_addrlen); ((struct sockaddr_in *)p->ai_addr)->sin_family = p->ai_family; /* limitation: the service must be a port _number_ */ ((struct sockaddr_in *)p->ai_addr)->sin_port = htons(atoi(service)); /* limitation: the node must be in numbers-and-dots notation */ if (!node && (ai_flags & AI_PASSIVE)) { ((struct sockaddr_in *)p->ai_addr)->sin_addr.s_addr = INADDR_ANY; } else { ((struct sockaddr_in *)p->ai_addr)->sin_addr.s_addr = inet_addr(node); } *res = p; return 0; } void freeaddrinfo(struct addrinfo *res) { free(res->ai_addr); free(res); } #endif /* !HAVE_GETADDRINFO */ #if !defined(HAVE_DECL_GAI_STRERROR) && !defined(gai_strerror) const char *gai_strerror(int errcode) { return strerror(errcode); } #endif /* !HAVE_DECL_GAI_STRERROR */ hamlib-4.6.5/lib/win32termios.h0000664000175000017500000003115115056640442011740 /*------------------------------------------------------------------------- | rxtx is a native interface to serial ports in java. | Copyright 1997-2002 by Trent Jarvi taj@www.linux.org.uk. | | 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.1 of the License, or (at your option) any later version. | | If you compile this program with cygwin32 tools this package falls | under the GPL. See COPYING.CYGNUS for details. | | 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 | Lesser General Public License for more details. | | 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | | This file was taken from rxtx-2.1-7pre16 and adaptated for Hamlib. --------------------------------------------------------------------------*/ #ifndef _WIN32TERMIOS_H #define _WIN32TERMIOS_H #ifndef _WIN32S_H_ #define _WIN32S_H_ #include #include #include #include #ifdef TRACE #define ENTER(x) report("entering "x" \n"); #define LEAVE(x) report("leaving "x" \n"); #else #define ENTER(x) #define LEAVE(x) #endif /* TRACE */ #define YACK() \ { \ char *allocTextBuf, message[1024]; \ unsigned int errorCode = GetLastError(); \ FormatMessage ( \ FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM, \ NULL, \ errorCode, \ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \ (LPSTR)&allocTextBuf, \ 16, \ NULL ); \ snprintf( message, sizeof (message), "Error 0x%x at %s(%d): %s\n", errorCode, __FILE__, __LINE__, allocTextBuf); \ report_error( message ); \ LocalFree(allocTextBuf); \ } typedef unsigned char cc_t; typedef int32_t speed_t; typedef int32_t tcflag_t; /* structs are from linux includes or linux man pages to match interfaces. */ #ifndef _TIMESPEC_DEFINED struct timespec { time_t tv_sec; long tv_nsec; }; #endif #define NCCS 32 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_cc[NCCS]; /* control characters */ cc_t c_line; /* line discipline (== c_cc[33]) */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; /* for TIOCGSERIAL and TIOCSSERIAL of interest are baud_base and * custom_divisor * --- NOTE: This is not used. Win32 sets custom speeds on the * kernel side. */ struct serial_struct { /* Mainly we are after baud_base/custom_diviser to match the ioctl() in SerialImp.c */ int custom_divisor; /* use to set unsupported speeds */ int baud_base; /* use to set unsupported speeds */ unsigned short close_delay, closing_wait, iomem_reg_shift; int type, line, irq, flags, xmit_fifo_size, hub6; unsigned int port, port_high; char io_type; unsigned char *iomem_base; }; struct serial_icounter_struct { int cts; /* clear to send count */ int dsr; /* data set ready count */ int rng; /* ring count */ int dcd; /* carrier detect count */ int rx; /* received byte count */ int tx; /* transmitted byte count */ int frame; /* frame error count */ int overrun; /* hardware overrun error count */ int parity; /* parity error count */ int brk; /* break count */ int buf_overrun; /* buffer overrun count */ int reserved[9]; /* unused */ }; struct termios_list { char filename[512]; int my_errno; int interrupt; int event_flag; int tx_happened; unsigned long *hComm; struct termios *ttyset; struct serial_struct *sstruct; /* for DTR DSR */ unsigned char MSR; struct async_struct *astruct; struct serial_icounter_struct *sis; int open_flags; OVERLAPPED rol; OVERLAPPED wol; OVERLAPPED sol; int fd; struct termios_list *next; struct termios_list *prev; }; int win32_serial_test( char * ); int win32_serial_open(const char *File, int flags, ... ); int win32_serial_close(int fd); int win32_serial_read(int fd, void *b, int size); int win32_serial_write(int fd, const char *Str, int length); int win32_serial_ioctl(int fd, int request, ... ); int win32_serial_fcntl(int fd, int command, ...); struct termios_list *win32_serial_find_port(int); /* * lcc winsock.h conflicts */ #ifndef __LCC__ int win32_serial_select(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *); #define SELECT win32_serial_select #endif #define OPEN win32_serial_open #define CLOSE win32_serial_close #define READ win32_serial_read #define WRITE win32_serial_write #define IOCTL win32_serial_ioctl #define FCNTL win32_serial_fcntl #if 0 /* local functions */ void termios_interrupt_event_loop( int , int ); void termios_setflags( int , int[] ); struct termios_list *find_port( int ); int usleep(unsigned int usec); const char *get_dos_port(const char *); void set_errno(int); char *sterror(int); int B_to_CBR(int); int CBR_to_B(int); int termios_to_bytesize(int); int bytesize_to_termios(int); #endif int tcgetattr(int Fd, struct termios *s_termios); int tcsetattr(int Fd, int when, struct termios *); speed_t cfgetospeed(struct termios *s_termios); speed_t cfgetispeed(struct termios *s_termios); int cfsetspeed(struct termios *, speed_t speed); int cfsetospeed(struct termios *, speed_t speed); int cfsetispeed ( struct termios *, speed_t speed); int tcflush ( int , int ); int tcgetpgrp ( int ); int tcsetpgrp ( int , int ); int tcdrain ( int ); int tcflow ( int , int ); int tcsendbreak ( int , int ); /* int fstat(int fd, ... ); */ void cfmakeraw(struct termios *s_termios); #if 0 int termiosGetParityErrorChar( int ); void termiosSetParityError( int, char ); #endif #define O_NOCTTY 0400 /* not for fcntl */ #define O_NONBLOCK 00004 #define O_NDELAY O_NONBLOCK #define O_SYNC 040000 #define O_FSYNC O_SYNC #define O_ASYNC 020000 /* fcntl, for BSD compatibility */ #define F_DUPFD 0 /* dup */ #define F_GETFD 1 /* get f_flags */ #define F_SETFD 2 /* set f_flags */ #define F_GETFL 3 /* more flags (cloexec) */ #define F_SETFL 4 #define F_GETLK 7 #define F_SETLK 8 #define F_SETLKW 9 #define F_SETOWN 5 /* for sockets. */ #define F_GETOWN 6 /* for sockets. */ /* for F_[GET|SET]FL */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ /* for posix fcntl() and lockf() */ #define F_RDLCK 1 #define F_WRLCK 2 #define F_UNLCK 8 /* for old implementation of bsd flock () */ #define F_EXLCK 16 /* or 3 */ #define F_SHLCK 32 /* or 4 */ /* operations for bsd flock(), also used by the kernel implementation */ #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ #define LOCK_NB 4 /* or'd with one of the above to prevent blocking */ #define LOCK_UN 8 /* remove lock */ /* c_cc characters */ #define VINTR 0 #define VQUIT 1 #define VERASE 2 #define VKILL 3 #define VEOF 4 #define VTIME 5 #define VMIN 6 #define VSWTC 7 #define VSTART 8 #define VSTOP 9 #define VSUSP 10 #define VEOL 11 #define VREPRINT 12 #define VDISCARD 13 #define VWERASE 14 #define VLNEXT 15 #define VEOL2 16 /* c_iflag bits */ #define IGNBRK 0000001 #define BRKINT 0000002 #define IGNPAR 0000004 #define PARMRK 0000010 #define INPCK 0000020 #define ISTRIP 0000040 #define INLCR 0000100 #define IGNCR 0000200 #define ICRNL 0000400 #define IXON 0002000 #define IXANY 0004000 #define IXOFF 0010000 #define IMAXBEL 0020000 #define CRTS_IFLOW 0040000 #define CCTS_OFLOW 0100000 #define CIGNORE 0400000 #define CRTSCTS 020000000000 /* flow control */ #define HARDWARE_FLOW_CONTROL CRTSCTS #define CRTSXOFF 010000000000 /* c_oflag bits */ #define OPOST 0000001 #define ONLCR 0000002 #define OLCUC 0000004 #define OCRNL 0000010 #define ONOCR 0000020 #define ONLRET 0000040 #define OFILL 00000100 #define OFDEL 00000200 #define NLDLY 00001400 #define NL0 00000000 #define NL1 00000400 #define NL2 00001000 #define NL3 00001400 #define TABDLY 00006000 #define TAB0 00000000 #define TAB1 00002000 #define TAB2 00004000 #define TAB3 00006000 #define CRDLY 00030000 #define CR0 00000000 #define CR1 00010000 #define CR2 00020000 #define CR3 00030000 #define FFDLY 00040000 #define FF0 00000000 #define FF1 00040000 #define BSDLY 00100000 #define BS0 00000000 #define BS1 00100000 #define VTDLY 00200000 #define VT0 00000000 #define VT1 00200000 #define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ /* c_cflag bit meaning */ # define CBAUD 0010017 #define B0 0000000 /* hang up */ #define B50 0000001 #define B75 0000002 #define B110 0000003 #define B134 0000004 #define B150 0000005 #define B200 0000006 #define B300 0000007 #define B600 0000010 #define B1200 0000011 #define B1800 0000012 #define B2400 0000013 #define B4800 0000014 #define B9600 0000015 #define B19200 0000016 #define B38400 0000017 #define B57600 0010001 #define B115200 0010002 #define B230400 0010003 #define B460800 0010004 #define B500000 0010005 #define B576000 0010006 #define B921600 0010007 #define B1000000 0010010 #define B1152000 0010011 #define B1500000 0010012 #define B2000000 0010013 #define B2500000 0010014 #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 /* glue for unsupported linux speeds see also SerialImp.h.h */ #define B14400 1010001 #define B28800 1010002 #define B128000 1010003 #define B256000 1010004 #define EXTA B19200 #define EXTB B38400 #define CSIZE 0000060 #define CS5 0000000 #define CS6 0000020 #define CS7 0000040 #define CS8 0000060 #define CSTOPB 0000100 #define CREAD 0000200 #define PARENB 0000400 #define PARODD 0001000 #define HUPCL 0002000 #define CLOCAL 0004000 # define CBAUDEX 0010000 # define CIBAUD 002003600000 /* input baud rate (not used) */ # define CRTSCTS 020000000000 /* flow control */ /* c_l flag */ #define ISIG 0000001 #define ICANON 0000002 #define XCASE 0000004 #define ECHO 0000010 #define ECHOE 0000020 #define ECHOK 0000040 #define ECHONL 0000100 #define NOFLSH 0000200 #define TOSTOP 0000400 #define ECHOCTL 0001000 #define ECHOPRT 0002000 #define ECHOKE 0004000 #define FLUSHO 0010000 #define PENDIN 0040000 #define IEXTEN 0100000 /* glue for unsupported windows speeds */ #define CBR_230400 230400 #define CBR_28800 28800 #define CBR_460800 460800 #define CBR_500000 500000 #define CBR_576000 576000 #define CBR_921600 921600 #define CBR_1000000 1000000 #define CBR_1152000 1152000 #define CBR_1500000 1500000 #define CBR_2000000 2000000 #define CBR_2500000 2500000 #define CBR_3000000 3000000 #define CBR_3500000 3500000 #define CBR_4000000 4000000 /* Values for the ACTION argument to `tcflow'. */ #define TCOOFF 0 #define TCOON 1 #define TCIOFF 2 #define TCION 3 /* Values for the QUEUE_SELECTOR argument to `tcflush'. */ #define TCIFLUSH 0 #define TCOFLUSH 1 #define TCIOFLUSH 2 /* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ #define TCSANOW 0 #define TCSADRAIN 1 #define TCSAFLUSH 2 /* ioctls */ #define TIOCSERGETLSR 0x5459 #endif /*_WIN32S_H_*/ /* unused ioctls */ #define TCSBRK 0x5409 #define TIOCCBRK 0x540a #define TIOCSBRK 0x540b #define TIOCOUTQ 0x5411 #define TIOCMGET 0x5415 #define TIOCMBIS 0x5416 #define TIOCMBIC 0x5417 #define TIOCMSET 0x5418 #define TIOCGSOFTCAR 0x5419 #define TIOCSSOFTCAR 0x541a #define TIOCSER_TEMP 0x01 /* #define FIONREAD 0x541b TIOC[GS]SERIAL is not used on win32. It was dropped after we could not find a way to get/set buad_base and divisor directly. #define TIOCGSERIAL 0x541e #define TIOCSSERIAL 0x541f */ #define TCSBRKP 0x5425 #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 #define TIOCSERSWILD 0x5455 #define TIOCSERGSTRUCT 0x5458 #define TIOCSERGETMULTI 0x545a #define TIOCSERSETMULTI 0x545b #define TIOCMIWAIT 0x545c /* this would require being able to get the number of overruns ... */ /* FIXME frame and parity errors caused crashes in testing BlackBox */ #define TIOCGICOUNT 0x545d /* ioctl errors */ #define ENOIOCTLCMD 515 #define EBADFD 77 /* modem lines */ #define TIOCM_LE 0x001 #define TIOCM_DTR 0x002 #define TIOCM_RTS 0x004 #define TIOCM_ST 0x008 #define TIOCM_SR 0x010 #define TIOCM_CTS 0x020 #define TIOCM_CAR 0x040 #define TIOCM_RNG 0x080 #define TIOCM_DSR 0x100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RI TIOCM_RNG #define CMSPAR 010000000000 /* mark or space parity */ #endif /* _WIN32TERMIOS_H */ hamlib-4.6.5/lib/gettimeofday.c0000664000175000017500000000067315056640442012054 #include #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H # include #endif #ifdef HAVE_SYS_TIME_H #include #endif /* * broken implementation for WIN32. * FIXME: usec precision */ int gettimeofday(struct timeval *tv, struct timezone *tz) { if (tv) { time_t tm; time(&tm); tv->tv_sec = tm; tv->tv_usec = 0; } return 0; } hamlib-4.6.5/lib/getopt.c0000664000175000017500000005754015056640442010702 /* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* NOTE!!! AIX requires this to be the first thing in the file. Do not put ANYTHING before it! */ #include #if !__STDC__ && !defined(const) && IN_GCC #define const #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv(); static char * my_index(str, chr) const char *str; int chr; { while (*str) { if (*str == chr) { return (char *) str; } str++; } return 0; } static void my_bcopy(from, to, size) const char *from; char *to; int size; { int i; for (i = 0; i < size; i++) { to[i] = from[i]; } } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange(argv) char **argv; { int nonopts_size = (last_nonopt - first_nonopt) * sizeof(char *); char **temp = (char **) calloc(1, nonopts_size); /* Interchange the two blocks of data in ARGV. */ my_bcopy((char *) &argv[first_nonopt], (char *) temp, nonopts_size); my_bcopy((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], (optind - last_nonopt) * sizeof(char *)); my_bcopy((char *) temp, (char *) &argv[first_nonopt + optind - last_nonopt], nonopts_size); /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; free(temp); } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal(argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv("POSIXLY_CORRECT") != NULL) { ordering = REQUIRE_ORDER; } else { ordering = PERMUTE; } } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) { exchange((char **) argv); } else if (last_nonopt != optind) { first_nonopt = optind; } /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { optind++; } last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp(argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) { exchange((char **) argv); } else if (first_nonopt == last_nonopt) { first_nonopt = optind; } last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) { optind = first_nonopt; } return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) { return EOF; } optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound = 0; int option_index; while (*s && *s != '=') { s++; } /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp(p->name, nextchar, s - nextchar)) { if (s - nextchar == strlen(p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ { ambig = 1; } } if (ambig && !exact) { if (opterr) fprintf(stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen(nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) { optarg = s + 1; } else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen(nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) { optarg = argv[optind++]; } else { if (opterr) fprintf(stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen(nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen(nextchar); if (longind != NULL) { *longind = option_index; } if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index(optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf(stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf(stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index(optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') { ++optind; } if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf(stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else { fprintf(stderr, "%s: unrecognized option `-%c'\n", argv[0], c); } #else /* 1003.2 specifies the format of this message. */ fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else { optarg = 0; } nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf(stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') { c = ':'; } else { c = '?'; } } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ { optarg = argv[optind++]; } nextchar = NULL; } } return c; } } #ifdef GETOPT int getopt(argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal(argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main(argc, argv) int argc; char **argv; { while (1) { int c; int digit_optind = 0; int this_option_optind = optind ? optind : 1; c = getopt(argc, argv, "abc:d:0123456789"); if (c == EOF) { break; } switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) { printf("digits occur in two different argv-elements.\n"); } digit_optind = this_option_optind; printf("option %c\n", c); break; case 'a': printf("option a\n"); break; case 'b': printf("option b\n"); break; case 'c': printf("option c with value `%s'\n", optarg); break; case '?': break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) { printf("%s ", argv[optind++]); } printf("\n"); } exit(0); } #endif /* TEST */ hamlib-4.6.5/lib/asyncpipe.c0000664000175000017500000002040015056640442011354 #include #include "asyncpipe.h" #if defined(WIN32) && defined(HAVE_WINDOWS_H) static volatile long pipe_serial_nunber; int async_pipe_create(hamlib_async_pipe_t **pipe_out, unsigned long pipe_buffer_size, unsigned long pipe_connect_timeout_millis) { DWORD error_code; CHAR pipe_name[MAX_PATH]; hamlib_async_pipe_t *pipe; pipe = calloc(1, sizeof(hamlib_async_pipe_t)); if (pipe == NULL) { return -RIG_ENOMEM; } if (pipe_buffer_size == 0) { pipe_buffer_size = PIPE_BUFFER_SIZE_DEFAULT; } SNPRINTF(pipe_name, sizeof(pipe_name), "\\\\.\\Pipe\\Hamlib.%08lx.%08lx", GetCurrentProcessId(), InterlockedIncrement(&pipe_serial_nunber) ); pipe->read = CreateNamedPipe( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, // Number of pipes pipe_buffer_size, // Out buffer size pipe_buffer_size, // In buffer size pipe_connect_timeout_millis, // Timeout in ms NULL); if (!pipe->read) { free(pipe); return -RIG_EINTERNAL; } pipe->write = CreateFile( pipe_name, GENERIC_WRITE, 0, // No sharing NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL // Template file ); if (pipe->write == INVALID_HANDLE_VALUE) { error_code = GetLastError(); CloseHandle(pipe->read); free(pipe); SetLastError(error_code); return -RIG_EINTERNAL; } pipe->read_overlapped.hEvent = CreateEvent( NULL, // default security attribute TRUE, // manual-reset event FALSE, // initial state = not signaled NULL); // unnamed event object if (pipe->read_overlapped.hEvent == NULL) { error_code = GetLastError(); CloseHandle(pipe->read); CloseHandle(pipe->write); free(pipe); SetLastError(error_code); return -RIG_EINTERNAL; } pipe->write_overlapped.hEvent = CreateEvent( NULL, // default security attribute TRUE, // manual-reset event FALSE, // initial state = not signaled NULL); // unnamed event object if (pipe->write_overlapped.hEvent == NULL) { error_code = GetLastError(); CloseHandle(pipe->read_overlapped.hEvent); CloseHandle(pipe->read); CloseHandle(pipe->write); free(pipe); SetLastError(error_code); return -RIG_EINTERNAL; } *pipe_out = pipe; return RIG_OK; } void async_pipe_close(hamlib_async_pipe_t *pipe) { if (pipe->read != NULL) { CloseHandle(pipe->read); pipe->read = NULL; } if (pipe->write != NULL) { CloseHandle(pipe->write); pipe->write = NULL; } if (pipe->read_overlapped.hEvent != NULL) { CloseHandle(pipe->read_overlapped.hEvent); pipe->read_overlapped.hEvent = NULL; } if (pipe->write_overlapped.hEvent != NULL) { CloseHandle(pipe->write_overlapped.hEvent); pipe->write_overlapped.hEvent = NULL; } free(pipe); } ssize_t async_pipe_read(hamlib_async_pipe_t *pipe, void *buf, size_t count, int timeout) { HANDLE event_handles[1] = { pipe->read_overlapped.hEvent, }; HANDLE read_handle = pipe->read; LPOVERLAPPED overlapped = &pipe->read_overlapped; DWORD wait_result; int result; ssize_t bytes_read = 0; result = ReadFile(read_handle, buf, count, NULL, overlapped); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? break; case ERROR_IO_PENDING: wait_result = WaitForMultipleObjects(1, event_handles, FALSE, timeout); switch (wait_result) { case WAIT_OBJECT_0 + 0: break; case WAIT_TIMEOUT: if (count == 0) { // Zero-length reads are used to wait for incoming data, // so the I/O operation needs to be cancelled in case of a timeout CancelIo(read_handle); return -RIG_ETIMEOUT; } else { // Should not happen, as reads with count > 0 are used only when there is data available in the pipe return -RIG_EINTERNAL; } default: result = GetLastError(); rig_debug(RIG_DEBUG_ERR, "%s: WaitForMultipleObjects() error: %d\n", __func__, result); return -RIG_EINTERNAL; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: ReadFile() error: %d\n", __func__, result); return -RIG_EIO; } } result = GetOverlappedResult(read_handle, overlapped, (LPDWORD) &bytes_read, FALSE); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? break; case ERROR_IO_PENDING: // Shouldn't happen? return -RIG_ETIMEOUT; default: rig_debug(RIG_DEBUG_ERR, "%s: GetOverlappedResult() error: %d\n", __func__, result); return -RIG_EIO; } } return bytes_read; } int async_pipe_wait_for_data(hamlib_async_pipe_t *pipe, int timeout) { unsigned char data; int result; // Use a zero-length read to wait for data in pipe result = async_pipe_read(pipe, &data, 0, timeout); if (result > 0) { return RIG_OK; } return result; } ssize_t async_pipe_write(hamlib_async_pipe_t *pipe, const unsigned char *buf, size_t count, int timeout) { HANDLE event_handles[1] = { pipe->write_overlapped.hEvent, }; HANDLE write_handle = pipe->write; LPOVERLAPPED overlapped = &pipe->write_overlapped; DWORD wait_result; int result; ssize_t bytes_written = 0; result = WriteFile(write_handle, buf, count, NULL, overlapped); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? break; case ERROR_IO_PENDING: wait_result = WaitForMultipleObjects(1, event_handles, FALSE, timeout); switch (wait_result) { case WAIT_OBJECT_0 + 0: break; case WAIT_TIMEOUT: CancelIo(write_handle); return -RIG_ETIMEOUT; default: result = GetLastError(); rig_debug(RIG_DEBUG_ERR, "%s: WaitForMultipleObjects() error: %d\n", __func__, result); return -RIG_EINTERNAL; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: WriteFile() error: %d\n", __func__, result); return -RIG_EIO; } } result = GetOverlappedResult(write_handle, overlapped, (LPDWORD) &bytes_written, FALSE); if (!result) { result = GetLastError(); switch (result) { case ERROR_SUCCESS: // No error? break; case ERROR_IO_PENDING: // Shouldn't happen? return -RIG_ETIMEOUT; default: rig_debug(RIG_DEBUG_ERR, "%s: GetOverlappedResult() error: %d\n", __func__, result); return -RIG_EIO; } } return bytes_written; } #endif hamlib-4.6.5/lib/Makefile.am0000664000175000017500000000041215056640442011252 EXTRA_DIST = getopt.c getopt.h getopt_long.c usleep.c \ termios.c win32termios.h gettimeofday.c getaddrinfo.c noinst_LTLIBRARIES = libmisc.la libmisc_la_SOURCES = cJSON.c cJSON.h asyncpipe.c asyncpipe.h precise_time.c libmisc_la_LIBADD = $(LTLIBOBJS) $(NET_LIBS) hamlib-4.6.5/THANKS0000664000175000017500000000207315056640442007370 This file lists people who contributed indirectly to Hamlib, by generously making information available. Be they thanked for their openness. WiNRADiO backend ---------------- * Harish Pillay 9v1hp and Pascal Brisset and their excellent LiNRADiO project. URL: http://linradio.sourceforge.net/ Icom CI-V backend ----------------- * Ekki Plicht DF4OR and his excellent web site on the CI-V interface. URL: http://www.plicht.de/ekki/civ/ * Karl Kramer DG8FZ for his V24/CI-V cable and his CSMA/CD explanation of the bus. URL: http://KarlKramer.de/ ... x71ci_v.htm * Simon Collings, RS-232 Interfacing for Receiver Control URL: http://www.scnt01426.pwp.blueyonder.co.uk/Articles/RS-232/RS-232.htm * Kai Altenfelder for supporting us and providing documentation Icom PCR backend ---------------- * Ghetto's team, PCR-1000 ICOM receiver URL: http://www.philtered.net/icomlib.phtml Other Assistance ---------------- * Special thanks to Ed Hare, W1RFI, and the American Radio Relay League for technical support. hamlib-4.6.5/LICENSE0000664000175000017500000000463415056640442007467 Hamlib - Ham Radio Control Libraries (C) 2010 Lockless Inc. for winpthreads.h Copyright (C) 2000,2001 Frank Singleton Copyright (C) 2000,2001 Stephane Fillod Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009, 2010,2011,2012 The Hamlib Group See the included README.md file for more information on Hamlib and the Hamlib Project or visit http://www.hamlib.org for documentation and links to the source code of Hamlib. The 'AUTHORS' file lists contributors known as the The Hamlib Group. The frontend library source code files and associated backend library source code files are licensed and released under the Lesser GNU Public License (LGPL): 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.1 of the License, or (at your option) any later version. 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 Lesser General Public License for more details. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA The included file 'COPYING.LIB' is a copy of the GNU Lesser General Public License. Various other supplied program source files and example source files are licensed and released under the GNU Public License (GPL): This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. The included file 'COPYING' is a copy of the GNU General Public License. hamlib-4.6.5/Android.mk0000664000175000017500000000442215056640442010366 TOP_PATH := $(call my-dir) include $(TOP_PATH)/src/Android.mk include $(TOP_PATH)/rigs/adat/Android.mk include $(TOP_PATH)/rigs/alinco/Android.mk include $(TOP_PATH)/rigs/aor/Android.mk include $(TOP_PATH)/rigs/barrett/Android.mk include $(TOP_PATH)/rigs/dorji/Android.mk include $(TOP_PATH)/rigs/drake/Android.mk include $(TOP_PATH)/rigs/dummy/Android.mk include $(TOP_PATH)/rigs/elad/Android.mk include $(TOP_PATH)/rigs/flexradio/Android.mk include $(TOP_PATH)/rigs/icmarine/Android.mk include $(TOP_PATH)/rigs/icom/Android.mk include $(TOP_PATH)/rigs/jrc/Android.mk include $(TOP_PATH)/rigs/kachina/Android.mk include $(TOP_PATH)/rigs/kenwood/Android.mk include $(TOP_PATH)/rigs/kit/Android.mk include $(TOP_PATH)/rigs/lowe/Android.mk include $(TOP_PATH)/rigs/pcr/Android.mk include $(TOP_PATH)/rigs/prm80/Android.mk include $(TOP_PATH)/rigs/racal/Android.mk include $(TOP_PATH)/rigs/rft/Android.mk include $(TOP_PATH)/rigs/rs/Android.mk include $(TOP_PATH)/rigs/skanti/Android.mk include $(TOP_PATH)/rigs/tapr/Android.mk include $(TOP_PATH)/rigs/tentec/Android.mk include $(TOP_PATH)/rigs/tuner/Android.mk include $(TOP_PATH)/rigs/uniden/Android.mk include $(TOP_PATH)/rigs/wj/Android.mk include $(TOP_PATH)/rigs/yaesu/Android.mk include $(TOP_PATH)/rotators/amsat/Android.mk include $(TOP_PATH)/rotators/ars/Android.mk include $(TOP_PATH)/rotators/celestron/Android.mk include $(TOP_PATH)/rotators/cnctrk/Android.mk include $(TOP_PATH)/rotators/grbltrk/Android.mk include $(TOP_PATH)/rotators/easycomm/Android.mk include $(TOP_PATH)/rotators/ether6/Android.mk include $(TOP_PATH)/rotators/fodtrack/Android.mk include $(TOP_PATH)/rotators/gs232a/Android.mk include $(TOP_PATH)/rotators/heathkit/Android.mk include $(TOP_PATH)/rotators/ioptron/Android.mk include $(TOP_PATH)/rotators/m2/Android.mk include $(TOP_PATH)/rotators/meade/Android.mk include $(TOP_PATH)/rotators/prosistel/Android.mk include $(TOP_PATH)/rotators/rotorez/Android.mk include $(TOP_PATH)/rotators/sartek/Android.mk include $(TOP_PATH)/rotators/satel/Android.mk include $(TOP_PATH)/rotators/skywatcher/Android.mk include $(TOP_PATH)/rotators/spid/Android.mk include $(TOP_PATH)/rotators/ts7400/Android.mk include $(TOP_PATH)/rotators/radant/Android.mk include $(TOP_PATH)/rotators/androidsensor/Android.mk include $(TOP_PATH)/tests/Android.mk hamlib-4.6.5/tests/0000775000175000017500000000000015056640475007703 5hamlib-4.6.5/tests/dumpcaps_rot.h0000664000175000017500000000010215056640443012460 #include int dumpconf_list(ROT *rot, FILE *fout); hamlib-4.6.5/tests/testbcd.c0000664000175000017500000000253615056640443011420 /* * Very simple test program to check BCD conversion against some other --SF * This is mainly to test freq2bcd and bcd2freq functions. */ #include #include #include #include #include "misc.h" #define MAXDIGITS 32 int main(int argc, char *argv[]) { unsigned char b[(MAXDIGITS + 1) / 2]; freq_t f = 0; int digits = 10; int i; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s [digits]\n", argv[0]); exit(1); } f = (freq_t)atoll(argv[1]); if (argc > 2) { digits = atoi(argv[2]); if (digits > MAXDIGITS) { exit(1); } } printf("Little Endian mode\n"); printf("Frequency: %"PRIfreq"\n", f); to_bcd(b, f, digits); printf("BCD: %2.2x", b[0]); for (i = 1; i < (digits + 1) / 2; i++) { printf(",%2.2x", b[i]); } // cppcheck-suppress * printf("\nResult after recoding: %"PRIll"\n", (int64_t)from_bcd(b, digits)); printf("\nBig Endian mode\n"); printf("Frequency: %"PRIfreq"\n", f); to_bcd_be(b, f, digits); printf("BCD: %2.2x", b[0]); for (i = 1; i < (digits + 1) / 2; i++) { printf(",%2.2x", b[i]); } printf("\nResult after recoding: %"PRIll"\n", (int64_t)from_bcd_be(b, digits)); return 0; } hamlib-4.6.5/tests/testrigopen.c0000664000175000017500000000256515056640443012335 /* * Hamlib sample program */ #include #include #include #include #include #include #include "misc.h" #include #define SERIAL_PORT "/dev/ttyUSB0" int callback(const struct rig_caps *caps, rig_ptr_t rigp) { RIG *rig = (RIG *) rigp; rig = rig_init(caps->rig_model); if (!rig) { fprintf(stderr, "Unknown rig num: %u\n", caps->rig_model); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } const char *port = "/dev/pts/3"; rig_set_conf(rig, rig_token_lookup(rig, "rig_pathname"), port); printf("%20s:", caps->model_name); fflush(stdout); struct timeval start, end; gettimeofday(&start, NULL); rig_open(rig); gettimeofday(&end, NULL); double dstart = start.tv_sec + start.tv_usec / 1e6; double dend = end.tv_sec + end.tv_usec / (double)1e6; printf(" %.1f\n", dend - dstart); rig_close(rig); /* close port */ rig_cleanup(rig); /* if you care about memory */ return 1; } int main(int argc, char *argv[]) { RIG rig; printf("testing rig timeouts when rig powered off\n"); /* Turn off backend debugging output */ rig_set_debug_level(RIG_DEBUG_NONE); rig_load_all_backends(); rig_list_foreach(callback, &rig); return 0; } hamlib-4.6.5/tests/testgrid.c0000664000175000017500000000167215056640443011615 #include #include int main(int argc, char *argv[]) { int retval; char *grid = NULL; double lat = 0, lon = 0; switch (argc) { case 1: grid = "EM49hv"; break; case 2: grid = argv[1]; break; case 3: sscanf(argv[1], "%lg", &lat); sscanf(argv[2], "%lg", &lon); break; default: fprintf(stderr, "Unknown # of arguments...expected 1 (grid) or 2 (lat/lon)\n"); return 1; } if (grid) { retval = locator2longlat(&lon, &lat, grid); if (retval == RIG_OK) { printf("Locator %s = Lat:%g, Lon:%g\n", grid, lat, lon); } } else { char locator[24]; retval = longlat2locator(lon, lat, locator, 6); if (retval == RIG_OK) { printf("Locator lat:%g,lon:%g = %s\n", lat, lon, locator); } } return retval; } hamlib-4.6.5/tests/cachetest.c0000664000175000017500000001143015056640443011724 /* This program does a number of iterations of v f m t s * By Michael Black W9MDB * This simulates what WSJT-X and JTDX do * Used in testing caching effects that have been added * Original performance against dummy device with 20ms delays showed * about 50 calls/sec to get frequency. After caching was added can * do about 37,000 calls/sec or about 740 times faster. * To compile: * gcc -I../src -I../include -g -o cachetest cachetest.c -lhamlib * To test dummy device cache effect: * dummy without any cache -- 12 iterations per second * ./cachetest 1 "" 0 12 0 * Elapsed:Elapsed 1.004sec * * dummy with 500ms cache (default value) -- 12 iterations in 0.071sec * ./cachetest 1 "" 0 12 500 * Elapsed 0.071sec * * dummy with 5700 iterations in less than 1 second with 500ms cache * ./cachetest 1 "" 0 5700 500 * Elapsed 0.872sec * * ic-706mkiig -- no cache * ./cachetest 3011 /dev/ttyUSB0 19200 12 0 * Elapsed 1.182sec * * ic-706mkiig -- 500ms cache * ./cachetest 3011 /dev/ttyUSB0 19200 12 500 * Elapsed 0.13sec */ #include #include #include #include #include #include "sprintflst.h" #include "misc.h" int main(int argc, char *argv[]) { RIG *my_rig; char *rig_file, *info_buf; freq_t freq; int retcode; int model; int baud; int loops; int cache_timeout = 500; int i; struct timespec start, startall; if (argc < 5) { fprintf(stderr, "Usage: %s model port baud loops [cachetimems]\n", argv[0]); fprintf(stderr, "cachetimems defaults to 500ms, 0 to disable or pick your own cache time\n"); fprintf(stderr, "To test rigctld: %s 2 127.0.0.1:4532 0 1000 500\n", argv[0]); exit(1); } model = atoi(argv[1]); baud = atoi(argv[3]); loops = atoi(argv[4]); if (argc == 6) { cache_timeout = atoi(argv[5]); } rig_set_debug(RIG_DEBUG_NONE); /* Instantiate a rig */ my_rig = rig_init(model); // your rig model. /* Set up serial port, baud rate */ rig_file = argv[2]; // your serial device strncpy(RIGPORT(my_rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); RIGPORT(my_rig)->parm.serial.rate = baud; // your baud rate /* Open my rig */ retcode = rig_open(my_rig); if (retcode != RIG_OK) { fprintf(stderr, "%s: rig_open failed %s\n", __func__, rigerror(retcode)); return 1; } rig_set_cache_timeout_ms(my_rig, HAMLIB_CACHE_ALL, cache_timeout); /* Give me ID info, e.g., firmware version. */ info_buf = (char *)rig_get_info(my_rig); if (info_buf) { strtok(info_buf, "\r\n"); printf("Rig_info: '%s'\n", info_buf); } elapsed_ms(&startall, HAMLIB_ELAPSED_SET); for (i = 0; i < loops; ++i) { rmode_t mode; pbwidth_t width; vfo_t vfo; ptt_t ptt; split_t split; elapsed_ms(&start, HAMLIB_ELAPSED_SET); retcode = rig_get_vfo(my_rig, &vfo); if (retcode != RIG_OK) { printf("Get vfo failed?? Err=%s\n", rigerror(retcode)); } printf("%4dms: VFO = %s\n", (int)elapsed_ms(&start, HAMLIB_ELAPSED_GET), rig_strvfo(vfo)); elapsed_ms(&start, HAMLIB_ELAPSED_SET); retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq); if (retcode != RIG_OK) { printf("Get freq failed?? Err=%s\n", rigerror(retcode)); } printf("%4dms: VFO freq. = %.1f Hz\n", (int)elapsed_ms(&start, HAMLIB_ELAPSED_GET), freq); elapsed_ms(&start, HAMLIB_ELAPSED_SET); retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &mode, &width); if (retcode != RIG_OK) { printf("Get mode failed?? Err=%s\n", rigerror(retcode)); } printf("%4dms: Current mode = %s, width = %ld\n", (int)elapsed_ms(&start, HAMLIB_ELAPSED_GET), rig_strrmode(mode), width); elapsed_ms(&start, HAMLIB_ELAPSED_SET); retcode = rig_get_ptt(my_rig, RIG_VFO_A, &ptt); if (retcode != RIG_OK) { printf("Get ptt failed?? Err=%s\n", rigerror(retcode)); } printf("%4dms: ptt=%d\n", (int)elapsed_ms(&start, HAMLIB_ELAPSED_GET), ptt); #if 1 elapsed_ms(&start, HAMLIB_ELAPSED_SET); retcode = rig_get_split_vfo(my_rig, RIG_VFO_A, &split, &vfo); if (retcode != RIG_OK) { printf("Get split_vfo failed?? Err=%s\n", rigerror(retcode)); } printf("%4dms: split=%d, tx_vfo=%s\n", (int)elapsed_ms(&start, HAMLIB_ELAPSED_GET), split, rig_strvfo(vfo)); #endif } printf("Elapsed %gsec\n", (int)elapsed_ms(&startall, HAMLIB_ELAPSED_GET) / 1000.0); rig_close(my_rig); return 0; }; hamlib-4.6.5/tests/dumpmem.c0000664000175000017500000002257115056640443011435 /* * dumpmem.c - Copyright (C) 2001 Stephane Fillod * This programs dumps the memory contents of a rig. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include "misc.h" #define SERIAL_PORT "/dev/ttyS0" static char *decode_modes(rmode_t modes); static int dump_chan(RIG *rig, int chan_num); int main(int argc, const char *argv[]) { RIG *my_rig; int status, i, j; if (argc != 2) { fprintf(stderr, "%s \n", argv[0]); exit(1); } my_rig = rig_init(atoi(argv[1])); if (!my_rig) { fprintf(stderr, "Unknown rig num: %d\n", atoi(argv[1])); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } strncpy(RIGPORT(my_rig)->pathname, SERIAL_PORT, HAMLIB_FILPATHLEN - 1); if (rig_open(my_rig)) { exit(2); } status = rig_set_vfo(my_rig, RIG_VFO_B); if (status != RIG_OK) { printf("rig_set_vfo: error = %s \n", rigerror(status)); } /* * chan_t is used to describe what memory your rig is equipped with * cf. chan_list field in caps * Example for the Ic706MkIIG (99 memory channels, 2 scan edges, 2 call chans): * chan_t chan_list[] = { * { 1, 99, RIG_MTYPE_MEM, 0 }, * { 100, 103, RIG_MTYPE_EDGE, 0 }, * { 104, 105, RIG_MTYPE_CALL, 0 }, * RIG_CHAN_END * } */ struct rig_state *rs = STATE(my_rig); for (i = 0; rs->chan_list[i].type; i++) { for (j = rs->chan_list[i].startc; j <= rs->chan_list[i].endc; j++) { dump_chan(my_rig, j); } } rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ printf("port %s closed ok \n", SERIAL_PORT); return 0; } /* * NB: this function is not reentrant, because of the static buf. * but who cares? --SF */ static char *decode_modes(rmode_t modes) { static char buf[80]; buf[0] = '\0'; if (modes & RIG_MODE_AM) { strcat(buf, "AM "); } if (modes & RIG_MODE_CW) { strcat(buf, "CW "); } if (modes & RIG_MODE_USB) { strcat(buf, "USB "); } if (modes & RIG_MODE_LSB) { strcat(buf, "LSB "); } if (modes & RIG_MODE_RTTY) { strcat(buf, "RTTY "); } if (modes & RIG_MODE_FM) { strcat(buf, "FM "); } #ifdef RIG_MODE_WFM if (modes & RIG_MODE_WFM) { strcat(buf, "WFM "); } #endif return buf; } int dump_chan(RIG *rig, int chan_num) { channel_t chan; int status; char freqbuf[20]; chan.vfo = RIG_VFO_MEM; chan.channel_num = chan_num; status = rig_get_channel(rig, RIG_VFO_NONE, &chan, 1); if (status != RIG_OK) { printf("rig_get_channel: error = %s \n", rigerror(status)); return status; } printf("Channel: %d\n", chan.channel_num); sprintf_freq(freqbuf, sizeof(freqbuf), chan.freq); printf("Frequency: %s\n", freqbuf); printf("Mode: %s\n", decode_modes(chan.mode)); sprintf_freq(freqbuf, sizeof(freqbuf), chan.width); printf("Width: %s\n", freqbuf); printf("VFO: %s\n", rig_strvfo(chan.vfo)); printf("Split: %d\n", chan.split); sprintf_freq(freqbuf, sizeof(freqbuf), chan.tx_freq); printf("TXFrequency: %s\n", freqbuf); printf("TXMode: %s\n", decode_modes(chan.tx_mode)); sprintf_freq(freqbuf, sizeof(freqbuf), chan.tx_width); printf("TXWidth: %s\n", freqbuf); printf("Shift: %s\n", rig_strptrshift(chan.rptr_shift)); sprintf_freq(freqbuf, sizeof(freqbuf), chan.rptr_offs); printf("Offset: %s%s\n", chan.rptr_offs > 0 ? "+" : "", freqbuf); printf("Antenna: %u\n", chan.ant); sprintf_freq(freqbuf, sizeof(freqbuf), chan.tuning_step); printf("Step: %s\n", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan.rit); printf("RIT: %s%s\n", chan.rit > 0 ? "+" : "", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan.xit); printf("XIT: %s%s\n", chan.xit > 0 ? "+" : "", freqbuf); printf("CTCSS: %u.%uHz\n", chan.ctcss_tone / 10, chan.ctcss_tone % 10); printf("CTCSSsql: %u.%uHz\n", chan.ctcss_sql / 10, chan.ctcss_sql % 10); printf("DCS: %u.%u\n", chan.dcs_code / 10, chan.dcs_code % 10); printf("DCSsql: %u.%u\n", chan.dcs_sql / 10, chan.dcs_sql % 10); printf("Name: %s\n", chan.channel_desc); printf("Functions: "); if (chan.funcs != 0) { if (chan.funcs & RIG_FUNC_FAGC) { printf("FAGC "); } if (chan.funcs & RIG_FUNC_NB) { printf("NB "); } if (chan.funcs & RIG_FUNC_COMP) { printf("COMP "); } if (chan.funcs & RIG_FUNC_VOX) { printf("VOX "); } if (chan.funcs & RIG_FUNC_TONE) { printf("TONE "); } if (chan.funcs & RIG_FUNC_TSQL) { printf("TSQL "); } if (chan.funcs & RIG_FUNC_SBKIN) { printf("SBKIN "); } if (chan.funcs & RIG_FUNC_FBKIN) { printf("FBKIN "); } if (chan.funcs & RIG_FUNC_ANF) { printf("ANF "); } if (chan.funcs & RIG_FUNC_NR) { printf("NR "); } if (chan.funcs & RIG_FUNC_AIP) { printf("AIP "); } if (chan.funcs & RIG_FUNC_APF) { printf("APF "); } if (chan.funcs & RIG_FUNC_MON) { printf("MON "); } if (chan.funcs & RIG_FUNC_MN) { printf("MN "); } if (chan.funcs & RIG_FUNC_RF) { printf("RF "); } printf("\n"); } else { printf("none\n"); } if (rig_has_set_level(rig, RIG_LEVEL_PREAMP)) { printf("PREAMP: %ddB\n", chan.levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i); } if (rig_has_set_level(rig, RIG_LEVEL_ATT)) { printf("ATT: %ddB\n", chan.levels[rig_setting2idx(RIG_LEVEL_ATT)].i); } if (rig_has_set_level(rig, RIG_LEVEL_AF)) { printf("AF: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_AF)].f); } if (rig_has_set_level(rig, RIG_LEVEL_RF)) { printf("RF: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_RF)].f); } if (rig_has_set_level(rig, RIG_LEVEL_SQL)) { printf("SQL: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_SQL)].f); } if (rig_has_set_level(rig, RIG_LEVEL_IF)) { printf("IF: %dHz\n", chan.levels[rig_setting2idx(RIG_LEVEL_IF)].i); } if (rig_has_set_level(rig, RIG_LEVEL_APF)) { printf("APF: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_APF)].f); } if (rig_has_set_level(rig, RIG_LEVEL_NR)) { printf("NR: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_NR)].f); } if (rig_has_set_level(rig, RIG_LEVEL_PBT_IN)) { printf("PBT_IN: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_PBT_IN)].f); } if (rig_has_set_level(rig, RIG_LEVEL_PBT_OUT)) { printf("PBT_OUT: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_PBT_OUT)].f); } if (rig_has_set_level(rig, RIG_LEVEL_CWPITCH)) { printf("CWPITCH: %dHz\n", chan.levels[rig_setting2idx(RIG_LEVEL_CWPITCH)].i); } if (rig_has_set_level(rig, RIG_LEVEL_RFPOWER)) { printf("RFPOWER: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_RFPOWER)].f); } if (rig_has_set_level(rig, RIG_LEVEL_MICGAIN)) { printf("MICGAIN: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_MICGAIN)].f); } if (rig_has_set_level(rig, RIG_LEVEL_COMP)) { printf("COMP: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_COMP)].f); } if (rig_has_set_level(rig, RIG_LEVEL_BALANCE)) { printf("BALANCE: %g%%\n", 100 * chan.levels[rig_setting2idx(RIG_LEVEL_BALANCE)].f); } if (rig_has_set_level(rig, RIG_LEVEL_KEYSPD)) { printf("KEYSPD: %d\n", chan.levels[rig_setting2idx(RIG_LEVEL_KEYSPD)].i); } if (rig_has_set_level(rig, RIG_LEVEL_NOTCHF)) { printf("NOTCHF: %d\n", chan.levels[rig_setting2idx(RIG_LEVEL_NOTCHF)].i); } if (rig_has_set_level(rig, RIG_LEVEL_AGC)) { printf("AGC: %d\n", chan.levels[rig_setting2idx(RIG_LEVEL_AGC)].i); } if (rig_has_set_level(rig, RIG_LEVEL_BKINDL)) { printf("BKINDL: %d\n", chan.levels[rig_setting2idx(RIG_LEVEL_BKINDL)].i); } return 0; } hamlib-4.6.5/tests/testrotctld.pl0000775000175000017500000005072315056640443012540 #! /usr/bin/perl # testrotctld.pl - (C) 2008,2010 Nate Bargmann, n0nb@arrl.net # A Perl test script for the rotctld program. # # # It connects to the rotctld TCP port (default 4533) and queries the daemon # for some common rot information and sets some values. It also aims to # provide a bit of example code for Perl scripting. # # This program utilizes the Extended Response protocol of rotctld in line # response mode. See the rotctld(1) man page for details. ############################################################################# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # See the file 'COPYING' in the main Hamlib distribution directory for the # complete text of the GNU Public License version 2. # ############################################################################# # Perl modules this script uses use warnings; use strict; use IO::Socket; use Getopt::Long; use Pod::Usage; # Global variables my $socket; my $host = 'localhost'; my $port = 4533; my %rot_state = (); # State of the rotor--position, etc. my %rot_caps = (); # Rotor capabilities from \dump_caps my $man = 0; my $help = 0; my $debug = 0; my $user_in; my $ret_val; # Error values returned from rotctld by Hamlib name my %errstr = ( RIG_OK => "0", # No error, operation completed successfully RIG_EINVAL => "-1", # invalid parameter RIG_ECONF => "-2", # invalid configuration (serial,..) RIG_ENOMEM => "-3", # memory shortage RIG_ENIMPL => "-4", # function not implemented, but will be RIG_ETIMEOUT => "-5", # communication timed out RIG_EIO => "-6", # IO error, including open failed RIG_EINTERNAL => "-7", # Internal Hamlib error, huh?! RIG_EPROTO => "-8", # Protocol error RIG_ERJCTED => "-9", # Command rejected by the rot RIG_ETRUNC => "-10", # Command performed, but arg truncated RIG_ENAVAIL => "-11", # function not available RIG_ENTARGET => "-12", # VFO not targetable RIG_BUSERROR => "-13", # Error talking on the bus RIG_BUSBUSY => "-14", # Collision on the bus RIG_EARG => "-15", # NULL RIG handle or any invalid pointer parameter in get arg RIG_EVFO => "-16", # Invalid VFO RIG_EDOM => "-17", # Argument out of domain of func # testctld specific error values from -100 onward CTLD_OK => "-100", # testrotctld -- No error CTLD_ENIMPL => "-103", # testrotctld -- %rot_caps reports backend function not implemented CTLD_EPROTO => "-108", # testrotctld -- Echoed command mismatch or other error ); # Error values returned from rotctld by Hamlib value my %errval = reverse %errstr; # Rotor '\move' command token values my %direct = ( UP => '2', DOWN => '4', LEFT => '8', CCW => '8', # Synonym for LEFT RIGHT => '16', CW => '16', # Synonym for RIGHT ); ############################################################################# # Main program # ############################################################################# # Parse command line options argv_opts(); # Create the new socket. # 'localhost' may be replaced by any hostname or IP address where a # rotctld instance is running. # Timeout is set to 5 seconds. $socket = new IO::Socket::INET (PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Type => SOCK_STREAM, Timeout => 5 ) or die $@; print "Welcome to testrotctld.pl a program to test 'rotctld'\n"; print "Type '?' or 'help' for commands help.\n\n"; # Populate %rot_caps from \dump_caps $ret_val = dump_caps(); # Tell user what rotor rotctld is working with if ($ret_val eq $errstr{'RIG_OK'}) { print "Hamlib Model: " . $rot_caps{'Caps dump for model'} . "\t"; print "Common Name: " . $rot_caps{'Mfg name'} . ' ' . $rot_caps{'Model name'} . "\n\n\n"; } else { errmsg ($ret_val); } # Interactive loop do { print "rotctld command: "; chomp($user_in = <>); # P, \set_pos if ($user_in =~ /^(P|\\set_pos)\s+([-+]?([0-9]*\.)?[0-9]+)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { if ($rot_caps{'Can set Position'} eq 'Y') { # Get the entered az and el values print "Az = $2, El = $4\n" if $debug; $ret_val = rot_cmd('set_pos', $2, $4); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # p, \get_pos elsif ($user_in =~ /^(p|\\get_pos)\b$/) { if ($rot_caps{'Can get Position'} eq 'Y') { # Query rot and process result $ret_val = rot_cmd('get_pos'); if ($ret_val eq $errstr{'RIG_OK'}) { print "Azimuth: " . $rot_state{Azimuth} . "\n"; print "Elevation: " . $rot_state{Elevation} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # M, \move elsif ($user_in =~ /^(M|\\move)\s+([A-Z]+)\s+(\d+)\b$/) { if ($rot_caps{'Can Move'} eq 'Y') { # Get the entered mode and passband values print "Move = $direct{$2}, Speed = $3\n" if $debug; $ret_val = rot_cmd('move', $direct{$2}, $3); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # S, \stop elsif ($user_in =~ /^(S|\\stop)\b$/) { if ($rot_caps{'Can Stop'} eq 'Y') { print "Stop\n" if $debug; $ret_val = rot_cmd('stop'); # $vfo not used! unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # K, \park elsif ($user_in =~ /^(K|\\park)\b$/) { if ($rot_caps{'Can Park'} eq 'Y') { print "Park\n" if $debug; $ret_val = rot_cmd('park'); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # R, \reset elsif ($user_in =~ /^(R|\\reset)\s+(\d)\b$/) { if ($rot_caps{'Can Reset'} eq 'Y') { print "Reset\n" if $debug; $ret_val = rot_cmd('reset', $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # _, \get_info elsif ($user_in =~ /^(_|\\get_info)\b$/) { if ($rot_caps{'Can get Info'} eq 'Y') { print "Get info\n" if $debug; $ret_val = rot_cmd('get_info'); if ($ret_val eq $errstr{'RIG_OK'}) { print "Info: " . $rot_state{Info} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # L, \lonlat2loc elsif ($user_in =~ /^(L|\\lonlat2loc)\s+([-+]?([0-9]*\.)?[0-9]+)\s+([-+]?([0-9]*\.)?[0-9]+)\s+(\d+)\b$/) { print "Longitude = $2, Latitude = $4, Length = $6\n" if $debug; $ret_val = rot_cmd('lonlat2loc', $2, $4, $6); if ($ret_val eq $errstr{'RIG_OK'}) { print "Locator: " . $rot_state{Locator} . "\n\n"; } else { errmsg ($ret_val); } } # l, \loc2lonlat elsif ($user_in =~ /^(l|\\loc2lonlat)\s+([A-Za-z0-9]+)\b$/) { print "Locator = $2\n" if $debug; $ret_val = rot_cmd('loc2lonlat', $2); if ($ret_val eq $errstr{'RIG_OK'}) { print "Longitude: " . $rot_state{Longitude} . "\n"; print "Latitude: " . $rot_state{Latitude} . "\n\n"; } else { errmsg ($ret_val); } } # D, \dms2dec elsif ($user_in =~ /^(D|\\dms2dec)\s+[+-]?(\d+)\s+(\d+)\s+(([0-9]*\.)?[0-9]+)\s+(\d)\b$/) { print "Degrees = $2, Minutes = $3, Seconds = $4, S/W = $6\n" if $debug; $ret_val = rot_cmd('dms2dec', $2, $3, $4, $6); if ($ret_val eq $errstr{'RIG_OK'}) { print "Decimal Degrees: " . $rot_state{'Dec Degrees'} . "\n\n"; } else { errmsg ($ret_val); } } # d, \dec2dms elsif ($user_in =~ /^(d|\\dec2dms)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { print "Decimal Degrees = $2\n" if $debug; $ret_val = rot_cmd('dec2dms', $2); if ($ret_val eq $errstr{'RIG_OK'}) { print "Degrees: " . $rot_state{Degrees} . "\n"; print "Minutes: " . $rot_state{Minutes} . "\n"; print "Seconds: " . $rot_state{Seconds} . "\n"; print "South/West: " . $rot_state{'S/W'} . "\n\n"; } else { errmsg ($ret_val); } } # E, \dmmm2dec elsif ($user_in =~ /^(E|\\dmmm2dec)\s+[+-]?(\d+)\s+(([0-9]*\.)?[0-9]+)\s+(\d)\b$/) { print "Degrees = $2, Minutes = $3, S/W = $5\n" if $debug; $ret_val = rot_cmd('dmmm2dec', $2, $3, $5); if ($ret_val eq $errstr{'RIG_OK'}) { print "Decimal Degrees: " . $rot_state{'Dec Deg'} . "\n\n"; } else { errmsg ($ret_val); } } # e, \dec2dmmm elsif ($user_in =~ /^(e|\\dec2dmmm)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { print "Decimal Degrees = $2\n" if $debug; $ret_val = rot_cmd('dec2dmmm', $2); if ($ret_val eq $errstr{'RIG_OK'}) { print "Degrees: " . $rot_state{Degrees} . "\n"; print "Decimal Minutes: " . $rot_state{'Dec Minutes'} . "\n"; print "South/West: " . $rot_state{'S/W'} . "\n\n"; } else { errmsg ($ret_val); } } # B, \qrb elsif ($user_in =~ /^(B|\\qrb)\s+([-+]?([0-9]*\.)?[0-9]+)\s+([-+]?([0-9]*\.)?[0-9]+)\s+([-+]?([0-9]*\.)?[0-9]+)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { print "Lon 1 = $2, Lat 1 = $4, Lon 2 = $6, Lat 2 = $8\n" if $debug; $ret_val = rot_cmd('qrb', $2, $4, $6, $8); if ($ret_val eq $errstr{'RIG_OK'}) { print "Distance (km): " . $rot_state{'QRB Distance'} . "\n"; print "Azimuth (Deg): " . $rot_state{'QRB Azimuth'} . "\n\n"; } else { errmsg ($ret_val); } } # A, \a_sp2a_lp elsif ($user_in =~ /^(A|\\a_sp2a_lp)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { print "Short Path Degrees = $2\n" if $debug; $ret_val = rot_cmd('a_sp2a_lp', $2); if ($ret_val eq $errstr{'RIG_OK'}) { print "Long Path Degrees: " . $rot_state{'Long Path Deg'} . "\n\n"; } else { errmsg ($ret_val); } } # a, \d_sp2d_lp elsif ($user_in =~ /^(a|\\d_sp2d_lp)\s+([-+]?([0-9]*\.)?[0-9]+)\b$/) { print "Short Path km = $2\n" if $debug; $ret_val = rot_cmd('d_sp2d_lp', $2); if ($ret_val eq $errstr{'RIG_OK'}) { print "Long Path km: " . $rot_state{'Long Path km'} . "\n\n"; } else { errmsg ($ret_val); } } # 1, \dump_caps elsif ($user_in =~ /^(1|\\dump_caps)\b$/) { $ret_val = dump_caps(); if ($ret_val eq $errstr{'RIG_OK'}) { print "Model: " . $rot_caps{'Caps dump for model'} . "\n"; print "Manufacturer: " . $rot_caps{'Mfg name'} . "\n"; print "Name: " . $rot_caps{'Model name'} . "\n\n"; } else { errmsg ($ret_val); } } # ?, help elsif ($user_in =~ /^\?|^help\b$/) { print <) { # rotctld terminates each line with '\n' chomp; push @lines, $_; return @lines if $_ =~ /^RPRT/; } } # Builds the %rot_state hash from the lines returned by rotctld which are of the # form "Azimuth: 90.000000, elevation: 45.000000", etc. sub get_state { my ($key, $val); foreach (@_) { ($key, $val) = split(/: /, $_); $rot_state{$key} = $val; } } # Parse the (large) \dump_caps command response into %rot_caps. # TODO: process all lines of output sub get_caps { my ($key, $val); foreach (@_) { if (($_ =~ /^Caps .*:/) or ($_ =~ /^Model .*:/) or ($_ =~ /^Mfg .*:/) or ($_ =~ /^Can .*:/) ) { ($key, $val) = split(/:\s+/, $_); $rot_caps{$key} = $val; } } } # Extract the Hamlib error value returned with the last line from rotctld sub get_errno { chomp @_; my @errno = split(/ /, $_[0]); return $errno[1]; } # FIXME: Better argument handling sub errmsg { unless (($_[0] eq $errstr{'CTLD_EPROTO'}) or ($_[0] eq $errstr{'CTLD_ENIMPL'})) { print "rotctld returned Hamlib $errval{$_[0]}\n\n"; } elsif ($_[0] eq $errstr{'CTLD_EPROTO'}) { print "Echoed command mismatch\n\n"; } elsif ($_[0] eq $errstr{'CTLD_ENIMPL'}) { print "Function not yet implemented in Hamlib rot backend\n\n"; } } # Parse the command line for supported options. Print help text as needed. sub argv_opts { # Parse options and print usage if there is a syntax error, # or if usage was explicitly requested. GetOptions('help|?' => \$help, man => \$man, "port=i" => \$port, "host=s" => \$host, debug => \$debug ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-verbose => 2) if $man; } # POD for pod2usage __END__ =head1 NAME testctld.pl - A test and example program for 'rotctld' written in Perl. =head1 SYNOPSIS testctld.pl [options] Options: --host Hostname or IP address of target 'rotctld' process --port TCP Port of target 'rotctld' process --help Brief help message --man Full documentation --debug Enable debugging output =head1 DESCRIPTION B provides a set of functions to interactively test the Hamlib I TCP/IP network daemon. It also aims to be an example of programming code to control a rotor via TCP/IP in Hamlib. =head1 OPTIONS =over 8 =item B<--host> Hostname or IP address of the target I process. Default is I which should resolve to 127.0.0.1 if I is configured correctly. =item B<--port> TCP port of the target I process. Default is 4533. Multiple instances of I will require unique port numbers. =item B<--help> Prints a brief help message and exits. =item B<--man> Prints this manual page and exits. =item B<--debug> Enables debugging output to the console. =back =head1 COMMANDS Commands are the same as described in the rotctld(1) man page. This is only a brief summary. P, \set_pos Set the rotor's Azimuth and Elevation p, \get_pos Get the rotor's Azimuth and Elevation M. \move Move Up, Down, Left, Right at Speed S, \stop Stop rotation K, \park Set the rotor to the park position R, \reset Reset the rotor _, \get_info Get the rotor Model Name 1, \dump_caps Get the rot capabilities and display select values These commands are for the locator support API. L, \lonlat2loc Convert Longitude and Latitude to Maidenhead square l, \loc2lonlat Convert Maidenhead square to Longitude and Latitude D, \dms2dec Convert Degrees, Minutes, Seconds to Decimal Degrees d, \dec2dms Convert Decimal Degrees to Degrees, Minutes, Seconds E, \dmmm2dec Convert Degrees, Decimal Minutes to Decimal Degrees e, \dec2dmmm Convert Decimal Degrees to Degrees, Decimal Minutes B, \qrb Compute distance and azimuth between Lon 1, Lat 1, and Lon 2, Lat 2 A, \a_sp2a_lp Compute Long Path Azimuth from Short Path Azimuth a, \d_sp2d_lp Compute Long Path Distance from Short Path Distance =cut hamlib-4.6.5/tests/rig_split_lst.awk0000775000175000017500000000475315056640443013214 #!/usr/bin/awk -f # (c) 2007-2009 Stephane Fillod # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # This program is to be piped from: # tests/rigctl -l |sort -n | rig_split_lst.awk BEGIN { bkendlst[0]="dummy" bkendlst[1]="yaesu" bkendlst[2]="kenwood" bkendlst[3]="icom" bkendlst[4]="pcr" bkendlst[5]="aor" bkendlst[6]="jrc" bkendlst[7]="radioshack" bkendlst[8]="uniden" bkendlst[9]="drake" bkendlst[10]="lowe" bkendlst[11]="racal" bkendlst[12]="wj" bkendlst[13]="ek" bkendlst[14]="skanti" bkendlst[15]="winradio" bkendlst[16]="tentec" bkendlst[17]="alinco" bkendlst[18]="kachina" bkendlst[20]="gnuradio" bkendlst[21]="microtune" bkendlst[22]="tapr" bkendlst[23]="flexradio" bkendlst[24]="rft" bkendlst[25]="kit" bkendlst[26]="tuner" bkendlst[27]="rs" bkendlst[28]="unknown" if (lst_dir == "") lst_dir="." else lst_dir=lst_dir for (bke in bkendlst) { print " " \ " Hamlib rig matrix

" \ "

" \ "" \ "" > lst_dir"/"bkendlst[bke]"_lst.html" } } # 0 1 2 3 4 5 # 012345678901234567890123456789012345678901234567890123456789 # 2004 GNU GNU Radio GrAudio I&Q 0.1.2 New $1 ~ /^[0-9]+$/ { num=$1 mfg=$2 sub("^[0-9]+\t","") model=substr($0,17,24) ver=substr($0,41,8) status=substr($0,49) printf "" \ "\n", num,num,mfg,model,ver,status >> lst_dir"/"bkendlst[int(num/100)]"_lst.html" } END { for (bke in bkendlst) { print "
Rig#MfgModelVers.Status
%d%s%s%s%s
" >> lst_dir"/"bkendlst[bke]"_lst.html" } } hamlib-4.6.5/tests/dumpcaps_amp.c0000664000175000017500000001112015056640443012426 /* * dumpcaps_amp.c - Copyright (C) 2000-2012 Stephane Fillod * This programs dumps the capabilities of a backend rig. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include "sprintflst.h" #include "ampctl_parse.h" #include "amplifier.h" /* * the amp may be in amp_init state, but not opened */ int dumpcaps_amp(const AMP *amp, FILE *fout) { const struct amp_caps *caps; int backend_warnings = 0; static char prntbuf[1024]; if (!amp || !amp->caps) { return -RIG_EINVAL; } caps = amp->caps; fprintf(fout, "Caps dump for model:\t%d\n", caps->amp_model); fprintf(fout, "Model name:\t\t%s\n", caps->model_name); fprintf(fout, "Mfg name:\t\t%s\n", caps->mfg_name); fprintf(fout, "Backend version:\t%s\n", caps->version); fprintf(fout, "Backend copyright:\t%s\n", caps->copyright); fprintf(fout, "Backend status:\t\t%s\n", rig_strstatus(caps->status)); fprintf(fout, "Amp type:\t\t"); switch (caps->amp_type & AMP_TYPE_MASK) { case AMP_TYPE_OTHER: fprintf(fout, "Other\n"); break; default: fprintf(fout, "Unknown type=%d\n", caps->amp_type); backend_warnings++; } fprintf(fout, "Port type:\t\t"); switch (caps->port_type) { case RIG_PORT_SERIAL: fprintf(fout, "RS-232\n"); fprintf(fout, "Serial speed:\t\t%d..%d baud, %d%c%d, ctrl=%s\n", caps->serial_rate_min, caps->serial_rate_max, caps->serial_data_bits, caps->serial_parity == RIG_PARITY_NONE ? 'N' : caps->serial_parity == RIG_PARITY_ODD ? 'O' : caps->serial_parity == RIG_PARITY_EVEN ? 'E' : caps->serial_parity == RIG_PARITY_MARK ? 'M' : 'S', caps->serial_stop_bits, caps->serial_handshake == RIG_HANDSHAKE_NONE ? "NONE" : (caps->serial_handshake == RIG_HANDSHAKE_XONXOFF ? "XONXOFF" : "CTS/RTS") ); break; case RIG_PORT_PARALLEL: fprintf(fout, "Parallel\n"); break; case RIG_PORT_DEVICE: fprintf(fout, "Device driver\n"); break; case RIG_PORT_USB: fprintf(fout, "USB\n"); break; case RIG_PORT_NETWORK: fprintf(fout, "Network link\n"); break; case RIG_PORT_UDP_NETWORK: fprintf(fout, "UDP Network link\n"); break; case RIG_PORT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); backend_warnings++; } fprintf(fout, "Write delay:\t\t%dms, timeout %dms, %d retr%s\n", caps->write_delay, caps->timeout, caps->retry, (caps->retry == 1) ? "y" : "ies"); fprintf(fout, "Post write delay:\t%dms\n", caps->post_write_delay); fprintf(fout, "Has priv data:\t\t%c\n", caps->priv != NULL ? 'Y' : 'N'); amp_sprintf_level(prntbuf, sizeof(prntbuf), caps->has_get_level); fprintf(fout, "Get level: %s\n", prntbuf); /* * Status is either 'Y'es, 'E'mulated, 'N'o * * TODO: keep me up-to-date with API call list! */ fprintf(fout, "Has Init:\t\t%c\n", caps->amp_init != NULL ? 'Y' : 'N'); fprintf(fout, "Has Cleanup:\t\t%c\n", caps->amp_cleanup != NULL ? 'Y' : 'N'); fprintf(fout, "Has Open:\t\t%c\n", caps->amp_open != NULL ? 'Y' : 'N'); fprintf(fout, "Has Close:\t\t%c\n", caps->amp_close != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Conf:\t\t%c\n", caps->set_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Conf:\t\t%c\n", caps->get_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can Reset:\t\t%c\n", caps->reset != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Info:\t\t%c\n", caps->get_info != NULL ? 'Y' : 'N'); fprintf(fout, "\nOverall backend warnings: %d\n", backend_warnings); return backend_warnings; } hamlib-4.6.5/tests/rigctltcp.c0000664000175000017500000012231415056640443011760 /* * rigctltcp.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2008,2010,2011,2012,2013 * (C) The Hamlib Group 2012-2022 * * This program test/control a radio using Hamlib. * It takes commands from a tcp network connection. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include #endif #include #include #include #include #include #include #include #include /* See NOTES */ #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_PTHREAD # include #endif #include #include "misc.h" #include "network.h" #include "riglist.h" #include "rigctl_parse.h" /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "m:r:p:d:P:D:s:S:c:T:t:C:W:w:x:z:lLuovhVZMRA:n:" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"ptt-file", 1, 0, 'p'}, {"dcd-file", 1, 0, 'd'}, {"ptt-type", 1, 0, 'P'}, {"dcd-type", 1, 0, 'D'}, {"serial-speed", 1, 0, 's'}, {"separator", 1, 0, 'S'}, {"civaddr", 1, 0, 'c'}, {"listen-addr", 1, 0, 'T'}, {"port", 1, 0, 't'}, {"set-conf", 1, 0, 'C'}, {"list", 0, 0, 'l'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"vfo", 0, 0, 'o'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"twiddle_timeout", 1, 0, 'W'}, {"twiddle_rit", 1, 0, 'w'}, {"uplink", 1, 0, 'x'}, {"debug-time-stamps", 0, 0, 'Z'}, {"multicast-addr", 1, 0, 'M'}, {"multicast-port", 1, 0, 'n'}, {"password", 1, 0, 'A'}, {"rigctld-idle", 0, 0, 'R'}, {0, 0, 0, 0} }; struct handle_data { RIG *rig; int sock; struct sockaddr_storage cli_addr; socklen_t clilen; int vfo_mode; int use_password; }; void *handle_socket(void *arg); void usage(void); #ifdef HAVE_PTHREAD static unsigned client_count; #endif static RIG *my_rig; /* handle to rig (instance) */ static volatile int rig_opened = 0; static int verbose; #ifdef HAVE_SIG_ATOMIC_T static sig_atomic_t volatile ctrl_c; #else static int volatile ctrl_c; #endif const char *portno = "4531"; const char *src_addr = NULL; /* INADDR_ANY */ const char *multicast_addr = "0.0.0.0"; int multicast_port = 4532; extern char rigctld_password[65]; char resp_sep = '\n'; extern int lock_mode; extern powerstat_t rig_powerstat; static int rigctld_idle = 0; // if true then rig will close when no clients are connected #define MAXCONFLEN 2048 void mutex_rigctld(int lock) { #ifdef HAVE_PTHREAD static pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER; if (lock) { pthread_mutex_lock(&client_lock); rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock engaged\n", __func__); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock disengaged\n", __func__); pthread_mutex_unlock(&client_lock); } #endif } #ifdef WIN32 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (fdwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: ctrl_c = 1; return TRUE; default: return FALSE; } } #else static void signal_handler(int sig) { switch (sig) { case SIGINT: ctrl_c = 1; break; default: /* do nothing */ break; } } #endif static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } int main(int argc, char *argv[]) { rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int show_conf = 0; int dump_caps_opt = 0; const char *rig_file = NULL, *ptt_file = NULL, *dcd_file = NULL; ptt_type_t ptt_type = RIG_PTT_NONE; dcd_type_t dcd_type = RIG_DCD_NONE; int serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; struct addrinfo hints, *result, *saved_result; int sock_listen; int reuseaddr = 1; int twiddle_timeout = 0; int twiddle_rit = 0; int uplink = 0; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; char rigstartup[1024]; char vbuf[1024]; #if HAVE_SIGACTION struct sigaction act; #endif #ifdef HAVE_PTHREAD pthread_t thread; pthread_attr_t attr; #endif struct handle_data *arg; int vfo_mode = 0; /* vfo_mode=0 means target VFO is current VFO */ int i; extern int is_rigctld; struct rig_state *rs; is_rigctld = 1; int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf)); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: setvbuf err=%s\n", __func__, strerror(err)); } while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': printf("rigctltcp %s\n", hamlib_version2); exit(0); case 'R': rigctld_idle = 1; break; case 'A': strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1); //char *md5 = rig_make_m d5(rigctld_password); char md5[HAMLIB_SECRET_LENGTH + 1]; rig_password_generate_secret(rigctld_password, md5); printf("Secret key: %s\n", md5); rig_settings_save("sharedkey", md5, e_CHAR); break; case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; case 'd': if (!optarg) { usage(); /* wrong arg count */ exit(1); } dcd_file = optarg; break; case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "CM108")) { ptt_type = RIG_PTT_CM108; } else if (!strcmp(optarg, "GPIO")) { ptt_type = RIG_PTT_GPIO; } else if (!strcmp(optarg, "GPION")) { ptt_type = RIG_PTT_GPION; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { puts("Unrecognised PTT type, using NONE"); ptt_type = RIG_PTT_NONE; } break; case 'D': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { dcd_type = RIG_DCD_RIG; } else if (!strcmp(optarg, "DSR")) { dcd_type = RIG_DCD_SERIAL_DSR; } else if (!strcmp(optarg, "CTS")) { dcd_type = RIG_DCD_SERIAL_CTS; } else if (!strcmp(optarg, "CD")) { dcd_type = RIG_DCD_SERIAL_CAR; } else if (!strcmp(optarg, "PARALLEL")) { dcd_type = RIG_DCD_PARALLEL; } else if (!strcmp(optarg, "CM108")) { dcd_type = RIG_DCD_CM108; } else if (!strcmp(optarg, "GPIO")) { dcd_type = RIG_DCD_GPIO; } else if (!strcmp(optarg, "GPION")) { dcd_type = RIG_DCD_GPION; } else if (!strcmp(optarg, "NONE")) { dcd_type = RIG_DCD_NONE; } else { puts("Unrecognised DCD type, using NONE"); dcd_type = RIG_DCD_NONE; } break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 'S': if (!optarg) { usage(); /* wrong arg count */ exit(1); } resp_sep = *optarg; rig_debug(RIG_DEBUG_VERBOSE, "%s: resp_sep=%c\n", __func__, resp_sep); break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } portno = optarg; break; case 'T': if (!optarg) { usage(); /* wrong arg count */ exit(1); } src_addr = optarg; break; case 'o': vfo_mode++; //rig_debug(RIG_DEBUG_ERR, "%s: #0 vfo_mode=%d\n", __func__, vfo_mode); break; case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'W': if (!optarg) { usage(); /* wrong arg count */ exit(1); } twiddle_timeout = atoi(optarg); fprintf(stderr, "twiddle_timeout is deprecated...use e.g. --set-conf=twiddle_timeout=5\n"); break; case 'w': if (!optarg) { usage(); /* wrong arg count */ exit(1); } twiddle_rit = atoi(optarg); fprintf(stderr, "twiddle_rit is deprecated...use e.g. --set-conf=twiddle_rit=1\n"); break; case 'x': if (!optarg) { usage(); /* wrong arg count */ exit(1); } uplink = atoi(optarg); break; case 'Z': rig_set_debug_time_stamp(1); break; case 'M': if (!optarg) { usage(); /* wrong arg count */ exit(1); } multicast_addr = optarg; break; case 'n': if (!optarg) { usage(); /* wrong arg count */ exit(1); } multicast_port = atoi(optarg); if (multicast_port == 0) { fprintf(stderr, "Invalid multicast port: %s\n", optarg); exit(1); } break; default: usage(); /* unknown option? */ exit(1); } } #if 0 if (!vfo_mode) { printf("Recommend using --vfo switch for rigctld if client supports it\n"); printf("rigctl and netrigctl will automatically detect vfo mode\n"); } #endif rig_set_debug(verbose); SNPRINTF(rigstartup, sizeof(rigstartup), "%s(%d) Startup:", __FILE__, __LINE__); for (i = 0; i < argc; ++i) { strcat(rigstartup, " "); strcat(rigstartup, argv[i]); } rig_debug(RIG_DEBUG_VERBOSE, "%s\n", rigstartup); rig_debug(RIG_DEBUG_VERBOSE, "rigctltcp %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); rig_debug(RIG_DEBUG_VERBOSE, "Max# of rigctld client services=%d\n", NI_MAXSERV); my_rig = rig_init(my_model); if (!my_rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } retcode = -RIG_ENIMPL; // retcode = set_conf(my_rig, conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } if (rig_file) { strncpy(RIGPORT(my_rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } rs = STATE(my_rig); rs->twiddle_timeout = twiddle_timeout; rs->twiddle_rit = twiddle_rit; rs->uplink = uplink; rig_debug(RIG_DEBUG_TRACE, "%s: twiddle=%d, uplink=%d, twiddle_rit=%d\n", __func__, rs->twiddle_timeout, rs->uplink, rs->twiddle_rit); /* * ex: RIG_PTT_PARALLEL and /dev/parport0 */ if (ptt_type != RIG_PTT_NONE) { PTTPORT(my_rig)->type.ptt = ptt_type; rs->pttport_deprecated.type.ptt = ptt_type; // This causes segfault since backend rig_caps are const // rigctld will use the STATE(rig) version of this for clients //my_rig->caps->ptt_type = ptt_type; } if (dcd_type != RIG_DCD_NONE) { DCDPORT(my_rig)->type.dcd = dcd_type; rs->dcdport_deprecated.type.dcd = dcd_type; } if (ptt_file) { strncpy(PTTPORT(my_rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); strncpy(rs->pttport_deprecated.pathname, ptt_file, HAMLIB_FILPATHLEN - 1); } if (dcd_file) { strncpy(DCDPORT(my_rig)->pathname, dcd_file, HAMLIB_FILPATHLEN - 1); strncpy(rs->dcdport_deprecated.pathname, dcd_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(my_rig)->parm.serial.rate = serial_rate; rs->rigport_deprecated.parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); } /* * print out conf parameters */ if (show_conf) { rig_token_foreach(my_rig, print_conf_list, (rig_ptr_t)my_rig); } /* * print out conf parameters, and exits immediately * We may be interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps(my_rig, stdout); rig_cleanup(my_rig); /* if you care about memory */ exit(0); } /* attempt to open rig to check early for issues */ retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s %s %s \n", rigerror(retcode), rig_file, strerror(errno)); // continue even if opening the rig fails, because it may be powered off } if (verbose > RIG_DEBUG_ERR) { printf("Opened rig model %u, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); // Normally we keep the rig open to speed up the 1st client connect // But some rigs like the FT-736 have to lock the rig for CAT control // So they need to release the rig when no clients are connected if (rigctld_idle) { rig_close(my_rig); /* we will reopen for clients */ if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %u, '%s - will reopen for clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } #ifdef __MINGW32__ # ifndef SO_OPENTYPE # define SO_OPENTYPE 0x7008 # endif # ifndef SO_SYNCHRONOUS_NONALERT # define SO_SYNCHRONOUS_NONALERT 0x20 # endif # ifndef INVALID_SOCKET # define INVALID_SOCKET -1 # endif WSADATA wsadata; if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) { fprintf(stderr, "WSAStartup socket error\n"); exit(1); } { int sockopt = SO_SYNCHRONOUS_NONALERT; setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt)); } #endif /* * Prepare listening socket */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM;/* TCP socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ retcode = getaddrinfo(src_addr, portno, &hints, &result); if (retcode == 0 && result->ai_family == AF_INET6) { rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV6\n", __func__); } else if (retcode == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV4\n", __func__); } else { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode)); exit(2); } saved_result = result; enum multicast_item_e items = RIG_MULTICAST_POLL | RIG_MULTICAST_TRANSCEIVE | RIG_MULTICAST_SPECTRUM; retcode = network_multicast_publisher_start(my_rig, multicast_addr, multicast_port, items); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: network_multicast_server failed: %s\n", __FILE__, rigerror(retcode)); // we will consider this non-fatal for now } do { sock_listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock_listen < 0) { handle_error(RIG_DEBUG_ERR, "socket"); freeaddrinfo(saved_result); /* No longer needed */ exit(2); } if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } #ifdef IPV6_V6ONLY if (AF_INET6 == result->ai_family) { /* allow IPv4 mapped to IPv6 clients Windows and BSD default this to 1 (i.e. disallowed) and we prefer it off */ int sockopt = 0; if (setsockopt(sock_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&sockopt, sizeof(sockopt)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } } #endif if (0 == bind(sock_listen, result->ai_addr, result->ai_addrlen)) { break; } handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); #ifdef __MINGW32__ closesocket(sock_listen); #else close(sock_listen); #endif } while ((result = result->ai_next) != NULL); freeaddrinfo(saved_result); /* No longer needed */ if (NULL == result) { rig_debug(RIG_DEBUG_ERR, "%s: bind error - no available interface\n", __func__); exit(1); } if (listen(sock_listen, 4) < 0) { handle_error(RIG_DEBUG_ERR, "listening"); exit(1); } #if HAVE_SIGACTION #ifdef SIGPIPE /* Ignore SIGPIPE as we will handle it at the write()/send() calls that will consequently fail with EPIPE. All child threads will inherit this disposition which is what we want. */ memset(&act, 0, sizeof act); act.sa_handler = SIG_IGN; act.sa_flags = SA_RESTART; if (sigaction(SIGPIPE, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE"); } #endif #ifdef SIGINT memset(&act, 0, sizeof act); act.sa_handler = signal_handler; if (sigaction(SIGINT, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGINT"); } #endif #elif defined (WIN32) if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler"); } #elif HAVE_SIGNAL #ifdef SIGPIPE if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) { handle_error(RIG_DEBUG_ERR, "signal SIGPIPE"); } #endif #ifdef SIGINT if (SIG_ERR == signal(SIGINT, signal_handler)) { handle_error(RIG_DEBUG_ERR, "signal SIGINT"); } #endif #endif /* * main loop accepting connections */ rig_debug(RIG_DEBUG_TRACE, "%s: rigctltcp listening on port %s\n", __func__, portno); do { fd_set set; struct timeval timeout; arg = calloc(1, sizeof(struct handle_data)); if (!arg) { rig_debug(RIG_DEBUG_ERR, "calloc: %s\n", strerror(errno)); exit(1); } if (rigctld_password[0] != 0) { arg->use_password = 1; } /* use select to allow for periodic checks for CTRL+C */ FD_ZERO(&set); FD_SET(sock_listen, &set); timeout.tv_sec = 5; timeout.tv_usec = 0; retcode = select(sock_listen + 1, &set, NULL, NULL, &timeout); if (retcode == -1) { int errno_stored = errno; rig_debug(RIG_DEBUG_ERR, "%s: select() failed: %s\n", __func__, strerror(errno_stored)); if (ctrl_c) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ctrl_c when retcode==-1\n", __func__); break; } if (errno == EINTR) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ignoring interrupted system call\n", __func__); //retcode = 0; // not used? } } else if (retcode == 0) { if (ctrl_c) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ctrl_c when retcode==0\n", __func__); break; } } else { arg->rig = my_rig; arg->clilen = sizeof(arg->cli_addr); arg->vfo_mode = vfo_mode; arg->sock = accept(sock_listen, (struct sockaddr *)&arg->cli_addr, &arg->clilen); if (arg->sock < 0) { handle_error(RIG_DEBUG_ERR, "accept"); break; } if ((retcode = getnameinfo((struct sockaddr const *)&arg->cli_addr, arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection opened from %s:%s\n", host, serv); #ifdef HAVE_PTHREAD pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); retcode = pthread_create(&thread, &attr, handle_socket, arg); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "pthread_create: %s\n", strerror(retcode)); break; } #else handle_socket(arg); #endif } } while (!ctrl_c); rig_debug(RIG_DEBUG_VERBOSE, "%s: while loop done\n", __func__); #ifdef HAVE_PTHREAD /* allow threads to finish current action */ mutex_rigctld(1); if (client_count) { rig_debug(RIG_DEBUG_WARN, "%u outstanding client(s)\n", client_count); } rig_close(my_rig); mutex_rigctld(0); #else rig_close(my_rig); /* close port */ #endif network_multicast_publisher_stop(my_rig); rig_cleanup(my_rig); /* if you care about memory */ #ifdef __MINGW32__ WSACleanup(); #endif return 0; } static FILE *get_fsockout(struct handle_data *handle_data_arg) { #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); return _fdopen(sock_osfhandle, "wb"); #else return fdopen(handle_data_arg->sock, "wb"); #endif } static FILE *get_fsockin(struct handle_data *handle_data_arg) { #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); if (sock_osfhandle == -1) { rig_debug(RIG_DEBUG_ERR, "_open_osfhandle error: %s\n", strerror(errno)); return NULL; } return _fdopen(sock_osfhandle, "rb"); #else return fdopen(handle_data_arg->sock, "rb"); #endif } /* * This is the function run by the threads */ void *handle_socket(void *arg) { struct handle_data *handle_data_arg = (struct handle_data *)arg; FILE *fsockin = NULL; FILE *fsockout = NULL; int retcode = RIG_OK; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; rig_powerstat = RIG_POWER_ON; // defaults to power on fsockin = get_fsockin(handle_data_arg); if (!fsockin) { rig_debug(RIG_DEBUG_ERR, "%s: fdopen(0x%d) in: %s\n", __func__, handle_data_arg->sock, strerror(errno)); goto handle_exit; } fsockout = get_fsockout(handle_data_arg); if (!fsockout) { rig_debug(RIG_DEBUG_ERR, "%s: fdopen out: %s\n", __func__, strerror(errno)); fclose(fsockin); fsockin = NULL; goto handle_exit; } #ifdef HAVE_PTHREAD mutex_rigctld(1); ++client_count; #if 0 if (!client_count++) { retcode = rig_open(my_rig); if (RIG_OK == retcode && verbose > RIG_DEBUG_ERR) { printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } #endif mutex_rigctld(0); #else mutex_rigctld(1); retcode = rig_open(my_rig); mutex_rigctld(1); if (RIG_OK == retcode && verbose > RIG_DEBUG_ERR) { printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } #endif if (my_rig->caps->get_powerstat) { mutex_rigctld(1); rig_get_powerstat(my_rig, &rig_powerstat); mutex_rigctld(0); STATE(my_rig)->powerstat = rig_powerstat; } do { mutex_rigctld(1); if (!rig_opened) { retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; rig_debug(RIG_DEBUG_ERR, "%s: rig_open reopened retcode=%d\n", __func__, retcode); } mutex_rigctld(0); int nbytes; if (rig_opened) // only do this if rig is open { powerstat_t powerstat; unsigned char cmd[64]; unsigned char reply[64]; unsigned char *term = (unsigned char *)";"; rig_debug(RIG_DEBUG_TRACE, "%s: doing rigctl_parse vfo_mode=%d, secure=%d\n", __func__, handle_data_arg->vfo_mode, handle_data_arg->use_password); #if 0 retcode = rigctl_parse(handle_data_arg->rig, fsockin, fsockout, NULL, 0, mutex_rigctld, 1, 0, &handle_data_arg->vfo_mode, send_cmd_term, &ext_resp, &resp_sep, handle_data_arg->use_password); #else memset(cmd, 0, sizeof(cmd)); nbytes = -1; do { ++nbytes; int val = fgetc(fsockin); if (val == EOF) { goto client_done; } rig_debug(RIG_DEBUG_ERR, "%s: val=0x%02x @ %d\n", __func__, val, nbytes); cmd[nbytes] = val; } while (nbytes < sizeof(cmd) - 1 && cmd[nbytes] != ';' && cmd[nbytes] != 0xfd); ++nbytes; rig_debug(RIG_DEBUG_ERR, "%s: bytes=%d, cmd=%s\n", __func__, nbytes, cmd); if (cmd[nbytes - 1] == ';') { rig_debug(RIG_DEBUG_ERR, "%s: cmd kenwood=%s\n", __func__, cmd); term[0] = ';'; term[1] = 0; } else if (cmd[0] == 0xfe && cmd[1] == 0xfe) { rig_debug(RIG_DEBUG_ERR, "%s: cmd#2 icom=%s\n", __func__, cmd); dump_hex(cmd, nbytes); term[0] = 0xfd; term[1] = 0; } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown cmd:", __func__); dump_hex(cmd, nbytes); cmd[0] = 0; } // This should work with Icom binary cmds any ASCII cmd with last char being standard terminator // This means some of the 5-byte rigs won't be handled correctly -- to be fixed? #if 1 if (cmd[0] != 0) { memset(reply, 0, sizeof(reply)); rig_flush(RIGPORT(my_rig)); retcode = rig_send_raw(my_rig, cmd, nbytes, reply, sizeof(reply), term); if (retcode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: rig_send_raw error=%s\n", __func__, rigerror(retcode)); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: reply(%d bytes)='%s'\n", __func__, retcode, reply); fwrite(reply, 1, retcode, fsockout); fflush(fsockout); } } #endif #if 0 if (strncmp(cmd, "FA", 2) == 0) { char *s = "FA00014074000;"; printf("%s\n", s); fwrite(s, strlen(s), 1, fsockout); fflush(fsockout); } else if (strncmp(cmd, "FB", 2) == 0) { char *s = "FB00014075000;"; printf("%s\n", s); fwrite(s, strlen(s), 1, fsockout); fflush(fsockout); } else if (strncmp(cmd, "AG0", 2) == 0) { char *s = "AG0000;"; printf("%s\n", s); fwrite(s, strlen(s), 1, fsockout); fflush(fsockout); } else if (strncmp(cmd, "IF", 2) == 0) { char *s = "IF000101310001000+0000000000020010000;"; printf("%s\n", s); fwrite(s, strlen(s), 1, fsockout); fflush(fsockout); } #endif #endif if (retcode != 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rigctl_parse retcode=%d\n", __func__, retcode); } // update our power stat in case power gets turned off if (retcode == -RIG_ETIMEOUT && my_rig->caps->get_powerstat) // if we get a timeout we might be powered off { rig_get_powerstat(my_rig, &powerstat); rig_powerstat = powerstat; if (powerstat == RIG_POWER_OFF) { retcode = -RIG_EPOWER; } } } else { retcode = -RIG_EIO; } // if we get a hard error we try to reopen the rig again // this should cover short dropouts that can occur if (retcode < 0 && !RIG_IS_SOFT_ERRCODE(-retcode)) { int retry = 3; rig_debug(RIG_DEBUG_ERR, "%s: i/o error\n", __func__); do { mutex_rigctld(1); retcode = rig_close(my_rig); rig_opened = 0; mutex_rigctld(0); rig_debug(RIG_DEBUG_ERR, "%s: rig_close retcode=%d\n", __func__, retcode); hl_usleep(1000 * 1000); mutex_rigctld(1); if (!rig_opened) { retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; rig_debug(RIG_DEBUG_ERR, "%s: rig_open retcode=%d, opened=%d\n", __func__, retcode, rig_opened); } mutex_rigctld(0); } while (!ctrl_c && !rig_opened && retry-- > 0 && retcode != RIG_OK); } } while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode))); client_done: #if defined(HAVE_PTHREAD) if (rigctld_idle && client_count == 1) #else if (rigctld_idle) #endif { rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %s. Will reopen for new clients\n", my_rig->caps->model_name); } } #ifdef HAVE_PTHREAD --client_count; if (rigctld_idle && client_count > 0) { printf("%u client%s still connected so rig remains open\n", client_count, client_count > 1 ? "s" : ""); } #if 0 mutex_rigctld(1); /* Release rig if there are no clients */ if (!--client_count) { rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %d, '%s - no clients, will reopen for new clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } mutex_rigctld(0); #endif #else rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %d, '%s - will reopen for new clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } #endif if ((retcode = getnameinfo((struct sockaddr const *)&handle_data_arg->cli_addr, handle_data_arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection closed from %s:%s\n", host, serv); handle_exit: // for MINGW we close the handle before fclose #ifdef __MINGW32__ retcode = closesocket(handle_data_arg->sock); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "%s: fclose(fsockin) %s\n", __func__, strerror(retcode)); } #endif if (fsockin) { fclose(fsockin); } if (fsockout) { fclose(fsockout); } // for everybody else we close the handle after fclose #ifndef __MINGW32__ retcode = close(handle_data_arg->sock); if (retcode != 0 && errno != EBADF) { rig_debug(RIG_DEBUG_ERR, "%s: close(handle_data_arg->sock) %s\n", __func__, strerror(errno)); } #endif free(arg); #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif return NULL; } void usage(void) { printf("Usage: rigctltcp [OPTION]...\n" "Daemon serving COMMANDs to a connected radio transceiver or receiver.\n\n"); printf( " -m, --model=ID select radio model number. See model list (-l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -p, --ptt-file=DEVICE set device of the PTT device to operate on\n" " -d, --dcd-file=DEVICE set device of the DCD device to operate on\n" " -P, --ptt-type=TYPE set type of the PTT device to operate on\n" " -D, --dcd-type=TYPE set type of the DCD device to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -t, --port=NUM set TCP listening port, default %s\n" " -S, --separator=CHAR set char as rigctld response separator, default is \\n\n" " -T, --listen-addr=IPADDR set listening IP address, default ANY\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -o, --vfo do not default to VFO_CURR, require extra vfo arg\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -W, --twiddle_timeout=SECONDS timeout after detecting vfo manual change\n" " -w, --twiddle_rit=SECONDS suppress VFOB getfreq so RIT can be twiddled\n" " -x, --uplink set uplink get_freq ignore, 1=Sub, 2=Main\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -M, --multicast-addr=ADDR set multicast UDP address, default 0.0.0.0 (off), recommend 224.0.1.1\n" " -n, --multicast-port=PORT set multicast UDP port, default 4531\n" " -A, --password set password for rigctld access\n" " -R, --rigctld-idle make rigctld close the rig when no clients are connected\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n", portno); usage_rig(stdout); printf("\nError codes and messages\n"); for (enum rig_errcode_e e = 0; e < RIG_EEND; ++e) { printf("-%d - %s", e, rigerror2(e)); } printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/cachetest2.c0000664000175000017500000000720315056640443012011 /* This program does a fast iteration of v f m t s * By Michael Black W9MDB * This allows testing of another program using rigctld * to test changing vfo, freq, mode, PTT, or split and see the change immediately in this program. * Used in testing caching effects that have been added * To compile: * gcc -I../src -I../include -g -o cachetest2 cachetest2.c -lhamlib * To run: * rigctld * ./cachetest2 * Note: cachtest2 should show immediately when v f m t s are changed */ #include #include #include #include #include #include "sprintflst.h" #include "misc.h" int main(int argc, const char *argv[]) { RIG *my_rig; char *rig_file, *info_buf; int retcode; int model; int cache_timeout = 0; if (argc != 1) { fprintf(stderr, "Usage: %s\n", argv[0]); exit(1); } model = 2; rig_set_debug(RIG_DEBUG_NONE); /* Instantiate a rig */ my_rig = rig_init(model); // your rig model. /* Set up serial port, baud rate */ rig_file = "127.0.0.1:4532"; // your serial device strncpy(RIGPORT(my_rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); /* Open my rig */ retcode = rig_open(my_rig); if (retcode != RIG_OK) { fprintf(stderr, "%s: rig_open failed %s\n", __func__, rigerror(retcode)); return 1; } rig_set_cache_timeout_ms(my_rig, HAMLIB_CACHE_ALL, cache_timeout); /* Give me ID info, e.g., firmware version. */ info_buf = (char *)rig_get_info(my_rig); if (info_buf) { strtok(info_buf, "\r\n"); printf("Rig_info: '%s'\n", info_buf); } while (1) { static freq_t freq, freq_last = 0; static rmode_t mode, mode_last = 0; static pbwidth_t width, width_last = 0; static vfo_t vfo, vfo_last = RIG_VFO_NONE; static vfo_t txvfo, txvfo_last = RIG_VFO_NONE; static ptt_t ptt, ptt_last = -1; static split_t split, split_last = -1; retcode = rig_get_vfo(my_rig, &vfo); if (retcode != RIG_OK) { printf("Get vfo failed?? Err=%s\n", rigerror(retcode)); } if (vfo != vfo_last) { printf("VFO = %s\n", rig_strvfo(vfo)); vfo_last = vfo; } retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq); if (retcode != RIG_OK) { printf("Get freq failed?? Err=%s\n", rigerror(retcode)); } if (freq != freq_last) { printf("VFO freq. = %.1f Hz\n", freq); freq_last = freq; } retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &mode, &width); if (retcode != RIG_OK) { printf("Get mode failed?? Err=%s\n", rigerror(retcode)); } if (mode != mode_last || width != width_last) { printf("Current mode = %s, width = %ld\n", rig_strrmode(mode), width); mode_last = mode; width_last = width; } retcode = rig_get_ptt(my_rig, RIG_VFO_CURR, &ptt); if (retcode != RIG_OK) { printf("Get ptt failed?? Err=%s\n", rigerror(retcode)); } if (ptt != ptt_last) { printf("ptt=%d\n", ptt); ptt_last = ptt; } retcode = rig_get_split_vfo(my_rig, RIG_VFO_CURR, &split, &txvfo); if (retcode != RIG_OK) { printf("Get split_vfo failed?? Err=%s\n", rigerror(retcode)); } if (split != split_last || txvfo != txvfo_last) { printf("split=%d, tx_vfo=%s\n", split, rig_strvfo(vfo)); split_last = split; txvfo_last = txvfo; } } rig_close(my_rig); return 0; }; hamlib-4.6.5/tests/rigmatrix.c0000664000175000017500000005377215056640443012006 /* * rigmatrix.c - Copyright (C) 2000-2012 Stephane Fillod * This program generates the supported rig matrix in HTML format. * The code is rather ugly since this is only a try out. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include "misc.h" static setting_t bitmap_func, bitmap_level, bitmap_parm, bitmap_vfo_ops; int create_png_range(const freq_range_t rx_range_list[], const freq_range_t tx_range_list[], int num); int print_caps_sum(struct rig_caps *caps, void *data) { printf("%s%s" "%s%s", caps->rig_model, caps->model_name, caps->mfg_name, caps->version, rig_strstatus(caps->status)); switch (caps->rig_type & RIG_TYPE_MASK) { case RIG_TYPE_TRANSCEIVER: printf("Transceiver"); break; case RIG_TYPE_HANDHELD: printf("Handheld"); break; case RIG_TYPE_MOBILE: printf("Mobile"); break; case RIG_TYPE_RECEIVER: printf("Receiver"); break; case RIG_TYPE_PCRECEIVER: printf("PC Receiver"); break; case RIG_TYPE_SCANNER: printf("Scanner"); break; case RIG_TYPE_TRUNKSCANNER: printf("Trunking scanner"); break; case RIG_TYPE_COMPUTER: printf("Computer"); break; case RIG_TYPE_OTHER: printf("Other"); break; default: printf("Unknown"); } printf("range" "parms" "caps" "funcs" "funcs" "levels" "levels" "parms" "parms" "ops" "\n", caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model, caps->rig_model); return 1; /* !=0, we want them all ! */ } /* * IO params et al. */ int print_caps_parameters(struct rig_caps *caps, void *data) { printf("%s", caps->rig_model, caps->model_name); switch (caps->ptt_type) { case RIG_PTT_RIG: printf("rig"); break; case RIG_PTT_PARALLEL: printf("parallel"); break; case RIG_PTT_SERIAL_RTS: case RIG_PTT_SERIAL_DTR: printf("serial"); break; case RIG_PTT_NONE: printf("None"); break; default: printf("Unknown"); } printf(""); switch (caps->dcd_type) { case RIG_DCD_RIG: printf("rig"); break; case RIG_DCD_PARALLEL: printf("parallel"); break; case RIG_DCD_SERIAL_CTS: case RIG_DCD_SERIAL_DSR: printf("serial"); break; case RIG_DCD_NONE: printf("None"); break; default: printf("Unknown"); } printf(""); switch (caps->port_type) { case RIG_PORT_SERIAL: printf("serial"); break; case RIG_PORT_DEVICE: printf("device"); break; case RIG_PORT_NETWORK: printf("network"); break; case RIG_PORT_UDP_NETWORK: printf("UDP network"); break; case RIG_PORT_NONE: printf("None"); break; default: printf("Unknown"); } printf("%d%d%d%c%d%s", caps->serial_rate_min, caps->serial_rate_max, caps->serial_data_bits, caps->serial_parity == RIG_PARITY_NONE ? 'N' : caps->serial_parity == RIG_PARITY_ODD ? 'O' : caps->serial_parity == RIG_PARITY_EVEN ? 'E' : caps->serial_parity == RIG_PARITY_MARK ? 'M' : 'S', caps->serial_stop_bits, caps->serial_handshake == RIG_HANDSHAKE_NONE ? "none" : (caps->serial_handshake == RIG_HANDSHAKE_XONXOFF ? "XONXOFF" : "CTS/RTS")); printf("%dms%dms%dms%d\n", caps->write_delay, caps->post_write_delay, caps->timeout, caps->retry); return 1; } /* used by print_caps_caps and print_caps_level */ #define print_yn(fn) printf("%s", (fn) ? "Y":"N") /* * backend functions defined * * TODO: add new API calls! */ int print_caps_caps(struct rig_caps *caps, void *data) { printf("%s", caps->rig_model, caps->model_name); /* targetable_vfo is not a function, but a boolean */ print_yn(caps->targetable_vfo); print_yn(caps->set_freq); print_yn(caps->get_freq); print_yn(caps->set_mode); print_yn(caps->get_mode); print_yn(caps->set_vfo); print_yn(caps->get_vfo); print_yn(caps->set_ptt); print_yn(caps->get_ptt); print_yn(caps->get_dcd); print_yn(caps->set_rptr_shift); print_yn(caps->get_rptr_shift); print_yn(caps->set_rptr_offs); print_yn(caps->get_rptr_offs); print_yn(caps->set_split_freq); print_yn(caps->get_split_freq); print_yn(caps->set_split_vfo); print_yn(caps->get_split_vfo); print_yn(caps->set_ts); print_yn(caps->get_ts); print_yn(caps->set_ctcss_tone); print_yn(caps->get_ctcss_tone); print_yn(caps->set_dcs_code); print_yn(caps->get_dcs_code); print_yn(caps->set_powerstat); print_yn(caps->get_powerstat); print_yn(caps->set_trn); print_yn(caps->set_trn); print_yn(caps->decode_event); print_yn(caps->get_info); printf("\n"); return 1; } /* * Get/Set parm abilities */ int print_caps_parm(struct rig_caps *caps, void *data) { setting_t parm; int i; if (!data) { return 0; } parm = (*(int *)data) ? caps->has_set_parm : caps->has_get_parm; printf("%s", (*(int *)data) ? "set" : "get", caps->rig_model, caps->model_name); /* * bitmap_parm: only those who have a label */ for (i = 0; i < RIG_SETTING_MAX; i++) { if (rig_idx2setting(i) & bitmap_parm) { print_yn(parm & rig_idx2setting(i)); } } printf("\n"); return 1; } /* * VFO Ops capabilities */ int print_caps_vfo_ops(struct rig_caps *caps, void *data) { setting_t vfo_ops; int i; if (!data) { return 0; } // Only set for these vfo_ops = (*(int *)data) ? caps->vfo_ops : caps->vfo_ops; printf("%s", (*(int *)data) ? "op" : "op", caps->rig_model, caps->model_name); /* * bitmap_vfo_ops: only those who have a label */ for (i = 0; i < RIG_SETTING_MAX; i++) { if (rig_idx2setting(i) & bitmap_vfo_ops) { print_yn(vfo_ops & rig_idx2setting(i)); } } printf("\n"); return 1; } /* * Get/Set level abilities */ int print_caps_level(struct rig_caps *caps, void *data) { setting_t level; int i; if (!data) { return 0; } level = (*(int *)data) ? caps->has_set_level : caps->has_get_level; printf("%s", (*(int *)data) ? "set" : "get", caps->rig_model, caps->model_name); /* * bitmap_level: only those who have a label */ for (i = 0; i < 32; i++) { if (rig_idx2setting(i) & bitmap_level) { print_yn(level & rig_idx2setting(i)); } } printf("\n"); return 1; } /* * Get/Set func abilities */ int print_caps_func(struct rig_caps *caps, void *data) { setting_t func; int i; if (!data) { return 0; } func = (*(int *)data) ? caps->has_set_func : caps->has_get_func; printf("%s", (*(int *)data) ? "set" : "get", caps->rig_model, caps->model_name); /* * bitmap_func: only those who have a label */ for (i = 0; i < RIG_SETTING_MAX; i++) { if (rig_idx2setting(i) & bitmap_func) { print_yn(func & rig_idx2setting(i)); } } printf("\n"); return 1; } /* * inlined PNG graphics * * FIXME: default output pics is for region2: add region 1 too! */ int print_caps_range(struct rig_caps *caps, void *data) { create_png_range(caps->rx_range_list2, caps->tx_range_list2, caps->rig_model); printf("%s" "", caps->rig_model, caps->model_name, caps->rig_model); return 1; } #define RANGE_WIDTH 600 #define RANGE_HEIGHT 16 #define RANGE_MIDHEIGHT (RANGE_HEIGHT/2) #define RX_R 0 #define RX_G 255 #define RX_B 255 #define TX_R 0 #define TX_G 0 #define TX_B 255 #define HF_H 10 #define VHF_H 30 #define UHF_H 50 #define IM_LGD 21 static void draw_range(const freq_range_t range_list[], gdImagePtr im_rng, int h1, int h2, int rgb) { int i; for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { float start_pix, end_pix; if (range_list[i].startf == 0 && range_list[i].endf == 0) { break; } start_pix = range_list[i].startf; end_pix = range_list[i].endf; /* * HF */ if (range_list[i].startf < MHz(30)) { start_pix = start_pix / MHz(30) * RANGE_WIDTH; end_pix = end_pix / MHz(30) * RANGE_WIDTH; if (end_pix >= RANGE_WIDTH) { end_pix = RANGE_WIDTH - 1; } start_pix += IM_LGD; end_pix += IM_LGD; gdImageFilledRectangle(im_rng, start_pix, HF_H + h1, end_pix, HF_H + h2, rgb); } /* * VHF */ start_pix = range_list[i].startf; end_pix = range_list[i].endf; if ((range_list[i].startf > MHz(30) && range_list[i].startf < MHz(300)) || (range_list[i].startf < MHz(30) && range_list[i].endf > MHz(30))) { start_pix = (start_pix - MHz(30)) / MHz(300) * RANGE_WIDTH; end_pix = (end_pix - MHz(30)) / MHz(300) * RANGE_WIDTH; if (start_pix < 0) { start_pix = 0; } if (end_pix >= RANGE_WIDTH) { end_pix = RANGE_WIDTH - 1; } start_pix += IM_LGD; end_pix += IM_LGD; gdImageFilledRectangle(im_rng, start_pix, VHF_H + h1, end_pix, VHF_H + h2, rgb); } /* * UHF */ start_pix = range_list[i].startf; end_pix = range_list[i].endf; if ((range_list[i].startf > MHz(300) && range_list[i].startf < GHz(3)) || (range_list[i].startf < MHz(300) && range_list[i].endf > MHz(300))) { start_pix = (start_pix - MHz(300)) / GHz(3) * RANGE_WIDTH; end_pix = (end_pix - MHz(300)) / GHz(3) * RANGE_WIDTH; if (start_pix < 0) { start_pix = 0; } if (end_pix >= RANGE_WIDTH) { end_pix = RANGE_WIDTH - 1; } start_pix += IM_LGD; end_pix += IM_LGD; gdImageFilledRectangle(im_rng, start_pix, UHF_H + h1, end_pix, UHF_H + h2, rgb); } } } int create_png_range(const freq_range_t rx_range_list[], const freq_range_t tx_range_list[], int num) { FILE *out; /* Input and output images */ gdImagePtr im_rng; char rng_fname[128]; /* Color indexes */ #if 0 int white; #endif int black; int rx_rgb, tx_rgb; /* Create output image, x by y pixels. */ im_rng = gdImageCreate(RANGE_WIDTH + IM_LGD, UHF_H + RANGE_HEIGHT); /* First color allocated is background. */ // white = gdImageColorAllocate(im_rng, 255, 255, 255); gdImageColorAllocate(im_rng, 255, 255, 255); black = gdImageColorAllocate(im_rng, 0, 0, 0); #if 0 /* Set transparent color. */ gdImageColorTransparent(im_rng, white); #endif /* Try to load demoin.png and paste part of it into the output image. */ tx_rgb = gdImageColorAllocate(im_rng, TX_R, TX_G, TX_B); rx_rgb = gdImageColorAllocate(im_rng, RX_R, RX_G, RX_B); draw_range(rx_range_list, im_rng, 0, RANGE_MIDHEIGHT - 1, rx_rgb); draw_range(tx_range_list, im_rng, RANGE_MIDHEIGHT, RANGE_HEIGHT - 1, tx_rgb); gdImageRectangle(im_rng, IM_LGD, HF_H, IM_LGD + RANGE_WIDTH - 1, HF_H + RANGE_HEIGHT - 1, black); gdImageRectangle(im_rng, IM_LGD, VHF_H, IM_LGD + RANGE_WIDTH - 1, VHF_H + RANGE_HEIGHT - 1, black); gdImageRectangle(im_rng, IM_LGD, UHF_H, IM_LGD + RANGE_WIDTH - 1, UHF_H + RANGE_HEIGHT - 1, black); /* gdImageStringUp */ gdImageString(im_rng, gdFontSmall, 1, HF_H + 1, (unsigned char *) "HF", black); gdImageString(im_rng, gdFontSmall, 1, VHF_H + 1, (unsigned char *) "VHF", black); gdImageString(im_rng, gdFontSmall, 1, UHF_H + 1, (unsigned char *) "UHF", black); /* Make output image interlaced (allows "fade in" in some viewers, and in the latest web browsers) */ gdImageInterlace(im_rng, 1); snprintf(rng_fname, sizeof(rng_fname), "range%d.png", num); out = fopen(rng_fname, "wb"); /* Write PNG */ gdImagePng(im_rng, out); fclose(out); gdImageDestroy(im_rng); return 0; } int main(int argc, char *argv[]) { time_t gentime; int set_or_get; int i, nbytes, nbytes_total = 0; char *pbuf, prntbuf[4096]; rig_load_all_backends(); printf(""); printf("" "" "" "" "" "" "" "" "" "" "\n"); rig_list_foreach(print_caps_sum, NULL); printf("
ModelMfgVers.StatusTypeFreq. rangeParametersCapabilitiesGet funcSet funcGet levelSet levelGet parmSet parmVFO Ops
\n"); printf("

"); printf("\n"); printf("" "" "" "\n"); rig_list_foreach(print_caps_parameters, NULL); printf("
ModelPTTDCDPortSpeed minSpeed maxParm.HandshakeWrite delayPost delayTimeoutRetry
\n"); printf("

"); printf("\n"); printf("\n"); rig_list_foreach(print_caps_range, NULL); printf("
ModelFreq. range
\n"); printf("

"); printf("\n"); printf("" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n"); rig_list_foreach(print_caps_caps, NULL); printf("
ModelTarget VFOSet freqGet freqSet modeGet modeSet VFOGet VFOSet PTTGet PTTGet DCDSet rptr shiftGet rptr shiftSet rptr offsGet rptr offsSet split frqGet split frqSet splitGet splitSet tsGet tsSet CTCSSGet CTCSSSet DCSGet DCSSet Power StatGet Power StatSet trnGet trnDecodeGet info
\n"); printf("

"); bitmap_func = 0; prntbuf[0] = '\0'; pbuf = prntbuf; for (i = 0; i < RIG_SETTING_MAX; i++) { setting_t func = rig_idx2setting(i); const char *s = rig_strfunc(func); if (!s) { continue; } bitmap_func |= func; nbytes = strlen("") + strlen(s) + 1; nbytes_total += nbytes; pbuf += snprintf(pbuf, sizeof(pbuf) - nbytes_total, "%s", s); if (strlen(pbuf) > sizeof(pbuf) + nbytes) { printf("Buffer overflow in %s\n", __func__); } } printf("Has set func"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 1; rig_list_foreach(print_caps_func, &set_or_get); printf("
Model
\n"); printf("

"); printf("Has get func"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 0; rig_list_foreach(print_caps_func, &set_or_get); printf("
Model
\n"); printf("

"); bitmap_level = 0; prntbuf[0] = '\0'; pbuf = prntbuf; for (i = 0; i < RIG_SETTING_MAX; i++) { setting_t level = rig_idx2setting(i); const char *s = rig_strlevel(level); if (!s) { continue; } bitmap_level |= level; nbytes = strlen("") + strlen(s) + 1; nbytes_total += nbytes; pbuf += snprintf(pbuf, sizeof(pbuf) - nbytes_total, "%s", s); if (strlen(pbuf) > sizeof(pbuf) + nbytes) { printf("Buffer overflow in %s\n", __func__); } } printf("Set level"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 1; rig_list_foreach(print_caps_level, &set_or_get); printf("
Model
\n"); printf("

"); printf("Get level"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 0; rig_list_foreach(print_caps_level, &set_or_get); printf("
Model
\n"); printf("

"); bitmap_parm = 0; prntbuf[0] = '\0'; pbuf = prntbuf; for (i = 0; i < RIG_SETTING_MAX; i++) { setting_t parm = rig_idx2setting(i); const char *s = rig_strparm(parm); if (!s) { continue; } bitmap_parm |= parm; nbytes = strlen("") + strlen(s) + 1; nbytes_total += nbytes; pbuf += snprintf(pbuf, sizeof(pbuf) - nbytes_total, "%s", s); if (strlen(pbuf) > sizeof(pbuf) + nbytes) { printf("Buffer overflow in %s\n", __func__); } } printf("Set parm"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 1; rig_list_foreach(print_caps_parm, &set_or_get); printf("
Model
\n"); printf("

"); printf("Get parm"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 0; rig_list_foreach(print_caps_parm, &set_or_get); printf("
Model
\n"); printf("

"); bitmap_vfo_ops = 0; prntbuf[0] = '\0'; pbuf = prntbuf; for (i = 0; i < RIG_SETTING_MAX; i++) { setting_t op = rig_idx2setting(i); const char *s = rig_strvfop(op); if (!s) { continue; } bitmap_vfo_ops |= op; nbytes = strlen("") + strlen(s) + 1; nbytes_total += nbytes; pbuf += snprintf(pbuf, sizeof(pbuf) - nbytes_total, "%s", s); if (strlen(pbuf) > sizeof(pbuf) + nbytes) { printf("Buffer overflow in %s\n", __func__); } } printf("VFO Ops"); printf("\n"); printf("%s\n", prntbuf); set_or_get = 0; rig_list_foreach(print_caps_vfo_ops, &set_or_get); printf("
Model
\n"); printf("

"); time(&gentime); printf("Rigmatrix generated %s\n", ctime(&gentime)); printf("\n"); return 0; } hamlib-4.6.5/tests/dumpstate.c0000664000175000017500000007400615056640443011777 /* * dumpstate.c - Copyright (C) 2000-2012 Stephane Fillod * This programs dumps the capabilities of a backend rig. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include "misc.h" #include "riglist.h" #include "sprintflst.h" #include "rigctl_parse.h" #include "../rigs/icom/icom.h" void range_print(FILE *fout, const struct freq_range_list range_list[], int rx); int range_sanity_check(const struct freq_range_list range_list[], int rx); int ts_sanity_check(const struct tuning_step_list tuning_step[]); static void dump_chan_caps(const channel_cap_t *chan, FILE *fout); struct rig_type_s { int type; char *description; }; static struct rig_type_s rig_type[] = { {RIG_TYPE_OTHER, "Other"}, {RIG_FLAG_RECEIVER, "Receiver"}, {RIG_FLAG_TRANSMITTER, "Transmitter"}, {RIG_FLAG_SCANNER, "Scanner"}, {RIG_FLAG_MOBILE, "Mobile"}, {RIG_FLAG_HANDHELD, "Handheld"}, {RIG_FLAG_COMPUTER, "Computer"}, {RIG_FLAG_TRANSCEIVER, "Transceiver"}, {RIG_FLAG_TRUNKING, "Trunking scanner"}, {RIG_FLAG_APRS, "APRS"}, {RIG_FLAG_TNC, "TNC"}, {RIG_FLAG_DXCLUSTER, "DxCluster"}, {RIG_FLAG_DXCLUSTER, "DxCluster"}, {RIG_FLAG_TUNER, "Tuner"}, {-1, "?\n"} }; static int print_ext(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { return print_ext_param(cfp, ptr); } /* * the rig may be in rig_init state, but not opened */ int dumpstate(RIG *rig, FILE *fout) { const struct rig_caps *caps; struct rig_state *rs = STATE(rig); int status, i; int can_esplit, can_echannel; char freqbuf[20]; int backend_warnings = 0; char warnbuf[4096]; char prntbuf[4096]; /* a malloc would be better.. */ char *label1, *label2, *label3, *label4, *label5; char *labelrx1; // , *labelrx2, *labelrx3, *labelrx4, *labelrx5; warnbuf[0] = 0; prntbuf[0] = 0; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; fprintf(fout, "Caps dump for model: %u\n", rs->rig_model); fprintf(fout, "Model name:\t%s\n", rs->model_name); fprintf(fout, "Mfg name:\t%s\n", rs->mfg_name); fprintf(fout, "Hamlib version:\t%s\n", hamlib_version2); fprintf(fout, "Backend version:\t%s\n", rs->version); fprintf(fout, "Backend copyright:\t%s\n", rs->copyright); fprintf(fout, "Backend status:\t%s\n", rig_strstatus(rs->status)); fprintf(fout, "Rig type:\t"); char *unknown = "Unknown"; for (i = 0; rig_type[i].type != -1; ++i) { if ((rig_type[i].type & rs->rig_type) == rig_type[i].type) { fprintf(fout, "%s ", rig_type[i].description); unknown = ""; } } fprintf(fout, "%s\n", unknown); if (strlen(unknown) > 0) { strcat(warnbuf, " RIG_TYPE"); backend_warnings++; } fprintf(fout, "PTT type:\t"); switch (rs->ptt_type) { case RIG_PTT_RIG: fprintf(fout, "Rig capable\n"); break; case RIG_PTT_RIG_MICDATA: fprintf(fout, "Rig capable (Mic/Data)\n"); break; case RIG_PTT_PARALLEL: fprintf(fout, "Parallel port (DATA0)\n"); break; case RIG_PTT_SERIAL_RTS: fprintf(fout, "Serial port (CTS/RTS)\n"); break; case RIG_PTT_SERIAL_DTR: fprintf(fout, "Serial port (DTR/DSR)\n"); break; case RIG_PTT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " PTT_TYPE"); backend_warnings++; } fprintf(fout, "DCD type:\t"); switch (rs->dcd_type) { case RIG_DCD_RIG: fprintf(fout, "Rig capable\n"); break; case RIG_DCD_PARALLEL: fprintf(fout, "Parallel port (/STROBE)\n"); break; case RIG_DCD_SERIAL_CTS: fprintf(fout, "Serial port (CTS/RTS)\n"); break; case RIG_DCD_SERIAL_DSR: fprintf(fout, "Serial port (DTR/DSR)\n"); break; case RIG_DCD_SERIAL_CAR: fprintf(fout, "Serial port (CD)\n"); break; case RIG_DCD_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " DCD_TYPE"); backend_warnings++; } fprintf(fout, "Port type:\t"); switch (rs->port_type) { case RIG_PORT_SERIAL: fprintf(fout, "RS-232\n"); fprintf(fout, "Serial speed: %d..%d baud, %d%c%d, ctrl=%s\n", rs->serial_rate_min, rs->serial_rate_max, rs->serial_data_bits, rs->serial_parity == RIG_PARITY_NONE ? 'N' : rs->serial_parity == RIG_PARITY_ODD ? 'O' : rs->serial_parity == RIG_PARITY_EVEN ? 'E' : rs->serial_parity == RIG_PARITY_MARK ? 'M' : 'S', rs->serial_stop_bits, rs->serial_handshake == RIG_HANDSHAKE_NONE ? "NONE" : (rs->serial_handshake == RIG_HANDSHAKE_XONXOFF ? "XONXOFF" : "CTS/RTS") ); break; case RIG_PORT_PARALLEL: fprintf(fout, "Parallel\n"); break; case RIG_PORT_DEVICE: fprintf(fout, "Device driver\n"); break; case RIG_PORT_USB: fprintf(fout, "USB\n"); break; case RIG_PORT_NETWORK: fprintf(fout, "Network link\n"); break; case RIG_PORT_UDP_NETWORK: fprintf(fout, "UDP Network link\n"); break; case RIG_PORT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " PORT_TYPE"); backend_warnings++; } fprintf(fout, "Write delay: %dms, timeout %dms, %d retry\n", rs->write_delay, rs->timeout, rs->retry); fprintf(fout, "Post write delay: %dms\n", rs->post_write_delay); fprintf(fout, "Has targetable VFO: %s\n", rs->targetable_vfo ? "Y" : "N"); fprintf(fout, "Has async data support: %s\n", rs->async_data_supported ? "Y" : "N"); fprintf(fout, "Announce: 0x%x\n", rs->announces); fprintf(fout, "Max RIT: -%ld.%ldkHz/+%ld.%ldkHz\n", rs->max_rit / 1000, rs->max_rit % 1000, rs->max_rit / 1000, rs->max_rit % 1000); fprintf(fout, "Max XIT: -%ld.%ldkHz/+%ld.%ldkHz\n", rs->max_xit / 1000, rs->max_xit % 1000, rs->max_xit / 1000, rs->max_xit % 1000); fprintf(fout, "Max IF-SHIFT: -%ld.%ldkHz/+%ld.%ldkHz\n", rs->max_ifshift / 1000, rs->max_ifshift % 1000, rs->max_ifshift / 1000, rs->max_ifshift % 1000); fprintf(fout, "Preamp:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i] != 0; i++) { fprintf(fout, " %ddB", rs->preamp[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "Attenuator:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i] != 0; i++) { fprintf(fout, " %ddB", rs->attenuator[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "AGC levels:"); const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rs->priv; if (priv_caps && RIG_BACKEND_NUM(rs->rig_model) == RIG_ICOM && priv_caps->agc_levels_present) { for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST; i++) { fprintf(fout, " %d=%s", priv_caps->agc_levels[i].level, rig_stragclevel(priv_caps->agc_levels[i].level)); } } else { for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && i < rs->agc_level_count; i++) { fprintf(fout, " %d=%s", rs->agc_levels[i], rig_stragclevel(rs->agc_levels[i])); } } if (i == 0) { fprintf(fout, " %d=%s", RIG_AGC_NONE, rig_stragclevel(RIG_AGC_NONE)); } fprintf(fout, "\n"); fprintf(fout, "CTCSS:"); for (i = 0; rs->ctcss_list && i < 60 && rs->ctcss_list[i] != 0; i++) { fprintf(fout, " %u.%1u", rs->ctcss_list[i] / 10, rs->ctcss_list[i] % 10); } if (i == 0) { fprintf(fout, " None"); } else { fprintf(fout, " Hz, %d tones", i); } fprintf(fout, "\n"); fprintf(fout, "DCS:"); for (i = 0; rs->dcs_list && i < 128 && rs->dcs_list[i] != 0; i++) { fprintf(fout, " %u", rs->dcs_list[i]); } if (i == 0) { fprintf(fout, " None"); } else { fprintf(fout, ", %d codes", i); } fprintf(fout, "\n"); rig_sprintf_func(prntbuf, sizeof(prntbuf), rs->has_get_func); fprintf(fout, "Get functions: %s\n", prntbuf); rig_sprintf_func(prntbuf, sizeof(prntbuf), rs->has_set_func); fprintf(fout, "Set functions: %s\n", prntbuf); fprintf(fout, "Extra functions:\n"); rig_ext_func_foreach(rig, print_ext, fout); rig_sprintf_level_gran(prntbuf, sizeof(prntbuf), rs->has_get_level, rs->level_gran); fprintf(fout, "Get level: %s\n", prntbuf); if ((rs->has_get_level & RIG_LEVEL_RAWSTR) && rs->str_cal.size == 0 && !(rs->has_get_level & RIG_LEVEL_STRENGTH)) { fprintf(fout, "Warning--backend has get RAWSTR, but not calibration data\n"); strcat(warnbuf, " RAWSTR_level"); backend_warnings++; } rig_sprintf_level_gran(prntbuf, sizeof(prntbuf), rs->has_set_level, rs->level_gran); fprintf(fout, "Set level: %s\n", prntbuf); if (rs->has_set_level & RIG_LEVEL_READONLY_LIST) { //fprintf(fout, "Warning--backend can set readonly levels=0x%0llx\n", rs->has_set_level & RIG_LEVEL_READONLY_LIST); fprintf(fout, "Warning--backend can set readonly levels\n"); strcat(warnbuf, " READONLY_LEVEL"); backend_warnings++; } fprintf(fout, "Extra levels:\n"); rig_ext_level_foreach(rig, print_ext, fout); rig_sprintf_parm_gran(prntbuf, sizeof(prntbuf), rs->has_get_parm, rs->parm_gran); fprintf(fout, "Get parameters: %s\n", prntbuf); rig_sprintf_parm_gran(prntbuf, sizeof(prntbuf), rs->has_set_parm, rs->parm_gran); fprintf(fout, "Set parameters: %s\n", prntbuf); if (rs->has_set_parm & RIG_PARM_READONLY_LIST) { fprintf(fout, "Warning--backend can set readonly parms!\n"); strcat(warnbuf, " READONLY_PARM"); backend_warnings++; } fprintf(fout, "Extra parameters:\n"); rig_ext_parm_foreach(rig, print_ext, fout); if (rs->mode_list != 0) { rig_sprintf_mode(prntbuf, sizeof(prntbuf), rs->mode_list); } else { strcpy(prntbuf, "None. This backend might be bogus!\n"); strcat(warnbuf, " MODE_LIST"); backend_warnings++; } fprintf(fout, "Mode list: %s\n", prntbuf); if (rs->vfo_list != 0) { rig_sprintf_vfo(prntbuf, sizeof(prntbuf), rs->vfo_list); } else { strcpy(prntbuf, "None. This backend might be bogus!\n"); strcat(warnbuf, " VFO_LIST"); backend_warnings++; } fprintf(fout, "VFO list: %s\n", prntbuf); rig_sprintf_vfop(prntbuf, sizeof(prntbuf), rs->vfo_ops); fprintf(fout, "VFO Ops: %s\n", prntbuf); rig_sprintf_scan(prntbuf, sizeof(prntbuf), rs->scan_ops); fprintf(fout, "Scan Ops: %s\n", prntbuf); fprintf(fout, "Number of banks:\t%d\n", rs->bank_qty); fprintf(fout, "Memory name desc size:\t%d\n", rs->chan_desc_sz); fprintf(fout, "Memories:"); for (i = 0; i < HAMLIB_CHANLSTSIZ && rs->chan_list[i].type; i++) { fprintf(fout, "\n\t%d..%d: \t%s", rs->chan_list[i].startc, rs->chan_list[i].endc, rig_strmtype(rs->chan_list[i].type)); fprintf(fout, "\n\t Mem caps: "); dump_chan_caps(&rs->chan_list[i].mem_caps, fout); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); label1 = rs->tx_range_list1->label; label1 = label1 == NULL ? "TBD" : label1; fprintf(fout, "TX ranges #1 for %s:\n", label1); range_print(fout, rs->tx_range_list1, 0); labelrx1 = rs->rx_range_list1->label; labelrx1 = labelrx1 == NULL ? "TBD" : labelrx1; fprintf(fout, "RX ranges #1 for %s:\n", labelrx1); range_print(fout, rs->rx_range_list1, 1); label2 = rs->rx_range_list2->label; label2 = label2 == NULL ? "TBD" : label2; fprintf(fout, "TX ranges #2 for %s:\n", label2); range_print(fout, rs->tx_range_list2, 0); label2 = rs->rx_range_list2->label; label2 = label2 == NULL ? "TBD" : label2; fprintf(fout, "RX ranges #2 for %s:\n", label2); range_print(fout, rs->rx_range_list2, 1); label3 = rs->rx_range_list3->label; label3 = label3 == NULL ? "TBD" : label3; fprintf(fout, "TX ranges #3 for %s:\n", label3); range_print(fout, rs->tx_range_list3, 0); label3 = rs->rx_range_list3->label; label3 = label3 == NULL ? "TBD" : label3; fprintf(fout, "RX ranges #3 for %s:\n", label3); range_print(fout, rs->rx_range_list3, 1); label4 = rs->rx_range_list4->label; label4 = label4 == NULL ? "TBD" : label4; fprintf(fout, "TX ranges #4 for %s:\n", label4); range_print(fout, rs->tx_range_list5, 0); label4 = rs->rx_range_list4->label; label4 = label4 == NULL ? "TBD" : label4; fprintf(fout, "RX ranges #4 for %s:\n", label4); range_print(fout, rs->rx_range_list5, 1); label5 = rs->rx_range_list5->label; label5 = label5 == NULL ? "TBD" : label5; fprintf(fout, "TX ranges #5 for %s:\n", label5); range_print(fout, rs->tx_range_list5, 0); label5 = rs->rx_range_list5->label; label5 = label5 == NULL ? "TBD" : label5; fprintf(fout, "RX ranges #5 for %s:\n", label5); range_print(fout, rs->rx_range_list5, 1); status = range_sanity_check(rs->tx_range_list1, 0); fprintf(fout, "TX ranges #1 status for %s:\t%s (%d)\n", label1, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#1"); backend_warnings++; } status = range_sanity_check(rs->rx_range_list1, 1); fprintf(fout, "RX ranges #1 status for %s:\t%s (%d)\n", labelrx1, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#1"); backend_warnings++; } status = range_sanity_check(rs->tx_range_list2, 0); fprintf(fout, "TX ranges #2 status for %s:\t%s (%d)\n", label2, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#2"); backend_warnings++; } status = range_sanity_check(rs->rx_range_list2, 1); fprintf(fout, "RX ranges #2 status for %s:\t%s (%d)\n", label2, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#2"); backend_warnings++; } status = range_sanity_check(rs->tx_range_list3, 0); fprintf(fout, "TX ranges #3 status for %s:\t%s (%d)\n", label3, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#3"); backend_warnings++; } status = range_sanity_check(rs->rx_range_list3, 1); fprintf(fout, "RX ranges #3 status for %s:\t%s (%d)\n", label3, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#3"); backend_warnings++; } status = range_sanity_check(rs->tx_range_list4, 0); fprintf(fout, "TX ranges #4 status for %s:\t%s (%d)\n", label4, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#4"); backend_warnings++; } status = range_sanity_check(rs->rx_range_list4, 1); fprintf(fout, "RX ranges #4 status for %s:\t%s (%d)\n", label4, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#4"); backend_warnings++; } status = range_sanity_check(rs->tx_range_list5, 0); fprintf(fout, "TX ranges #5 status for %s:\t%s (%d)\n", label5, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#5"); backend_warnings++; } status = range_sanity_check(rs->rx_range_list5, 1); fprintf(fout, "RX ranges #5 status for %s:\t%s (%d)\n", label5, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#5"); backend_warnings++; } fprintf(fout, "Tuning steps:"); for (i = 0; i < HAMLIB_TSLSTSIZ && !RIG_IS_TS_END(rs->tuning_steps[i]); i++) { if (rs->tuning_steps[i].ts == RIG_TS_ANY) { strcpy(freqbuf, "ANY"); /* strcpy! Looks safe for now */ } else { sprintf_freq(freqbuf, sizeof(freqbuf), rs->tuning_steps[i].ts); } rig_sprintf_mode(prntbuf, sizeof(prntbuf), rs->tuning_steps[i].modes); fprintf(fout, "\n\t%s: \t%s", freqbuf, prntbuf); } if (i == 0) { fprintf(fout, " None! This backend might be bogus!"); strcat(warnbuf, " TUNING_STEPS"); backend_warnings++; } fprintf(fout, "\n"); status = ts_sanity_check(rs->tuning_steps); fprintf(fout, "Tuning steps status:\t%s (%d)\n", status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TUNING_SANE"); backend_warnings++; } fprintf(fout, "Filters:"); for (i = 0; i < HAMLIB_FLTLSTSIZ && !RIG_IS_FLT_END(rs->filters[i]); i++) { if (rs->filters[i].width == RIG_FLT_ANY) { strcpy(freqbuf, "ANY"); } else { sprintf_freq(freqbuf, sizeof(freqbuf), rs->filters[i].width); } rig_sprintf_mode(prntbuf, sizeof(prntbuf), rs->filters[i].modes); fprintf(fout, "\n\t%s: \t%s", freqbuf, prntbuf); } if (i == 0) { fprintf(fout, " None. This backend might be bogus!"); strcat(warnbuf, " FILTERS"); backend_warnings++; } fprintf(fout, "\n"); fprintf(fout, "Bandwidths:"); for (i = 1; i < RIG_MODE_TESTS_MAX; i <<= 1) { pbwidth_t pbnorm = rig_passband_normal(rig, i); if (pbnorm == 0) { continue; } sprintf_freq(freqbuf, sizeof(freqbuf), pbnorm); fprintf(fout, "\n\t%s\tNormal: %s,\t", rig_strrmode(i), freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_narrow(rig, i)); fprintf(fout, "Narrow: %s,\t", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_wide(rig, i)); fprintf(fout, "Wide: %s", freqbuf); } fprintf(fout, "\n"); fprintf(fout, "Spectrum scopes:"); for (i = 0; i < HAMLIB_MAX_SPECTRUM_SCOPES && rs->spectrum_scopes[i].name != NULL; i++) { fprintf(fout, " %d=\"%s\"", rs->spectrum_scopes[i].id, rs->spectrum_scopes[i].name); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); rig_sprintf_spectrum_modes(prntbuf, sizeof(prntbuf), rs->spectrum_modes); fprintf(fout, "Spectrum modes: %s\n", prntbuf); rig_sprintf_spectrum_spans(prntbuf, sizeof(prntbuf), rs->spectrum_spans); fprintf(fout, "Spectrum spans: %s\n", prntbuf); rig_sprintf_spectrum_avg_modes(prntbuf, sizeof(prntbuf), rs->spectrum_avg_modes); fprintf(fout, "Spectrum averaging modes: %s\n", prntbuf); fprintf(fout, "Spectrum attenuator:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->spectrum_attenuator[i] != 0; i++) { fprintf(fout, " %ddB", rs->spectrum_attenuator[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "Has priv data:\t%c\n", rs->priv != NULL ? 'Y' : 'N'); /* * Status is either 'Y'es, 'E'mulated, 'N'o * * TODO: keep me up-to-date with API call list! */ fprintf(fout, "Has Init:\t%c\n", rig->caps->rig_init != NULL ? 'Y' : 'N'); fprintf(fout, "Has Cleanup:\t%c\n", rig->caps->rig_cleanup != NULL ? 'Y' : 'N'); fprintf(fout, "Has Open:\t%c\n", rig->caps->rig_open != NULL ? 'Y' : 'N'); fprintf(fout, "Has Close:\t%c\n", rig->caps->rig_close != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Conf:\t%c\n", rig->caps->set_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Conf:\t%c\n", rig->caps->get_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Frequency:\t%c\n", rig->caps->set_freq != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Frequency:\t%c\n", rig->caps->get_freq != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Mode:\t%c\n", rig->caps->set_mode != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Mode:\t%c\n", rig->caps->get_mode != NULL ? 'Y' : 'N'); fprintf(fout, "Can set VFO:\t%c\n", rig->caps->set_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can get VFO:\t%c\n", rig->caps->get_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can set PTT:\t%c\n", rig->caps->set_ptt != NULL ? 'Y' : 'N'); fprintf(fout, "Can get PTT:\t%c\n", rig->caps->get_ptt != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCD:\t%c\n", rig->caps->get_dcd != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Repeater Duplex:\t%c\n", rig->caps->set_rptr_shift != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Repeater Duplex:\t%c\n", rig->caps->get_rptr_shift != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Repeater Offset:\t%c\n", rig->caps->set_rptr_offs != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Repeater Offset:\t%c\n", rig->caps->get_rptr_offs != NULL ? 'Y' : 'N'); can_esplit = rig->caps->set_split_vfo && (rig->caps->set_vfo || (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && rig->caps->vfo_op)); fprintf(fout, "Can set Split Freq:\t%c\n", rig->caps->set_split_freq != NULL ? 'Y' : (can_esplit && rig->caps->set_freq ? 'E' : 'N')); fprintf(fout, "Can get Split Freq:\t%c\n", rig->caps->get_split_freq != NULL ? 'Y' : (can_esplit && rig->caps->get_freq ? 'E' : 'N')); fprintf(fout, "Can set Split Mode:\t%c\n", rig->caps->set_split_mode != NULL ? 'Y' : (can_esplit && rig->caps->set_mode ? 'E' : 'N')); fprintf(fout, "Can get Split Mode:\t%c\n", rig->caps->get_split_mode != NULL ? 'Y' : (can_esplit && rig->caps->get_mode ? 'E' : 'N')); fprintf(fout, "Can set Split VFO:\t%c\n", rig->caps->set_split_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Split VFO:\t%c\n", rig->caps->get_split_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Tuning Step:\t%c\n", rig->caps->set_ts != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Tuning Step:\t%c\n", rig->caps->get_ts != NULL ? 'Y' : 'N'); fprintf(fout, "Can set RIT:\t%c\n", rig->caps->set_rit != NULL ? 'Y' : 'N'); fprintf(fout, "Can get RIT:\t%c\n", rig->caps->get_rit != NULL ? 'Y' : 'N'); fprintf(fout, "Can set XIT:\t%c\n", rig->caps->set_xit != NULL ? 'Y' : 'N'); fprintf(fout, "Can get XIT:\t%c\n", rig->caps->get_xit != NULL ? 'Y' : 'N'); fprintf(fout, "Can set CTCSS:\t%c\n", rig->caps->set_ctcss_tone != NULL ? 'Y' : 'N'); fprintf(fout, "Can get CTCSS:\t%c\n", rig->caps->get_ctcss_tone != NULL ? 'Y' : 'N'); fprintf(fout, "Can set DCS:\t%c\n", rig->caps->set_dcs_code != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCS:\t%c\n", rig->caps->get_dcs_code != NULL ? 'Y' : 'N'); fprintf(fout, "Can set CTCSS Squelch:\t%c\n", rig->caps->set_ctcss_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can get CTCSS Squelch:\t%c\n", rig->caps->get_ctcss_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can set DCS Squelch:\t%c\n", rig->caps->set_dcs_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCS Squelch:\t%c\n", rig->caps->get_dcs_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Power Stat:\t%c\n", rig->caps->set_powerstat != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Power Stat:\t%c\n", rig->caps->get_powerstat != NULL ? 'Y' : 'N'); fprintf(fout, "Can Reset:\t%c\n", rig->caps->reset != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Ant:\t%c\n", rig->caps->get_ant != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Ant:\t%c\n", rig->caps->set_ant != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Transceive:\t%c\n", rig->caps->set_trn != NULL ? 'Y' : rig->caps->transceive == RIG_TRN_RIG ? 'E' : 'N'); fprintf(fout, "Can get Transceive:\t%c\n", rig->caps->get_trn != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Func:\t%c\n", rig->caps->set_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Func:\t%c\n", rig->caps->get_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Level:\t%c\n", rig->caps->set_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Level:\t%c\n", rig->caps->get_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Param:\t%c\n", rig->caps->set_parm != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Param:\t%c\n", rig->caps->get_parm != NULL ? 'Y' : 'N'); fprintf(fout, "Can send DTMF:\t%c\n", rig->caps->send_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can recv DTMF:\t%c\n", rig->caps->recv_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Morse:\t%c\n", rig->caps->send_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can stop Morse:\t%c\n", rig->caps->stop_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can wait Morse:\t%c\n", rig->caps->wait_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Voice:\t%c\n", rig->caps->send_voice_mem != NULL ? 'Y' : 'N'); fprintf(fout, "Can decode Events:\t%c\n", rig->caps->decode_event != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Bank:\t%c\n", rig->caps->set_bank != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Mem:\t%c\n", rig->caps->set_mem != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Mem:\t%c\n", rig->caps->get_mem != NULL ? 'Y' : 'N'); can_echannel = rig->caps->set_mem && ((rig->caps->set_vfo && ((rs->vfo_list & RIG_VFO_MEM) == RIG_VFO_MEM)) || (rig->caps->vfo_op && rig_has_vfo_op(rig, RIG_OP_TO_VFO | RIG_OP_FROM_VFO))); fprintf(fout, "Can set Channel:\t%c\n", rig->caps->set_channel != NULL ? 'Y' : (can_echannel ? 'E' : 'N')); fprintf(fout, "Can get Channel:\t%c\n", rig->caps->get_channel != NULL ? 'Y' : (can_echannel ? 'E' : 'N')); fprintf(fout, "Can ctl Mem/VFO:\t%c\n", rig->caps->vfo_op != NULL ? 'Y' : 'N'); fprintf(fout, "Can Scan:\t%c\n", rig->caps->scan != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Info:\t%c\n", rig->caps->get_info != NULL ? 'Y' : 'N'); fprintf(fout, "Can get power2mW:\t%c\n", caps->power2mW != NULL ? 'Y' : 'N'); fprintf(fout, "Can get mW2power:\t%c\n", caps->mW2power != NULL ? 'Y' : 'N'); fprintf(fout, "\nOverall backend warnings: %d %c %s\n", backend_warnings, warnbuf[0] != 0 ? '=' : ' ', warnbuf); return backend_warnings; } static void dump_chan_caps(const channel_cap_t *chan, FILE *fout) { if (chan->bank_num) { fprintf(fout, "BANK "); } if (chan->ant) { fprintf(fout, "ANT "); } if (chan->freq) { fprintf(fout, "FREQ "); } if (chan->mode) { fprintf(fout, "MODE "); } if (chan->width) { fprintf(fout, "WIDTH "); } if (chan->tx_freq) { fprintf(fout, "TXFREQ "); } if (chan->tx_mode) { fprintf(fout, "TXMODE "); } if (chan->tx_width) { fprintf(fout, "TXWIDTH "); } if (chan->split) { fprintf(fout, "SPLIT "); } if (chan->rptr_shift) { fprintf(fout, "RPTRSHIFT "); } if (chan->rptr_offs) { fprintf(fout, "RPTROFS "); } if (chan->tuning_step) { fprintf(fout, "TS "); } if (chan->rit) { fprintf(fout, "RIT "); } if (chan->xit) { fprintf(fout, "XIT "); } if (chan->funcs) { fprintf(fout, "FUNC "); /* TODO: iterate over the list */ } if (chan->levels) { fprintf(fout, "LEVEL "); /* TODO: iterate over the list */ } if (chan->ctcss_tone) { fprintf(fout, "TONE "); } if (chan->ctcss_sql) { fprintf(fout, "CTCSS "); } if (chan->dcs_code) { fprintf(fout, "DCSCODE "); } if (chan->dcs_sql) { fprintf(fout, "DCSSQL "); } if (chan->scan_group) { fprintf(fout, "SCANGRP "); } if (chan->flags) { fprintf(fout, "FLAG "); /* TODO: iterate over the RIG_CHFLAG's */ } if (chan->channel_desc) { fprintf(fout, "NAME "); } if (chan->ext_levels) { fprintf(fout, "EXTLVL "); } } hamlib-4.6.5/tests/dumpcaps.c0000664000175000017500000010671515056640443011610 /* * dumpcaps.c - Copyright (C) 2000-2012 Stephane Fillod * This programs dumps the capabilities of a backend rig. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include "misc.h" #include "riglist.h" #include "sprintflst.h" #include "rigctl_parse.h" #include "../rigs/icom/icom.h" #include "dumpcaps.h" void range_print(FILE *fout, const struct freq_range_list range_list[], int rx); int range_sanity_check(const struct freq_range_list range_list[], int rx); int ts_sanity_check(const struct tuning_step_list tuning_step[]); static void dump_chan_caps(const channel_cap_t *chan, FILE *fout); struct rig_type_s { int type; char *description; }; struct rig_type_s rig_type[] = { {RIG_TYPE_OTHER, "Other"}, {RIG_FLAG_RECEIVER, "Receiver"}, {RIG_FLAG_TRANSMITTER, "Transmitter"}, {RIG_FLAG_SCANNER, "Scanner"}, {RIG_FLAG_MOBILE, "Mobile"}, {RIG_FLAG_HANDHELD, "Handheld"}, {RIG_FLAG_COMPUTER, "Computer"}, {RIG_FLAG_TRANSCEIVER, "Transceiver"}, {RIG_FLAG_TRUNKING, "Trunking scanner"}, {RIG_FLAG_APRS, "APRS"}, {RIG_FLAG_TNC, "TNC"}, {RIG_FLAG_DXCLUSTER, "DxCluster"}, {RIG_FLAG_DXCLUSTER, "DxCluster"}, {RIG_FLAG_TUNER, "Tuner"}, {-1, "?\n"} }; static int print_ext(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { return print_ext_param(cfp, ptr); } /* * the rig may be in rig_init state, but not opened */ int dumpcaps(RIG *rig, FILE *fout) { const struct rig_caps *caps; struct rig_state *rs; int status, i; int can_esplit, can_echannel; char freqbuf[20]; int backend_warnings = 0; char warnbuf[4096]; char prntbuf[8192]; /* a malloc would be better.. */ char *label1, *label2, *label3, *label4, *label5; char *labelrx1; // , *labelrx2, *labelrx3, *labelrx4, *labelrx5; warnbuf[0] = 0; prntbuf[0] = 0; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; rs = STATE(rig); fprintf(fout, "Caps dump for model: %u\n", caps->rig_model); fprintf(fout, "Model name:\t%s\n", caps->model_name); fprintf(fout, "Mfg name:\t%s\n", caps->mfg_name); fprintf(fout, "Hamlib version:\t%s\n", hamlib_version2); fprintf(fout, "Backend version:\t%s\n", caps->version); fprintf(fout, "Backend copyright:\t%s\n", caps->copyright); fprintf(fout, "Backend status:\t%s\n", rig_strstatus(caps->status)); fprintf(fout, "Rig type:\t"); char *unknown = "Unknown"; for (i = 0; rig_type[i].type != -1; ++i) { if ((rig_type[i].type & caps->rig_type) == rig_type[i].type) { fprintf(fout, "%s ", rig_type[i].description); unknown = ""; } } fprintf(fout, "%s\n", unknown); if (strlen(unknown) > 0) { strcat(warnbuf, " RIG_TYPE"); backend_warnings++; } fprintf(fout, "PTT type:\t"); switch (caps->ptt_type) { case RIG_PTT_RIG: fprintf(fout, "Rig capable\n"); break; case RIG_PTT_RIG_MICDATA: fprintf(fout, "Rig capable (Mic/Data)\n"); break; case RIG_PTT_PARALLEL: fprintf(fout, "Parallel port (DATA0)\n"); break; case RIG_PTT_SERIAL_RTS: fprintf(fout, "Serial port (CTS/RTS)\n"); break; case RIG_PTT_SERIAL_DTR: fprintf(fout, "Serial port (DTR/DSR)\n"); break; case RIG_PTT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " PTT_TYPE"); backend_warnings++; } fprintf(fout, "DCD type:\t"); switch (caps->dcd_type) { case RIG_DCD_RIG: fprintf(fout, "Rig capable\n"); break; case RIG_DCD_PARALLEL: fprintf(fout, "Parallel port (/STROBE)\n"); break; case RIG_DCD_SERIAL_CTS: fprintf(fout, "Serial port (CTS/RTS)\n"); break; case RIG_DCD_SERIAL_DSR: fprintf(fout, "Serial port (DTR/DSR)\n"); break; case RIG_DCD_SERIAL_CAR: fprintf(fout, "Serial port (CD)\n"); break; case RIG_DCD_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " DCD_TYPE"); backend_warnings++; } fprintf(fout, "Port type:\t"); switch (caps->port_type) { case RIG_PORT_SERIAL: fprintf(fout, "RS-232\n"); fprintf(fout, "Serial speed: %d..%d baud, %d%c%d, ctrl=%s\n", caps->serial_rate_min, caps->serial_rate_max, caps->serial_data_bits, caps->serial_parity == RIG_PARITY_NONE ? 'N' : caps->serial_parity == RIG_PARITY_ODD ? 'O' : caps->serial_parity == RIG_PARITY_EVEN ? 'E' : caps->serial_parity == RIG_PARITY_MARK ? 'M' : 'S', caps->serial_stop_bits, caps->serial_handshake == RIG_HANDSHAKE_NONE ? "NONE" : (caps->serial_handshake == RIG_HANDSHAKE_XONXOFF ? "XONXOFF" : "CTS/RTS") ); break; case RIG_PORT_PARALLEL: fprintf(fout, "Parallel\n"); break; case RIG_PORT_DEVICE: fprintf(fout, "Device driver\n"); break; case RIG_PORT_USB: fprintf(fout, "USB\n"); break; case RIG_PORT_NETWORK: fprintf(fout, "Network link\n"); break; case RIG_PORT_UDP_NETWORK: fprintf(fout, "UDP Network link\n"); break; case RIG_PORT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); strcat(warnbuf, " PORT_TYPE"); backend_warnings++; } fprintf(fout, "Write delay: %dms, timeout %dms, %d retry\n", caps->write_delay, caps->timeout, caps->retry); fprintf(fout, "Post write delay: %dms\n", caps->post_write_delay); fprintf(fout, "Has targetable VFO: %s\n", caps->targetable_vfo ? "Y" : "N"); fprintf(fout, "Targetable features:"); if (caps->targetable_vfo & RIG_TARGETABLE_FREQ) { fprintf(fout, " FREQ"); } if (caps->targetable_vfo & RIG_TARGETABLE_MODE) { fprintf(fout, " MODE"); } if (caps->targetable_vfo & RIG_TARGETABLE_TONE) { fprintf(fout, " TONE"); } if (caps->targetable_vfo & RIG_TARGETABLE_FUNC) { fprintf(fout, " FUNC"); } if (caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { fprintf(fout, " LEVEL"); } if (caps->targetable_vfo & RIG_TARGETABLE_RITXIT) { fprintf(fout, " RITXIT"); } if (caps->targetable_vfo & RIG_TARGETABLE_PTT) { fprintf(fout, " PTT"); } if (caps->targetable_vfo & RIG_TARGETABLE_MEM) { fprintf(fout, " MEM"); } if (caps->targetable_vfo & RIG_TARGETABLE_BANK) { fprintf(fout, " BANK"); } if (caps->targetable_vfo & RIG_TARGETABLE_ANT) { fprintf(fout, " ANT"); } if (caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { fprintf(fout, " ROOFING"); } if (caps->targetable_vfo & RIG_TARGETABLE_SPECTRUM) { fprintf(fout, " SPECTRUM"); } if (caps->targetable_vfo & RIG_TARGETABLE_BAND) { fprintf(fout, " BAND"); } if (caps->targetable_vfo == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "Has async data support: %s\n", caps->async_data_supported ? "Y" : "N"); fprintf(fout, "Announce: 0x%x\n", caps->announces); fprintf(fout, "Max RIT: -%ld.%ldkHz/+%ld.%ldkHz\n", caps->max_rit / 1000, caps->max_rit % 1000, caps->max_rit / 1000, caps->max_rit % 1000); fprintf(fout, "Max XIT: -%ld.%ldkHz/+%ld.%ldkHz\n", caps->max_xit / 1000, caps->max_xit % 1000, caps->max_xit / 1000, caps->max_xit % 1000); fprintf(fout, "Max IF-SHIFT: -%ld.%ldkHz/+%ld.%ldkHz\n", caps->max_ifshift / 1000, caps->max_ifshift % 1000, caps->max_ifshift / 1000, caps->max_ifshift % 1000); fprintf(fout, "Preamp:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && caps->preamp[i] != 0; i++) { fprintf(fout, " %ddB", caps->preamp[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "Attenuator:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && caps->attenuator[i] != 0; i++) { fprintf(fout, " %ddB", caps->attenuator[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "AGC levels:"); const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; if (priv_caps && RIG_BACKEND_NUM(rig->caps->rig_model) == RIG_ICOM && priv_caps->agc_levels_present) { for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST ; i++) { fprintf(fout, " %d=%s", priv_caps->agc_levels[i].level, rig_stragclevel(priv_caps->agc_levels[i].level)); } } else { for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && i < caps->agc_level_count; i++) { fprintf(fout, " %d=%s", caps->agc_levels[i], rig_stragclevel(caps->agc_levels[i])); } } if (i == 0) { fprintf(fout, " %d=%s", RIG_AGC_NONE, rig_stragclevel(RIG_AGC_NONE)); } fprintf(fout, "\n"); fprintf(fout, "CTCSS:"); for (i = 0; caps->ctcss_list && i < 60 && caps->ctcss_list[i] != 0; i++) { fprintf(fout, " %u.%1u", caps->ctcss_list[i] / 10, caps->ctcss_list[i] % 10); } if (i == 0) { fprintf(fout, " None"); } else { fprintf(fout, " Hz, %d tones", i); } fprintf(fout, "\n"); fprintf(fout, "DCS:"); for (i = 0; caps->dcs_list && i < 128 && caps->dcs_list[i] != 0; i++) { fprintf(fout, " %u", caps->dcs_list[i]); } if (i == 0) { fprintf(fout, " None"); } else { fprintf(fout, ", %d codes", i); } fprintf(fout, "\n"); rig_sprintf_func(prntbuf, sizeof(prntbuf), caps->has_get_func); fprintf(fout, "Get functions: %s\n", prntbuf); rig_sprintf_func(prntbuf, sizeof(prntbuf), caps->has_set_func); fprintf(fout, "Set functions: %s\n", prntbuf); fprintf(fout, "Extra functions:\n"); rig_ext_func_foreach(rig, print_ext, fout); rig_sprintf_level_gran(prntbuf, sizeof(prntbuf), caps->has_get_level, caps->level_gran); fprintf(fout, "Get level: %s\n", prntbuf); if ((caps->has_get_level & RIG_LEVEL_RAWSTR) && caps->str_cal.size == 0 && !(caps->has_get_level & RIG_LEVEL_STRENGTH)) { fprintf(fout, "Warning--backend has get RAWSTR, but not calibration data\n"); strcat(warnbuf, " RAWSTR_level"); backend_warnings++; } rig_sprintf_level_gran(prntbuf, sizeof(prntbuf), caps->has_set_level, caps->level_gran); fprintf(fout, "Set level: %s\n", prntbuf); if (caps->has_set_level & RIG_LEVEL_READONLY_LIST) { //fprintf(fout, "Warning--backend can set readonly levels=0x%0llx\n", caps->has_set_level & RIG_LEVEL_READONLY_LIST); fprintf(fout, "Warning--backend can set readonly levels\n"); strcat(warnbuf, " READONLY_LEVEL"); backend_warnings++; } fprintf(fout, "Extra levels:\n"); rig_ext_level_foreach(rig, print_ext, fout); rig_sprintf_parm_gran(prntbuf, sizeof(prntbuf), caps->has_get_parm, caps->parm_gran); fprintf(fout, "Get parameters: %s\n", prntbuf); rig_sprintf_parm_gran(prntbuf, sizeof(prntbuf), caps->has_set_parm, caps->parm_gran); fprintf(fout, "Set parameters: %s\n", prntbuf); if (caps->has_set_parm & RIG_PARM_READONLY_LIST) { fprintf(fout, "Warning--backend can set readonly parms!\n"); strcat(warnbuf, " READONLY_PARM"); backend_warnings++; } fprintf(fout, "Extra parameters:\n"); rig_ext_parm_foreach(rig, print_ext, fout); if (rs->mode_list != 0) { rig_sprintf_mode(prntbuf, sizeof(prntbuf), rs->mode_list); } else { strcpy(prntbuf, "None. This backend might be bogus!\n"); strcat(warnbuf, " MODE_LIST"); backend_warnings++; } fprintf(fout, "Mode list: %s\n", prntbuf); if (rs->vfo_list != 0) { rig_sprintf_vfo(prntbuf, sizeof(prntbuf), rs->vfo_list); } else { strcpy(prntbuf, "None. This backend might be bogus!\n"); strcat(warnbuf, " VFO_LIST"); backend_warnings++; } fprintf(fout, "VFO list: %s\n", prntbuf); rig_sprintf_vfop(prntbuf, sizeof(prntbuf), caps->vfo_ops); fprintf(fout, "VFO Ops: %s\n", prntbuf); rig_sprintf_scan(prntbuf, sizeof(prntbuf), caps->scan_ops); fprintf(fout, "Scan Ops: %s\n", prntbuf); fprintf(fout, "Number of banks:\t%d\n", caps->bank_qty); fprintf(fout, "Memory name desc size:\t%d\n", caps->chan_desc_sz); fprintf(fout, "Memories:"); for (i = 0; i < HAMLIB_CHANLSTSIZ && caps->chan_list[i].type; i++) { fprintf(fout, "\n\t%d..%d: \t%s", caps->chan_list[i].startc, caps->chan_list[i].endc, rig_strmtype(caps->chan_list[i].type)); fprintf(fout, "\n\t Mem caps: "); dump_chan_caps(&caps->chan_list[i].mem_caps, fout); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); label1 = caps->tx_range_list1->label; label1 = label1 == NULL ? "TBD" : label1; fprintf(fout, "TX ranges #1 for %s:\n", label1); range_print(fout, caps->tx_range_list1, 0); labelrx1 = caps->rx_range_list1->label; labelrx1 = labelrx1 == NULL ? "TBD" : labelrx1; fprintf(fout, "RX ranges #1 for %s:\n", labelrx1); range_print(fout, caps->rx_range_list1, 1); label2 = caps->rx_range_list2->label; label2 = label2 == NULL ? "TBD" : label2; fprintf(fout, "TX ranges #2 for %s:\n", label2); range_print(fout, caps->tx_range_list2, 0); label2 = caps->rx_range_list2->label; label2 = label2 == NULL ? "TBD" : label2; fprintf(fout, "RX ranges #2 for %s:\n", label2); range_print(fout, caps->rx_range_list2, 1); label3 = caps->rx_range_list3->label; label3 = label3 == NULL ? "TBD" : label3; fprintf(fout, "TX ranges #3 for %s:\n", label3); range_print(fout, caps->tx_range_list3, 0); label3 = caps->rx_range_list3->label; label3 = label3 == NULL ? "TBD" : label3; fprintf(fout, "RX ranges #3 for %s:\n", label3); range_print(fout, caps->rx_range_list3, 1); label4 = caps->rx_range_list4->label; label4 = label4 == NULL ? "TBD" : label4; fprintf(fout, "TX ranges #4 for %s:\n", label4); range_print(fout, caps->tx_range_list5, 0); label4 = caps->rx_range_list4->label; label4 = label4 == NULL ? "TBD" : label4; fprintf(fout, "RX ranges #4 for %s:\n", label4); range_print(fout, caps->rx_range_list5, 1); label5 = caps->rx_range_list5->label; label5 = label5 == NULL ? "TBD" : label5; fprintf(fout, "TX ranges #5 for %s:\n", label5); range_print(fout, caps->tx_range_list5, 0); label5 = caps->rx_range_list5->label; label5 = label5 == NULL ? "TBD" : label5; fprintf(fout, "RX ranges #5 for %s:\n", label5); range_print(fout, caps->rx_range_list5, 1); status = range_sanity_check(caps->tx_range_list1, 0); fprintf(fout, "TX ranges #1 status for %s:\t%s (%d)\n", label1, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#1"); backend_warnings++; } status = range_sanity_check(caps->rx_range_list1, 1); fprintf(fout, "RX ranges #1 status for %s:\t%s (%d)\n", labelrx1, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#1"); backend_warnings++; } status = range_sanity_check(caps->tx_range_list2, 0); fprintf(fout, "TX ranges #2 status for %s:\t%s (%d)\n", label2, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#2"); backend_warnings++; } status = range_sanity_check(caps->rx_range_list2, 1); fprintf(fout, "RX ranges #2 status for %s:\t%s (%d)\n", label2, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#2"); backend_warnings++; } status = range_sanity_check(caps->tx_range_list3, 0); fprintf(fout, "TX ranges #3 status for %s:\t%s (%d)\n", label3, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#3"); backend_warnings++; } status = range_sanity_check(caps->rx_range_list3, 1); fprintf(fout, "RX ranges #3 status for %s:\t%s (%d)\n", label3, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#3"); backend_warnings++; } status = range_sanity_check(caps->tx_range_list4, 0); fprintf(fout, "TX ranges #4 status for %s:\t%s (%d)\n", label4, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#4"); backend_warnings++; } status = range_sanity_check(caps->rx_range_list4, 1); fprintf(fout, "RX ranges #4 status for %s:\t%s (%d)\n", label4, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#4"); backend_warnings++; } status = range_sanity_check(caps->tx_range_list5, 0); fprintf(fout, "TX ranges #5 status for %s:\t%s (%d)\n", label5, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TX#5"); backend_warnings++; } status = range_sanity_check(caps->rx_range_list5, 1); fprintf(fout, "RX ranges #5 status for %s:\t%s (%d)\n", label5, status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " RX#5"); backend_warnings++; } fprintf(fout, "Tuning steps:"); for (i = 0; i < HAMLIB_TSLSTSIZ && !RIG_IS_TS_END(caps->tuning_steps[i]); i++) { if (caps->tuning_steps[i].ts == RIG_TS_ANY) { strcpy(freqbuf, "ANY"); /* strcpy! Looks safe for now */ } else { sprintf_freq(freqbuf, sizeof(freqbuf), caps->tuning_steps[i].ts); } rig_sprintf_mode(prntbuf, sizeof(prntbuf), caps->tuning_steps[i].modes); fprintf(fout, "\n\t%s: \t%s", freqbuf, prntbuf); } if (i == 0) { fprintf(fout, " None! This backend might be bogus!"); strcat(warnbuf, " TUNING_STEPS"); backend_warnings++; } fprintf(fout, "\n"); status = ts_sanity_check(caps->tuning_steps); fprintf(fout, "Tuning steps status:\t%s (%d)\n", status ? "Bad" : "OK", status); if (status) { strcat(warnbuf, " TUNING_SANE"); backend_warnings++; } fprintf(fout, "Filters:"); for (i = 0; i < HAMLIB_FLTLSTSIZ && !RIG_IS_FLT_END(caps->filters[i]); i++) { if (caps->filters[i].width == RIG_FLT_ANY) { strcpy(freqbuf, "ANY"); } else { sprintf_freq(freqbuf, sizeof(freqbuf), caps->filters[i].width); } rig_sprintf_mode(prntbuf, sizeof(prntbuf), caps->filters[i].modes); fprintf(fout, "\n\t%s: \t%s", freqbuf, prntbuf); } if (i == 0) { fprintf(fout, " None. This backend might be bogus!"); strcat(warnbuf, " FILTERS"); backend_warnings++; } fprintf(fout, "\n"); fprintf(fout, "Bandwidths:"); for (i = 1; i < RIG_MODE_TESTS_MAX; i <<= 1) { pbwidth_t pbnorm = rig_passband_normal(rig, i); if (pbnorm == 0) { continue; } sprintf_freq(freqbuf, sizeof(freqbuf), pbnorm); fprintf(fout, "\n\t%s\tNormal: %s,\t", rig_strrmode(i), freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_narrow(rig, i)); fprintf(fout, "Narrow: %s,\t", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_wide(rig, i)); fprintf(fout, "Wide: %s", freqbuf); } fprintf(fout, "\n"); fprintf(fout, "Spectrum scopes:"); for (i = 0; i < HAMLIB_MAX_SPECTRUM_SCOPES && caps->spectrum_scopes[i].name != NULL; i++) { fprintf(fout, " %d=\"%s\"", caps->spectrum_scopes[i].id, caps->spectrum_scopes[i].name); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); rig_sprintf_spectrum_modes(prntbuf, sizeof(prntbuf), caps->spectrum_modes); fprintf(fout, "Spectrum modes: %s\n", prntbuf); rig_sprintf_spectrum_spans(prntbuf, sizeof(prntbuf), caps->spectrum_spans); fprintf(fout, "Spectrum spans: %s\n", prntbuf); rig_sprintf_spectrum_avg_modes(prntbuf, sizeof(prntbuf), caps->spectrum_avg_modes); fprintf(fout, "Spectrum averaging modes: %s\n", prntbuf); fprintf(fout, "Spectrum attenuator:"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && caps->spectrum_attenuator[i] != 0; i++) { fprintf(fout, " %ddB", caps->spectrum_attenuator[i]); } if (i == 0) { fprintf(fout, " None"); } fprintf(fout, "\n"); fprintf(fout, "Has priv data:\t%c\n", caps->priv != NULL ? 'Y' : 'N'); /* * Status is either 'Y'es, 'E'mulated, 'N'o * * TODO: keep me up-to-date with API call list! */ fprintf(fout, "Has Init:\t%c\n", caps->rig_init != NULL ? 'Y' : 'N'); fprintf(fout, "Has Cleanup:\t%c\n", caps->rig_cleanup != NULL ? 'Y' : 'N'); fprintf(fout, "Has Open:\t%c\n", caps->rig_open != NULL ? 'Y' : 'N'); fprintf(fout, "Has Close:\t%c\n", caps->rig_close != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Conf:\t%c\n", caps->set_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Conf:\t%c\n", caps->get_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Frequency:\t%c\n", caps->set_freq != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Frequency:\t%c\n", caps->get_freq != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Mode:\t%c\n", caps->set_mode != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Mode:\t%c\n", caps->get_mode != NULL ? 'Y' : 'N'); fprintf(fout, "Can set VFO:\t%c\n", caps->set_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can get VFO:\t%c\n", caps->get_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can set PTT:\t%c\n", caps->set_ptt != NULL ? 'Y' : 'N'); fprintf(fout, "Can get PTT:\t%c\n", caps->get_ptt != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCD:\t%c\n", caps->get_dcd != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Repeater Duplex:\t%c\n", caps->set_rptr_shift != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Repeater Duplex:\t%c\n", caps->get_rptr_shift != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Repeater Offset:\t%c\n", caps->set_rptr_offs != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Repeater Offset:\t%c\n", caps->get_rptr_offs != NULL ? 'Y' : 'N'); can_esplit = caps->set_split_vfo && (caps->set_vfo || (rig_has_vfo_op(rig, RIG_OP_TOGGLE) && caps->vfo_op)); fprintf(fout, "Can set Split Freq:\t%c\n", caps->set_split_freq != NULL ? 'Y' : (can_esplit && caps->set_freq ? 'E' : 'N')); fprintf(fout, "Can get Split Freq:\t%c\n", caps->get_split_freq != NULL ? 'Y' : (can_esplit && caps->get_freq ? 'E' : 'N')); fprintf(fout, "Can set Split Mode:\t%c\n", caps->set_split_mode != NULL ? 'Y' : (can_esplit && caps->set_mode ? 'E' : 'N')); fprintf(fout, "Can get Split Mode:\t%c\n", caps->get_split_mode != NULL ? 'Y' : (can_esplit && caps->get_mode ? 'E' : 'N')); fprintf(fout, "Can set Split VFO:\t%c\n", caps->set_split_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Split VFO:\t%c\n", caps->get_split_vfo != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Tuning Step:\t%c\n", caps->set_ts != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Tuning Step:\t%c\n", caps->get_ts != NULL ? 'Y' : 'N'); fprintf(fout, "Can set RIT:\t%c\n", caps->set_rit != NULL ? 'Y' : 'N'); fprintf(fout, "Can get RIT:\t%c\n", caps->get_rit != NULL ? 'Y' : 'N'); fprintf(fout, "Can set XIT:\t%c\n", caps->set_xit != NULL ? 'Y' : 'N'); fprintf(fout, "Can get XIT:\t%c\n", caps->get_xit != NULL ? 'Y' : 'N'); fprintf(fout, "Can set CTCSS:\t%c\n", caps->set_ctcss_tone != NULL ? 'Y' : 'N'); fprintf(fout, "Can get CTCSS:\t%c\n", caps->get_ctcss_tone != NULL ? 'Y' : 'N'); fprintf(fout, "Can set DCS:\t%c\n", caps->set_dcs_code != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCS:\t%c\n", caps->get_dcs_code != NULL ? 'Y' : 'N'); fprintf(fout, "Can set CTCSS Squelch:\t%c\n", caps->set_ctcss_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can get CTCSS Squelch:\t%c\n", caps->get_ctcss_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can set DCS Squelch:\t%c\n", caps->set_dcs_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can get DCS Squelch:\t%c\n", caps->get_dcs_sql != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Power Stat:\t%c\n", caps->set_powerstat != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Power Stat:\t%c\n", caps->get_powerstat != NULL ? 'Y' : 'N'); fprintf(fout, "Can Reset:\t%c\n", caps->reset != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Ant:\t%c\n", caps->get_ant != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Ant:\t%c\n", caps->set_ant != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Transceive:\t%c\n", caps->set_trn != NULL ? 'Y' : caps->transceive == RIG_TRN_RIG ? 'E' : 'N'); fprintf(fout, "Can get Transceive:\t%c\n", caps->get_trn != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Func:\t%c\n", caps->set_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Func:\t%c\n", caps->get_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Level:\t%c\n", caps->set_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Level:\t%c\n", caps->get_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Param:\t%c\n", caps->set_parm != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Param:\t%c\n", caps->get_parm != NULL ? 'Y' : 'N'); fprintf(fout, "Can send DTMF:\t%c\n", caps->send_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can recv DTMF:\t%c\n", caps->recv_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Morse:\t%c\n", caps->send_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can stop Morse:\t%c\n", caps->stop_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can wait Morse:\t%c\n", caps->wait_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Voice:\t%c\n", caps->send_voice_mem != NULL ? 'Y' : 'N'); fprintf(fout, "Can decode Events:\t%c\n", caps->decode_event != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Bank:\t%c\n", caps->set_bank != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Mem:\t%c\n", caps->set_mem != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Mem:\t%c\n", caps->get_mem != NULL ? 'Y' : 'N'); can_echannel = caps->set_mem && ((caps->set_vfo && ((rs->vfo_list & RIG_VFO_MEM) == RIG_VFO_MEM)) || (caps->vfo_op && rig_has_vfo_op(rig, RIG_OP_TO_VFO | RIG_OP_FROM_VFO))); fprintf(fout, "Can set Channel:\t%c\n", caps->set_channel != NULL ? 'Y' : (can_echannel ? 'E' : 'N')); fprintf(fout, "Can get Channel:\t%c\n", caps->get_channel != NULL ? 'Y' : (can_echannel ? 'E' : 'N')); fprintf(fout, "Can ctl Mem/VFO:\t%c\n", caps->vfo_op != NULL ? 'Y' : 'N'); fprintf(fout, "Can Scan:\t%c\n", caps->scan != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Info:\t%c\n", caps->get_info != NULL ? 'Y' : 'N'); fprintf(fout, "Can get power2mW:\t%c\n", caps->power2mW != NULL ? 'Y' : 'N'); fprintf(fout, "Can get mW2power:\t%c\n", caps->mW2power != NULL ? 'Y' : 'N'); fprintf(fout, "\nOverall backend warnings: %d %c %s\n", backend_warnings, warnbuf[0] != 0 ? '=' : ' ', warnbuf); return backend_warnings; } void range_print(FILE *fout, const struct freq_range_list range_list[], int rx) { int i; char prntbuf[1024]; /* a malloc would be better.. */ for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { if (range_list[i].startf == 0 && range_list[i].endf == 0) { break; } fprintf(fout, "\t%.0f Hz - %.0f Hz\n", range_list[i].startf, range_list[i].endf); fprintf(fout, "\t\tVFO list: "); rig_sprintf_vfo(prntbuf, sizeof(prntbuf), range_list[i].vfo); fprintf(fout, "%s", prntbuf); fprintf(fout, "\n"); fprintf(fout, "\t\tMode list: "); rig_sprintf_mode(prntbuf, sizeof(prntbuf), range_list[i].modes); fprintf(fout, "%s", prntbuf); fprintf(fout, "\n"); fprintf(fout, "\t\tAntenna list: "); rig_sprintf_ant(prntbuf, sizeof(prntbuf), range_list[i].ant); fprintf(fout, "%s", prntbuf); fprintf(fout, "\n"); if (!rx) { char *label_lo = "W"; char *label_hi = "W"; double low = range_list[i].low_power / 1000.0f; double hi = range_list[i].high_power / 1000.0f; if (low < 0) { label_lo = "mW"; low *= 1000; } if (low < 0) { label_lo = "uW"; low *= 1000; } if (hi < 0) { label_hi = "mW"; hi *= 1000; } if (hi < 0) { label_hi = "uW"; hi *= 1000; } fprintf(fout, "\t\tLow power: %g %s, High power: %g %s\n", low, label_lo, hi, label_hi); } } } /* * check for: * - start_freq < end_freq return_code = -1 * - modes are not 0 return_code = -2 * - if(rx), low_power, high_power set to -1 return_code = -3 * else, power is > 0 * - array is ended by a {0,0,0,0,0} element (before boundary) rc = -4 * - ranges with same modes do not overlap rc = -5 * ->fprintf(stderr,)! * * TODO: array is sorted in ascending freq order */ int range_sanity_check(const struct freq_range_list range_list[], int rx) { int i; for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { if (range_list[i].startf == 0 && range_list[i].endf == 0) { break; } if (range_list[i].startf > range_list[i].endf) { return -1; } if (range_list[i].modes == 0) { return -2; } if (rx) { if (range_list[i].low_power > 0 && range_list[i].high_power > 0) { return -3; } } else { if (!(range_list[i].low_power >= RIG_FREQ_NONE && range_list[i].high_power >= RIG_FREQ_NONE)) { return -3; } if (range_list[i].low_power > range_list[i].high_power) { return -3; } } } if (i == HAMLIB_FRQRANGESIZ) { return -4; } return 0; } /* * check for: * - steps sorted in ascending order return_code=-1 * - modes are not 0 return_code=-2 * - array is ended by a {0,0,0,0,0} element (before boundary) rc=-4 * * TODO: array is sorted in ascending freq order */ int ts_sanity_check(const struct tuning_step_list tuning_step[]) { int i; shortfreq_t last_ts; rmode_t last_modes; last_ts = 0; last_modes = RIG_MODE_NONE; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (RIG_IS_TS_END(tuning_step[i])) { break; } if (tuning_step[i].ts != RIG_TS_ANY && tuning_step[i].ts < last_ts && last_modes == tuning_step[i].modes) { return -1; } if (tuning_step[i].modes == 0) { return -2; } last_ts = tuning_step[i].ts; last_modes = tuning_step[i].modes; } if (i == HAMLIB_TSLSTSIZ) { return -4; } return 0; } static void dump_chan_caps(const channel_cap_t *chan, FILE *fout) { if (chan->bank_num) { fprintf(fout, "BANK "); } if (chan->ant) { fprintf(fout, "ANT "); } if (chan->freq) { fprintf(fout, "FREQ "); } if (chan->mode) { fprintf(fout, "MODE "); } if (chan->width) { fprintf(fout, "WIDTH "); } if (chan->split) { fprintf(fout, "SPLIT "); } if (chan->tx_freq) { fprintf(fout, "TXFREQ "); } if (chan->tx_mode) { fprintf(fout, "TXMODE "); } if (chan->tx_width) { fprintf(fout, "TXWIDTH "); } if (chan->split) { fprintf(fout, "SPLIT "); } if (chan->rptr_shift) { fprintf(fout, "RPTRSHIFT "); } if (chan->rptr_offs) { fprintf(fout, "RPTROFS "); } if (chan->tuning_step) { fprintf(fout, "TS "); } if (chan->rit) { fprintf(fout, "RIT "); } if (chan->xit) { fprintf(fout, "XIT "); } if (chan->funcs) { fprintf(fout, "FUNC "); /* TODO: iterate over the list */ } if (chan->levels) { fprintf(fout, "LEVEL "); /* TODO: iterate over the list */ } if (chan->ctcss_tone) { fprintf(fout, "TONE "); } if (chan->ctcss_sql) { fprintf(fout, "CTCSS "); } if (chan->dcs_code) { fprintf(fout, "DCSCODE "); } if (chan->dcs_sql) { fprintf(fout, "DCSSQL "); } if (chan->scan_group) { fprintf(fout, "SCANGRP "); } if (chan->flags) { fprintf(fout, "FLAG "); /* TODO: iterate over the RIG_CHFLAG's */ } if (chan->channel_desc) { fprintf(fout, "NAME "); } if (chan->ext_levels) { fprintf(fout, "EXTLVL "); } } int dumpconf(RIG *rig, FILE *fout) { fprintf(fout, "model: %s\n", rig->caps->model_name); rig_token_foreach(rig, print_conf_list, (rig_ptr_t)rig); return 0; } int dumpconf_list(RIG *rig, FILE *fout) { rig_token_foreach(rig, print_conf_list2, (rig_ptr_t)rig); return 0; } int dumpconf_list_rot(ROT *rot, FILE *fout) { rot_token_foreach(rot, print_conf_list2, rot); return 0; } hamlib-4.6.5/tests/ampctld.c0000664000175000017500000004425515056640443011420 /* * ampctld.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2010,2011,2012,2013 * * This program test/control an amplifier using Hamlib. * It takes commands from network connection. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include /* See NOTES */ #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_PTHREAD # include #endif #include #include "ampctl_parse.h" #include "amplist.h" #include "rig.h" struct handle_data { AMP *amp; int sock; struct sockaddr_storage cli_addr; socklen_t clilen; }; void *handle_socket(void *arg); void usage(); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "m:r:s:C:t:T:LuvhVlZ" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"amp-file", 1, 0, 'r'}, {"serial-speed", 1, 0, 's'}, {"port", 1, 0, 't'}, {"listen-addr", 1, 0, 'T'}, {"list", 0, 0, 'l'}, {"set-conf", 1, 0, 'C'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"debug-time-stamps", 0, 0, 'Z'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; int interactive = 1; /* no cmd because of daemon */ int prompt = 0 ; /* Daemon mode for rigparse return string */ const char *portno = "4531"; const char *src_addr = NULL; /* INADDR_ANY */ char send_cmd_term = '\r'; /* send_cmd termination char */ #define MAXCONFLEN 2048 static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } int main(int argc, char *argv[]) { AMP *my_amp; /* handle to amp (instance) */ amp_model_t my_model = AMP_MODEL_DUMMY; int retcode; /* generic return code from functions */ int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; const char *amp_file = NULL; int serial_rate = 0; char conf_parms[MAXCONFLEN] = ""; struct addrinfo hints, *result, *saved_result; int sock_listen; int reuseaddr = 1; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; #ifdef HAVE_PTHREAD pthread_t thread; pthread_attr_t attr; #endif struct handle_data *arg; #ifdef SIGPIPE #if HAVE_SIGACTION struct sigaction act; #endif #endif while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } amp_file = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } portno = optarg; break; case 'T': if (!optarg) { usage(); /* wrong arg count */ exit(1); } src_addr = optarg; break; case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "ampctld, %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); my_amp = amp_init(my_model); if (!my_amp) { fprintf(stderr, "Unknown amp num %d, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } char *token = strtok(conf_parms, ","); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = amp_token_lookup(my_amp, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = amp_set_conf(my_amp, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } token = strtok(NULL, ","); } if (amp_file) { strncpy(AMPPORT(my_amp)->pathname, amp_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { AMPPORT(my_amp)->parm.serial.rate = serial_rate; } /* * print out conf parameters */ if (show_conf) { amp_token_foreach(my_amp, print_conf_list, (rig_ptr_t)my_amp); } /* * Print out conf parameters, and exits immediately as we may be * interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps_amp(my_amp, stdout); amp_cleanup(my_amp); /* if you care about memory */ exit(0); } retcode = amp_open(my_amp); if (retcode != RIG_OK) { fprintf(stderr, "amp_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened amp model %d, '%s'\n", my_amp->caps->amp_model, my_amp->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_amp->caps->version, rig_strstatus(my_amp->caps->status)); #ifdef __MINGW32__ # ifndef SO_OPENTYPE # define SO_OPENTYPE 0x7008 # endif # ifndef SO_SYNCHRONOUS_NONALERT # define SO_SYNCHRONOUS_NONALERT 0x20 # endif # ifndef INVALID_SOCKET # define INVALID_SOCKET -1 # endif WSADATA wsadata; if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) { fprintf(stderr, "WSAStartup socket error\n"); exit(1); } { int sockopt = SO_SYNCHRONOUS_NONALERT; setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt)); } #endif /* * Prepare listening socket */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* TCP socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ retcode = getaddrinfo(src_addr, portno, &hints, &result); if (retcode != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode)); exit(2); } saved_result = result; do { sock_listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock_listen < 0) { handle_error(RIG_DEBUG_ERR, "socket"); freeaddrinfo(result); /* No longer needed */ exit(1); } if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(result); /* No longer needed */ exit(1); } #ifdef IPV6_V6ONLY if (AF_INET6 == result->ai_family) { /* allow IPv4 mapped to IPv6 clients, MS & BSD default this to 1 i.e. disallowed */ int sockopt = 0; if (setsockopt(sock_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&sockopt, sizeof(sockopt)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } } #endif if (0 == bind(sock_listen, result->ai_addr, result->ai_addrlen)) { break; } handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); #ifdef __MINGW32__ closesocket(sock_listen); #else close(sock_listen); #endif } while ((result = result->ai_next) != NULL); freeaddrinfo(saved_result); /* No longer needed */ if (NULL == result) { rig_debug(RIG_DEBUG_ERR, "%s: bind error - no available interface\n", __func__); exit(1); } if (listen(sock_listen, 4) < 0) { handle_error(RIG_DEBUG_ERR, "listening"); exit(1); } #ifdef SIGPIPE /* Ignore SIGPIPE as we will handle it at the write()/send() calls that will consequently fail with EPIPE. All child threads will inherit this disposition which is what we want. */ #if HAVE_SIGACTION memset(&act, 0, sizeof act); act.sa_handler = SIG_IGN; act.sa_flags = SA_RESTART; if (sigaction(SIGPIPE, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction"); } #elif HAVE_SIGNAL if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) { handle_error(RIG_DEBUG_ERR, "signal"); } #endif #endif /* * main loop accepting connections */ do { arg = calloc(1, sizeof(struct handle_data)); if (!arg) { rig_debug(RIG_DEBUG_ERR, "calloc: %s\n", strerror(errno)); exit(1); } arg->amp = my_amp; arg->clilen = sizeof(arg->cli_addr); arg->sock = accept(sock_listen, (struct sockaddr *) &arg->cli_addr, &arg->clilen); if (arg->sock < 0) { handle_error(RIG_DEBUG_ERR, "accept"); break; } if ((retcode = getnameinfo((struct sockaddr const *)&arg->cli_addr, arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection opened from %s:%s\n", host, serv); #ifdef HAVE_PTHREAD pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); retcode = pthread_create(&thread, &attr, handle_socket, arg); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "pthread_create: %s\n", strerror(retcode)); break; } #else handle_socket(arg); #endif } while (retcode == 0); amp_close(my_amp); /* close port */ amp_cleanup(my_amp); /* if you care about memory */ #ifdef __MINGW32__ WSACleanup(); #endif return 0; } /* * This is the function run by the threads */ void *handle_socket(void *arg) { struct handle_data *handle_data_arg = (struct handle_data *)arg; FILE *fsockin; FILE *fsockout; int retcode; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); if (sock_osfhandle == -1) { rig_debug(RIG_DEBUG_ERR, "_open_osfhandle error: %s\n", strerror(errno)); goto handle_exit; } fsockin = _fdopen(sock_osfhandle, "rb"); #else fsockin = fdopen(handle_data_arg->sock, "rb"); #endif if (!fsockin) { rig_debug(RIG_DEBUG_ERR, "fdopen in: %s\n", strerror(errno)); goto handle_exit; } #ifdef __MINGW32__ fsockout = _fdopen(sock_osfhandle, "wb"); #else fsockout = fdopen(handle_data_arg->sock, "wb"); #endif if (!fsockout) { rig_debug(RIG_DEBUG_ERR, "fdopen out: %s\n", strerror(errno)); fclose(fsockin); goto handle_exit; } do { retcode = ampctl_parse(handle_data_arg->amp, fsockin, fsockout, NULL, 0); if (ferror(fsockin) || ferror(fsockout)) { retcode = 1; } } while (retcode == 0 || retcode == 2); if ((retcode = getnameinfo((struct sockaddr const *)&handle_data_arg->cli_addr, handle_data_arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection closed from %s:%s\n", host, serv); fclose(fsockin); #ifndef __MINGW32__ fclose(fsockout); #endif handle_exit: #ifdef __MINGW32__ closesocket(handle_data_arg->sock); #else close(handle_data_arg->sock); #endif free(arg); #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif return NULL; } void usage() { printf("Usage: ampctld [OPTION]... [COMMAND]...\n" "Daemon serving COMMANDs to a connected amplifier.\n\n"); printf( " -m, --model=ID select amplifier model number. See model list (-l)\n" " -r, --amp-file=DEVICE set device of the amplifier to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -t, --port=NUM set TCP listening port, default %s\n" " -T, --listen-addr=IPADDR set listening IP address, default ANY\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n", portno); usage_amp(stdout); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rigctl.c0000664000175000017500000006364615056640443011265 /* * rigctl.c - (C) Stephane Fillod 2000-2010 * (C) Nate Bargmann 2003,2006,2008,2010,2011,2012,2013 * (C) The Hamlib Group 2002,2006,2007,2012 * * This program test/control a radio using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include #include #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # include # define HST_SHRT_OPTS "iI" # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ #else /* no history */ #define HST_SHRT_OPTS "" #endif /* HAVE_READLINE_HISTORY */ #include #include "misc.h" #include "rigctl_parse.h" #include "riglist.h" #include "token.h" #define MAXNAMSIZ 32 #define MAXNBOPT 100 /* max number of different options */ static void usage(void); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "+m:r:p:d:P:D:s:c:t:lC:LuonvhVYZ!#" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"ptt-file", 1, 0, 'p'}, {"dcd-file", 1, 0, 'd'}, {"ptt-type", 1, 0, 'P'}, {"dcd-type", 1, 0, 'D'}, {"serial-speed", 1, 0, 's'}, {"civaddr", 1, 0, 'c'}, {"send-cmd-term", 1, 0, 't'}, {"list", 0, 0, 'l'}, {"set-conf", 1, 0, 'C'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"vfo", 0, 0, 'o'}, {"no-restore-ai", 0, 0, 'n'}, {"ignore-err", 0, 0, 'Y'}, {"debug-time-stamps", 0, 0, 'Z'}, #ifdef HAVE_READLINE_HISTORY {"read-history", 0, 0, 'i'}, {"save-history", 0, 0, 'I'}, #endif {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"cookie", 0, 0, '!'}, {"skip-init", 0, 0, '#'}, {0, 0, 0, 0} }; extern char rig_resp_sep; extern powerstat_t rig_powerstat; static RIG *my_rig; /* handle to rig (instance) */ #ifdef HAVE_SIG_ATOMIC_T static sig_atomic_t volatile ctrl_c = 0; #else static int volatile ctrl_c = 0; #endif #define MAXCONFLEN 2048 #ifdef WIN32 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (fdwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: ctrl_c = 1; return TRUE; default: return FALSE; } } #else static void signal_handler(int sig) { switch (sig) { case SIGINT: case SIGTERM: fprintf(stderr, "\nTerminating application, caught signal %d\n", sig); // Close stdin to stop reading input fclose(stdin); ctrl_c = 1; break; default: /* do nothing */ break; } } #endif static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } int main(int argc, char *argv[]) { rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int exitcode; int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; int ignore_rig_open_error = 0; #ifdef HAVE_READLINE_HISTORY int rd_hist = 0; int sv_hist = 0; const char *hist_dir = NULL; const char hist_file[] = "/.rigctl_history"; char *hist_path = NULL; #endif /* HAVE_READLINE_HISTORY */ const char *rig_file = NULL, *ptt_file = NULL, *dcd_file = NULL; ptt_type_t ptt_type = RIG_PTT_NONE; dcd_type_t dcd_type = RIG_DCD_NONE; int serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; int interactive; /* if no cmd on command line, switch to interactive */ int prompt = 1; /* Print prompt in rigctl */ int vfo_opt = 0; /* vfo_opt = 0 means target VFO is 'currVFO' */ char send_cmd_term = '\r'; /* send_cmd termination char */ int ext_resp = 0; int i; char rigstartup[1024]; char vbuf[1024]; rig_powerstat = RIG_POWER_ON; // defaults to power on struct timespec powerstat_check_time; #if HAVE_SIGACTION struct sigaction act; #endif int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf)); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: setvbuf err=%s\n", __func__, strerror(err)); } while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS HST_SHRT_OPTS, long_options, &option_index); if (c == -1) { break; } switch (c) { case '#': skip_init = 1; break; case '!': cookie_use = 1; break; case 'h': usage(); exit(0); case 'V': printf("rigctl %s\n", hamlib_version2); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; case 'd': if (!optarg) { usage(); /* wrong arg count */ exit(1); } dcd_file = optarg; break; case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "CM108")) { ptt_type = RIG_PTT_CM108; } else if (!strcmp(optarg, "GPIO")) { ptt_type = RIG_PTT_GPIO; } else if (!strcmp(optarg, "GPION")) { ptt_type = RIG_PTT_GPION; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { puts("Unrecognised PTT type, using NONE"); ptt_type = RIG_PTT_NONE; } break; case 'D': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { dcd_type = RIG_DCD_RIG; } else if (!strcmp(optarg, "DSR")) { dcd_type = RIG_DCD_SERIAL_DSR; } else if (!strcmp(optarg, "CTS")) { dcd_type = RIG_DCD_SERIAL_CTS; } else if (!strcmp(optarg, "CD")) { dcd_type = RIG_DCD_SERIAL_CAR; } else if (!strcmp(optarg, "PARALLEL")) { dcd_type = RIG_DCD_PARALLEL; } else if (!strcmp(optarg, "CM108")) { dcd_type = RIG_DCD_CM108; } else if (!strcmp(optarg, "GPIO")) { dcd_type = RIG_DCD_GPIO; } else if (!strcmp(optarg, "GPION")) { dcd_type = RIG_DCD_GPION; } else if (!strcmp(optarg, "NONE")) { dcd_type = RIG_DCD_NONE; } else { puts("Unrecognised DCD type, using NONE"); dcd_type = RIG_DCD_NONE; } break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (strlen(optarg) > 1) { send_cmd_term = strtol(optarg, NULL, 0); } else { send_cmd_term = optarg[0]; } break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 'o': vfo_opt = 1; break; case 'n': rig_no_restore_ai(); break; #ifdef HAVE_READLINE_HISTORY case 'i': rd_hist++; break; case 'I': sv_hist++; break; #endif /* HAVE_READLINE_HISTORY */ case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': rig_set_debug(verbose); list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Y': ignore_rig_open_error = 1; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); SNPRINTF(rigstartup, sizeof(rigstartup), "%s(%d) Startup:", __FILE__, __LINE__); for (i = 0; i < argc; ++i) { strcat(rigstartup, " "); strcat(rigstartup, argv[i]); } rig_debug(RIG_DEBUG_VERBOSE, "%s\n", rigstartup); rig_debug(RIG_DEBUG_VERBOSE, "rigctl %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); /* * at least one command on command line, * disable interactive mode */ if (optind < argc) { interactive = 0; // skip_init here caused segfault on rigctl -m 2041 -r /dev/pts/4 M CW 250 b 73 //skip_init = 1; } else { interactive = 1; } my_rig = rig_init(my_model); if (!my_rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } my_rig->caps->ptt_type = ptt_type; char *token = strtok(conf_parms, ","); struct rig_state *rs = STATE(my_rig); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = rig_token_lookup(my_rig, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = rig_set_conf(my_rig, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } ptt_type = my_rig->caps->ptt_type; // in case we set the ptt_type with set_conf token = strtok(NULL, ","); } if (rig_file) { rig_set_conf(my_rig, TOK_PATHNAME, rig_file); } /* * ex: RIG_PTT_PARALLEL and /dev/parport0 */ if (ptt_type != RIG_PTT_NONE) { PTTPORT(my_rig)->type.ptt = ptt_type; } if (dcd_type != RIG_DCD_NONE) { DCDPORT(my_rig)->type.dcd = dcd_type; } if (ptt_file) { strncpy(PTTPORT(my_rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); // default to RTS when ptt_type is not specified if (ptt_type == RIG_PTT_NONE) { rig_debug(RIG_DEBUG_VERBOSE, "%s: defaulting to RTS PTT\n", __func__); my_rig->caps->ptt_type = ptt_type = RIG_PTT_SERIAL_RTS; } } if (dcd_file) { strncpy(DCDPORT(my_rig)->pathname, dcd_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(my_rig)->parm.serial.rate = serial_rate; rs->rigport_deprecated.parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); } /* * print out conf parameters */ if (show_conf) { dumpconf(my_rig, stdout); } /* * print out capabilities, and exit immediately * We may be interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { // if rigctld then we need to open to get the rig caps if (my_model == RIG_MODEL_NETRIGCTL) { int ret; rig_set_debug(verbose); my_rig = rig_init(my_model); if ((ret = rig_open(my_rig)) != RIG_OK) { fprintf(stderr, "Unable to open rigctld: %s\n", rigerror(ret)); exit(1); } rig_close(my_rig); dumpstate(my_rig, stdout); rig_close(my_rig); exit(0); } dumpcaps(my_rig, stdout); rig_cleanup(my_rig); /* if you care about memory */ exit(0); } retcode = rig_open(my_rig); if (retcode != RIG_OK) { // fprintf(stderr, "rig_open: error = %s %s \n", rig_file, // rigerror(retcode)); if (!ignore_rig_open_error) { exit(2); } } if (verbose > 0) { printf("Opened rig model %u, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } if (!skip_init && my_rig->caps->get_powerstat) { rig_get_powerstat(my_rig, &rig_powerstat); rs->powerstat = rig_powerstat; } if (my_rig->caps->rig_model == RIG_MODEL_NETRIGCTL) { /* We automatically detect if we need to be in vfo mode or not */ int rigctld_vfo_opt = netrigctl_get_vfo_mode(my_rig); vfo_opt = rs->vfo_opt = rigctld_vfo_opt; rig_debug(RIG_DEBUG_TRACE, "%s vfo_opt=%d\n", __func__, vfo_opt); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); exitcode = 0; #ifdef HAVE_LIBREADLINE if (interactive && prompt) { rl_readline_name = "rigctl"; #ifdef HAVE_READLINE_HISTORY using_history(); /* Initialize Readline History */ if (rd_hist || sv_hist) { int hist_path_size; struct stat hist_dir_stat; if (!(hist_dir = getenv("RIGCTL_HIST_DIR"))) { hist_dir = getenv("HOME"); } if (((stat(hist_dir, &hist_dir_stat) == -1) && (errno == ENOENT)) || !(S_ISDIR(hist_dir_stat.st_mode))) { fprintf(stderr, "Warning: %s is not a directory!\n", hist_dir); } hist_path_size = sizeof(char) * (strlen(hist_dir) + strlen(hist_file) + 1); hist_path = (char *)calloc(hist_path_size, sizeof(char)); SNPRINTF(hist_path, hist_path_size, "%s%s", hist_dir, hist_file); } if (rd_hist && hist_path) { if (read_history(hist_path) == ENOENT) { fprintf(stderr, "Warning: Could not read history from %s\n", hist_path); } } #endif /* HAVE_READLINE_HISTORY */ } #endif /* HAVE_LIBREADLINE */ int rig_opened = 1; // our rig is already open #if HAVE_SIGACTION #ifdef SIGPIPE /* Ignore SIGPIPE as we will handle it at the write()/send() calls that will consequently fail with EPIPE. All child threads will inherit this disposition which is what we want. */ memset(&act, 0, sizeof act); act.sa_handler = SIG_IGN; act.sa_flags = SA_RESTART; if (sigaction(SIGPIPE, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE"); } #endif #ifdef SIGINT memset(&act, 0, sizeof act); act.sa_handler = signal_handler; if (sigaction(SIGINT, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGINT"); } #endif #ifdef SIGTERM memset(&act, 0, sizeof act); act.sa_handler = signal_handler; if (sigaction(SIGTERM, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM"); } #endif #elif defined (WIN32) if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler"); } #elif HAVE_SIGNAL #ifdef SIGPIPE if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) { handle_error(RIG_DEBUG_ERR, "signal SIGPIPE"); } #endif #ifdef SIGINT if (SIG_ERR == signal(SIGINT, signal_handler)) { handle_error(RIG_DEBUG_ERR, "signal SIGINT"); } #endif #ifdef SIGTERM if (SIG_ERR == signal(SIGTERM, signal_handler)) { handle_error(RIG_DEBUG_ERR, "signal SIGTERM"); } #endif #endif elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_SET); do { if (!rig_opened) { // rig may have closed on us to try once to reopen retcode = rig_open(my_rig); rig_debug(RIG_DEBUG_WARN, "%s: rig_open again retcode=%d\n", __func__, retcode); } retcode = rigctl_parse(my_rig, stdin, stdout, argv, argc, NULL, interactive, prompt, &vfo_opt, send_cmd_term, &ext_resp, &rig_resp_sep, 0); // If we get a timeout, the rig might be powered off // Update our power status in case power gets turned off // Check power status if rig is powered off, but not more often than once per second if (my_rig->caps->get_powerstat && (retcode == -RIG_ETIMEOUT || (retcode == -RIG_EPOWER && elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_GET) >= 1000))) { powerstat_t powerstat; rig_get_powerstat(my_rig, &powerstat); rig_powerstat = powerstat; if (powerstat == RIG_POWER_OFF || powerstat == RIG_POWER_STANDBY) { retcode = -RIG_EPOWER; } elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_SET); } // if we get a hard error we try to reopen the rig again // this should cover short dropouts that can occur if (retcode < 0 && !RIG_IS_SOFT_ERRCODE(-retcode)) { int retry = 3; rig_debug(RIG_DEBUG_ERR, "%s: i/o error\n", __func__); do { retcode = rig_close(my_rig); hl_usleep(1000 * 1000); rig_debug(RIG_DEBUG_ERR, "%s: rig_close retcode=%d\n", __func__, retcode); retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; rig_debug(RIG_DEBUG_ERR, "%s: rig_open retcode=%d\n", __func__, retcode); } while (retry-- > 0 && retcode != RIG_OK); } } while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode))); if (interactive && prompt) { #ifdef HAVE_READLINE_HISTORY if (sv_hist && hist_path) { if (write_history(hist_path) == ENOENT) { fprintf(stderr, "\nWarning: Could not write history to %s\n", hist_path); } } if ((rd_hist || sv_hist) && hist_path) { free(hist_path); hist_path = (char *)NULL; } #endif /* HAVE_READLINE_HISTORY */ } rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ return exitcode; } void usage(void) { printf("Usage: rigctl [OPTION]... [COMMAND]...\n" "Send COMMANDs to a connected radio transceiver or receiver.\n\n"); printf( " -m, --model=ID select radio model number. See model list (-l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -p, --ptt-file=DEVICE set device of the PTT device to operate on\n" " -d, --dcd-file=DEVICE set device of the DCD device to operate on\n" " -P, --ptt-type=TYPE set type of the PTT device to operate on\n" " -D, --dcd-type=TYPE set type of the DCD device to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -t, --send-cmd-term=CHAR set send_cmd command termination char\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -o, --vfo do not default to VFO_CURR, require extra vfo arg\n" " -n, --no-restore-ai do not restore auto information mode on rig\n" #ifdef HAVE_READLINE_HISTORY " -i, --read-history read prior interactive session history\n" " -I, --save-history save current interactive session history\n" #endif " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Y, --ignore-err ignore rig_open errors\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" " -!, --cookie use cookie control\n" " -#, --skip-init skip rig initialization\n" " - read commands from standard input\n" "\n" ); usage_rig(stdout); printf("\nError codes and messages\n"); for (enum rig_errcode_e e = 0; e < RIG_EEND; ++e) { printf("-%d - %s", e, rigerror2(e)); } printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rigswr.c0000664000175000017500000002326715056640443011311 /* * rigswr.c - (C) Stephane Fillod and Thierry Leconte 2004 * * This program outputs an swr curve value using Hamlib. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include "misc.h" #include "riglist.h" /* * Prototypes */ static void usage(); static void version(); static int set_conf(RIG *rig, char *conf_parms); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. */ #define SHORT_OPTIONS "m:r:s:c:C:p:P:vhV" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"serial-speed", 1, 0, 's'}, {"civaddr", 1, 0, 'c'}, {"set-conf", 1, 0, 'C'}, {"ptt-file", 1, 0, 'p'}, {"ptt-type", 1, 0, 'P'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; #define MAXCONFLEN 2048 int main(int argc, char *argv[]) { RIG *rig; /* handle to rig (nstance) */ rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int verbose = 0; const char *rig_file = NULL, *ptt_file = NULL; ptt_type_t ptt_type = RIG_PTT_NONE; int serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; freq_t freq, freqstop; freq_t step = kHz(100); value_t pwr; while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { ptt_type = atoi(optarg); } break; case 'v': verbose++; break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose < 2 ? RIG_DEBUG_WARN : verbose); rig_debug(RIG_DEBUG_VERBOSE, "rigswr, %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); if (optind + 1 >= argc) { usage(); exit(1); } rig = rig_init(my_model); if (!rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } retcode = set_conf(rig, conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } if (ptt_type != RIG_PTT_NONE) { PTTPORT(rig)->type.ptt = ptt_type; } if (ptt_file) { strncpy(PTTPORT(rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); } if (rig_file) { strncpy(RIGPORT(rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(rig)->parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(rig, rig_token_lookup(rig, "civaddr"), civaddr); } if (!rig_has_get_level(rig, RIG_LEVEL_SWR) || PTTPORT(rig)->type.ptt == RIG_PTT_NONE) { fprintf(stderr, "rig backend for %s could not get SWR" "or has insufficient capability\nSorry\n", rig->caps->model_name); exit(3); } retcode = rig_open(rig); if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened rig model %u, '%s'\n", rig->caps->rig_model, rig->caps->model_name); } freq = atof(argv[optind++]); freqstop = atof(argv[optind++]); if (optind < argc) { step = atof(argv[optind]); } rig_set_freq(rig, RIG_VFO_CURR, freq); rig_set_mode(rig, RIG_VFO_CURR, RIG_MODE_CW, RIG_PASSBAND_NORMAL); pwr.f = 0.25; /* 25% of RF POWER */ rig_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, pwr); while (freq <= freqstop) { value_t swr; rig_set_ptt(rig, RIG_VFO_CURR, RIG_PTT_ON); hl_usleep(500000); rig_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_SWR, &swr); rig_set_ptt(rig, RIG_VFO_CURR, RIG_PTT_OFF); printf("%10.0f %4.2f\n", freq, swr.f); freq += step; rig_set_freq(rig, RIG_VFO_CURR, freq); } rig_close(rig); return 0; } void version() { printf("rigswr, %s\n\n", hamlib_version2); printf("%s\n", hamlib_copyright); } void usage() { printf("Usage: rigswr [OPTION]... start_freq stop_freq [freq_step]\n" "Output SWR vs Frequency.\n\n"); printf( " -m, --model=ID select radio model number. See model list (rigctl -l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -p, --ptt-file=DEVICE set device of the PTT device to operate on\n" " -P, --ptt-type=TYPE set type of the PTT device to operate on\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n" ); printf("\nReport bugs to .\n"); } static int set_conf(RIG *rig, char *conf_parms) { char *p, *n; p = conf_parms; while (p && *p != '\0') { int ret; /* FIXME: left hand value of = cannot be null */ char *q = strchr(p, '='); if (!q) { return RIG_EINVAL; } *q++ = '\0'; n = strchr(q, ','); if (n) { *n++ = '\0'; } ret = rig_set_conf(rig, rig_token_lookup(rig, p), q); if (ret != RIG_OK) { return ret; } p = n; } return RIG_OK; } hamlib-4.6.5/tests/testmW2power.c0000664000175000017500000000334215056640443012406 /* * Hamlib sample program to test transceive mode (async event) */ #include #include #include #include #include #include int nrigs = 0; int callback(const struct rig_caps *caps, rig_ptr_t rigp) { RIG *rig = (RIG *) rigp; switch (caps->rig_model) { case RIG_MODEL_NETRIGCTL: return 1; break; } rig = rig_init(caps->rig_model); if (!rig) { fprintf(stderr, "Unknown rig num: %u\n", caps->rig_model); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } if (caps->mW2power) { nrigs++; printf("%20s:", caps->model_name); fflush(stdout); float fpow; unsigned int mwpower = 1 * 1000; freq_t freq = MHz(14); int retcode = rig_mW2power(rig, &fpow, mwpower, freq, RIG_MODE_CW); if (retcode != RIG_OK) { printf("rig_mW2power: error = %s \n", rigerror(retcode)); return 1; } if (fpow < 0.009 || fpow > .11) { // printf("rig=%d, fpow=%g, min=%d, max=%d\n", caps->rig_model, fpow, caps->); printf("rig=%u, fpow=%g\n", caps->rig_model, fpow); // we call again to make debugging this section easier rig_mW2power(rig, &fpow, mwpower, freq, RIG_MODE_CW); } else { printf("\n"); } } rig_cleanup(rig); /* if you care about memory */ return 1; } int main(int argc, char *argv[]) { RIG *rig; rig_set_debug(RIG_DEBUG_NONE); rig_load_all_backends(); rig_list_foreach(callback, &rig); printf("Done testing %d rigs\n", nrigs); return 0; } hamlib-4.6.5/tests/testrigcaps.c0000664000175000017500000000076115056640443012316 #include #include // we have a const *char HAMLIB_CHECK_RIG_CAPS defined in most backends // if the structure ever changes it will produce an error during rig_init int main() { printf("Check rig_caps offsets\n"); printf("If structure changes will break shared library API\n"); RIG *rig; rig_set_debug_level(RIG_DEBUG_ERR); rig = rig_init(1); if (rig == NULL) { return 1; } printf("Offsets are OK (i.e. have not changed)\n"); return 0; } hamlib-4.6.5/tests/rig_bench.c0000664000175000017500000000634315056640443011710 /* * Hamlib rig_bench program */ #include #include #include #include #include #include #include "misc.h" #define LOOP_COUNT 100 #define SERIAL_PORT "/dev/ttyUSB0" int main(int argc, const char *argv[]) { RIG *my_rig; /* handle to rig (nstance) */ int retcode; /* generic return code from functions */ rig_model_t myrig_model; unsigned i; struct timeval tv1, tv2; float elapsed; rig_set_debug(RIG_DEBUG_ERR); /* * allocate memory, setup & open port */ if (argc < 2) { hamlib_port_t myport; /* may be overridden by backend probe */ myport.type.rig = RIG_PORT_SERIAL; myport.parm.serial.rate = 19200; myport.parm.serial.data_bits = 8; myport.parm.serial.stop_bits = 1; myport.parm.serial.parity = RIG_PARITY_NONE; myport.parm.serial.handshake = RIG_HANDSHAKE_NONE; strncpy(myport.pathname, SERIAL_PORT, HAMLIB_FILPATHLEN - 1); rig_load_all_backends(); myrig_model = rig_probe(&myport); } else { myrig_model = atoi(argv[1]); } my_rig = rig_init(myrig_model); if (!my_rig) { fprintf(stderr, "Unknown rig num: %u\n", myrig_model); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } printf("Opened rig model %u, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); printf("Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); printf("Serial speed: %d baud\n", RIGPORT(my_rig)->parm.serial.rate); #if 0 // if we want to bench serial or network I/O use this time rig_set_cache_timeout_ms(my_rig, HAMLIB_CACHE_ALL, 0); #endif strncpy(RIGPORT(my_rig)->pathname, SERIAL_PORT, HAMLIB_FILPATHLEN - 1); retcode = rig_open(my_rig); if (retcode != RIG_OK) { printf("rig_open: error = %s\n", rigerror(retcode)); exit(2); } printf("Port %s opened ok\n", SERIAL_PORT); printf("Perform %d loops...\n", LOOP_COUNT); /* * we're not using getrusage here because we want effective time */ gettimeofday(&tv1, NULL); for (i = 0; i < LOOP_COUNT; i++) { freq_t freq; rmode_t rmode; pbwidth_t width; retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq); if (retcode != RIG_OK) { printf("rig_get_freq: error = %s \n", rigerror(retcode)); exit(1); } retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); if (retcode != RIG_OK) { printf("rig_get_mode: error = %s \n", rigerror(retcode)); exit(1); } } gettimeofday(&tv2, NULL); elapsed = tv2.tv_sec - tv1.tv_sec + (tv2.tv_usec - tv1.tv_usec) / 1000000.0; printf("Elapsed: %.3fs, Avg: %f loops/s, %f s/loop\n", elapsed, LOOP_COUNT / elapsed, elapsed / LOOP_COUNT); rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ printf("port %s closed ok \n", SERIAL_PORT); return 0; } hamlib-4.6.5/tests/testcookie.c0000664000175000017500000001110515056640443012131 #include // GET tests static int test1() { int retcode; // Normal get char cookie[HAMLIB_COOKIE_SIZE]; retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#1a OK\n"); } else {printf("Test#1a Failed\n"); return 1;} // Should be able to release and get it right back rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie)); retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#1b OK\n"); } else {printf("Test#1b Failed\n"); return 1;} // Doing a get when another cookie is active should fail char cookie2[HAMLIB_COOKIE_SIZE]; cookie2[0] = 0; retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2)); if (retcode == RIG_OK) { printf("Test#1c OK\n"); } else {printf("Test#1c Failed\n"); return 1;} #if 0 // after 1 second we should be able to get a cookie // this means the cookie holder did not renew within 1 second hl_usleep(1500 * 1000); // after 1 second we should be able to get a cookie retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2)); if (retcode == RIG_OK) { printf("Test#1d OK\n"); } else {printf("Test#1d Failed\n"); return 1;} #endif retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie2, sizeof(cookie2)); if (retcode == RIG_OK) { printf("Test#1e OK\n"); } else {printf("Test#1e Failed\n"); return 1;} return 0; } // RENEW tests static int test2() { int retcode; char cookie[HAMLIB_COOKIE_SIZE]; retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#2a OK %s\n", cookie); } else {printf("Test#2a Failed\n"); return 1;} retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#2b OK\n"); } else {printf("Test#2b Failed\n"); return 1;} // get another cookie should work char cookie2[HAMLIB_COOKIE_SIZE]; retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2)); if (retcode == RIG_OK) { printf("Test#2c OK %s\n", cookie2); } else {printf("Test#2c Failed\n"); return 1;} // should not be able to renew 1st cookie retcode = rig_cookie(NULL, RIG_COOKIE_RENEW, cookie, sizeof(cookie)); if (retcode != RIG_OK) { printf("Test#2d OK\n"); } else {printf("Test#2d Failed cookie=%s\n", cookie); return 1;} // release cookie2 again to clean up test retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie2, sizeof(cookie2)); if (retcode == RIG_OK) { printf("Test#2e OK\n"); } else {printf("Test#2e Failed\n"); return 1;} return 0; } // Input sanity checks static int test3_invalid_input() { int retcode; char cookie[HAMLIB_COOKIE_SIZE]; int n = 0; /* Make sure any value smaller than HAMLIB_COOKIE_SIZE is rejected */ for (unsigned int i = 0; i < HAMLIB_COOKIE_SIZE; i++) { retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, i); if (retcode != -RIG_EINVAL) { n++; printf("Test#3a failed at %u bytes\n", i); } } if (n == 0) { printf("Test#3a OK\n"); } /* Make sure a NULL cookie is ignored */ retcode = rig_cookie(NULL, RIG_COOKIE_GET, NULL, sizeof(cookie)); if (retcode == -RIG_EINVAL) { printf("Test#3b OK\n"); } else {printf("Test#3b Failed\n"); return 1;} /* Make sure an invalid command is dropped with proto error */ retcode = rig_cookie(NULL, RIG_COOKIE_RENEW + 1, cookie, sizeof(cookie)); if (retcode == -RIG_EPROTO) { printf("Test#3c OK\n"); } else {printf("Test#3c Failed\n"); return 1;} return 0; } static int test4_large_cookie_size() { int retcode; char cookie[HAMLIB_COOKIE_SIZE * 2]; /* Using a larger cookie should also work */ retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#4a OK\n"); } else {printf("Test#4a Failed\n"); return 1;} /* Cookie should be smaller the maximum specified by lib */ //if (strlen(cookie) < HAMLIB_COOKIE_SIZE) { printf("Test#4b OK\n"); } //else {printf("Test#4b Failed\n"); return 1;} /* Release the cookie again to clean up */ retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie)); if (retcode == RIG_OK) { printf("Test#4c OK\n"); } else {printf("Test#4c Failed\n"); return 1;} return 0; } int main() { rig_set_debug(RIG_DEBUG_VERBOSE); if (test1()) { return 1; } if (test2()) { return 1; } if (test3_invalid_input()) { return 1; } if (test4_large_cookie_size()) { return 1; } return 0; } hamlib-4.6.5/tests/hamlibmodels.c0000664000175000017500000000164215056640443012425 /* Example showing host to list all models */ #include #include #include char *list[1000]; // as of 2023-01-17 we have 275 rigs so this should cover us for long time int nmodels = 0; static int hash_model_list(const struct rig_caps *caps, void *data) { char s[256]; sprintf(s, "%s %s", caps->mfg_name, caps->model_name); list[nmodels] = strdup(s); ++nmodels; return 1; /* !=0, we want them all ! */ } int mycmp(const void *p1, const void *p2) { const char **s1 = (const char **)p1; const char **s2 = (const char **)p2; return strcasecmp(*s1, *s2); } int main() { rig_set_debug_level(RIG_DEBUG_NONE); rig_load_all_backends(); rig_list_foreach(hash_model_list, NULL); qsort(list, nmodels, sizeof(list) / 1000, mycmp); for (int i = 0; i < nmodels; ++i) { printf("%s\n", list[i]); } printf("%d models\n", nmodels); return 0; } hamlib-4.6.5/tests/uthash.h0000664000175000017500000016257315056640443011301 /* Copyright (c) 2003-2011, Troy D. Hanson http://uthash.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTHASH_H #define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ #include /* exit() */ /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ source) this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ #ifdef _MSC_VER /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define DECLTYPE(x) (decltype(x)) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #define DECLTYPE(x) #endif #else /* GNU, Sun and other compilers */ #define DECLTYPE(x) (__typeof(x)) #endif #ifdef NO_DECLTYPE #define DECLTYPE_ASSIGN(dst,src) \ do { \ char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ } while(0) #else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ } while(0) #endif /* a number of the hash function use uint32_t which isn't defined on win32 */ #ifdef _MSC_VER typedef unsigned int uint32_t; typedef unsigned char uint8_t; #else #include /* uint32_t */ #endif #define UTHASH_VERSION 1.9.4 #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #define uthash_free(ptr,sz) free(ptr) /* free fcn */ #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ #define uthash_expand_fyi(tbl) /* can be defined to log expands */ /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ /* calculate the element whose hash handle address is hhe */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ unsigned _hf_bkt,_hf_hashv; \ out=NULL; \ if (head) { \ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ keyptr,keylen,out); \ } \ } \ } while (0) #ifdef HASH_BLOOM #define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) #define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) #define HASH_BLOOM_MAKE(tbl) \ do { \ (tbl)->bloom_nbits = HASH_BLOOM; \ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ } while (0); #define HASH_BLOOM_FREE(tbl) \ do { \ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ } while (0); #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) #define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) #define HASH_BLOOM_ADD(tbl,hashv) \ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #define HASH_BLOOM_TEST(tbl,hashv) \ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else #define HASH_BLOOM_MAKE(tbl) #define HASH_BLOOM_FREE(tbl) #define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif #define HASH_MAKE_TABLE(hh,head) \ do { \ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ (head)->hh.tbl->tail = &((head)->hh); \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_MAKE((head)->hh.tbl); \ (head)->hh.tbl->signature = HASH_SIGNATURE; \ } while(0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ unsigned _ha_bkt; \ (add)->hh.next = NULL; \ (add)->hh.key = (char*)keyptr; \ (add)->hh.keylen = keylen_in; \ if (!(head)) { \ head = (add); \ (head)->hh.prev = NULL; \ HASH_MAKE_TABLE(hh,head); \ } else { \ (head)->hh.tbl->tail->next = (add); \ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ (head)->hh.tbl->tail = &((add)->hh); \ } \ (head)->hh.tbl->num_items++; \ (add)->hh.tbl = (head)->hh.tbl; \ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ (add)->hh.hashv, _ha_bkt); \ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ HASH_FSCK(hh,head); \ } while(0) #define HASH_TO_BKT( hashv, num_bkts, bkt ) \ do { \ bkt = ((hashv) & ((num_bkts) - 1)); \ } while(0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. * The use of _hd_hh_del below deserves special explanation. * These used to be expressed using (delptr) but that led to a bug * if someone used the same symbol for the head and deletee, like * HASH_DELETE(hh,users,users); * We want that to work, but by changing the head (users) below * we were forfeiting our ability to further refer to the deletee (users) * in the patch-up process. Solution: use scratch space to * copy the deletee pointer, then the latter references are via that * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ do { \ struct UT_hash_handle *_hd_hh_del; \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ uthash_free((head)->hh.tbl->buckets, \ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ head = NULL; \ } else { \ unsigned _hd_bkt; \ _hd_hh_del = &((delptr)->hh); \ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ (head)->hh.tbl->tail = \ (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ } \ if (_hd_hh_del->next) { \ ((UT_hash_handle*)((char*)_hd_hh_del->next + \ (head)->hh.tbl->hho))->prev = \ _hd_hh_del->prev; \ } \ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ (head)->hh.tbl->num_items--; \ } \ HASH_FSCK(hh,head); \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield,strlen(add->strfield),add) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_FIND_PTR(head,findptr,out) \ HASH_FIND(hh,head,findptr,sizeof(void *),out) #define HASH_ADD_PTR(head,ptrfield,add) \ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. */ #ifdef HASH_DEBUG #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) #define HASH_FSCK(hh,head) \ do { \ unsigned _bkt_i; \ unsigned _count, _bkt_count; \ char *_prev; \ struct UT_hash_handle *_thh; \ if (head) { \ _count = 0; \ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ _bkt_count = 0; \ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ _prev = NULL; \ while (_thh) { \ if (_prev != (char*)(_thh->hh_prev)) { \ HASH_OOPS("invalid hh_prev %p, actual %p\n", \ _thh->hh_prev, _prev ); \ } \ _bkt_count++; \ _prev = (char*)(_thh); \ _thh = _thh->hh_next; \ } \ _count += _bkt_count; \ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ HASH_OOPS("invalid bucket count %u, actual %u\n", \ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ } \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid hh item count %u, actual %u\n", \ (head)->hh.tbl->num_items, _count ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ _count = 0; \ _prev = NULL; \ _thh = &(head)->hh; \ while (_thh) { \ _count++; \ if (_prev !=(char*)(_thh->prev)) { \ HASH_OOPS("invalid prev %p, actual %p\n", \ _thh->prev, _prev ); \ } \ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ (head)->hh.tbl->hho) : NULL ); \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid app item count %u, actual %u\n", \ (head)->hh.tbl->num_items, _count ); \ } \ } \ } while (0) #else #define HASH_FSCK(hh,head) #endif /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ do { \ unsigned _klen = fieldlen; \ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) #else #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ #ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN #endif /* The Bernstein hash function, used in Perl prior to v5.6 */ #define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hb_keylen=keylen; \ char *_hb_key=(char*)(key); \ (hashv) = 0; \ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ bkt = (hashv) & (num_bkts-1); \ } while (0) /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _sx_i; \ char *_hs_key=(char*)(key); \ hashv = 0; \ for(_sx_i=0; _sx_i < keylen; _sx_i++) \ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ bkt = hashv & (num_bkts-1); \ } while (0) #define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _fn_i; \ char *_hf_key=(char*)(key); \ hashv = 2166136261UL; \ for(_fn_i=0; _fn_i < keylen; _fn_i++) \ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ bkt = hashv & (num_bkts-1); \ } while(0); #define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _ho_i; \ char *_ho_key=(char*)(key); \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ hashv += (hashv << 10); \ hashv ^= (hashv >> 6); \ } \ hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_JEN_MIX(a,b,c) \ do { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) #define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ char *_hj_key=(char*)(key); \ hashv = 0xfeedbeef; \ _hj_i = _hj_j = 0x9e3779b9; \ _hj_k = keylen; \ while (_hj_k >= 12) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + ( (unsigned)_hj_key[6] << 16 ) \ + ( (unsigned)_hj_key[7] << 24 ) ); \ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + ( (unsigned)_hj_key[10] << 16 ) \ + ( (unsigned)_hj_key[11] << 24 ) ); \ \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ _hj_k -= 12; \ } \ hashv += keylen; \ switch ( _hj_k ) { \ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ case 5: _hj_j += _hj_key[4]; \ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ case 1: _hj_i += _hj_key[0]; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ bkt = hashv & (num_bkts-1); \ } while(0) /* The Paul Hsieh hash function */ #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) #define get16bits(d) (*((const uint16_t *) (d))) #endif #if !defined (get16bits) #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif #define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ do { \ char *_sfh_key=(char*)(key); \ uint32_t _sfh_tmp, _sfh_len = keylen; \ \ int _sfh_rem = _sfh_len & 3; \ _sfh_len >>= 2; \ hashv = 0xcafebabe; \ \ /* Main loop */ \ for (;_sfh_len > 0; _sfh_len--) { \ hashv += get16bits (_sfh_key); \ _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ hashv = (hashv << 16) ^ _sfh_tmp; \ _sfh_key += 2*sizeof (uint16_t); \ hashv += hashv >> 11; \ } \ \ /* Handle end cases */ \ switch (_sfh_rem) { \ case 3: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 16; \ hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ hashv += hashv >> 11; \ break; \ case 2: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 11; \ hashv += hashv >> 17; \ break; \ case 1: hashv += *_sfh_key; \ hashv ^= hashv << 10; \ hashv += hashv >> 1; \ } \ \ /* Force "avalanching" of final 127 bits */ \ hashv ^= hashv << 3; \ hashv += hashv >> 5; \ hashv ^= hashv << 4; \ hashv += hashv >> 17; \ hashv ^= hashv << 25; \ hashv += hashv >> 6; \ bkt = hashv & (num_bkts-1); \ } while(0); #ifdef HASH_USING_NO_STRICT_ALIASING /* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * MurmurHash uses the faster approach only on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ #if (defined(__i386__) || defined(__x86_64__)) #define MUR_GETBLOCK(p,i) p[i] #else /* non intel */ #define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) #define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) #define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) #define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) #define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) #if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) #define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) #else /* assume little endian non-intel */ #define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) #endif #define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ MUR_ONE_THREE(p)))) #endif #define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) #define MUR_FMIX(_h) \ do { \ _h ^= _h >> 16; \ _h *= 0x85ebca6b; \ _h ^= _h >> 13; \ _h *= 0xc2b2ae35l; \ _h ^= _h >> 16; \ } while(0) #define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ do { \ const uint8_t *_mur_data = (const uint8_t*)(key); \ const int _mur_nblocks = (keylen) / 4; \ uint32_t _mur_h1 = 0xf88D5353; \ uint32_t _mur_c1 = 0xcc9e2d51; \ uint32_t _mur_c2 = 0x1b873593; \ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ int _mur_i; \ for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ uint32_t _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ \ _mur_h1 ^= _mur_k1; \ _mur_h1 = MUR_ROTL32(_mur_h1,13); \ _mur_h1 = _mur_h1*5+0xe6546b64; \ } \ const uint8_t *_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ uint32_t _mur_k1=0; \ switch((keylen) & 3) { \ case 3: _mur_k1 ^= _mur_tail[2] << 16; \ case 2: _mur_k1 ^= _mur_tail[1] << 8; \ case 1: _mur_k1 ^= _mur_tail[0]; \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ _mur_h1 ^= _mur_k1; \ } \ _mur_h1 ^= (keylen); \ MUR_FMIX(_mur_h1); \ hashv = _mur_h1; \ bkt = hashv & (num_bkts-1); \ } while(0) #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ do { \ if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ else out=NULL; \ while (out) { \ if (out->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ } \ if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \ else out = NULL; \ } \ } while(0) /* add an item to a bucket */ #define HASH_ADD_TO_BKT(head,addhh) \ do { \ head.count++; \ (addhh)->hh_next = head.hh_head; \ (addhh)->hh_prev = NULL; \ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ (head).hh_head=addhh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && (addhh)->tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS((addhh)->tbl); \ } \ } while(0) /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,hh_del) \ (head).count--; \ if ((head).hh_head == hh_del) { \ (head).hh_head = hh_del->hh_next; \ } \ if (hh_del->hh_prev) { \ hh_del->hh_prev->hh_next = hh_del->hh_next; \ } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of * the hash function as it applies to the key domain). * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write * * ceil(n/b) = (n/b) + ((n%b)?1:0) * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ unsigned _he_bkt; \ unsigned _he_bkt_i; \ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ memset(_he_new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->ideal_chain_maxlen = \ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ tbl->nonideal_items = 0; \ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ { \ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ while (_he_thh) { \ _he_hh_nxt = _he_thh->hh_next; \ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ tbl->nonideal_items++; \ _he_newbkt->expand_mult = _he_newbkt->count / \ tbl->ideal_chain_maxlen; \ } \ _he_thh->hh_prev = NULL; \ _he_thh->hh_next = _he_newbkt->hh_head; \ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ _he_thh; \ _he_newbkt->hh_head = _he_thh; \ _he_thh = _he_hh_nxt; \ } \ } \ uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ tbl->num_buckets *= 2; \ tbl->log2_num_buckets++; \ tbl->buckets = _he_new_buckets; \ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ (tbl->ineff_expands+1) : 0; \ if (tbl->ineff_expands > 1) { \ tbl->noexpand=1; \ uthash_noexpand_fyi(tbl); \ } \ uthash_expand_fyi(tbl); \ } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ /* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ do { \ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ if (head) { \ unsigned _hs_looping,_hs_insize,_hs_psize,_hs_qsize; \ _hs_insize = 1; \ _hs_looping = 1; \ _hs_list = &((head)->hh); \ while (_hs_looping) { \ int _hs_nmerges = 0; \ _hs_p = _hs_list; \ _hs_list = NULL; \ _hs_tail = NULL; \ while (_hs_p) { \ int _hs_i; \ _hs_nmerges++; \ _hs_q = _hs_p; \ _hs_psize = 0; \ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ _hs_psize++; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ if (! (_hs_q) ) break; \ } \ _hs_qsize = _hs_insize; \ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ if (_hs_psize == 0) { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else if (( \ cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ ) <= 0) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } \ if ( _hs_tail ) { \ _hs_tail->next = ((_hs_e) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ } else { \ _hs_list = _hs_e; \ } \ _hs_e->prev = ((_hs_tail) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ _hs_tail = _hs_e; \ } \ _hs_p = _hs_q; \ } \ if (_hs_tail) _hs_tail->next = NULL; \ if ( _hs_nmerges <= 1 ) { \ _hs_looping=0; \ (head)->hh.tbl->tail = _hs_tail; \ DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ } \ _hs_insize *= 2; \ } \ HASH_FSCK(hh,head); \ } \ } while (0) /* This function selects items from one hash into another hash. * The end result is that the selected items have dual presence * in both hashes. There is no copy of the items made; rather * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ unsigned _src_bkt, _dst_bkt; \ void *_last_elt=NULL, *_elt; \ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ if (src) { \ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ _src_hh; \ _src_hh = _src_hh->hh_next) { \ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ if (cond(_elt)) { \ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ _dst_hh->key = _src_hh->key; \ _dst_hh->keylen = _src_hh->keylen; \ _dst_hh->hashv = _src_hh->hashv; \ _dst_hh->prev = _last_elt; \ _dst_hh->next = NULL; \ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ if (!dst) { \ DECLTYPE_ASSIGN(dst,_elt); \ HASH_MAKE_TABLE(hh_dst,dst); \ } else { \ _dst_hh->tbl = (dst)->hh_dst.tbl; \ } \ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ (dst)->hh_dst.tbl->num_items++; \ _last_elt = _elt; \ _last_elt_hh = _dst_hh; \ } \ } \ } \ } \ HASH_FSCK(hh_dst,dst); \ } while (0) #define HASH_CLEAR(hh,head) \ do { \ if (head) { \ uthash_free((head)->hh.tbl->buckets, \ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ (head)=NULL; \ } \ } while(0) #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) #else #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) #endif /* obtain a count of items in the hash */ #define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. * (The multiplier is simply expand_mult+1). The whole idea of this * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; /* random signature used only to find hash tables in external analysis */ #define HASH_SIGNATURE 0xa0111fe1 #define HASH_BLOOM_SIGNATURE 0xb12220f2 typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets, log2_num_buckets; unsigned num_items; struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ /* in an ideal situation (all buckets used equally), no bucket would have * more than ceil(#items/#buckets) items. that's the ideal chain length. */ unsigned ideal_chain_maxlen; /* nonideal_items is the number of items in the hash whose chain position * exceeds the ideal chain maxlen. these items pay the penalty for an uneven * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash * function isn't a good fit for the key domain. When expansion is inhibited * the hash will still work, albeit no longer in constant time. */ unsigned ineff_expands, noexpand; uint32_t signature; /* used only to find hash tables in external analysis */ #ifdef HASH_BLOOM uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ uint8_t *bloom_bv; char bloom_nbits; #endif } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; #endif /* UTHASH_H */ hamlib-4.6.5/tests/dumpcaps.h0000664000175000017500000000010215056640443011574 #include int dumpconf_list(RIG *rig, FILE *fout); hamlib-4.6.5/tests/test2038.c0000664000175000017500000000153015056640443011255 /* 2038 test This is OK on 64-bit systems and mingw64 Does fail when compiled with gcc -m32 -o test2038 test2038.c */ #include #include #include int test2038(void) { time_t x; //printf("sizeof(time_t)=%d\n", (int)sizeof(time_t)); x = (time_t)((1U << 31) - 1); //printf("x=%lu\n", (unsigned long)x); char *s = ctime(&x); //printf("%s\n", s); //printf("x=%lu\n", (unsigned long)x); if (!strstr(s, "2038")) { return 1; } x += 1; s = ctime(&x); //printf("x=%lu\n", (unsigned long)x); //printf("%s\n", s); if (!strstr(s, "2038")) { return 1; } //printf("x=%lu\n", (unsigned long)x); //printf("%s\n", s); x += 1; s = ctime(&x); if (!strstr(s, "2038")) { return 1; } //printf("%s\n", s); return 0; } int main(void) { return test2038(); } hamlib-4.6.5/tests/rig_tests.h0000664000175000017500000000006515056640443011773 #include int rig_test_cw(RIG *rig); hamlib-4.6.5/tests/rig_tests.c0000664000175000017500000000135015056640443011764 #include #include #include // cppcheck-suppress unusedFunction int rig_test_cw(RIG *rig) { char *s = "SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS SOS"; //char *s = "TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST"; int i; ELAPSED1; ENTERFUNC; for (i = 0; i < strlen(s); ++i) { char cw[2]; cw[0] = s[i]; cw[1] = '\0'; int retval = rig_send_morse(rig, RIG_VFO_CURR, cw); hl_usleep(100 * 1000); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_send_morse error: %s\n", __func__, rigerror(retval)); } } ELAPSED2; RETURNFUNC(RIG_OK); } hamlib-4.6.5/tests/rigtestmcast.c0000664000175000017500000000170615056640443012477 #include #include #define TEST #ifdef TEST int main(int argc, const char *argv[]) { RIG *rig; rig_model_t myrig_model; rig_set_debug_level(RIG_DEBUG_WARN); if (argc > 1) { myrig_model = atoi(argv[1]); } else { myrig_model = 1035; } rig = rig_init(myrig_model); if (rig == NULL) { printf("Error in rig_init\n"); return 1; } #ifdef _WIN32 strncpy(RIGPORT(rig)->pathname, "COM37", HAMLIB_FILPATHLEN - 1); #else strncpy(RIGPORT(rig)->pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1); #endif RIGPORT(rig)->parm.serial.rate = 38400; rig_open(rig); // disabled until we change this to the other multicast capability #if 0 multicast_init(rig, "224.0.0.1", 4532); printf("threadid=%lld\n", (long long)STATE(rig)->multicast->threadid); pthread_join(STATE(rig)->multicast->threadid, NULL); pthread_exit(NULL); #endif return 0; } #endif hamlib-4.6.5/tests/rigctl_parse.c0000664000175000017500000045646215056640443012461 /* * rigctl_parse.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2003,2006,2008,2010,2011,2012,2013 * (C) Terry Embry 2008-2009 * (C) The Hamlib Group 2002,2006,2007,2008,2009,2010,2011 * * This program tests/controls a radio using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include #include #include // If true adds some debug statements to see flow of rigctl parsing int debugflow = 0; #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ /* no history */ #endif /* HAVE_READLINE_HISTORY */ #include #include "misc.h" #include "iofunc.h" #include "riglist.h" #include "sprintflst.h" #include "rigctl_parse.h" /* Hash table implementation See: http://uthash.sourceforge.net/ */ #include "uthash.h" #define STR1(S) #S #define STR(S) STR1(S) #define MAXNAMSIZ 32 #define MAXNBOPT 100 /* max number of different options */ #define MAXARGSZ 511 #define ARG_IN1 0x01 #define ARG_OUT1 0x02 #define ARG_IN2 0x04 #define ARG_OUT2 0x08 #define ARG_IN3 0x10 #define ARG_OUT3 0x20 #define ARG_IN4 0x40 #define ARG_OUT4 0x80 #define ARG_OUT5 0x100 #define ARG_IN_LINE 0x4000 #define ARG_NOVFO 0x8000 #define ARG_IN (ARG_IN1|ARG_IN2|ARG_IN3|ARG_IN4) #define ARG_OUT (ARG_OUT1|ARG_OUT2|ARG_OUT3|ARG_OUT4|ARG_OUT5) static int chk_vfo_executed; char rigctld_password[65]; int is_passwordOK; int is_rigctld; extern int lock_mode; // used by rigctld extern powerstat_t rig_powerstat; /* variables for readline support */ #ifdef HAVE_LIBREADLINE static char *input_line = (char *)NULL; static char *result = (char *)NULL; static char *parsed_input[sizeof(char *) * 5]; static const int have_rl = 1; #ifdef HAVE_READLINE_HISTORY static char *rp_hist_buf = (char *)NULL; #endif #else /* no readline */ static const int have_rl = 0; #endif struct test_table { unsigned char cmd; const char *name; int (*rig_routine)(RIG *, FILE *, FILE *, int, int, int *, char, int, char, const struct test_table *, vfo_t, const char *, const char *, const char *); int flags; const char *arg1; const char *arg2; const char *arg3; const char *arg4; const char *arg5; const char *arg6; }; #define CHKSCN1ARG(a) if ((a) != 1) { rig_debug(RIG_DEBUG_ERR,"%s: chkarg err\n", __func__);RETURNFUNC2(-RIG_EINVAL);} else do {} while(0) #define ACTION(f) rigctl_##f #define declare_proto_rig(f) static int (ACTION(f))(RIG *rig, \ FILE *fout, \ FILE *fin, \ int interactive, \ int prompt, \ int *vfo_opt, \ char send_cmd_term, \ int ext_resp, \ char resp_sep, \ const struct test_table *cmd, \ vfo_t vfo, \ const char *arg1, \ const char *arg2, \ const char *arg3) declare_proto_rig(set_freq); declare_proto_rig(get_freq); declare_proto_rig(set_rit); declare_proto_rig(get_rit); declare_proto_rig(set_xit); declare_proto_rig(get_xit); declare_proto_rig(set_mode); declare_proto_rig(get_mode); declare_proto_rig(get_modes); declare_proto_rig(get_mode_bandwidths); declare_proto_rig(set_vfo); declare_proto_rig(get_vfo); declare_proto_rig(get_rig_info); declare_proto_rig(get_vfo_info); declare_proto_rig(get_vfo_list); declare_proto_rig(set_ptt); declare_proto_rig(get_ptt); declare_proto_rig(get_ptt); declare_proto_rig(get_dcd); declare_proto_rig(set_rptr_shift); declare_proto_rig(get_rptr_shift); declare_proto_rig(set_rptr_offs); declare_proto_rig(get_rptr_offs); declare_proto_rig(set_ctcss_tone); declare_proto_rig(get_ctcss_tone); declare_proto_rig(set_dcs_code); declare_proto_rig(get_dcs_code); declare_proto_rig(set_ctcss_sql); declare_proto_rig(get_ctcss_sql); declare_proto_rig(set_dcs_sql); declare_proto_rig(get_dcs_sql); declare_proto_rig(set_split_freq); declare_proto_rig(get_split_freq); declare_proto_rig(set_split_mode); declare_proto_rig(get_split_mode); declare_proto_rig(set_split_freq_mode); declare_proto_rig(get_split_freq_mode); declare_proto_rig(set_split_vfo); declare_proto_rig(get_split_vfo); declare_proto_rig(set_ts); declare_proto_rig(get_ts); declare_proto_rig(power2mW); declare_proto_rig(mW2power); declare_proto_rig(set_level); declare_proto_rig(get_level); declare_proto_rig(set_func); declare_proto_rig(get_func); declare_proto_rig(set_parm); declare_proto_rig(get_parm); declare_proto_rig(set_bank); declare_proto_rig(set_mem); declare_proto_rig(get_mem); declare_proto_rig(vfo_op); declare_proto_rig(scan); declare_proto_rig(set_channel); declare_proto_rig(get_channel); declare_proto_rig(set_trn); declare_proto_rig(get_trn); declare_proto_rig(get_info); declare_proto_rig(dump_caps); declare_proto_rig(dump_conf); declare_proto_rig(dump_state); declare_proto_rig(set_ant); declare_proto_rig(get_ant); declare_proto_rig(reset); declare_proto_rig(send_morse); declare_proto_rig(stop_morse); declare_proto_rig(wait_morse); declare_proto_rig(send_voice_mem); declare_proto_rig(stop_voice_mem); declare_proto_rig(send_cmd); declare_proto_rig(set_powerstat); declare_proto_rig(get_powerstat); declare_proto_rig(send_dtmf); declare_proto_rig(recv_dtmf); declare_proto_rig(chk_vfo); declare_proto_rig(set_vfo_opt); declare_proto_rig(set_twiddle); declare_proto_rig(get_twiddle); declare_proto_rig(set_uplink); declare_proto_rig(set_cache); declare_proto_rig(get_cache); declare_proto_rig(halt); declare_proto_rig(pause); declare_proto_rig(password); //declare_proto_rig(set_password); declare_proto_rig(set_clock); declare_proto_rig(get_clock); declare_proto_rig(set_separator); declare_proto_rig(get_separator); declare_proto_rig(set_lock_mode); declare_proto_rig(get_lock_mode); declare_proto_rig(send_raw); declare_proto_rig(client_version); declare_proto_rig(hamlib_version); declare_proto_rig(test); declare_proto_rig(cm108_get_bit); declare_proto_rig(cm108_set_bit); declare_proto_rig(set_conf); declare_proto_rig(get_conf); /* * convention: upper case cmd is set, lowercase is get * * TODO: add missing rig_set_/rig_get_: sql, dcd, etc. * NB: 'q' 'Q' '?' are reserved by interactive mode interface * do NOT use -W since it's reserved by POSIX. * * Available alphabetic letters: -.--------------*-----W-Y- */ static struct test_table test_list[] = { #if 0 // implement set_freq VFO later if it can be detected { 'F', "set_freq", ACTION(set_freq), ARG_IN1 | ARG_OUT1, "Frequency" }, { 'f', "get_freq", ACTION(get_freq), ARG_OUT, "Frequency", "VFO" }, #else { 'F', "set_freq", ACTION(set_freq), ARG_IN1, "Frequency" }, #endif { 'f', "get_freq", ACTION(get_freq), ARG_OUT, "Frequency" }, { 'M', "set_mode", ACTION(set_mode), ARG_IN, "Mode", "Passband" }, { 'm', "get_mode", ACTION(get_mode), ARG_OUT, "Mode", "Passband" }, { 'I', "set_split_freq", ACTION(set_split_freq), ARG_IN, "TX Frequency" }, { 'i', "get_split_freq", ACTION(get_split_freq), ARG_OUT, "TX Frequency" }, { 'X', "set_split_mode", ACTION(set_split_mode), ARG_IN, "TX Mode", "TX Passband" }, { 'x', "get_split_mode", ACTION(get_split_mode), ARG_OUT, "TX Mode", "TX Passband" }, { 'K', "set_split_freq_mode", ACTION(set_split_freq_mode), ARG_IN, "TX Frequency", "TX Mode", "TX Passband" }, { 'k', "get_split_freq_mode", ACTION(get_split_freq_mode), ARG_OUT, "TX Frequency", "TX Mode", "TX Passband" }, { 'S', "set_split_vfo", ACTION(set_split_vfo), ARG_IN, "Split", "TX VFO" }, { 's', "get_split_vfo", ACTION(get_split_vfo), ARG_OUT, "Split", "TX VFO" }, { 'N', "set_ts", ACTION(set_ts), ARG_IN, "Tuning Step" }, { 'n', "get_ts", ACTION(get_ts), ARG_OUT, "Tuning Step" }, { 'L', "set_level", ACTION(set_level), ARG_IN, "Level", "Level Value" }, { 'l', "get_level", ACTION(get_level), ARG_IN1 | ARG_OUT2, "Level", "Level Value" }, { 'U', "set_func", ACTION(set_func), ARG_IN, "Func", "Func Status" }, { 'u', "get_func", ACTION(get_func), ARG_IN1 | ARG_OUT2, "Func", "Func Status" }, { 'P', "set_parm", ACTION(set_parm), ARG_IN | ARG_NOVFO, "Parm", "Parm Value" }, { 'p', "get_parm", ACTION(get_parm), ARG_IN1 | ARG_OUT2 | ARG_NOVFO, "Parm", "Parm Value" }, { 'G', "vfo_op", ACTION(vfo_op), ARG_IN, "Mem/VFO Op" }, { 'g', "scan", ACTION(scan), ARG_IN, "Scan Fct", "Scan Channel" }, { 'A', "set_trn", ACTION(set_trn), ARG_IN | ARG_NOVFO, "Transceive" }, { 'a', "get_trn", ACTION(get_trn), ARG_OUT | ARG_NOVFO, "Transceive" }, { 'R', "set_rptr_shift", ACTION(set_rptr_shift), ARG_IN, "Rptr Shift" }, { 'r', "get_rptr_shift", ACTION(get_rptr_shift), ARG_OUT, "Rptr Shift" }, { 'O', "set_rptr_offs", ACTION(set_rptr_offs), ARG_IN, "Rptr Offset" }, { 'o', "get_rptr_offs", ACTION(get_rptr_offs), ARG_OUT, "Rptr Offset" }, { 'C', "set_ctcss_tone", ACTION(set_ctcss_tone), ARG_IN, "CTCSS Tone" }, { 'c', "get_ctcss_tone", ACTION(get_ctcss_tone), ARG_OUT, "CTCSS Tone" }, { 'D', "set_dcs_code", ACTION(set_dcs_code), ARG_IN, "DCS Code" }, { 'd', "get_dcs_code", ACTION(get_dcs_code), ARG_OUT, "DCS Code" }, { 0x90, "set_ctcss_sql", ACTION(set_ctcss_sql), ARG_IN, "CTCSS Sql" }, { 0x91, "get_ctcss_sql", ACTION(get_ctcss_sql), ARG_OUT, "CTCSS Sql" }, { 0x92, "set_dcs_sql", ACTION(set_dcs_sql), ARG_IN, "DCS Sql" }, { 0x93, "get_dcs_sql", ACTION(get_dcs_sql), ARG_OUT, "DCS Sql" }, // //{ 'V', "set_vfo", ACTION(set_vfo), ARG_IN | ARG_NOVFO | ARG_OUT, "VFO" }, { 'V', "set_vfo", ACTION(set_vfo), ARG_IN | ARG_NOVFO, "VFO" }, { 'v', "get_vfo", ACTION(get_vfo), ARG_NOVFO | ARG_OUT, "VFO" }, { 'T', "set_ptt", ACTION(set_ptt), ARG_IN, "PTT" }, { 't', "get_ptt", ACTION(get_ptt), ARG_OUT, "PTT" }, { 'E', "set_mem", ACTION(set_mem), ARG_IN, "Memory#" }, { 'e', "get_mem", ACTION(get_mem), ARG_OUT, "Memory#" }, { 'H', "set_channel", ACTION(set_channel), ARG_IN | ARG_NOVFO, "Channel"}, { 'h', "get_channel", ACTION(get_channel), ARG_IN | ARG_NOVFO, "Channel", "Read Only" }, { 'B', "set_bank", ACTION(set_bank), ARG_IN, "Bank" }, { '_', "get_info", ACTION(get_info), ARG_OUT | ARG_NOVFO, "Info" }, { 'J', "set_rit", ACTION(set_rit), ARG_IN, "RIT" }, { 'j', "get_rit", ACTION(get_rit), ARG_OUT, "RIT" }, { 'Z', "set_xit", ACTION(set_xit), ARG_IN, "XIT" }, { 'z', "get_xit", ACTION(get_xit), ARG_OUT, "XIT" }, { 'Y', "set_ant", ACTION(set_ant), ARG_IN, "Antenna", "Option" }, { 'y', "get_ant", ACTION(get_ant), ARG_IN1 | ARG_OUT2, "AntCurr", "Option", "AntTx", "AntRx" }, { 0x87, "set_powerstat", ACTION(set_powerstat), ARG_IN | ARG_NOVFO, "Power Status" }, { 0x88, "get_powerstat", ACTION(get_powerstat), ARG_OUT | ARG_NOVFO, "Power Status" }, { 0x89, "send_dtmf", ACTION(send_dtmf), ARG_IN | ARG_NOVFO, "Digits" }, { 0x8a, "recv_dtmf", ACTION(recv_dtmf), ARG_OUT | ARG_NOVFO, "Digits" }, { '*', "reset", ACTION(reset), ARG_IN | ARG_NOVFO, "Reset" }, { 'w', "send_cmd", ACTION(send_cmd), ARG_IN1 | ARG_IN_LINE | ARG_OUT2 | ARG_NOVFO, "Cmd", "Reply" }, { 'W', "send_cmd_rx", ACTION(send_cmd), ARG_IN | ARG_OUT2 | ARG_NOVFO, "Cmd", "Reply"}, { 'b', "send_morse", ACTION(send_morse), ARG_IN | ARG_NOVFO | ARG_IN_LINE, "Morse" }, { 0xbb, "stop_morse", ACTION(stop_morse), ARG_NOVFO}, { 0xbc, "wait_morse", ACTION(wait_morse), ARG_NOVFO}, { 0x94, "send_voice_mem", ACTION(send_voice_mem), ARG_NOVFO | ARG_IN, "Voice Mem#" }, { 0xab, "stop_voice_mem", ACTION(stop_voice_mem), ARG_NOVFO}, { 0x8b, "get_dcd", ACTION(get_dcd), ARG_OUT | ARG_NOVFO, "DCD" }, { 0x8d, "set_twiddle", ACTION(set_twiddle), ARG_IN | ARG_NOVFO, "Timeout (secs)" }, { 0x8e, "get_twiddle", ACTION(get_twiddle), ARG_OUT | ARG_NOVFO, "Timeout (secs)" }, { 0x97, "uplink", ACTION(set_uplink), ARG_IN | ARG_NOVFO, "1=Sub, 2=Main" }, { 0x95, "set_cache", ACTION(set_cache), ARG_IN | ARG_NOVFO, "Timeout (msecs)" }, { 0x96, "get_cache", ACTION(get_cache), ARG_OUT | ARG_NOVFO, "Timeout (msecs)" }, { '2', "power2mW", ACTION(power2mW), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_OUT1 | ARG_NOVFO, "Power [0.0..1.0]", "Frequency", "Mode", "Power mW" }, { '4', "mW2power", ACTION(mW2power), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_OUT1 | ARG_NOVFO, "Pwr mW", "Freq", "Mode", "Power [0.0..1.0]" }, { '1', "dump_caps", ACTION(dump_caps), ARG_NOVFO }, { '3', "dump_conf", ACTION(dump_conf), ARG_NOVFO }, { 0x8f, "dump_state", ACTION(dump_state), ARG_OUT | ARG_NOVFO }, { 0xf0, "chk_vfo", ACTION(chk_vfo), ARG_NOVFO, "ChkVFO" }, /* rigctld only--check for VFO mode */ { 0xf2, "set_vfo_opt", ACTION(set_vfo_opt), ARG_NOVFO | ARG_IN, "Status" }, /* turn vfo option on/off */ { 0xf3, "get_vfo_info", ACTION(get_vfo_info), ARG_IN1 | ARG_NOVFO | ARG_OUT5, "VFO", "Freq", "Mode", "Width", "Split", "SatMode" }, /* get several vfo parameters at once */ { 0xf5, "get_rig_info", ACTION(get_rig_info), ARG_NOVFO | ARG_OUT, "RigInfo" }, /* get several vfo parameters at once */ { 0xf4, "get_vfo_list", ACTION(get_vfo_list), ARG_OUT | ARG_NOVFO, "VFOs" }, { 0xf6, "get_modes", ACTION(get_modes), ARG_OUT | ARG_NOVFO, "Modes" }, // { 0xf9, "get_clock", ACTION(get_clock), ARG_IN | ARG_NOVFO, "local/utc" }, { 0xf9, "get_clock", ACTION(get_clock), ARG_NOVFO }, { 0xf8, "set_clock", ACTION(set_clock), ARG_IN | ARG_NOVFO, "local or utc or YYYY-MM-DDTHH:MM:SS.sss+ZZ or YYYY-MM-DDTHH:MM+ZZ" }, { 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */ { 0x8c, "pause", ACTION(pause), ARG_IN | ARG_NOVFO, "Seconds" }, { 0x98, "password", ACTION(password), ARG_IN | ARG_NOVFO, "Password" }, // { 0x99, "set_password", ACTION(set_password), ARG_IN | ARG_NOVFO, "Password" }, { 0xf7, "get_mode_bandwidths", ACTION(get_mode_bandwidths), ARG_IN | ARG_NOVFO, "Mode" }, { 0xa0, "set_separator", ACTION(set_separator), ARG_IN | ARG_NOVFO, "Separator" }, { 0xa1, "get_separator", ACTION(get_separator), ARG_NOVFO, "Separator" }, { 0xa2, "set_lock_mode", ACTION(set_lock_mode), ARG_IN | ARG_NOVFO, "Locked" }, { 0xa3, "get_lock_mode", ACTION(get_lock_mode), ARG_NOVFO, "Locked" }, { 0xa4, "send_raw", ACTION(send_raw), ARG_NOVFO | ARG_IN1 | ARG_IN2 | ARG_OUT3, "Terminator", "Command", "Send raw answer" }, { 0xa5, "client_version", ACTION(client_version), ARG_NOVFO | ARG_IN1, "Version", "Client version" }, { 0xa6, "get_vfo_list", ACTION(get_vfo_list), ARG_NOVFO }, { 0xa7, "test", ACTION(test), ARG_NOVFO | ARG_IN, "routine" }, { 0xa8, "hamlib_version", ACTION(hamlib_version), ARG_NOVFO }, { 0xa9, "get_gpio", ACTION(cm108_get_bit), ARG_NOVFO | ARG_IN1 | ARG_OUT1, "GPIO#", "0/1" }, { 0xaa, "set_gpio", ACTION(cm108_set_bit), ARG_NOVFO | ARG_IN, "GPIO#", "0/1" }, { 0xac, "set_conf", ACTION(set_conf), ARG_NOVFO | ARG_IN, "Token", "Token Value" }, { 0xad, "get_conf", ACTION(get_conf), ARG_NOVFO | ARG_IN1 | ARG_OUT2, "Token", "Value"}, { 0x00, "", NULL }, }; static struct test_table *find_cmd_entry(int cmd) { int i; for (i = 0; test_list[i].cmd != 0x00; i++) { if (test_list[i].cmd == cmd) { break; } } if (test_list[i].cmd == 0x00) { return NULL; } return &test_list[i]; } /* Structure for hash table provided by uthash.h * * Structure and hash functions patterned after/copied from example.c * distributed with the uthash package. See: http://uthash.sourceforge.net/ */ struct mod_lst { int id; /* caps->rig_model This is the hash key */ char mfg_name[32]; /* caps->mfg_name */ char model_name[32]; /* caps->model_name */ char version[32]; /* caps->version */ char status[32]; /* caps->status */ char macro_name[32]; /* caps->status */ UT_hash_handle hh; /* makes this structure hashable */ }; /* Hash declaration. Must be initialized to NULL */ struct mod_lst *models = NULL; /* Add model information to the hash */ void hash_add_model(int id, const char *mfg_name, const char *model_name, const char *version, const char *status, const char *macro_name) { struct mod_lst *s; s = (struct mod_lst *)calloc(1, sizeof(struct mod_lst)); s->id = id; SNPRINTF(s->mfg_name, sizeof(s->mfg_name), "%s", mfg_name); SNPRINTF(s->model_name, sizeof(s->model_name), "%s", model_name); SNPRINTF(s->version, sizeof(s->version), "%s", version); SNPRINTF(s->status, sizeof(s->status), "%s", status); SNPRINTF(s->macro_name, sizeof(s->macro_name), "%s", macro_name); HASH_ADD_INT(models, id, s); /* id: name of key field */ } /* Hash sorting functions */ int hash_model_id_sort(struct mod_lst *a, struct mod_lst *b) { return (a->id > b->id); } void hash_sort_by_model_id() { if (models != NULL) { HASH_SORT(models, hash_model_id_sort); } else { rig_debug(RIG_DEBUG_ERR, "%s: models empty?\n", __func__); } } /* Delete hash */ void hash_delete_all() { struct mod_lst *current_model, *tmp; HASH_ITER(hh, models, current_model, tmp) { HASH_DEL(models, current_model); /* delete it (models advances to next) */ free(current_model); /* free it */ } } // modifies s to remove quotes static void strip_quotes(char *s) { char *s2; char *p; if (s[0] != '\"') { return; } // no quotes s2 = strdup(&s[1]); p = strrchr(s2, '"'); if (p) { *p = 0; } strcpy(s, s2); free(s2); } #ifdef HAVE_LIBREADLINE /* Frees allocated memory and sets pointers to NULL before calling readline * and then parses the input into space separated tokens. */ static void rp_getline(const char *s) { int i; /* free allocated memory and set pointers to NULL */ if (input_line) { free(input_line); input_line = (char *)NULL; } if (result) { result = (char *)NULL; } for (i = 0; i < 5; i++) { parsed_input[i] = NULL; } /* Action! Returns typed line with newline stripped. */ input_line = readline(s); } #endif /* * TODO: use Lex? */ static char parse_arg(const char *arg) { int i; for (i = 0; test_list[i].cmd != 0x00; i++) { if (!strncmp(arg, test_list[i].name, MAXNAMSIZ)) { return test_list[i].cmd; } } return 0; } /* * This scanf works even in presence of signals (timer, SIGIO, ..) */ static int scanfc(FILE *fin, const char *format, void *p) { do { int ret; *(char *)p = 0; ret = fscanf(fin, format, p); if (ret < 0) { if (errno == EINTR) { continue; } if (!feof(fin)) { rig_debug(RIG_DEBUG_TRACE, "%s fscanf of:", __func__); dump_hex((unsigned char *)p, strlen(p)); rig_debug(RIG_DEBUG_TRACE, " failed with format '%s'\n", format); ret = 0x0a; } } if (ret < 1) { rig_debug(RIG_DEBUG_TRACE, "%s: ret=%d\n", __func__, ret); } if (errno == 22) { return -22; } if (ferror(fin)) { rig_debug(RIG_DEBUG_ERR, "%s: errno=%d, %s\n", __func__, errno, strerror(errno)); } return ret; } while (1); } /* * function to get the next word from the command line or from stdin * until stdin exhausted. stdin is read if the special token '-' is * found on the command line. * * returns EOF when words exhausted * returns <0 is error number * returns >=0 when successful */ static int next_word(char *buffer, int argc, char *argv[], int newline) { int ret; char c; static int reading_stdin; if (!reading_stdin) { if (optind >= argc) { return EOF; } else if (newline && '-' == argv[optind][0] && 1 == strlen(argv[optind])) { ++optind; reading_stdin = 1; } } if (reading_stdin) { do { do { ret = scanf(" %c%" STR(MAXARGSZ) "[^ \t\n#]", &c, &buffer[1]); } while (EINTR == ret); if (ret > 0 && '#' == c) { do { ret = scanf("%*[^\n]"); } while (EINTR == ret); /* consume comments */ ret = 0; } } while (!ret); if (EOF == ret) { reading_stdin = 0; } else if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "scanf: %s\n", strerror(errno)); reading_stdin = 0; } else { buffer[0] = c; buffer[1 == ret ? 1 : MAXARGSZ] = '\0'; if (newline) { putchar('\n'); } fputs(buffer, stdout); putchar(' '); } } if (!reading_stdin) { if (optind < argc) { strncpy(buffer, argv[optind++], MAXARGSZ); buffer[MAXARGSZ] = '\0'; ret = 1; } else { ret = EOF; } } return ret; } #define fprintf_flush(f, a...) \ ({ fprintf((f), a); \ fflush((f)); \ \ }) int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc, sync_cb_t sync_cb, int interactive, int prompt, int *vfo_opt, char send_cmd_term, int *ext_resp_ptr, char *resp_sep_ptr, int use_password) { int retcode = -RIG_EINTERNAL; /* generic return code from functions */ unsigned char cmd; struct test_table *cmd_entry = NULL; struct rig_state *rs = STATE(my_rig); char command[MAXARGSZ + 1]; char arg1[MAXARGSZ + 1], *p1 = NULL; char arg2[MAXARGSZ + 1], *p2 = NULL; char arg3[MAXARGSZ + 1], *p3 = NULL; vfo_t vfo = RIG_VFO_CURR; char client_version[32]; rig_debug(RIG_DEBUG_TRACE, "%s: called, interactive=%d\n", __func__, interactive); /* cmd, internal, rigctld */ if (!(interactive && prompt && have_rl)) { if (interactive) { static int last_was_ret = 1; static int last_cmd; if (prompt) { fprintf_flush(fout, "\nRig command: "); } do { if ((retcode = scanfc(fin, "%c", &cmd)) < 1) { if (last_cmd == 0) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#1? retcode=%d, last_cmd=[empty]\n", __func__, retcode); } else { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#1? retcode=%d, last_cmd=%c\n", __func__, retcode, last_cmd); } return (RIGCTL_PARSE_ERROR); } if (cmd != 0xa && cmd != 0xd) { rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%c(%02x) handle=%d\n", __func__, isprint(cmd) ? cmd : ' ', cmd, fileno(fin)); } /* Extended response protocol requested with leading '+' on command * string--rigctld only! */ if (cmd == '+' && !prompt) { *ext_resp_ptr = 1; if (scanfc(fin, "%c", &cmd) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#2?\n", __func__); return (RIGCTL_PARSE_ERROR); } } else if (cmd == '+' && prompt) { return (RIG_OK); } if (cmd != '\\' && cmd != '_' && cmd != '#' && cmd != '(' && cmd != ')' && ispunct(cmd) && !prompt) { *ext_resp_ptr = 1; *resp_sep_ptr = cmd; if (scanfc(fin, "%c", &cmd) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#3?\n", __func__); return (RIGCTL_PARSE_ERROR); } } else if (cmd != '\\' && cmd != '?' && cmd != '_' && cmd != '#' && cmd != '(' && cmd != ')' && ispunct(cmd) && prompt) { return (RIG_OK); } /* command by name */ if (cmd == '\\') { char cmd_name[MAXNAMSIZ], *pcmd = cmd_name; if (scanfc(fin, "%c", pcmd) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#4?\n", __func__); return (RIGCTL_PARSE_ERROR); } retcode = fscanf(fin, "%s", ++pcmd); if (retcode == 0 || retcode == EOF) { rig_debug(RIG_DEBUG_WARN, "%s: unable to scan %c\n", __func__, *(pcmd - 1)); } while (*++pcmd); *pcmd = '\0'; cmd = parse_arg((char *)cmd_name); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s handle=%d\n", __func__, cmd_name, fileno(fin)); break; } //rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd==0x%02x\n", __func__, cmd); if (cmd == 0x0a || cmd == 0x0d) { if (last_was_ret) { if (prompt) { fprintf(fout, "? for help, q to quit.\n"); fprintf_flush(fout, "\nRig command: "); } return (RIG_OK); } last_was_ret = 1; } } while (cmd == 0x0a || cmd == 0x0d); last_was_ret = 0; /* comment line */ if (cmd == '#') { while (cmd != '\n' && cmd != '\r') { if (scanfc(fin, "%c", &cmd) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#6?\n", __func__); return (RIGCTL_PARSE_ERROR); } } return (RIG_OK); } rs->vfo_opt = *vfo_opt; if (cmd == 'Q' || cmd == 'q') { rig_debug(RIG_DEBUG_TRACE, "%s: quit returning NETRIGCTL_RET 0\n", __func__); if (interactive && !prompt) { fprintf(fout, "%s0\n", NETRIGCTL_RET); } fflush(fout); return (RIGCTL_PARSE_END); } if (cmd == '?') { usage_rig(fout); fflush(fout); return (RIG_OK); } } else { /* parse rest of command line */ retcode = next_word(command, argc, argv, 1); if (EOF == retcode) { return (RIGCTL_PARSE_END); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } else if ('\0' == command[1]) { cmd = command[0]; } else { cmd = parse_arg(command); } } if (strcmp(command,"skip-init")==0) { // no-op now since it's automatic in non-interactive mode return(RIG_OK); } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { if (cmd == 0) { fprintf(stderr, "Command '%s' not found!\n", command); } else if (cmd != ' ') { fprintf(stderr, "Command '%c' not found!\n", cmd); } return (RIG_OK); } if (!(cmd_entry->flags & ARG_NOVFO) && *vfo_opt) { if (interactive) { arg1[0] = fgetc(fin); arg1[1] = 0; if (prompt && arg1[0] == 0x0a) { fprintf_flush(fout, "VFO: "); } if (scanfc(fin, "%s", arg1) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#7?\n", __func__); return (RIGCTL_PARSE_ERROR); } vfo = rig_parse_vfo(arg1); } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } vfo = rig_parse_vfo(arg1); } } if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug1\n", __func__); } if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug2\n", __func__); } if (interactive) { char *nl; if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug2a\n", __func__); } if (fgets(arg1, MAXARGSZ, fin) == NULL) { return (RIGCTL_PARSE_ERROR); } if (arg1[0] == 0xa) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug2b\n", __func__); } if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (fgets(arg1, MAXARGSZ, fin) == NULL) { return (RIGCTL_PARSE_ERROR); } } nl = strchr(arg1, 0xa); if (nl) { *nl = '\0'; /* chomp */ } /* skip a space arg if first arg...happens parsing rigctld commands */ { p1 = arg1[0] == ' ' ? arg1 + 1 : arg1; } } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return (RIGCTL_PARSE_END); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } p1 = arg1; } } else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug3\n", __func__); } if (interactive) { arg1[0] = fgetc(fin); arg1[1] = 0; if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug4 arg1=%c\n", __func__, arg1[0]); } if (prompt && arg1[0] == 0x0a) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (scanfc(fin, "%s", arg1) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#8?\n", __func__); return (RIGCTL_PARSE_ERROR); } p1 = arg1; } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return (1); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } p1 = arg1; } } if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug5\n", __func__); } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug6\n", __func__); } if (interactive) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug7\n", __func__); } arg2[0] = fgetc(fin); arg2[1] = 0; if (prompt && arg2[0] == 0x0a) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug8\n", __func__); } fprintf_flush(fout, "%s: ", cmd_entry->arg2); } if (scanfc(fin, "%s", arg2) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#9?\n", __func__); return (RIGCTL_PARSE_ERROR); } p2 = arg2; } else { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug9\n", __func__); } retcode = next_word(arg2, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return (RIGCTL_PARSE_END); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } p2 = arg2; } } if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug10\n", __func__); } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug11\n", __func__); } if (interactive) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug12\n", __func__); } if (prompt) { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug13\n", __func__); } fprintf_flush(fout, "%s: ", cmd_entry->arg3); } if (scanfc(fin, "%s", arg3) < 1) { rig_debug(RIG_DEBUG_WARN, "%s: nothing to scan#10?\n", __func__); return (RIGCTL_PARSE_ERROR); } p3 = arg3; } else { if (debugflow) { rig_debug(RIG_DEBUG_TRACE, "%s: debug14\n", __func__); } retcode = next_word(arg3, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return (RIGCTL_PARSE_END); } else if (retcode < 0) { return (RIGCTL_PARSE_ERROR); } p3 = arg3; } } } #ifdef HAVE_LIBREADLINE if (interactive && prompt && have_rl) { int j, x; #ifdef HAVE_READLINE_HISTORY /* Minimum space for 32+1+32+1+128+1+128+1+128+1 = 453 chars, so * allocate 512 chars cleared to zero for safety. */ rp_hist_buf = (char *)calloc(512, sizeof(char)); #endif rp_getline("\nRig command: "); /* EOF (Ctl-D) received on empty input line, bail out gracefully. */ if (!input_line) { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } /* Q or q to quit */ if (!(strncasecmp(input_line, "q", 1))) { free(rp_hist_buf); return (RIGCTL_PARSE_END); } /* '?' for help */ if (!(strncmp(input_line, "?", 1))) { usage_rig(fout); fflush(fout); free(rp_hist_buf); return (RIG_OK); } /* '#' for comment */ if (!(strncmp(input_line, "#", 1))) { free(rp_hist_buf); return (RIG_OK); } /* Blank line entered */ if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } rig_debug(RIG_DEBUG_TRACE, "%s: input_line: %s\n", __func__, input_line); /* Split input_line on any number of spaces to get the command token * Tabs are intercepted by readline for completion and a newline * causes readline to return the typed text. If more than one * argument is given, it will be parsed out later. */ result = strtok(input_line, " "); readline_repeat: /* parsed_input stores pointers into input_line where the token strings * start. */ if (result) { parsed_input[0] = result; } else { /* Oops! Invoke GDB!! */ fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } /* At this point parsed_input contains the typed text of the command * with surrounding space characters removed. If Readline History is * available, copy the command string into a history buffer. */ /* Single character command */ if ((strlen(parsed_input[0]) == 1) && (*parsed_input[0] != '\\')) { cmd = *parsed_input[0]; #ifdef HAVE_READLINE_HISTORY /* Store what is typed, not validated, for history. */ if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], 1); } #endif } /* Test the command token, parsed_input[0] */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) > 1)) { char cmd_name[MAXNAMSIZ]; /* if there is no terminating '\0' character in the source string, * srncpy() doesn't add one even if the supplied length is less * than the destination array. Truncate the source string here. */ if (strlen(parsed_input[0] + 1) >= MAXNAMSIZ) { *(parsed_input[0] + MAXNAMSIZ) = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], MAXNAMSIZ); } #endif /* The starting position of the source string is the first * character past the initial '\'. */ SNPRINTF(cmd_name, sizeof(cmd_name), "%s", parsed_input[0] + 1); /* Sanity check as valid multiple character commands consist of * alphanumeric characters and the underscore ('_') character. */ for (j = 0; cmd_name[j] != '\0'; j++) { if (!(isalnum((int)cmd_name[j]) || cmd_name[j] == '_')) { fprintf(stderr, "Valid multiple character command names contain alphanumeric characters plus '_'\n"); free(rp_hist_buf); return (RIG_OK); } } cmd = parse_arg(cmd_name); } /* Single '\' entered, prompt again */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) == 1)) { free(rp_hist_buf); return (RIG_OK); } /* Multiple characters but no leading '\' */ else { fprintf(stderr, "Precede multiple character command names with '\\'\n"); free(rp_hist_buf); return (RIG_OK); } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { if (cmd == '\0') { fprintf(stderr, "Command '%s' not found!\n", parsed_input[0]); } else { fprintf(stderr, "Command '%c' not found!\n", cmd); } free(rp_hist_buf); return (RIG_OK); } /* If vfo_opt is enabled (-o|--vfo) check if already given * or prompt for it. */ if (!(cmd_entry->flags & ARG_NOVFO) && *vfo_opt) { /* Check if VFO was given with command. */ result = strtok(NULL, " "); if (result) { x = 1; parsed_input[x] = result; } /* Need to prompt if a VFO string was not given. */ else { x = 0; rp_getline("VFO: "); if (!input_line) { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } /* Blank line entered */ if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } /* Get the first token of input, the rest, if any, will be * used later. */ result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } } /* VFO name tokens are presently quite short. Truncate excessively * long strings. */ if (strlen(parsed_input[x]) >= MAXNAMSIZ) { *(parsed_input[x] + (MAXNAMSIZ - 1)) = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXNAMSIZ); } #endif /* Sanity check, VFO names are alpha only. */ for (j = 0; j < MAXNAMSIZ && parsed_input[x][j] != '\0'; j++) { if (!(isalpha((int)parsed_input[x][j]))) { parsed_input[x][j] = '\0'; break; } } vfo = rig_parse_vfo(parsed_input[x]); if (vfo == RIG_VFO_NONE) { fprintf(stderr, "Warning: VFO '%s' unrecognized, using 'currVFO' instead.\n", parsed_input[x]); vfo = RIG_VFO_CURR; } } /* \send_cmd, \send_morse */ if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { /* Check for a non-existent delimiter so as to not break up * remaining line into separate tokens (spaces OK). */ result = strtok(NULL, "\0"); if (*vfo_opt && result) { x = 2; parsed_input[x] = result; } else if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); /* Blank line entered */ if (input_line && !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } if (input_line) { parsed_input[x] = input_line; } else { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } } /* The arg1 array size is MAXARGSZ + 1 so truncate it to fit if larger. */ if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } /* Normal argument parsing. */ else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { result = strtok(NULL, " "); if (*vfo_opt && result) { x = 2; parsed_input[x] = result; } else if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { result = strtok(NULL, " "); if (*vfo_opt && result) { x = 3; parsed_input[x] = result; } else if (result) { x = 2; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg2) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg2); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg2, parsed_input[x]); p2 = arg2; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { result = strtok(NULL, " "); if (*vfo_opt && result) { x = 4; parsed_input[x] = result; } else if (result) { x = 3; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg3) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg3); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); free(rp_hist_buf); return (RIG_OK); } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); free(rp_hist_buf); return (RIGCTL_PARSE_END); } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg3, parsed_input[x]); p3 = arg3; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { add_history(rp_hist_buf); free(rp_hist_buf); rp_hist_buf = (char *)NULL; } #endif } #endif // HAVE_LIBREADLINE if (sync_cb) { sync_cb(1); } /* lock if necessary */ if (!prompt) { rig_debug(RIG_DEBUG_TRACE, "rigctl(d): %c '%s' '%s' '%s' '%s'\n", cmd, rig_strvfo(vfo), p1 ? p1 : "", p2 ? p2 : "", p3 ? p3 : ""); } /* * Extended Response protocol: output received command name and arguments * response. Don't send command header on '\chk_vfo' command. */ if (p1) { strip_quotes(p1); } if (interactive && *ext_resp_ptr && !prompt && cmd != 0xf0) { char a1[MAXARGSZ + 2]; char a2[MAXARGSZ + 2]; char a3[MAXARGSZ + 2]; char vfo_str[MAXARGSZ + 2]; *vfo_opt == 0 ? vfo_str[0] = '\0' : snprintf(vfo_str, sizeof(vfo_str), " %s", rig_strvfo(vfo)); // exception for get_vfo_info cmd which fails with log4om otherwise if (*vfo_opt && cmd != 0xf3) { p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), ":%s", p1); } else { p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1); } p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2); p3 == NULL ? a3[0] = '\0' : snprintf(a3, sizeof(a3), " %s", p3); if (cmd == 'b') { strtok(a1, "\r\n"); } fprintf(fout, "%s:%s%s%s%s%c", cmd_entry->name, vfo_str, a1, a2, a3, *resp_sep_ptr); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt=%d\n", __func__, *vfo_opt); if (rs->comm_state == 0) { rig_debug(RIG_DEBUG_WARN, "%s: %p rig not open...trying to reopen\n", __func__, &rs->comm_state); rig_open(my_rig); } // chk_vfo is the one command we'll allow without a password // since it's in the initial handshake int preCmd = 0; // some command are allowed without password to satisfy rigctld initialization from rigctl -m 2 if (cmd_entry->arg1 != NULL) { if (strcmp(cmd_entry->arg1, "ChkVFO") == 0) { preCmd = 1; } else if (strcmp(cmd_entry->arg1, "VFO") == 0) { preCmd = 1; } else if (strcmp(cmd_entry->arg1, "Password") == 0) { preCmd = 1; } } if (use_password && !is_passwordOK && (cmd_entry->arg1 != NULL) && !preCmd) { rig_debug(RIG_DEBUG_ERR, "%s: password has not been provided\n", __func__); fflush(fin); retcode = -RIG_ESECURITY; } else { // Allow only certain commands when the rig is powered off if (rs->powerstat == RIG_POWER_OFF && (rig_powerstat == RIG_POWER_OFF || rig_powerstat == RIG_POWER_STANDBY) && cmd_entry->cmd != '1' // dump_caps && cmd_entry->cmd != '3' // dump_conf && cmd_entry->cmd != 0x8f // dump_state && cmd_entry->cmd != 0xf0 // chk_vfo && cmd_entry->cmd != 0x87 // set_powerstat && cmd_entry->cmd != 0x88 // get_powerstat && cmd_entry->cmd != 0xa5 // client_version && cmd_entry->cmd != 0xf2 // set_vfo_opt && my_rig->caps->rig_model != RIG_MODEL_POWERSDR) // some rigs can do stuff when powered off { rig_debug(RIG_DEBUG_WARN, "%s: command %s not allowed when rig is powered off\n", __func__, cmd_entry->name); retcode = -RIG_EPOWER; } else { retcode = (*cmd_entry->rig_routine)(my_rig, fout, fin, interactive, prompt, vfo_opt, send_cmd_term, *ext_resp_ptr, *resp_sep_ptr, cmd_entry, vfo, p1, p2 ? p2 : "", p3 ? p3 : ""); } // we need to copy client_version to our thread in case there are multiple client versions // client_version is used to determine any backward compatibility requirements or problems strncpy(client_version, rs->client_version, sizeof(client_version)); } if (retcode == -RIG_EIO) { rig_debug(RIG_DEBUG_ERR, "%s: RIG_EIO?\n", __func__); if (sync_cb) { sync_cb(0); } /* unlock if necessary */ return (retcode); } if (retcode != RIG_OK) { /* only for rigctld */ if (interactive && !prompt) { rig_debug(RIG_DEBUG_TRACE, "%s: return#1 "NETRIGCTL_RET "%d\n", __func__, retcode); fprintf(fout, NETRIGCTL_RET "%d\n", retcode); *ext_resp_ptr = 0; *resp_sep_ptr = '\n'; } else { fprintf(fout, //"%s: error = %s\n", //cmd_entry->name, "error = %s\n", rigerror(retcode)); } } else { /* only for rigctld */ if (interactive && !prompt) { /* netrigctl RIG_OK */ if (!(cmd_entry->flags & ARG_OUT) && !*ext_resp_ptr && cmd != 0xf0) { rig_debug(RIG_DEBUG_TRACE, "%s: return#2 "NETRIGCTL_RET "0\n", __func__); fprintf(fout, NETRIGCTL_RET "0\n"); } /* Extended Response protocol */ else if (*ext_resp_ptr && cmd != 0xf0) { rig_debug(RIG_DEBUG_TRACE, "%s: return#3 "NETRIGCTL_RET "0\n", __func__); fprintf(fout, NETRIGCTL_RET "0\n"); *ext_resp_ptr = 0; *resp_sep_ptr = '\n'; } } } if (*resp_sep_ptr != '\n') { fprintf(fout, "\n"); } fflush(fout); #ifdef HAVE_LIBREADLINE if (input_line != NULL && (result = strtok(NULL, " "))) { goto readline_repeat; } #endif if (sync_cb) { sync_cb(0); } /* unlock if necessary */ return (retcode); } declare_proto_rig(hamlib_version) { fprintf(fout, "rigctl(d), %s\n\n", hamlib_version2); fprintf(fout, "%s\n", hamlib_copyright); return RIG_OK; } declare_proto_rig(client_version) { struct rig_state *rs = STATE(rig); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", arg1, resp_sep); strncpy(rs->client_version, arg1, sizeof(rs->client_version) - 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: client_version=%s\n", __func__, rs->client_version); return RIG_OK; } void usage_rig(FILE *fout) { int i; fprintf(fout, "Commands (some may not be available for this rig):\n"); for (i = 0; test_list[i].cmd != 0; i++) { int nbspaces = 18; fprintf(fout, "%c: %-16s(", isprint(test_list[i].cmd) ? test_list[i].cmd : '?', test_list[i].name); if (test_list[i].arg1 && (test_list[i].flags & ARG_IN1)) { nbspaces -= fprintf(fout, "%s", test_list[i].arg1); } if (test_list[i].arg2 && (test_list[i].flags & ARG_IN2)) { nbspaces -= fprintf(fout, ",%s", test_list[i].arg2); } if (test_list[i].arg3 && (test_list[i].flags & ARG_IN3)) { nbspaces -= fprintf(fout, ",%s", test_list[i].arg3); } if (i % 2) { fprintf(fout, ")\n"); } else { fprintf(fout, ")%*s", nbspaces, " "); } } fprintf(fout, "\n\nIn interactive mode prefix long command names with '\\', e.g. '\\dump_state'\n\n" "The special command '-' is used to read further commands from standard input\n" "Commands and arguments read from standard input must be white space separated,\n" "comments are allowed, comments start with the # character and continue to the\n" "end of the line.\n"); } int print_conf_list(const struct confparams *cfp, rig_ptr_t data) { RIG *rig = (RIG *) data; int i; char buf[128] = ""; rig_get_conf(rig, cfp->token, buf); printf("%s: \"%s\"\n" "\t" "Default: %s, Value: %s\n", cfp->name, cfp->tooltip, cfp->dflt, buf); switch (cfp->type) { case RIG_CONF_INT: printf("\tRange: %.0f..%.0f, step %.0f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; case RIG_CONF_NUMERIC: printf("\tRange: %g..%g, step %.1f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; case RIG_CONF_COMBO: if (!cfp->u.c.combostr[0]) { break; } printf("\tCombo: %s", cfp->u.c.combostr[0]); for (i = 1 ; i < RIG_COMBO_MAX && cfp->u.c.combostr[i]; i++) { printf(", %s", cfp->u.c.combostr[i]); } printf("\n"); break; case RIG_CONF_STRING: printf("\tString.\n"); break; case RIG_CONF_CHECKBUTTON: printf("\tCheck button.\n"); break; case RIG_CONF_BUTTON: printf("\tButton.\n"); break; default: printf("\tUnknown conf\n"); } return 1; /* !=0, we want them all ! */ } // short list for rigctl/rigctld display int print_conf_list2(const struct confparams *cfp, rig_ptr_t data) { RIG *rig = (RIG *) data; char buf[128] = ""; rig_get_conf(rig, cfp->token, buf); fprintf(stdout, "%s: \"%s\"\n" "\t" "Default: %s, Value: %s\n", cfp->name, cfp->tooltip, cfp->dflt, buf); return 1; /* !=0, we want them all ! */ } static int hash_model_list(const struct rig_caps *caps, void *data) { hash_add_model(caps->rig_model, caps->mfg_name, caps->model_name, caps->version, caps->macro_name, rig_strstatus(caps->status)); return 1; /* !=0, we want them all ! */ } void print_model_list() { struct mod_lst *s; for (s = models; s != NULL; s = (struct mod_lst *)(s->hh.next)) { printf("%6d %-23s%-24s%-16s%-12s%s\n", s->id, s->mfg_name, s->model_name, s->version, s->macro_name, s->status); if (strcmp(s->mfg_name, "Misc") == 0 || strcmp(s->mfg_name, "Other") == 0 || strcmp(s->mfg_name, "Dummy") == 0) { printf("Do not use %s as mfg_name\n", s->mfg_name); exit(0); } if (strcmp(s->model_name, "Misc") == 0 || strcmp(s->model_name, "Other") == 0) { printf("Do not use %s as model_name\n", s->model_name); exit(0); } } } void list_models() { int status; rig_load_all_backends(); printf(" Rig # Mfg Model Version Status Macro\n"); status = rig_list_foreach(hash_model_list, NULL); if (status != RIG_OK) { printf("rig_list_foreach: error = %s \n", rigerror(status)); exit(2); } hash_sort_by_model_id(); print_model_list(); hash_delete_all(); } /* * static int (f)(RIG *rig, FILE *fout, int interactive, const struct test_table *cmd, * vfo_t vfo, const void *arg1, const void *arg2, const void *arg3) */ /* 'F' */ declare_proto_rig(set_freq) { freq_t freq; int retval; #if 0 // implement set_freq VFO later if it can be detected char *fmt = "%"PRIll"%c"; #endif ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%"SCNfreq, &freq)); retval = rig_set_freq(rig, vfo, freq); if (retval == RIG_OK) { //fprintf(fout, "%s%c", rig_strvfo(vfo), resp_sep); //fprintf(fout, fmt, (int64_t)freq, resp_sep); } RETURNFUNC2(retval); } /* 'f' */ declare_proto_rig(get_freq) { int status; freq_t freq; // cppcheck-suppress * char *fmt = "%"PRIll"%c"; ENTERFUNC2; status = rig_get_freq(rig, vfo, &freq); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); /* i.e. "Frequency" */ } fprintf(fout, fmt, (int64_t)freq, resp_sep); #if 0 // this extra VFO being returned was confusing Log4OM if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); /* i.e. "Frequency" */ } fprintf(fout, "%s%c", rig_strvfo(vfo), resp_sep); #endif RETURNFUNC2(status); } /* 'J' */ declare_proto_rig(set_rit) { shortfreq_t rit; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%ld", &rit)); RETURNFUNC2(rig_set_rit(rig, vfo, rit)); } /* 'j' */ declare_proto_rig(get_rit) { int status; shortfreq_t rit; ENTERFUNC2; status = rig_get_rit(rig, vfo, &rit); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%ld%c", rit, resp_sep); RETURNFUNC2(status); } /* 'Z' */ declare_proto_rig(set_xit) { shortfreq_t xit; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%ld", &xit)); RETURNFUNC2(rig_set_xit(rig, vfo, xit)); } /* 'z' */ declare_proto_rig(get_xit) { int status; shortfreq_t xit; ENTERFUNC2; status = rig_get_xit(rig, vfo, &xit); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%ld%c", xit, resp_sep); RETURNFUNC2(status); } /* 'M' */ declare_proto_rig(set_mode) { rmode_t mode; pbwidth_t width; struct rig_state *rs = STATE(rig); ENTERFUNC2; if (rs->lock_mode || lock_mode) { RETURNFUNC2(RIG_OK); } if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_mode(s, sizeof(s), rs->mode_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } mode = rig_parse_mode(arg1); CHKSCN1ARG(sscanf(arg2, "%ld", &width)); if (rs->lock_mode) { RETURNFUNC2(RIG_OK); } RETURNFUNC2(rig_set_mode(rig, vfo, mode, width)); } /* 'm' */ declare_proto_rig(get_mode) { int status; rmode_t mode; pbwidth_t width; ENTERFUNC2; status = rig_get_mode(rig, vfo, &mode, &width); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", rig_strrmode(mode), resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%ld%c", width, resp_sep); RETURNFUNC2(status); } /* 'V' */ declare_proto_rig(set_vfo) { int retval; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_vfo(s, sizeof(s), STATE(rig)->vfo_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } vfo = rig_parse_vfo(arg1); if (vfo == RIG_VFO_NONE) { int c; while ((c = fgetc(fin)) != '\n' && c != '\r' && c > 0); return -RIG_EINVAL; } retval = rig_set_vfo(rig, vfo); #if 0 // see if we can make this dynamic if (retval == RIG_OK) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { // fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", rig_strvfo(vfo), resp_sep); } #endif if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_vfo(%s) failed, requested %s\n", __func__, rig_strvfo(vfo), arg1); } RETURNFUNC2(retval); } /* 'v' */ declare_proto_rig(get_vfo) { int status; ENTERFUNC2; status = rig_get_vfo(rig, &vfo); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", rig_strvfo(vfo), resp_sep); RETURNFUNC2(status); } declare_proto_rig(get_rig_info) { char buf[1024]; // big enough to last numerous years hopefully int ret; ENTERFUNC2; ret = rig_get_rig_info(rig, buf, sizeof(buf)); if (ret != RIG_OK) { RETURNFUNC2(ret); } fprintf(fout, "%s\n", buf); RETURNFUNC2(RIG_OK); } /* '\get_vfo_info' */ declare_proto_rig(get_vfo_info) { int retval; ENTERFUNC2; ELAPSED1; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_vfo(s, sizeof(s), STATE(rig)->vfo_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } vfo = rig_parse_vfo(arg1); freq_t freq = 0; rmode_t mode = RIG_MODE_NONE; pbwidth_t width = 0; split_t split; int satmode = 0; retval = rig_get_vfo_info(rig, vfo, &freq, &mode, &width, &split, &satmode); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); } const char *modestr = rig_strrmode(mode); if (strlen(modestr) == 0) { modestr = "None"; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: %.0f%c", cmd->arg2, freq, resp_sep); fprintf(fout, "%s: %s%c", cmd->arg3, modestr, resp_sep); fprintf(fout, "%s: %d%c", cmd->arg4, (int)width, resp_sep); fprintf(fout, "%s: %d%c", cmd->arg5, (int)split, resp_sep); fprintf(fout, "%s: %d%c", cmd->arg6, (int)satmode, resp_sep); } else { fprintf(fout, "%.0f%c%s%c%d%c%d%c%d\n", freq, resp_sep, modestr, resp_sep, (int)width, resp_sep, (int)split, resp_sep, (int)satmode); } ELAPSED2; RETURNFUNC2(retval); } /* '\get_vfo_list' */ declare_proto_rig(get_vfo_list) { static char prntbuf[256]; ENTERFUNC2; rig_sprintf_vfo(prntbuf, sizeof(prntbuf), STATE(rig)->vfo_list); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c\n", prntbuf[0] ? prntbuf : "None", ext_resp); RETURNFUNC2(RIG_OK); } /* '\test' */ declare_proto_rig(test) { ENTERFUNC2; if (!strcmp(arg1, "?")) { fprintf(fout, "cw\n"); RETURNFUNC2(RIG_OK); } if (strcmp(arg1, "cw") == 0) { rig_test_cw(rig); } RETURNFUNC2(RIG_OK); } /* '\get_modes' */ declare_proto_rig(get_modes) { static char prntbuf[1024]; int i; char freqbuf[32]; ENTERFUNC2; rig_strrmodes(STATE(rig)->mode_list, prntbuf, sizeof(prntbuf)); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", prntbuf[0] ? prntbuf : "None", ext_resp); fprintf(fout, "\nBandwidths:"); for (i = 1; i < RIG_MODE_TESTS_MAX; i <<= 1) { pbwidth_t pbnorm = rig_passband_normal(rig, i); if (pbnorm == 0) { continue; } sprintf_freq(freqbuf, sizeof(freqbuf), pbnorm); fprintf(fout, "\n\t%s\tNormal: %s,\t", rig_strrmode(i), freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_narrow(rig, i)); fprintf(fout, "Narrow: %s,\t", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), rig_passband_wide(rig, i)); fprintf(fout, "Wide: %s", freqbuf); } RETURNFUNC2(RIG_OK); } declare_proto_rig(get_mode_bandwidths) { int i; char freqbuf[32]; ENTERFUNC2; rmode_t mode = rig_parse_mode(arg1); for (i = 1; i < RIG_MODE_TESTS_MAX; i <<= 1) { if (i != mode) { continue; } if (mode == RIG_MODE_CWR) { mode = RIG_MODE_CW; } if (mode == RIG_MODE_RTTYR) { mode = RIG_MODE_RTTY; } pbwidth_t pbnorm = rig_passband_normal(rig, i); if (pbnorm == 0) { continue; } // sprintf_freq(freqbuf, sizeof(freqbuf), pbnorm); SNPRINTF(freqbuf, sizeof(freqbuf), "%ldHz", pbnorm); fprintf(fout, "Mode=%s\n", rig_strrmode(i)); fprintf(fout, "Normal=%s\n", freqbuf); SNPRINTF(freqbuf, sizeof(freqbuf), "%ldHz", rig_passband_narrow(rig, i)); fprintf(fout, "Narrow=%s\n", freqbuf); SNPRINTF(freqbuf, sizeof(freqbuf), "%ldHz", rig_passband_wide(rig, i)); fprintf(fout, "Wide=%s", freqbuf); } RETURNFUNC2(RIG_OK); } /* 'T' */ declare_proto_rig(set_ptt) { int scr; ptt_t ptt; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &scr)); ptt = scr; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_ptt ptt=%d\n", __func__, ptt); /* * We allow RIG_PTT_ON_MIC and RIG_PTT_ON_DATA arriving from netrigctl. * However, if the rig does not have two separate CAT commands, or if * the rig is actually switched by a hardware signal (DTR etc.), then * we map this to RIG_PTT_ON. * Currently, this is not really necessary here because it is taken * case of in rig_set_ptt, but you never know .... */ switch (ptt) { case RIG_PTT_ON_MIC: case RIG_PTT_ON_DATA: // No longer map this -- is confusing rigctld and MICDATA rigs // https://github.com/Hamlib/Hamlib/issues/998 #if 0 // map to a legal value if (rig->caps->ptt_type != RIG_PTT_RIG_MICDATA) { rig_debug(RIG_DEBUG_ERR, "%s: pttport.type.ptt=%d\n", __func__, PTTPORT(rig)->type.ptt); ptt = RIG_PTT_ON; } #endif break; case RIG_PTT_ON: case RIG_PTT_OFF: // nothing to do break; default: // this case is not handled in hamlib, but we guard against // illegal parameters here. The hamlib behaviour is to switch // on PTT whenever ptt != RIG_PTT_OFF. RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_ERR, "%s: ptt=%d\n", __func__, ptt); RETURNFUNC2(rig_set_ptt(rig, vfo, ptt)); } /* 't' */ declare_proto_rig(get_ptt) { int status; ptt_t ptt = 0; ENTERFUNC2; status = rig_get_ptt(rig, vfo, &ptt); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } /* TODO MICDATA */ fprintf(fout, "%d%c", ptt, resp_sep); RETURNFUNC2(status); } /* '0x8b' */ declare_proto_rig(get_dcd) { int status; dcd_t dcd; ENTERFUNC2; status = rig_get_dcd(rig, vfo, &dcd); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", dcd, resp_sep); RETURNFUNC2(status); } /* 'R' */ declare_proto_rig(set_rptr_shift) { rptr_shift_t rptr_shift; ENTERFUNC2; rptr_shift = rig_parse_rptr_shift(arg1); RETURNFUNC2(rig_set_rptr_shift(rig, vfo, rptr_shift)); } /* 'r' */ declare_proto_rig(get_rptr_shift) { int status; rptr_shift_t rptr_shift; ENTERFUNC2; status = rig_get_rptr_shift(rig, vfo, &rptr_shift); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", rig_strptrshift(rptr_shift), resp_sep); RETURNFUNC2(status); } /* 'O' */ declare_proto_rig(set_rptr_offs) { unsigned long rptr_offs; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%lu", &rptr_offs)); RETURNFUNC2(rig_set_rptr_offs(rig, vfo, rptr_offs)); } /* 'o' */ declare_proto_rig(get_rptr_offs) { int status; shortfreq_t rptr_offs; ENTERFUNC2; status = rig_get_rptr_offs(rig, vfo, &rptr_offs); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%ld%c", rptr_offs, resp_sep); RETURNFUNC2(status); } /* 'C' */ declare_proto_rig(set_ctcss_tone) { tone_t tone; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%u", &tone)); RETURNFUNC2(rig_set_ctcss_tone(rig, vfo, tone)); } /* 'c' */ declare_proto_rig(get_ctcss_tone) { int status; tone_t tone; ENTERFUNC2; status = rig_get_ctcss_tone(rig, vfo, &tone); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", tone, resp_sep); RETURNFUNC2(status); } /* 'D' */ declare_proto_rig(set_dcs_code) { tone_t code; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%u", &code)); RETURNFUNC2(rig_set_dcs_code(rig, vfo, code)); } /* 'd' */ declare_proto_rig(get_dcs_code) { int status; tone_t code; ENTERFUNC2; status = rig_get_dcs_code(rig, vfo, &code); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", code, resp_sep); RETURNFUNC2(status); } /* '0x90' */ declare_proto_rig(set_ctcss_sql) { tone_t tone; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%u", &tone)); RETURNFUNC2(rig_set_ctcss_sql(rig, vfo, tone)); } /* '0x91' */ declare_proto_rig(get_ctcss_sql) { int status; tone_t tone; ENTERFUNC2; status = rig_get_ctcss_sql(rig, vfo, &tone); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", tone, resp_sep); RETURNFUNC2(status); } /* '0x92' */ declare_proto_rig(set_dcs_sql) { tone_t code; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%u", &code)); RETURNFUNC2(rig_set_dcs_sql(rig, vfo, code)); } /* '0x93' */ declare_proto_rig(get_dcs_sql) { int status; tone_t code; ENTERFUNC2; status = rig_get_dcs_sql(rig, vfo, &code); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", code, resp_sep); RETURNFUNC2(status); } /* 'I' */ declare_proto_rig(set_split_freq) { freq_t txfreq; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%"SCNfreq, &txfreq)); RETURNFUNC2(rig_set_split_freq(rig, txvfo, txfreq)); } /* 'i' */ declare_proto_rig(get_split_freq) { int status; freq_t txfreq; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; status = rig_get_split_freq(rig, txvfo, &txfreq); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%"PRIll"%c", (int64_t)txfreq, resp_sep); RETURNFUNC2(status); } /* 'X' */ declare_proto_rig(set_split_mode) { rmode_t mode; int width; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_mode(s, sizeof(s), STATE(rig)->mode_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } // mode could be RIG_MODE_NONE here // we treat it as non-fatal // rig_parse_mode will spit out error msg mode = rig_parse_mode(arg1); CHKSCN1ARG(sscanf(arg2, "%d", &width)); RETURNFUNC2(rig_set_split_mode(rig, txvfo, mode, (pbwidth_t) width)); } /* 'x' */ declare_proto_rig(get_split_mode) { int status; rmode_t mode; pbwidth_t width; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; status = rig_get_split_mode(rig, txvfo, &mode, &width); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", rig_strrmode(mode), resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%ld%c", width, resp_sep); RETURNFUNC2(status); } /* 'K' */ declare_proto_rig(set_split_freq_mode) { freq_t freq; rmode_t mode; int width; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_mode(s, sizeof(s), STATE(rig)->mode_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } CHKSCN1ARG(sscanf(arg1, "%"SCNfreq, &freq)); mode = rig_parse_mode(arg2); CHKSCN1ARG(sscanf(arg3, "%d", &width)); RETURNFUNC2(rig_set_split_freq_mode(rig, txvfo, freq, mode, (pbwidth_t) width)); } /* 'k' */ declare_proto_rig(get_split_freq_mode) { int status; freq_t freq; rmode_t mode; pbwidth_t width; vfo_t txvfo = RIG_VFO_TX; ENTERFUNC2; status = rig_get_split_freq_mode(rig, txvfo, &freq, &mode, &width); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%"PRIll"%c", (int64_t)freq, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%s%c", rig_strrmode(mode), resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%ld%c", width, resp_sep); RETURNFUNC2(status); } /* 'S' */ declare_proto_rig(set_split_vfo) { int split; vfo_t tx_vfo; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &split)); if (!strcmp(arg2, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_vfo(s, sizeof(s), STATE(rig)->vfo_list); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } tx_vfo = rig_parse_vfo(arg2); if (tx_vfo == RIG_VFO_NONE) { RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): rx_vfo = %s, tx_vfo = %s\n", __func__, __LINE__, rig_strvfo(vfo), rig_strvfo(tx_vfo)); RETURNFUNC2(rig_set_split_vfo(rig, vfo, (split_t) split, tx_vfo)); } /* 's' */ declare_proto_rig(get_split_vfo) { int status; split_t split; vfo_t tx_vfo; ENTERFUNC2; status = rig_get_split_vfo(rig, vfo, &split, &tx_vfo); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", split, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%s%c", rig_strvfo(tx_vfo), resp_sep); RETURNFUNC2(status); } /* 'N' */ declare_proto_rig(set_ts) { unsigned long ts; char s[SPRINTF_MAX_SIZE]; ENTERFUNC2; if (!strcmp(arg1, "?")) { rig_sprintf_tuning_steps(s, sizeof(s), rig->caps->tuning_steps); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } CHKSCN1ARG(sscanf(arg1, "%lu", &ts)); RETURNFUNC2(rig_set_ts(rig, vfo, ts)); } /* 'n' */ declare_proto_rig(get_ts) { int status; shortfreq_t ts; ENTERFUNC2; status = rig_get_ts(rig, vfo, &ts); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%ld%c", ts, resp_sep); RETURNFUNC2(status); } /* '2' */ declare_proto_rig(power2mW) { int status; float power; freq_t freq; rmode_t mode; unsigned int mwp; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%f", &power)); CHKSCN1ARG(sscanf(arg2, "%"SCNfreq, &freq)); mode = rig_parse_mode(arg3); status = rig_power2mW(rig, &mwp, power, freq, mode); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%i%c", mwp, resp_sep); RETURNFUNC2(status); } /* '4' */ declare_proto_rig(mW2power) { int status; float power; freq_t freq; rmode_t mode; unsigned int mwp; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%u", &mwp)); CHKSCN1ARG(sscanf(arg2, "%"SCNfreq, &freq)); mode = rig_parse_mode(arg3); status = rig_mW2power(rig, &power, mwp, freq, mode); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%f%c", power, resp_sep); RETURNFUNC2(status); } /* * RIG_CONF_ extparm's type: * NUMERIC: val.f * COMBO: val.i, starting from 0 * STRING: val.s * CHECKBUTTON: val.i 0/1 * * 'L' */ declare_proto_rig(set_level) { setting_t level; value_t val; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_level(s, sizeof(s), STATE(rig)->has_set_level); fputs(s, fout); if (rig->caps->set_ext_level) { sprintf_level_ext(s, sizeof(s), rig->caps->extlevels); fputs(s, fout); } fputc('\n', fout); RETURNFUNC2(RIG_OK); } level = rig_parse_level(arg1); if ((!strcmp(arg2, "?") || arg2[0] == 0) && level == RIG_LEVEL_METER) { fprintf(fout, "COMP ALC SWR ID/IC VDD DB PO TEMP%c", resp_sep); RETURNFUNC2(RIG_OK); } // some Java apps send comma in international setups so substitute period char *p = strchr(arg2, ','); if (p) { *p = '.'; } if (!rig_has_set_level(rig, level)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { RETURNFUNC2(-RIG_ENAVAIL); /* no such parameter */ } switch (cfp->type) { case RIG_CONF_BUTTON: /* arg is ignored */ val.i = 0; // avoid passing uninitialized data break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); break; case RIG_CONF_INT: CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); break; case RIG_CONF_NUMERIC: CHKSCN1ARG(sscanf(arg2, "%g", &val.f)); break; case RIG_CONF_STRING: val.cs = arg2; break; default: RETURNFUNC2(-RIG_ECONF); } RETURNFUNC2(rig_set_ext_level(rig, vfo, cfp->token, val)); } int dummy; if (level == RIG_LEVEL_METER && sscanf(arg2, "%d", &dummy) <= 0) { if (strcmp(arg2, "COMP") == 0) { arg2 = "2"; } else if (strcmp(arg2, "ALC") == 0) { arg2 = "4"; } else if (strcmp(arg2, "SWR") == 0) { arg2 = "1"; } else if (strcmp(arg2, "ID") == 0 || strcmp(arg2, "IC") == 0) { arg2 = "8"; } else if (strcmp(arg2, "VDD") == 0) { arg2 = "64"; } else if (strcmp(arg2, "DB") == 0) { arg2 = "16"; } else if (strcmp(arg2, "PO") == 0) { arg2 = "32"; } else if (strcmp(arg2, "TEMP") == 0) { arg2 = "128"; } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown meter=%s, only know COMP,ALC,SWR,ID/IC,VDD,DB,PO,TEMP\n", __func__, arg2); RETURNFUNC2(-RIG_EINVAL); } } if (RIG_LEVEL_IS_FLOAT(level)) { CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); } else { CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); } RETURNFUNC2(rig_set_level(rig, vfo, level, val)); } /* 'l' */ declare_proto_rig(get_level) { int status; setting_t level; value_t val; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_level(s, sizeof(s), STATE(rig)->has_get_level); fputs(s, fout); if (rig->caps->get_ext_level) { sprintf_level_ext(s, sizeof(s), rig->caps->extlevels); fprintf(fout, "%s%c", s, resp_sep); } fputc('\n', fout); RETURNFUNC2(RIG_OK); } level = rig_parse_level(arg1); if (!rig_has_get_level(rig, level)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { rig_debug(RIG_DEBUG_ERR, "%s: level not found=%s\n", __func__, arg1); RETURNFUNC2(-RIG_EINVAL); /* no such parameter */ } status = rig_get_ext_level(rig, vfo, cfp->token, &val); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } switch (cfp->type) { case RIG_CONF_BUTTON: /* there's no sense in retrieving value of stateless button */ RETURNFUNC2(-RIG_EINVAL); case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(fout, "%d%c", val.i, resp_sep); break; case RIG_CONF_NUMERIC: fprintf(fout, "%g%c", val.f, resp_sep); break; case RIG_CONF_INT: fprintf(fout, "%.0f%c", val.f, resp_sep); break; case RIG_CONF_STRING: fprintf(fout, "%s%c", val.s, resp_sep); break; default: RETURNFUNC2(-RIG_ECONF); } RETURNFUNC2(status); } status = rig_get_level(rig, vfo, level, &val); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } if (level == RIG_LEVEL_METER && interactive && prompt) { // we will show text answers as they make morse sense for rigtl switch (val.i) { case RIG_METER_COMP: fprintf(fout, "%d=%s%c", val.i, "COMP", resp_sep); break; case RIG_METER_ALC: fprintf(fout, "%d=%s%c", val.i, "ALC", resp_sep); break; case RIG_METER_SWR: fprintf(fout, "%d=%s%c", val.i, "SWR", resp_sep); break; case RIG_METER_IC: fprintf(fout, "%d=%s%c", val.i, "IC", resp_sep); break; case RIG_METER_VDD: fprintf(fout, "%d=%s%c", val.i, "VDD", resp_sep); break; case RIG_METER_DB: fprintf(fout, "%d=%s%c", val.i, "DB", resp_sep); break; case RIG_METER_PO: fprintf(fout, "%d=%s%c", val.i, "PO", resp_sep); break; case RIG_METER_TEMP: fprintf(fout, "%d=%s%c", val.i, "TEMP", resp_sep); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown meter=%d, only know COMP,ALC,SWR,ID/IC,VDD,DB,PO,TEMP\n", __func__, val.i); RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(RIG_OK); } if (RIG_LEVEL_IS_FLOAT(level)) { fprintf(fout, "%g%c", val.f, resp_sep); } else { fprintf(fout, "%d%c", val.i, resp_sep); } RETURNFUNC2(status); } /* 'U' */ declare_proto_rig(set_func) { setting_t func; int func_stat; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_func(s, sizeof(s), STATE(rig)->has_set_func); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } func = rig_parse_func(arg1); if (!rig_has_set_func(rig, func)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { RETURNFUNC2(-RIG_ENAVAIL); /* no such parameter */ } CHKSCN1ARG(sscanf(arg2, "%d", &func_stat)); RETURNFUNC2(rig_set_ext_func(rig, vfo, cfp->token, func_stat)); } CHKSCN1ARG(sscanf(arg2, "%d", &func_stat)); RETURNFUNC2(rig_set_func(rig, vfo, func, func_stat)); } /* 'u' */ declare_proto_rig(get_func) { int status; setting_t func; int func_stat; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_func(s, sizeof(s), STATE(rig)->has_get_func); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } func = rig_parse_func(arg1); if (!rig_has_get_func(rig, func)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { RETURNFUNC2(-RIG_EINVAL); /* no such parameter */ } status = rig_get_ext_func(rig, vfo, cfp->token, &func_stat); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", func_stat, resp_sep); RETURNFUNC2(status); } status = rig_get_func(rig, vfo, func, &func_stat); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", func_stat, resp_sep); RETURNFUNC2(status); } /* 'P' */ declare_proto_rig(set_parm) { setting_t parm; value_t val; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_parm(s, sizeof(s), STATE(rig)->has_set_parm); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } if (strcmp(arg1, "BANDSELECT") == 0 && !strcmp(arg2, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_parm_gran(s, sizeof(s) - 1, RIG_PARM_BANDSELECT, rig->caps->parm_gran); char *p = strchr(s, ')'); if (p) { *p = 0; } p = strchr(s, '('); if (p) { char *comma; while ((comma = strchr(p, ','))) { *comma = ' '; } fprintf(fout, "%s\n", p + 1); RETURNFUNC2(RIG_OK); } else { RETURNFUNC2(-RIG_EINTERNAL); } } if (strcmp(arg1, "KEYERTYPE") == 0 && strcmp(arg2, "?") != 0) { if (strcmp(arg2, "STRAIGHT") == 0) {arg2 = "0";} else if (strcmp(arg2, "BUG") == 0) {arg2 = "1";} else if (strcmp(arg2, "PADDLE") == 0) {arg2 = "2";} } parm = rig_parse_parm(arg1); if (!rig_has_set_parm(rig, parm)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { RETURNFUNC2(-RIG_EINVAL); /* no such parameter */ } switch (cfp->type) { case RIG_CONF_BUTTON: /* arg is ignored */ val.i = 0; // avoid passing uninitialized data break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); break; case RIG_CONF_INT: CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); break; case RIG_CONF_NUMERIC: CHKSCN1ARG(sscanf(arg2, "%g", &val.f)); break; case RIG_CONF_STRING: #if 0 if (parm == RIG_PARM_KEYERTYPE) { val.i = atoi(arg2); } else #endif { val.cs = arg2; } break; case RIG_CONF_BINARY: val.b.d = (unsigned char *)arg2; break; default: RETURNFUNC2(-RIG_ECONF); } RETURNFUNC2(rig_set_ext_parm(rig, cfp->token, val)); } if (RIG_PARM_IS_FLOAT(parm)) { CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); } else if (RIG_PARM_IS_STRING(parm)) { #if 0 if (parm == RIG_PARM_KEYERTYPE) { val.i = atoi(arg2); } else #endif { val.cs = arg2; } } else { CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); } RETURNFUNC2(rig_set_parm(rig, parm, val)); } /* 'p' */ declare_proto_rig(get_parm) { int status; setting_t parm; value_t val; char buffer[RIG_BIN_MAX]; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_parm(s, sizeof(s), STATE(rig)->has_get_parm); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } parm = rig_parse_parm(arg1); if (!rig_has_get_parm(rig, parm)) { const struct confparams *cfp; cfp = rig_ext_lookup(rig, arg1); if (!cfp) { RETURNFUNC2(-RIG_EINVAL); /* no such parameter */ } switch (cfp->type) { case RIG_CONF_STRING: memset(buffer, '0', sizeof(buffer)); buffer[sizeof(buffer) - 1] = 0; val.s = buffer; break; case RIG_CONF_BINARY: memset(buffer, 0, sizeof(buffer)); val.b.d = (unsigned char *)buffer; val.b.l = RIG_BIN_MAX; break; default: break; } status = rig_get_ext_parm(rig, cfp->token, &val); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } switch (cfp->type) { case RIG_CONF_BUTTON: /* there's not sense in retrieving value of stateless button */ RETURNFUNC2(-RIG_EINVAL); case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(fout, "%d%c", val.i, resp_sep); break; case RIG_CONF_INT: fprintf(fout, "%.0f%c", val.f, resp_sep); break; case RIG_CONF_NUMERIC: fprintf(fout, "%g%c", val.f, resp_sep); break; case RIG_CONF_STRING: fprintf(fout, "%s%c", val.s, resp_sep); break; case RIG_CONF_BINARY: dump_hex((unsigned char *)buffer, val.b.l); fprintf(fout, "%c", resp_sep); break; default: RETURNFUNC2(-RIG_ECONF); } RETURNFUNC2(status); } status = rig_get_parm(rig, parm, &val); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } if (parm == RIG_PARM_KEYERTYPE) { char *s = "STRAIGHT"; if (val.i == 1) { s = "BUG"; } else if (val.i == 2) { s = "PADDLE"; } fprintf(fout, "%s%cv", s, resp_sep); } else if (RIG_PARM_IS_FLOAT(parm)) { rig_debug(RIG_DEBUG_ERR, "%s: float\n", __func__); fprintf(fout, "%f%c", val.f, resp_sep); } else if (RIG_PARM_IS_STRING(parm)) { rig_debug(RIG_DEBUG_ERR, "%s: string\n", __func__); fprintf(fout, "%s%c", val.s, resp_sep); } else { rig_debug(RIG_DEBUG_ERR, "%s: int\n", __func__); fprintf(fout, "%d%c", val.i, resp_sep); } RETURNFUNC2(status); } /* 'B' */ declare_proto_rig(set_bank) { int bank; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &bank)); RETURNFUNC2(rig_set_bank(rig, vfo, bank)); } /* 'E' */ declare_proto_rig(set_mem) { int ch; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &ch)); RETURNFUNC2(rig_set_mem(rig, vfo, ch)); } /* 'e' */ declare_proto_rig(get_mem) { int status; int ch; ENTERFUNC2; status = rig_get_mem(rig, vfo, &ch); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", ch, resp_sep); RETURNFUNC2(status); } /* 'G' */ declare_proto_rig(vfo_op) { vfo_op_t op; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_vfop(s, sizeof(s), STATE(rig)->vfo_ops); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } op = rig_parse_vfo_op(arg1); if (RIG_OP_NONE == op) { rig_debug(RIG_DEBUG_ERR, "%s: rig_parse_vfo failed with '%s'\n", __func__, arg1); RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(rig_vfo_op(rig, vfo, op)); } /* 'g' */ declare_proto_rig(scan) { scan_t op; int ch; ENTERFUNC2; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_scan(s, sizeof(s), rig->caps->scan_ops); fprintf(fout, "%s\n", s); RETURNFUNC2(RIG_OK); } op = rig_parse_scan(arg1); CHKSCN1ARG(sscanf(arg2, "%d", &ch)); RETURNFUNC2(rig_scan(rig, vfo, op, ch)); } /* 'H' */ declare_proto_rig(set_channel) { const channel_cap_t *mem_caps = NULL; const chan_t *chan_list; channel_t chan; int status; char s[16]; ENTERFUNC2; memset(&chan, 0, sizeof(channel_t)); if (isdigit((int)arg1[0])) { chan.vfo = RIG_VFO_MEM; CHKSCN1ARG(sscanf(arg1, "%d", &chan.channel_num)); /* * find mem_caps in caps, we'll need it later */ chan_list = rig_lookup_mem_caps(rig, chan.channel_num); if (chan_list) { mem_caps = &chan_list->mem_caps; } } else { chan.vfo = rig_parse_vfo(arg1); chan.channel_num = 0; /* TODO: mem_caps for VFO! */ /* either from mem, or reverse computed from caps */ } if (!mem_caps) { RETURNFUNC2(-RIG_ECONF); } if (mem_caps->bank_num) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "Bank Num: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.bank_num)); } #if 0 if (mem_caps->vfo) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "vfo (VFOA,MEM,etc...): "); } CHKSCN1ARG(scanfc(fin, "%s", s)); chan.vfo = rig_parse_vfo(s); } #endif if (mem_caps->ant) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "ant: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.ant)); } if (mem_caps->freq) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "Frequency: "); } CHKSCN1ARG(scanfc(fin, "%"SCNfreq, &chan.freq)); } if (mem_caps->mode) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "mode (FM,LSB,etc...): "); } CHKSCN1ARG(scanfc(fin, "%s", s)); chan.mode = rig_parse_mode(s); } if (mem_caps->width) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "width: "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.width)); } if (mem_caps->tx_freq) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "tx freq: "); } CHKSCN1ARG(scanfc(fin, "%"SCNfreq, &chan.tx_freq)); } if (mem_caps->tx_mode) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "tx mode (FM,LSB,etc...): "); } CHKSCN1ARG(scanfc(fin, "%s", s)); chan.tx_mode = rig_parse_mode(s); } if (mem_caps->tx_width) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "tx width: "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.tx_width)); } if (mem_caps->split) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "split (0,1): "); } CHKSCN1ARG(scanfc(fin, "%d", &status)); chan.split = status; } if (mem_caps->tx_vfo) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "tx vfo (VFOA,MEM,etc...): "); } CHKSCN1ARG(scanfc(fin, "%s", s)); chan.tx_vfo = rig_parse_vfo(s); } if (mem_caps->rptr_shift) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "rptr shift (+-0): "); } CHKSCN1ARG(scanfc(fin, "%s", s)); chan.rptr_shift = rig_parse_rptr_shift(s); } if (mem_caps->rptr_offs) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "rptr offset: "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.rptr_offs)); } if (mem_caps->tuning_step) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "tuning step: "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.tuning_step)); } if (mem_caps->rit) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "rit (Hz,0=off): "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.rit)); } if (mem_caps->xit) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "xit (Hz,0=off): "); } CHKSCN1ARG(scanfc(fin, "%ld", &chan.xit)); } if (mem_caps->funcs) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "funcs: "); } CHKSCN1ARG(scanfc(fin, "%lx", &chan.funcs)); } #if 0 /* for all levels (except READONLY), ask */ if (mem_caps->levels) { sscanf(arg1, "%d", &chan.levels); } #endif if (mem_caps->ctcss_tone) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "ctcss tone freq in tenth of Hz (0=off): "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.ctcss_tone)); } if (mem_caps->ctcss_sql) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "ctcss sql freq in tenth of Hz (0=off): "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.ctcss_sql)); } if (mem_caps->dcs_code) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "dcs code: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.dcs_code)); } if (mem_caps->dcs_sql) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "dcs sql: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.dcs_sql)); } if (mem_caps->scan_group) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "scan group: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.scan_group)); } if (mem_caps->flags) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "flags: "); } CHKSCN1ARG(scanfc(fin, "%d", &chan.flags)); } if (mem_caps->channel_desc) { if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf_flush(fout, "channel desc: "); } CHKSCN1ARG(scanfc(fin, "%s", s)); strcpy(chan.channel_desc, s); } #if 0 /* TODO: same as levels, allocate/free the array */ if (mem_caps->ext_levels) { sscanf(arg1, "%d", &chan.ext_levels[i].val.i); } #endif status = rig_set_channel(rig, vfo, &chan); RETURNFUNC2(status); } /* 'h' */ declare_proto_rig(get_channel) { int status; int read_only = 0; channel_t chan; ENTERFUNC2; memset(&chan, 0, sizeof(channel_t)); if (isdigit((int)arg1[0])) { chan.vfo = RIG_VFO_MEM; CHKSCN1ARG(sscanf(arg1, "%d", &chan.channel_num)); } else { chan.vfo = rig_parse_vfo(arg1); chan.channel_num = 0; } CHKSCN1ARG(sscanf(arg2, "%d", &read_only)); status = rig_get_channel(rig, RIG_VFO_NONE, &chan, read_only); if (status != RIG_OK) { RETURNFUNC2(status); } status = dump_chan(fout, rig, &chan); if (chan.ext_levels) { free(chan.ext_levels); } RETURNFUNC2(status); } /* 'A' */ /** * \deprecated Function deprecated. Use the new async data functionality instead. */ declare_proto_rig(set_trn) { ENTERFUNC2; RETURNFUNC2(-RIG_EDEPRECATED); } /* 'a' */ /** * \deprecated Function deprecated. Use the new async data functionality instead. */ declare_proto_rig(get_trn) { ENTERFUNC2; RETURNFUNC2(-RIG_EDEPRECATED); } /* '_' */ declare_proto_rig(get_info) { const char *s; ENTERFUNC2; s = rig_get_info(rig); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", s ? s : "None", resp_sep); RETURNFUNC2(RIG_OK); } int dump_chan(FILE *fout, RIG *rig, channel_t *chan) { int idx, firstloop = 1; char freqbuf[16]; char widthbuf[16]; char prntbuf[256]; ENTERFUNC2; fprintf(fout, "Channel: %d, Name: '%s'\n", chan->channel_num, chan->channel_desc); fprintf(fout, "VFO: %s, Antenna: %d, Split: %s\n", rig_strvfo(chan->vfo), chan->ant, chan->split == RIG_SPLIT_ON ? "ON" : "OFF"); sprintf_freq(freqbuf, sizeof(freqbuf), chan->freq); sprintf_freq(widthbuf, sizeof(widthbuf), chan->width); fprintf(fout, "Freq: %s\tMode: %s\tWidth: %s\n", freqbuf, rig_strrmode(chan->mode), widthbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan->tx_freq); sprintf_freq(widthbuf, sizeof(widthbuf), chan->tx_width); fprintf(fout, "txFreq: %s\ttxMode: %s\ttxWidth: %s\n", freqbuf, rig_strrmode(chan->tx_mode), widthbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan->rptr_offs); fprintf(fout, "Shift: %s, Offset: %s%s, ", rig_strptrshift(chan->rptr_shift), chan->rptr_offs > 0 ? "+" : "", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan->tuning_step); fprintf(fout, "Step: %s, ", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan->rit); fprintf(fout, "RIT: %s%s, ", chan->rit > 0 ? "+" : "", freqbuf); sprintf_freq(freqbuf, sizeof(freqbuf), chan->xit); fprintf(fout, "XIT: %s%s\n", chan->xit > 0 ? "+" : "", freqbuf); fprintf(fout, "CTCSS: %u.%uHz, ", chan->ctcss_tone / 10, chan->ctcss_tone % 10); fprintf(fout, "CTCSSsql: %u.%uHz, ", chan->ctcss_sql / 10, chan->ctcss_sql % 10); fprintf(fout, "DCS: %u.%u, ", chan->dcs_code / 10, chan->dcs_code % 10); fprintf(fout, "DCSsql: %u.%u\n", chan->dcs_sql / 10, chan->dcs_sql % 10); rig_sprintf_func(prntbuf, sizeof(prntbuf), chan->funcs); fprintf(fout, "Functions: %s\n", prntbuf); fprintf(fout, "Levels:"); for (idx = 0; idx < RIG_SETTING_MAX; idx++) { setting_t level = rig_idx2setting(idx); const char *level_s; if (!RIG_LEVEL_SET(level) || (!rig_has_set_level(rig, level) && !rig_has_get_level(rig, level))) { continue; } level_s = rig_strlevel(level); if (!level_s || level_s[0] == '\0') { continue; /* duh! */ } if (firstloop) { firstloop = 0; } else { fprintf(fout, ",\t"); } if (RIG_LEVEL_IS_FLOAT(level)) { fprintf(fout, " %s: %g%%", level_s, 100 * chan->levels[idx].f); } else { fprintf(fout, " %s: %d", level_s, chan->levels[idx].i); } } /* ext_levels */ for (idx = 0; chan->ext_levels && !RIG_IS_EXT_END(chan->ext_levels[idx]); idx++) { const struct confparams *cfp; char lstr[32]; cfp = rig_ext_lookup_tok(rig, chan->ext_levels[idx].token); if (!cfp) { RETURNFUNC2(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, chan->ext_levels[idx].val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", chan->ext_levels[idx].val.i); break; case RIG_CONF_INT: SNPRINTF(lstr, sizeof(lstr), "%.0f", chan->ext_levels[idx].val.f); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%g", chan->ext_levels[idx].val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", chan->ext_levels[idx].val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: continue; default: RETURNFUNC2(-RIG_EINTERNAL); } fprintf(fout, ",\t %s: %s", cfp->name, lstr); } fprintf(fout, "\n"); RETURNFUNC2(RIG_OK); } /* '1' */ declare_proto_rig(dump_caps) { ENTERFUNC2; #if 1 if (rig->caps->rig_model == RIG_MODEL_NETRIGCTL) { char cmd[32]; SNPRINTF(cmd, sizeof(cmd), "\\dump_caps\n"); dumpstate(rig, fout); } else #endif { dumpcaps(rig, fout); } RETURNFUNC2(RIG_OK); } /* For rigctld internal use */ declare_proto_rig(dump_state) { int i; struct rig_state *rs = STATE(rig); char buf[1024]; ENTERFUNC2; /* * - Protocol version */ #define RIGCTLD_PROT_VER 1 fprintf(fout, "%d\n", RIGCTLD_PROT_VER); fprintf(fout, "%d\n", rig->caps->rig_model); #if 0 // deprecated -- not one rig uses this fprintf(fout, "%d\n", rs->itu_region); #else // need to print something to maintain backward compatibility fprintf(fout, "%d\n", 0); #endif for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { fprintf(fout, "%"FREQFMT" %"FREQFMT" 0x%"PRXll" %d %d 0x%x 0x%x\n", rs->rx_range_list[i].startf, rs->rx_range_list[i].endf, rs->rx_range_list[i].modes, rs->rx_range_list[i].low_power, rs->rx_range_list[i].high_power, rs->rx_range_list[i].vfo, rs->rx_range_list[i].ant); } fprintf(fout, "0 0 0 0 0 0 0\n"); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { fprintf(fout, "%"FREQFMT" %"FREQFMT" 0x%"PRXll" %d %d 0x%x 0x%x\n", rs->tx_range_list[i].startf, rs->tx_range_list[i].endf, rs->tx_range_list[i].modes, rs->tx_range_list[i].low_power, rs->tx_range_list[i].high_power, rs->tx_range_list[i].vfo, rs->tx_range_list[i].ant); } fprintf(fout, "0 0 0 0 0 0 0\n"); for (i = 0; i < HAMLIB_TSLSTSIZ && !RIG_IS_TS_END(rs->tuning_steps[i]); i++) { fprintf(fout, "0x%"PRXll" %ld\n", rs->tuning_steps[i].modes, rs->tuning_steps[i].ts); } fprintf(fout, "0 0\n"); for (i = 0; i < HAMLIB_FLTLSTSIZ && !RIG_IS_FLT_END(rs->filters[i]); i++) { fprintf(fout, "0x%"PRXll" %ld\n", rs->filters[i].modes, rs->filters[i].width); } fprintf(fout, "0 0\n"); #if 0 chan_t chan_list[HAMLIB_CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif fprintf(fout, "%ld\n", rs->max_rit); fprintf(fout, "%ld\n", rs->max_xit); fprintf(fout, "%ld\n", rs->max_ifshift); fprintf(fout, "%d\n", rs->announces); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i]; i++) { fprintf(fout, "%d ", rs->preamp[i]); } fprintf(fout, "\n"); for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i]; i++) { fprintf(fout, "%d ", rs->attenuator[i]); } fprintf(fout, "\n"); fprintf(fout, "0x%"PRXll"\n", rs->has_get_func); fprintf(fout, "0x%"PRXll"\n", rs->has_set_func); fprintf(fout, "0x%"PRXll"\n", rs->has_get_level); fprintf(fout, "0x%"PRXll"\n", rs->has_set_level); fprintf(fout, "0x%"PRXll"\n", rs->has_get_parm); fprintf(fout, "0x%"PRXll"\n", rs->has_set_parm); // protocol 1 fields are "setting=value" // protocol 1 allows fields can be listed/processed in any order // protocol 1 fields can be multi-line -- just write the thing to allow for it // backward compatible as new values will just generate warnings rig_debug(RIG_DEBUG_ERR, "%s: chk_vfo_executed=%d\n", __func__, chk_vfo_executed); if (chk_vfo_executed) // for 3.3 compatibility { fprintf(fout, "vfo_ops=0x%x\n", rig->caps->vfo_ops); fprintf(fout, "ptt_type=0x%x\n", PTTPORT(rig)->type.ptt); fprintf(fout, "targetable_vfo=0x%x\n", rig->caps->targetable_vfo); fprintf(fout, "has_set_vfo=%d\n", rig->caps->set_vfo != NULL); fprintf(fout, "has_get_vfo=%d\n", rig->caps->get_vfo != NULL); fprintf(fout, "has_set_freq=%d\n", rig->caps->set_freq != NULL); fprintf(fout, "has_get_freq=%d\n", rig->caps->get_freq != NULL); fprintf(fout, "has_set_conf=%d\n", rig->caps->set_conf != NULL); fprintf(fout, "has_get_conf=%d\n", rig->caps->get_conf != NULL); #if 0 fprintf(fout, "has_set_parm=%d\n", rig->caps->set_parm != NULL); fprintf(fout, "has_get_parm=%d\n", rig->caps->get_parm != NULL); fprintf(fout, "parm_gran=0x%x\n", rig->caps->parm_gran); #endif // for the future // fprintf(fout, "has_set_trn=%d\n", rig->caps->set_trn != NULL); // fprintf(fout, "has_get_trn=%d\n", rig->caps->get_trn != NULL); fprintf(fout, "has_power2mW=%d\n", rig->caps->power2mW != NULL); fprintf(fout, "has_mW2power=%d\n", rig->caps->mW2power != NULL); fprintf(fout, "has_get_ant=%d\n", rig->caps->get_ant != NULL); fprintf(fout, "has_set_ant=%d\n", rig->caps->set_ant != NULL); fprintf(fout, "timeout=%d\n", rig->caps->timeout); fprintf(fout, "rig_model=%d\n", rig->caps->rig_model); fprintf(fout, "rigctld_version=%s\n", hamlib_version2); rig_sprintf_agc_levels(rig, buf, sizeof(buf)); if (strlen(buf) > 0) { fprintf(fout, "agc_levels=%s\n", buf); } if (rig->caps->ctcss_list) { fprintf(fout, "ctcss_list="); for (i = 0; i < CTCSS_LIST_SIZE && rig->caps->ctcss_list[i] != 0; i++) { fprintf(fout, " %u.%1u", rig->caps->ctcss_list[i] / 10, rig->caps->ctcss_list[i] % 10); } fprintf(fout, "\n"); } if (rig->caps->dcs_list) { fprintf(fout, "dcs_list="); for (i = 0; i < DCS_LIST_SIZE && rig->caps->dcs_list[i] != 0; i++) { fprintf(fout, " %u", rig->caps->dcs_list[i]); } fprintf(fout, "\n"); } fprintf(fout, "level_gran="); for (i = 0; i < RIG_SETTING_MAX; ++i) { if (RIG_LEVEL_IS_FLOAT(i)) { fprintf(fout, "%d=%g,%g,%g;", i, rs->level_gran[i].min.f, rs->level_gran[i].max.f, rs->level_gran[i].step.f); } else { fprintf(fout, "%d=%d,%d,%d;", i, rs->level_gran[i].min.i, rs->level_gran[i].max.i, rs->level_gran[i].step.i); } } fprintf(fout, "\nparm_gran="); for (i = 0; i < RIG_SETTING_MAX; ++i) { if (RIG_LEVEL_IS_FLOAT(i)) { fprintf(fout, "%d=%g,%g,%g;", i, rs->parm_gran[i].min.f, rs->parm_gran[i].max.f, rs->parm_gran[i].step.f); } else { fprintf(fout, "%d=%d,%d,%d;", i, rs->level_gran[i].min.i, rs->level_gran[i].max.i, rs->level_gran[i].step.i); } } fprintf(fout, "\n"); rs->rig_model = rig->caps->rig_model; fprintf(fout, "rig_model=%d\n", rs->rig_model); fprintf(fout, "hamlib_version=%s\n", hamlib_version2); fprintf(fout, "done\n"); } RETURNFUNC2(RIG_OK); } /* '3' */ declare_proto_rig(dump_conf) { ENTERFUNC2; dumpconf(rig, fout); RETURNFUNC2(RIG_OK); } /* 'Y' */ declare_proto_rig(set_ant) { ant_t ant; value_t option; // some rigs have a another option for the antenna ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &ant)); CHKSCN1ARG(sscanf(arg2, "%d", &option.i)); // assuming they are integer values RETURNFUNC2(rig_set_ant(rig, vfo, rig_idx2setting(ant - 1), option)); } /* 'y' */ declare_proto_rig(get_ant) { int status; ant_t ant, ant_curr, ant_tx, ant_rx; value_t option; char antbuf[64]; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &ant)); if (ant == 0) // then we want the current antenna info { status = rig_get_ant(rig, vfo, RIG_ANT_CURR, &option, &ant_curr, &ant_tx, &ant_rx); } else { status = rig_get_ant(rig, vfo, rig_idx2setting(ant - 1), &option, &ant_curr, &ant_tx, &ant_rx); } if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } rig_sprintf_ant(antbuf, sizeof(antbuf), ant_curr); fprintf(fout, "%s%c", antbuf, resp_sep); //fprintf(fout, "%d%c", rig_setting2idx(ant_curr)+1, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", option.i, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } rig_sprintf_ant(antbuf, sizeof(antbuf), ant_tx); fprintf(fout, "%s%c", antbuf, resp_sep); //fprintf(fout, "%d%c", rig_setting2idx(ant_tx)+1, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } rig_sprintf_ant(antbuf, sizeof(antbuf), ant_rx); fprintf(fout, "%s%c", antbuf, resp_sep); //fprintf(fout, "%d%c", rig_setting2idx(ant_rx)+1, resp_sep); RETURNFUNC2(status); } /* '*' */ declare_proto_rig(reset) { int reset; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &reset)); RETURNFUNC2(rig_reset(rig, (reset_t) reset)); } /* 'b' */ declare_proto_rig(send_morse) { ENTERFUNC2; RETURNFUNC2(rig_send_morse(rig, vfo, arg1)); } /* 0xvv */ declare_proto_rig(stop_morse) { ENTERFUNC2; RETURNFUNC2(rig_stop_morse(rig, vfo)); } declare_proto_rig(wait_morse) { ENTERFUNC2; RETURNFUNC2(rig_wait_morse(rig, vfo)); } /* '8' */ declare_proto_rig(send_voice_mem) { int ch; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &ch)); RETURNFUNC2(rig_send_voice_mem(rig, vfo, ch)); } declare_proto_rig(stop_voice_mem) { ENTERFUNC2; RETURNFUNC2(rig_stop_voice_mem(rig, vfo)); } declare_proto_rig(send_dtmf) { ENTERFUNC2; RETURNFUNC2(rig_send_dtmf(rig, vfo, arg1)); } declare_proto_rig(recv_dtmf) { int status; int len; char digits[MAXARGSZ]; ENTERFUNC2; len = MAXARGSZ - 1; status = rig_recv_dtmf(rig, vfo, digits, &len); if (status != RIG_OK) { RETURNFUNC2(status); } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s\n", digits); RETURNFUNC2(status); } /* '0x87' */ declare_proto_rig(set_powerstat) { int stat; int retval; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &stat)); retval = rig_set_powerstat(rig, (powerstat_t) stat); if (retval == RIG_OK) { rig_powerstat = stat; // update our global so others can see powerstat } fflush(fin); RETURNFUNC2(retval); } /* '0x88' */ declare_proto_rig(get_powerstat) { int status; powerstat_t stat; ENTERFUNC2; status = rig_get_powerstat(rig, &stat); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d%c", stat, resp_sep); rig_powerstat = stat; // update our global so others can see powerstat RETURNFUNC2(status); } static int hasbinary(char *s, int len) { int i; for (i = 0; i < len; ++i) { if (!isascii(s[i])) { return (1); } } return 0; } /* * Special debugging purpose send command display reply until there's a * timeout. * * 'w' and 'W' */ extern int flrig_cat_string2(RIG *rig, const char *arg, char *value, int value_size); extern int flrig_cat_string(RIG *rig, const char *arg); static void toLowerCase(char *s) { if (s == NULL) { return; } // Check if the pointer is NULL while (*s) // Iterate until we hit the null terminator of the string { *s = tolower((unsigned char) * s); // Convert each character to lowercase s++; // Move to the next character } } declare_proto_rig(send_cmd) { int retval; hamlib_port_t *rp = RIGPORT(rig); int backend_num, cmd_len; #define BUFSZ 512 char bufcmd[BUFSZ * 5]; // allow for 5 chars for each binary unsigned char buf[BUFSZ]; char eom_buf[4] = { 0xa, 0xd, 0, 0 }; int binary = 0; int rxbytes = BUFSZ; int cmdcount = 1; int simulate = rig->caps->rig_model == RIG_MODEL_DUMMY || rig->caps->rig_model == RIG_MODEL_NONE || rp->rig == RIG_PORT_NONE; ENTERFUNC2; /* * binary protocols enter values as \0xZZ\0xYY.. */ backend_num = RIG_BACKEND_NUM(rig->caps->rig_model); rig_debug(RIG_DEBUG_TRACE, "%s: backend_num=%d\n", __func__, backend_num); if (rig->caps->rig_model == RIG_MODEL_FLRIG) { // call flrig raw send function cat_string or cat_priority_string flrig_cat_string2(rig, arg1, (char *)buf, sizeof(buf)); fwrite(cmd->arg2, 1, strlen(cmd->arg2), fout); /* i.e. "Frequency" */ fprintf(fout, ": %s\n", buf); RETURNFUNC2(RIG_OK); } // need to move the eom_buf to rig-specific backends // we'll let KENWOOD backends use the ; char in the rigctl commands if (backend_num == RIG_KENWOOD || backend_num == RIG_YAESU) { rig_debug(RIG_DEBUG_TRACE, "%s: KENWOOD\n", __func__); // eom_buf[0] = 0; send_cmd_term = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: arg1=%s\n", __func__, arg1); // note that hex sscanf expects at least 2 values to pass this check // is there any situation where only one x00 value would be written? unsigned int n, i1, i2; n = sscanf(arg1, "x%x x%x", &i1, &i2); if (send_cmd_term == -1 || backend_num == RIG_ICOM || backend_num == RIG_KACHINA || backend_num == RIG_MICROTUNE || ((strstr(arg1, "\\0x") || n == 2) && (rig->caps->rig_model != RIG_MODEL_NETRIGCTL)) ) { const char *p = arg1, *pp = NULL; int i; rig_debug(RIG_DEBUG_TRACE, "%s: send_cmd_term==-1, arg1=%s\n", __func__, arg1); if (arg1[strlen(arg1) - 1] != ';' && strstr(arg1, "\\0x") == NULL && sscanf(arg1, "x%x x%x", &i1, &i2) != 2) { rig_debug(RIG_DEBUG_ERR, "%s: expecting binary hex string here, either x00 xff or \\0x00 \\0xff or x00xff\n", __func__); RETURNFUNC2(-RIG_EINVAL); } for (i = 0; i < BUFSZ - 1 && p != pp; i++) { rig_debug(RIG_DEBUG_ERR, "%s: p=%s\n", __func__, p); pp = p + 1; bufcmd[i] = strtol(p + 1, (char **) &p, 0); } /* must save length to allow 0x00 to be sent as part of a command */ cmd_len = i - 1; /* no End Of Message chars */ eom_buf[0] = '\0'; } else if (rig->caps->rig_model == RIG_MODEL_NETRIGCTL) { rig_debug(RIG_DEBUG_TRACE, "%s: we're netrigctl#2\n", __func__); //SNPRINTF(bufcmd, sizeof(bufcmd), "%s %s\n", cmd->cmd, arg1); if (cmd->cmd == 'w') { SNPRINTF(bufcmd, sizeof(bufcmd), "%c %s\n", cmd->cmd, arg1); } else { int nbytes = 0; int n = sscanf(arg2, "%d", &nbytes); if (n == 1) {SNPRINTF(bufcmd, sizeof(bufcmd), "%c %s %d\n", cmd->cmd, arg1, nbytes);} else {SNPRINTF(bufcmd, sizeof(bufcmd), "%c %s %s\n", cmd->cmd, arg1, arg2);} } cmd_len = strlen(bufcmd); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, len=%d\n", __func__, bufcmd, cmd_len); } else { char tmpbuf[64]; /* text protocol */ strncpy(bufcmd, arg1, BUFSZ - 1); strtok(bufcmd, "\0xa\0xd"); bufcmd[BUFSZ - 2] = '\0'; cmd_len = strlen(bufcmd); rig_debug(RIG_DEBUG_TRACE, "%s: bufcmd=%s\n", __func__, bufcmd); /* Automatic termination char */ if (send_cmd_term != 0) { bufcmd[cmd_len++] = send_cmd_term; } eom_buf[2] = send_cmd_term; SNPRINTF(tmpbuf, sizeof(tmpbuf), "0x%02x 0x%02x 0x%02x", eom_buf[0], eom_buf[1], eom_buf[2]); rig_debug(RIG_DEBUG_TRACE, "%s: text protocol, send_cmd_term=%s\n", __func__, tmpbuf); } rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%d, bufcmd=%s, cmd_len=%d\n", __func__, rp->fd, hasbinary(bufcmd, cmd_len) ? "BINARY" : bufcmd, cmd_len); set_transaction_active(rig); if (simulate) { rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", __func__, rig->caps->model_name); } else { rig_flush(rp); // we don't want the 'w' command to wait too long int save_retry = rp->retry; rp->retry = 0; retval = write_block(rp, (unsigned char *) bufcmd, cmd_len); rp->retry = save_retry; if (retval != RIG_OK) { rig_flush_force(rp, 1); set_transaction_inactive(rig); RETURNFUNC2(retval); } } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { rig_debug(RIG_DEBUG_TRACE, "%s: debug Cmd\n", __func__); fwrite(cmd->arg2, 1, strlen(cmd->arg2), fout); /* i.e. "Frequency" */ fwrite(": ", 1, 2, fout); /* i.e. "Frequency" */ } retval = 0; if (strstr(arg1, ";") || arg2[0] == ';') { char *p = strchr(arg1, ';'); while (p) { cmdcount++; p = strchr(p + 1, ';'); } // Kenwood, Yaeus, and similar eom_buf[0] = ';'; eom_buf[1] = 0; } else if (strstr(arg1, "xfd") || strstr(arg2, "xfd")) { char *s = strdup(arg1); toLowerCase(s); // ICOM answer terminator eom_buf[0] = 0xfd; eom_buf[1] = 0; char *p = strstr(s, "xfd"); while (p) { cmdcount++; p = strstr(p + 1, "xfd"); } free(s); } do { int hexval; rxbytes = BUFSZ; // leave room for CR if (arg2) // see if we have bytes or a hexval for terminating the 'W' command { sscanf(arg2, "%d", &rxbytes); if (sscanf(arg2, "\\0x%2x", &hexval) == 1) { eom_buf[0] = hexval; } } if (rxbytes > 0 && rxbytes != BUFSZ) { ++rxbytes; // need length + 1 for end of string eom_buf[0] = 0; } if (simulate) { if (retval == 0) { // Simulate a response by copying the command memcpy(buf, bufcmd, cmd_len); retval = cmd_len; } else { retval = 0; } } else { /* Assumes CR or LF is end of line char for all ASCII protocols. */ retval = read_string(rp, buf, rxbytes, eom_buf, strlen(eom_buf), 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error %s\n", __func__, rigerror(retval)); break; } } if (retval < BUFSZ) { buf[retval] = '\0'; } else { buf[BUFSZ - 1] = '\0'; } //if (rig->caps->rig_model != RIG_MODEL_NETRIGCTL) { // see if we have binary being returned binary = hasbinary((char *)buf, retval); } if (binary) // convert our buf to a hex representation { int i; char hex[8]; int hexbufbytes = retval * 6; char *hexbuf = calloc(hexbufbytes, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: sending binary, hexbuf size=%d\n", __func__, hexbufbytes); hexbuf[0] = 0; for (i = 0; i < retval; ++i) { SNPRINTF(hex, sizeof(hex), "\\0x%02X", (unsigned char)buf[i]); if ((strlen(hexbuf) + strlen(hex) + 1) >= hexbufbytes) { hexbufbytes *= 2; rig_debug(RIG_DEBUG_TRACE, "%s: doubling hexbuf size to %d\n", __func__, hexbufbytes); hexbuf = realloc(hexbuf, hexbufbytes); } strncat(hexbuf, hex, hexbufbytes - 1); } rig_flush_force(rp, 1); set_transaction_inactive(rig); rig_debug(RIG_DEBUG_TRACE, "%s: binary=%s, retval=%d\n", __func__, hexbuf, retval); fprintf(fout, "%s %d\n", hexbuf, retval); free(hexbuf); RETURNFUNC2(RIG_OK); } else { // we should be in printable ASCII here fprintf(fout, "%s%c", buf, cmdcount == 1 ? '\n' : '\0'); } } while ((retval > 0 && rxbytes == BUFSZ && eom_buf[0] != ';' && (unsigned char)eom_buf[0] != 0xfd) || --cmdcount > 1); rig_flush_force(rp, 1); set_transaction_inactive(rig); // we use fwrite in case of any nulls in binary return if (binary) { fwrite(buf, 1, retval, fout); } if (binary) { fwrite("\n", 1, 1, fout); } if (retval > 0 || retval == -RIG_ETIMEOUT) { retval = RIG_OK; } RETURNFUNC2(retval); } /* '0xf0'--test if rigctld called with -o|--vfo option */ declare_proto_rig(chk_vfo) { ENTERFUNC2; rig_debug(RIG_DEBUG_ERR, "%s: **********************************\n", __func__); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); /* i.e. "Frequency" */ } fprintf(fout, "%d\n", STATE(rig)->vfo_opt); chk_vfo_executed = 1; // this allows us to control dump_state version RETURNFUNC2(RIG_OK); } /* '(' -- turn vfo option on */ declare_proto_rig(set_vfo_opt) { int opt = 0; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &opt)); *vfo_opt = STATE(rig)->vfo_opt = opt; RETURNFUNC2(rig_set_vfo_opt(rig, opt)); } /* '0xf1'--halt rigctld daemon */ declare_proto_rig(halt) { /* a bit rough, TODO: clean daemon shutdown */ exit(0); return (RIG_OK); } /* '0x8c'--pause processing */ declare_proto_rig(pause) { unsigned seconds; CHKSCN1ARG(sscanf(arg1, "%u", &seconds)); sleep(seconds); return (RIG_OK); } int rigctld_password_check(RIG *rig, const char *md5) { int retval = -RIG_EINVAL; //fprintf(fout, "password %s\n", password); //rig_debug(RIG_DEBUG_TRACE, "%s: %s == %s\n", __func__, md5, rigctld_password); is_passwordOK = 0; char *mymd5 = rig_make_md5(rigctld_password); if (strcmp(md5, mymd5) == 0) { retval = RIG_OK; is_passwordOK = 1; } return (retval); } /* 0x98 */ declare_proto_rig(password) { int retval = -RIG_EPROTO; const char *key = arg1; ENTERFUNC2; if (is_rigctld) { retval = rigctld_password_check(rig, key); } else { retval = rig_password(rig, key); //retval = RIG_OK; } if (retval == RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: #1 password OK\n", __func__); //fprintf(fout, "Logged in\n"); } else { //rig_debug(RIG_DEBUG_ERR, "%s: password error, '%s'!='%s'\n", __func__, // key, rigctld_password); rig_debug(RIG_DEBUG_ERR, "%s: password error\n", __func__); } RETURNFUNC2(retval); } #if 0 // don't think we need this yet /* 0x99 */ declare_proto_rig(set_password) { const char *passwd = arg1; strncpy(rigctld_password, passwd, sizeof(passwd) - 1); rig_debug(RIG_DEBUG_ERR, "%s: set_password %s\n", __func__, rigctld_password); return (RIG_OK); } #endif /* '0x8d' */ declare_proto_rig(set_twiddle) { int seconds; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &seconds)); RETURNFUNC2(rig_set_twiddle(rig, seconds)); } /* '0x97' */ declare_proto_rig(set_uplink) { int val; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &val)); RETURNFUNC2(rig_set_uplink(rig, val)); } /* '0x8e' */ declare_proto_rig(get_twiddle) { int status; int seconds; ENTERFUNC2; status = rig_get_twiddle(rig, &seconds); if (status != RIG_OK) { RETURNFUNC2(status); } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d\n", seconds); RETURNFUNC2(status); } /* '0x95' */ declare_proto_rig(set_cache) { int ms; ENTERFUNC2; CHKSCN1ARG(sscanf(arg1, "%d", &ms)); RETURNFUNC2(rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, ms)); } /* '0x96' */ declare_proto_rig(get_cache) { int ms; ENTERFUNC2; ms = rig_get_cache_timeout_ms(rig, HAMLIB_CACHE_ALL); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d\n", ms); RETURNFUNC2(RIG_OK); } /* '0xf8' */ declare_proto_rig(set_clock) { int year, mon, day, hour = -1, min = -1, sec = 0; double msec = -1; int utc_offset = 0; int n; char timebuf[64]; ENTERFUNC2; if (arg1 && strcasecmp(arg1, "local") == 0) { date_strget(timebuf, sizeof(timebuf), 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: local time set = %s\n", __func__, timebuf); n = sscanf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%lf%d", &year, &mon, &day, &hour, &min, &sec, &msec, &utc_offset); } else if (arg1 && strcasecmp(arg1, "utc") == 0) { date_strget(timebuf, sizeof(timebuf), 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: utc time set = %s\n", __func__, timebuf); n = sscanf(timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%lf%d", &year, &mon, &day, &hour, &min, &sec, &msec, &utc_offset); } else if (arg1 && (arg1[16] == '+' || arg1[16] == '-')) { // YYYY-MM-DDTHH:MM+ZZ n = sscanf(arg1, "%04d-%02d-%02dT%02d:%02d%d", &year, &mon, &day, &hour, &min, &utc_offset); } else if (arg1 && (arg1[19] == '+' || arg1[19] == '-')) { // YYYY-MM-DDTHH:MM:SS+ZZ n = sscanf(arg1, "%04d-%02d-%02dT%02d:%02d:%02d%d", &year, &mon, &day, &hour, &min, &sec, &utc_offset); } else if (arg1 && (arg1[23] == '+' || arg1[23] == '-')) { // YYYY-MM-DDTHH:MM:SS.SSS+ZZ n = sscanf(arg1, "%04d-%02d-%02dT%02d:%02d:%02d%lf%d", &year, &mon, &day, &hour, &min, &sec, &msec, &utc_offset); } else { rig_debug(RIG_DEBUG_ERR, "%s: '%s' not valid time format\n", __func__, arg1); RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_VERBOSE, "%s: n=%d, %04d-%02d-%02dT%02d:%02d:%02d.%0.3f%s%02d\n", __func__, n, year, mon, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", (unsigned)abs(utc_offset)); if (abs(utc_offset) < 24) { utc_offset *= 100; } // allow for minutes offset too rig_debug(RIG_DEBUG_VERBOSE, "%s: utc_offset=%d\n", __func__, utc_offset); RETURNFUNC2(rig_set_clock(rig, year, mon, day, hour, min, sec, msec, utc_offset)); } /* '0xf9' */ declare_proto_rig(get_clock) { //char option[64]; int year, month, day, hour, min, sec, utc_offset, aoffset; int retval; double msec; ENTERFUNC2; //CHKSCN1ARG(sscanf(arg1, "%63s", option)); retval = rig_get_clock(rig, &year, &month, &day, &hour, &min, &sec, &msec, &utc_offset); aoffset = abs(utc_offset); fprintf(fout, "%04d-%02d-%02dT%02d:%02d:%06.3f%s%02d:%02d\n", year, month, day, hour, min, sec + msec / 1000, utc_offset >= 0 ? "+" : "-", aoffset / 100, aoffset % 100); return retval; } char rig_resp_sep = '\n'; /* '0xa0' */ declare_proto_rig(set_separator) { CHKSCN1ARG(sscanf(arg1, "%c", &rig_resp_sep)); rig_debug(RIG_DEBUG_ERR, "%s: arg1=%s, resp_sep=0x%x, %p\n", __func__, arg1, (unsigned int)rig_resp_sep, &rig_resp_sep); return RIG_OK; } /* '0xa1' */ declare_proto_rig(get_separator) { char buf[32]; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } sprintf(buf, "0x%x", rig_resp_sep); fprintf(fout, "%s\n", buf); return RIG_OK; } /* '0xa2' */ declare_proto_rig(set_lock_mode) { int lock; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); CHKSCN1ARG(sscanf(arg1, "%d", &lock)); if (is_rigctld) { rig_debug(RIG_DEBUG_ERR, "%s: rigctld lock\n", __func__); lock_mode = lock; retval = RIG_OK; } else { rig_debug(RIG_DEBUG_ERR, "%s: rig lock\n", __func__); retval = rig_set_lock_mode(rig, lock); } return retval; } /* '0xa3' */ declare_proto_rig(get_lock_mode) { int retval; int lock; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } if (is_rigctld) { rig_debug(RIG_DEBUG_ERR, "%s: rigctld lock\n", __func__); lock = lock_mode; retval = RIG_OK; } else { rig_debug(RIG_DEBUG_ERR, "%s: rig lock\n", __func__); retval = rig_get_lock_mode(rig, &lock); } if (retval != RIG_OK) { return retval; } fprintf(fout, "%d\n", lock); return RIG_OK; } static int parse_hex(const char *s, unsigned char *buf, int len) { int i = 0; buf[0] = 0; char *s2 = strdup(s); char *p = strtok(s2, ";:"); while (p) { unsigned int val; int n; if ((n = sscanf(p, "0x%2x", &val)) != 1) { n = sscanf(p, "x%2x", &val); } if (n == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse 0x??; or x??; from '%s'\n", __func__, s); } buf[i++] = val; p = strtok(NULL, ";:"); } free(s2); return i; } // sends whatever is in s -- no additions or changes done extern int netrigctl_send_raw(RIG *rig, char *s); /* 0xa4 */ declare_proto_rig(send_raw) { int result; int reply_len; unsigned char termbyte[1]; unsigned char *term = NULL; unsigned char buf[200]; unsigned char send[200]; unsigned char *sendp = (unsigned char *)arg2; int arg2_len = strlen(arg2); int is_binary = 0; int buf_len = sizeof(buf); int val = 0; if (rig->caps->rig_model == RIG_MODEL_NETRIGCTL) { char netbuf[1024]; int retval; snprintf(netbuf, sizeof(netbuf) - 1, "\\sendraw %s %s\n", arg2, arg3); rig_debug(RIG_DEBUG_ERR, "%s: calling netrigctl\n", __func__); retval = RIG_OK; return retval; } if (strcmp(arg1, ";") == 0) { termbyte[0] = ';'; term = termbyte; } else if (strcasecmp(arg1, "CR") == 0) { termbyte[0] = 0x0d; term = termbyte; } else if (strcasecmp(arg1, "LF") == 0) { termbyte[0] = 0x0a; term = termbyte; } else if (strcasecmp(arg1, "ICOM") == 0) { termbyte[0] = 0xfd; term = termbyte; } else if (sscanf(arg1, "0x%x", &val) == 1) { termbyte[0] = val; term = termbyte; } else if (sscanf(arg1, "%d", &val) == 1) { if (val < buf_len - 1) { // Reserve one byte more to allow padding with null buf_len = val + 1; } else { rig_debug(RIG_DEBUG_ERR, "%s: response length %d is larger than maximum of %d bytes", __func__, val, buf_len); return -RIG_EINVAL; } } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown arg1 val=%s, expected ';', 'CR', 'LF', 'ICOM', 0xFF (hex byte) or " "# of bytes where 0 means no reply and -1 means unknown", __func__, arg1); return -RIG_EINVAL; } if (strncmp(arg2, "0x", 2) == 0 || arg2[0] == 'x') { arg2_len = parse_hex(arg2, send, sizeof(send)); sendp = send; is_binary = 1; } rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); result = rig_send_raw(rig, (unsigned char *)sendp, arg2_len, buf, buf_len, term); if (result < 0) { return result; } reply_len = result; buf[buf_len + 1] = 0; // null terminate in case it's a string if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } if (reply_len == 0) { fprintf(fout, "No answer\n"); } else if (is_binary) { int i; for (i = 0; i < reply_len; ++i) { fprintf(fout, "0x%02x ", buf[i]); } fprintf(fout, "\n"); } else { fprintf(fout, "%s\n", buf); } return RIG_OK; } declare_proto_rig(cm108_get_bit) { rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); int gpio = -1; int bit = -1; // try GPIO format first int n = sscanf(arg1, "GPIO%d", &gpio); if (n == 0 || n == EOF) { n = sscanf(arg1, "%d", &gpio); } if (n != 1) { return -RIG_EINVAL; } int retval = rig_cm108_get_bit(PTTPORT(rig), gpio, &bit); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, strerror(retval)); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: gpio=%d\n", __func__, gpio); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d (simulated)\n", 1); return RIG_OK; } declare_proto_rig(cm108_set_bit) { rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); int gpio, bit = -1; // try GPIO format first int n = sscanf(arg1, "GPIO%d", &gpio); if (n == 0 || n == EOF) { n = sscanf(arg1, "%d", &gpio); } if (n != 1) { return -RIG_EINVAL; } n = sscanf(arg2, "%d", &bit); if (n != 1) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set gpio=%d, bit=%d\n", __func__, gpio, bit); int retval = rig_cm108_set_bit(PTTPORT(rig), gpio, bit); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, strerror(retval)); } return retval; } declare_proto_rig(get_conf) { int ret; rig_debug(RIG_DEBUG_ERR, "%s: \n", __func__); if (arg1 == NULL || arg1[0] == '?') { dumpconf_list(rig, stdout); debugmsgsave[0] = 0; debugmsgsave2[0] = 0; return RIG_OK; } hamlib_token_t mytoken = rig_token_lookup(rig, arg1); if (mytoken == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rig\n", __func__, arg1); ret = -RIG_EINVAL; } else { char value[4096]; // no max value known -- should we limit it? ret = rig_get_conf(rig, mytoken, value); if (ret != RIG_OK) { return ret; } fprintf(fout, "%s=%s\n", arg1, value); } return (ret); } declare_proto_rig(set_conf) { int ret; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (arg1[0] == '?') { dumpconf_list(rig, fout); debugmsgsave[0] = 0; debugmsgsave2[0] = 0; return RIG_OK; } hamlib_token_t mytoken = rig_token_lookup(rig, arg1); if (mytoken == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rig\n", __func__, arg1); ret = -RIG_EINVAL; } else { ret = rig_set_conf(rig, rig_token_lookup(rig, arg1), arg2); } return (ret); } hamlib-4.6.5/tests/ampctl_parse.h0000664000175000017500000000270115056640443012441 /* * ampctl_parse.h - (C) Stephane Fillod 2000-2008 * Derived from rotctl_parse.h - (C) Michael Black 2019 * * This program test/control an amplifier using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef AMPCTL_PARSE_H #define AMPCTL_PARSE_H #include #include /* * external prototype */ int dumpcaps_amp(const AMP *, FILE *); /* * Prototypes */ void usage_amp(FILE *); void version(); void list_models(); int print_conf_list(const struct confparams *cfp, rig_ptr_t data); int set_conf(AMP *my_amp, char *conf_parms); int ampctl_parse(AMP *my_amp, FILE *fin, FILE *fout, char *argv[], int argc); #endif /* AMPCTL_PARSE_H */ hamlib-4.6.5/tests/dumpcaps_rot.c0000664000175000017500000001752115056640443012470 /* * dumpcaps_rot.c - Copyright (C) 2000-2012 Stephane Fillod * This programs dumps the capabilities of a backend rig. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include "sprintflst.h" #include "rotator.h" #include "rotctl_parse.h" static int print_ext(ROT *rot, const struct confparams *cfp, rig_ptr_t ptr) { return print_ext_param(cfp, ptr); } /* * the rot may be in rot_init state, but not opened */ int dumpcaps_rot(ROT *rot, FILE *fout) { const struct rot_caps *caps; int backend_warnings = 0; static char prntbuf[1024]; if (!rot || !rot->caps) { return -RIG_EINVAL; } caps = rot->caps; fprintf(fout, "Caps dump for model:\t%d\n", caps->rot_model); fprintf(fout, "Model name:\t\t%s\n", caps->model_name); fprintf(fout, "Mfg name:\t\t%s\n", caps->mfg_name); fprintf(fout, "Backend version:\t%s\n", caps->version); fprintf(fout, "Backend copyright:\t%s\n", caps->copyright); fprintf(fout, "Backend status:\t\t%s\n", rig_strstatus(caps->status)); fprintf(fout, "Rot type:\t\t"); switch (caps->rot_type & ROT_TYPE_MASK) { case ROT_TYPE_OTHER: fprintf(fout, "Other\n"); break; case ROT_TYPE_AZIMUTH: fprintf(fout, "Azimuth\n"); break; case ROT_TYPE_ELEVATION: fprintf(fout, "Elevation\n"); break; case ROT_TYPE_AZEL: fprintf(fout, "Az-El\n"); break; default: fprintf(fout, "Unknown\n"); backend_warnings++; } fprintf(fout, "Port type:\t\t"); switch (caps->port_type) { case RIG_PORT_SERIAL: fprintf(fout, "RS-232\n"); fprintf(fout, "Serial speed:\t\t%d..%d bauds, %d%c%d, ctrl=%s\n", caps->serial_rate_min, caps->serial_rate_max, caps->serial_data_bits, caps->serial_parity == RIG_PARITY_NONE ? 'N' : caps->serial_parity == RIG_PARITY_ODD ? 'O' : caps->serial_parity == RIG_PARITY_EVEN ? 'E' : caps->serial_parity == RIG_PARITY_MARK ? 'M' : 'S', caps->serial_stop_bits, caps->serial_handshake == RIG_HANDSHAKE_NONE ? "NONE" : (caps->serial_handshake == RIG_HANDSHAKE_XONXOFF ? "XONXOFF" : "CTS/RTS") ); break; case RIG_PORT_PARALLEL: fprintf(fout, "Parallel\n"); break; case RIG_PORT_DEVICE: fprintf(fout, "Device driver\n"); break; case RIG_PORT_USB: fprintf(fout, "USB\n"); break; case RIG_PORT_NETWORK: fprintf(fout, "Network link\n"); break; case RIG_PORT_UDP_NETWORK: fprintf(fout, "UDP Network link\n"); break; case RIG_PORT_NONE: fprintf(fout, "None\n"); break; default: fprintf(fout, "Unknown\n"); backend_warnings++; } fprintf(fout, "Write delay:\t\t%dms, timeout %dms, %d retr%s\n", caps->write_delay, caps->timeout, caps->retry, (caps->retry == 1) ? "y" : "ies"); fprintf(fout, "Post write delay:\t%dms\n", caps->post_write_delay); if (ROTSTATE(rot)->has_status != 0) { rot_sprintf_status(prntbuf, sizeof(prntbuf), ROTSTATE(rot)->has_status); } else { strcpy(prntbuf, "None\n"); } fprintf(fout, "Status flags: %s\n", prntbuf); rot_sprintf_func(prntbuf, sizeof(prntbuf), caps->has_get_func); fprintf(fout, "Get functions: %s\n", prntbuf); rot_sprintf_func(prntbuf, sizeof(prntbuf), caps->has_set_func); fprintf(fout, "Set functions: %s\n", prntbuf); fprintf(fout, "Extra functions:\n"); rot_ext_func_foreach(rot, print_ext, fout); rot_sprintf_level_gran(prntbuf, sizeof(prntbuf), caps->has_get_level, caps->level_gran); fprintf(fout, "Get level: %s\n", prntbuf); rot_sprintf_level_gran(prntbuf, sizeof(prntbuf), caps->has_set_level, caps->level_gran); fprintf(fout, "Set level: %s\n", prntbuf); if (caps->has_set_level & ROT_LEVEL_READONLY_LIST) { fprintf(fout, "Warning--backend can set readonly levels!\n"); backend_warnings++; } fprintf(fout, "Extra levels:\n"); rot_ext_level_foreach(rot, print_ext, fout); rot_sprintf_parm_gran(prntbuf, sizeof(prntbuf), caps->has_get_parm, caps->parm_gran); fprintf(fout, "Get parameters: %s\n", prntbuf); rot_sprintf_parm_gran(prntbuf, sizeof(prntbuf), caps->has_set_parm, caps->parm_gran); fprintf(fout, "Set parameters: %s\n", prntbuf); if (caps->has_set_parm & ROT_PARM_READONLY_LIST) { fprintf(fout, "Warning--backend can set readonly parms!\n"); backend_warnings++; } fprintf(fout, "Extra parameters:\n"); rot_ext_parm_foreach(rot, print_ext, fout); fprintf(fout, "Min Azimuth:\t\t%.2f\n", caps->min_az); fprintf(fout, "Max Azimuth:\t\t%.2f\n", caps->max_az); fprintf(fout, "Min Elevation:\t\t%.2f\n", caps->min_el); fprintf(fout, "Max Elevation:\t\t%.2f\n", caps->max_el); fprintf(fout, "Has priv data:\t\t%c\n", caps->priv != NULL ? 'Y' : 'N'); /* * Status is either 'Y'es, 'E'mulated, 'N'o * * TODO: keep me up-to-date with API call list! */ fprintf(fout, "Has Init:\t\t%c\n", caps->rot_init != NULL ? 'Y' : 'N'); fprintf(fout, "Has Cleanup:\t\t%c\n", caps->rot_cleanup != NULL ? 'Y' : 'N'); fprintf(fout, "Has Open:\t\t%c\n", caps->rot_open != NULL ? 'Y' : 'N'); fprintf(fout, "Has Close:\t\t%c\n", caps->rot_close != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Conf:\t\t%c\n", caps->set_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Conf:\t\t%c\n", caps->get_conf != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Position:\t%c\n", caps->set_position != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Position:\t%c\n", caps->get_position != NULL ? 'Y' : 'N'); fprintf(fout, "Can Stop:\t\t%c\n", caps->stop != NULL ? 'Y' : 'N'); fprintf(fout, "Can Park:\t\t%c\n", caps->park != NULL ? 'Y' : 'N'); fprintf(fout, "Can Reset:\t\t%c\n", caps->reset != NULL ? 'Y' : 'N'); fprintf(fout, "Can Move:\t\t%c\n", caps->move != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Info:\t\t%c\n", caps->get_info != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Status:\t\t%c\n", caps->get_status != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Func:\t%c\n", caps->set_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Func:\t%c\n", caps->get_func != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Level:\t%c\n", caps->set_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Level:\t%c\n", caps->get_level != NULL ? 'Y' : 'N'); fprintf(fout, "Can set Param:\t%c\n", caps->set_parm != NULL ? 'Y' : 'N'); fprintf(fout, "Can get Param:\t%c\n", caps->get_parm != NULL ? 'Y' : 'N'); fprintf(fout, "\nOverall backend warnings: %d\n", backend_warnings); return backend_warnings; } int dumpconf_list(ROT *rot, FILE *fout) { rot_token_foreach(rot, print_conf_list, rot); return 0; } hamlib-4.6.5/tests/ampctl.c0000664000175000017500000003204415056640443011245 /* * ampctl.c - (C) Stephane Fillod 2000-2010 * (C) Nate Bargmann 2003,2007,2010,2011,2012,2013 * (C) The Hamlib Group 2002,2006 * (C) Derived from rotctl.c Michael Black W9MDB 2019 * * This program tests/controls an amplifier using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # include # define HST_SHRT_OPTS "iI" # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ #else /* no history */ # define HST_SHRT_OPTS "" #endif /* HAVE_READLINE_HISTORY */ #include #include "ampctl_parse.h" #include "amplist.h" #include "rig.h" /* * Prototypes */ void usage(); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "+m:r:s:C:t:LvhVluZ" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"amp-file", 1, 0, 'r'}, {"serial-speed", 1, 0, 's'}, {"send-cmd-term", 1, 0, 't'}, {"list", 0, 0, 'l'}, {"set-conf", 1, 0, 'C'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"debug-time-stamps", 0, 0, 'Z'}, #ifdef HAVE_READLINE_HISTORY {"read-history", 0, 0, 'i'}, {"save-history", 0, 0, 'I'}, #endif {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; #define MAXCONFLEN 2048 int interactive = 1; /* if no cmd on command line, switch to interactive */ int prompt = 1; /* Print prompt in ampctl */ char send_cmd_term = '\r'; /* send_cmd termination char */ int main(int argc, char *argv[]) { AMP *my_amp; /* handle to amp (instance) */ amp_model_t my_model = AMP_MODEL_DUMMY; int retcode; /* generic return code from functions */ int exitcode; int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; #ifdef HAVE_READLINE_HISTORY int rd_hist = 0; int sv_hist = 0; const char *hist_dir = NULL; const char hist_file[] = "/.ampctl_history"; char *hist_path = NULL; #endif /* HAVE_READLINE_HISTORY */ const char *amp_file = NULL; int serial_rate = 0; char conf_parms[MAXCONFLEN] = ""; while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS HST_SHRT_OPTS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } amp_file = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (strlen(optarg) > 1) { send_cmd_term = strtol(optarg, NULL, 0); } else { send_cmd_term = optarg[0]; } break; #ifdef HAVE_READLINE_HISTORY case 'i': rd_hist++; break; case 'I': sv_hist++; break; #endif /* HAVE_READLINE_HISTORY */ case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': rig_set_debug(0); list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "ampctl %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); /* * at least one command on command line, * disable interactive mode */ if (optind < argc) { interactive = 0; } my_amp = amp_init(my_model); if (!my_amp) { fprintf(stderr, "Unknown amp num %d, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } char *token = strtok(conf_parms, ","); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = amp_token_lookup(my_amp, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = amp_set_conf(my_amp, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } token = strtok(NULL, ","); } if (amp_file) { strncpy(AMPPORT(my_amp)->pathname, amp_file, HAMLIB_FILPATHLEN - 1); strncpy(AMPSTATE(my_amp)->ampport_deprecated.pathname, amp_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { AMPPORT(my_amp)->parm.serial.rate = serial_rate; AMPSTATE(my_amp)->ampport_deprecated.parm.serial.rate = serial_rate; } /* * print out conf parameters */ if (show_conf) { amp_token_foreach(my_amp, print_conf_list, (rig_ptr_t)my_amp); } /* * Print out capabilities, and exits immediately as we may be interested * only in caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps_amp(my_amp, stdout); amp_cleanup(my_amp); /* if you care about memory */ exit(0); } retcode = amp_open(my_amp); if (retcode != RIG_OK) { fprintf(stderr, "amp_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened amp model %d, '%s'\n", my_amp->caps->amp_model, my_amp->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_amp->caps->version, rig_strstatus(my_amp->caps->status)); exitcode = 0; #ifdef HAVE_LIBREADLINE if (interactive && prompt) { rl_readline_name = "ampctl"; #ifdef HAVE_READLINE_HISTORY using_history(); /* Initialize Readline History */ if (rd_hist || sv_hist) { int hist_path_size; struct stat hist_dir_stat; if (!(hist_dir = getenv("AMPCTL_HIST_DIR"))) { hist_dir = getenv("HOME"); } if (((stat(hist_dir, &hist_dir_stat) == -1) && (errno == ENOENT)) || !(S_ISDIR(hist_dir_stat.st_mode))) { fprintf(stderr, "Warning: %s is not a directory!\n", hist_dir); } hist_path_size = sizeof(char) * (strlen(hist_dir) + strlen(hist_file) + 1); hist_path = (char *)calloc(hist_path_size, sizeof(char)); SNPRINTF(hist_path, hist_path_size, "%s%s", hist_dir, hist_file); } if (rd_hist && hist_path) { if (read_history(hist_path) == ENOENT) { fprintf(stderr, "Warning: Could not read history from %s\n", hist_path); } } #endif /* HAVE_READLINE_HISTORY */ } #endif /* HAVE_LIBREADLINE */ do { retcode = ampctl_parse(my_amp, stdin, stdout, argv, argc); if (retcode == 2) { exitcode = 2; } } while (retcode == 0 || retcode == 2); if (interactive && prompt) { #ifdef HAVE_READLINE_HISTORY if (sv_hist && hist_path) { if (write_history(hist_path) == ENOENT) { fprintf(stderr, "\nWarning: Could not write history to %s\n", hist_path); } } if ((rd_hist || sv_hist) && hist_path) { free(hist_path); hist_path = (char *)NULL; } #endif /* HAVE_READLINE_HISTORY */ } amp_close(my_amp); /* close port */ amp_cleanup(my_amp); /* if you care about memory */ return exitcode; } void usage() { printf("Usage: ampctl [OPTION]... [COMMAND]...\n" "Send COMMANDs to a connected amplifier.\n\n"); printf( " -m, --model=ID select amplifier model number. See model list (-l)\n" " -r, --amp-file=DEVICE set device of the amplifier to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -t, --send-cmd-term=CHAR set send_cmd command termination char\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" #ifdef HAVE_READLINE_HISTORY " -i, --read-history read prior interactive session history\n" " -I, --save-history save current interactive session history\n" #endif " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" " - read commands from standard input\n" "\n" ); usage_amp(stdout); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rigctl_parse.h0000664000175000017500000000351115056640443012445 /* * rigctl_parse.h - (C) Stephane Fillod 2000-2010 * * This program test/control a radio using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef RIGCTL_PARSE_H #define RIGCTL_PARSE_H #include #include #define RIGCTL_PARSE_END 1 #define RIGCTL_PARSE_ERROR 2 /* * external prototype */ int dumpcaps(RIG *, FILE *); int dumpstate(RIG *, FILE *); int dumpconf(RIG *, FILE *); int dumpconf_list(RIG *, FILE *); /* * Prototypes */ void usage_rig(FILE *); void version(); void list_models(); int dump_chan(FILE *, RIG *, channel_t *); int print_conf_list(const struct confparams *cfp, rig_ptr_t data); int print_conf_list2(const struct confparams *cfp, rig_ptr_t data); int set_conf(RIG *my_rig, char *conf_parms); typedef void (*sync_cb_t)(int); int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc, sync_cb_t sync_cb, int interactive, int prompt, int * vfo_mode, char send_cmd_term, int * ext_resp_ptr, char * resp_sep_ptr, int use_password); #endif /* RIGCTL_PARSE_H */ hamlib-4.6.5/tests/rigctlcom.c0000664000175000017500000014452115056640443011754 /* * rigctlcom.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2008,2010,2011,2012,2013 * (C) Michael Black W9MDB 2018 - derived from rigctld.c * (C) The Hamlib Group 2012 * * This program is a TS-2000 emulator * It takes TS-2000 commands on the -R comport and sends them to the rig * on the -r comport. The -R port speed can be set with -S and always runs 8N1 * This allows programs that can do a TS-2000-over-serial-port to talk * to any rig that hamlib supports. * Also supports rigctld or flrig for multiple connections (i.e. rig sharing). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #ifdef WIN32 #define WIN32_LEAN_AND_MEAN // cppcheck-suppress * #include #endif // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include #ifdef HAVE_NETINET_IN_H // cppcheck-suppress * # include #endif #ifdef HAVE_ARPA_INET_H // cppcheck-suppress * # include #endif #ifdef HAVE_SYS_SOCKET_H // cppcheck-suppress * # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #include #include "misc.h" #include "iofunc.h" #include "rigctl_parse.h" #include "riglist.h" /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "B:m:r:R:p:d:P:D:s:S:c:C:lLuvhVZ" static struct option long_options[] = { {"mapa2b", 0, 0, 'B'}, {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"rig-file2", 1, 0, 'R'}, {"ptt-file", 1, 0, 'p'}, {"dcd-file", 1, 0, 'd'}, {"ptt-type", 1, 0, 'P'}, {"dcd-type", 1, 0, 'D'}, {"serial-speed", 1, 0, 's'}, {"serial-speed2", 1, 0, 'S'}, {"civaddr", 1, 0, 'c'}, {"set-conf", 1, 0, 'C'}, {"list", 0, 0, 'l'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"debug-time-stamps", 0, 0, 'Z'}, {0, 0, 0, 0} }; void usage(); static int handle_ts2000(void *arg); static RIG *my_rig; /* handle to rig */ static hamlib_port_t my_com; /* handle to virtual COM port */ static int verbose; /* CW Skimmer can only set VFOA */ /* IC7300 for example can run VFOA on FM and VFOB on CW */ /* So -A/--mapa2b changes set_freq on VFOA to VFOB */ /* This allows working CW Skimmer in split mode and transmit on VFOB */ static int mapa2b; /* maps set_freq on VFOA to VFOB instead */ static int kwidth; #ifdef HAVE_SIG_ATOMIC_T static sig_atomic_t volatile ctrl_c; #else static int volatile ctrl_c; #endif #define MAXCONFLEN 2048 #if 0 # ifdef WIN32 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { rig_debug(RIG_DEBUG_VERBOSE, "CtrlHandler called\n"); switch (fdwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: ctrl_c = 1; return TRUE; default: return FALSE; } } # else static void signal_handler(int sig) { switch (sig) { case SIGINT: ctrl_c = 1; break; default: /* do nothing */ break; } } # endif /* ifdef WIN32 */ #endif /* if 0 */ #if 0 static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; # ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } # else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); # endif /* ifdef __MINGW32__ */ } #endif /* if 0 */ int main(int argc, char *argv[]) { rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int show_conf = 0; int dump_caps_opt = 0; const char *rig_file = NULL, *rig_file2 = NULL, *ptt_file = NULL, *dcd_file = NULL; ptt_type_t ptt_type = RIG_PTT_NONE; dcd_type_t dcd_type = RIG_DCD_NONE; int serial_rate = 0; int serial_rate2 = 115200; /* virtual com port default speed */ char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; int status; printf("rigctlcom Version 1.6\n"); while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': rig_version(); exit(0); case 'B': mapa2b = 1; break; case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'R': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file2 = optarg; break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; case 'd': if (!optarg) { usage(); /* wrong arg count */ exit(1); } dcd_file = optarg; break; case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "CM108")) { ptt_type = RIG_PTT_CM108; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { ptt_type = atoi(optarg); } break; case 'D': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { dcd_type = RIG_DCD_RIG; } else if (!strcmp(optarg, "DSR")) { dcd_type = RIG_DCD_SERIAL_DSR; } else if (!strcmp(optarg, "CTS")) { dcd_type = RIG_DCD_SERIAL_CTS; } else if (!strcmp(optarg, "CD")) { dcd_type = RIG_DCD_SERIAL_CAR; } else if (!strcmp(optarg, "PARALLEL")) { dcd_type = RIG_DCD_PARALLEL; } else if (!strcmp(optarg, "NONE")) { dcd_type = RIG_DCD_NONE; } else { dcd_type = atoi(optarg); } break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'S': if (!optarg) { usage(); /* wrong arg count */ exit(1); } serial_rate2 = atoi(optarg); break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': rig_set_debug(verbose); list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "%s, %s\n", "rigctlcom", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); if (argc == 1) { usage(); exit(2); } my_rig = rig_init(my_model); if (!my_rig) { fprintf(stderr, "Unknown rig num %d, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } #if 0 retcode = -RIG_ENIMPL; retcode = set_conf(my_rig, conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } #endif if (my_model > 5 && !rig_file) { fprintf(stderr, "-r rig com port not provided\n"); exit(2); } if (rig_file) { strncpy(RIGPORT(my_rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } if (!rig_file2) { fprintf(stderr, "-R com port not provided\n"); exit(2); } strncpy(my_com.pathname, rig_file2, HAMLIB_FILPATHLEN - 1); /* * ex: RIG_PTT_PARALLEL and /dev/parport0 */ if (ptt_type != RIG_PTT_NONE) { PTTPORT(my_rig)->type.ptt = ptt_type; } if (dcd_type != RIG_DCD_NONE) { DCDPORT(my_rig)->type.dcd = dcd_type; } if (ptt_file) { strncpy(PTTPORT(my_rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); } if (dcd_file) { strncpy(DCDPORT(my_rig)->pathname, dcd_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(my_rig)->parm.serial.rate = serial_rate; } if (serial_rate2 != 0) { my_com.parm.serial.rate = serial_rate2; } if (civaddr) { rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); } /* * print out conf parameters */ if (show_conf) { rig_token_foreach(my_rig, print_conf_list, (rig_ptr_t)my_rig); } /* * print out conf parameters, and exits immediately * We may be interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps(my_rig, stdout); rig_cleanup(my_rig); /* if you care about memory */ exit(0); } /* open and close rig connection to check early for issues */ retcode = rig_open(my_rig); if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); /* * main loop */ my_com.type.rig = RIG_PORT_SERIAL; my_com.parm.serial.data_bits = 8; my_com.parm.serial.stop_bits = 1; my_com.timeout = 5000; my_com.parm.serial.parity = RIG_PARITY_NONE; my_com.parm.serial.handshake = RIG_HANDSHAKE_NONE; status = port_open(&my_com); if (status != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "Unable to open %s\n", my_com.pathname); exit(2); } if (verbose > 0) { fprintf(stderr, " %s opened for application program\n", my_com.pathname); } do { char ts2000[1024]; char *stop_set = ";\n\r"; memset(ts2000, 0, sizeof(ts2000)); status = read_string(&my_com, (unsigned char *) ts2000, sizeof(ts2000), stop_set, strlen(stop_set), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: status=%d\n", __func__, status); if (strlen(ts2000) > 0) { int retval = handle_ts2000(ts2000); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); } } } while (retcode == 0 && !ctrl_c); rig_debug(RIG_DEBUG_VERBOSE, "%s: rigctlcom exiting, retcode=%d, ctrl_c=%d\n", __func__, retcode, ctrl_c); rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ return 0; } static rmode_t ts2000_get_mode() { rmode_t mode; pbwidth_t width; rig_get_mode(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), &mode, &width); kwidth = width; #if 0 // Perhaps we should emulate a rig that has PKT modes instead?? int kwidth_ssb[] = { 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; int kwidth_am[] = { 10, 100, 200, 500 }; // still need to cover packet filter 00=wide, 01=nar switch (mode) { case RIG_MODE_LSB: mode = 1; kwidth = kwidth_ssb[width]; break; case RIG_MODE_USB: mode = 2; kwidth = kwidth_ssb[width]; break; case RIG_MODE_CW: mode = 3; kwidth = kwidth_am[width]; break; // is this correct? case RIG_MODE_FM: mode = 4; kwidth = kwidth_ssb[width]; break; case RIG_MODE_AM: mode = 5; kwidth = kwidth_am[width]; break; case RIG_MODE_RTTY: mode = 6; kwidth = kwidth_ssb[width]; break; case RIG_MODE_CWR: mode = 7; kwidth = kwidth_am[width]; break; // is this correct? case RIG_MODE_NONE: mode = 8; kwidth = kwidth_am[width]; break; // is this correct? case RIG_MODE_RTTYR: mode = 9; kwidth = kwidth_ssb[width]; break; case RIG_MODE_PKTUSB: mode = 2; kwidth = kwidth_ssb[width]; break; // need to change to a TS_2000 mode case RIG_MODE_PKTLSB: mode = 1; kwidth = kwidth_ssb[width]; break; // need to change to a TS_2000 mode default: mode = 0; break; } #else // Perhaps we should emulate a rig that has PKT modes instead?? //int kwidth_ssb[] = { 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; //int kwidth_am[] = { 10, 100, 200, 500 }; // still need to cover packet filter 00=wide, 01=nar switch (mode) { case RIG_MODE_LSB: mode = 1; break; case RIG_MODE_USB: mode = 2; break; case RIG_MODE_CW: mode = 3; break; // is this correct? case RIG_MODE_FM: mode = 4; break; case RIG_MODE_AM: mode = 5; break; case RIG_MODE_RTTY: mode = 6; break; case RIG_MODE_CWR: mode = 7; break; // is this correct? case RIG_MODE_NONE: mode = 8; break; // is this correct? case RIG_MODE_RTTYR: mode = 9; break; case RIG_MODE_PKTUSB: mode = 2; break; // need to change to a TS_2000 mode case RIG_MODE_PKTLSB: mode = 1;; break; // need to change to a TS_2000 mode default: mode = 0; break; } #endif return mode; } static int write_block2(void *func, hamlib_port_t *p, const char *txbuffer, size_t count) { int retval = write_block(p, (unsigned char *) txbuffer, count); hl_usleep(5000); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); } return retval; } /* * This handles the TS-2000 emulation */ static int handle_ts2000(void *arg) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, (char *)arg); // Handle all the queries if (strcmp(arg, "ID;") == 0) { char *reply = "ID019;"; return write_block2((void *)__func__, &my_com, reply, strlen(reply)); } if (strcmp(arg, "AI;") == 0) { char *reply = "AI0;"; return write_block2((void *)__func__, &my_com, reply, strlen(reply)); } else if (strcmp(arg, "IF;") == 0) { freq_t freq; // P1(11) int freq_step = 10; // P2(4) just use default value for now //int rit_xit_freq = 0; // P3(6) dummy value for now int rit = 0; // P4(1) dummy value for now int xit = 0; // P5(1) dummy value for now int bank1 = 0; // P6(1) dummy value for now int bank2 = 0; // P7(2) dummy value for now ptt_t ptt; // P8(1) rmode_t mode; // P9(1) vfo_t vfo; // P10(1) int scan = 0; // P11(1) dummy value for now split_t split = 0; // P12(1) int p13 = 0; // P13(1) Tone dummy value for now int p14 = 0; // P14(2) Tone Freq dummy value for now int p15 = 0; // P15(1) Shift status dummy value for now int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), &freq); char response[64]; char *fmt = // cppcheck-suppress * "IF%011"PRIll"%04d %1d%1d%1d%02d%1d%1"PRIll"%1d%1d%1d%1d%02d%1d;"; if (retval != RIG_OK) { return retval; } mode = ts2000_get_mode(); retval = rig_get_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), &ptt); if (retval != RIG_OK) { return retval; } // we need to know split status -- don't care about the vfo retval = rig_get_split_vfo(my_rig, RIG_VFO_CURR, &split, &vfo); if (retval != RIG_OK) { return retval; } retval = rig_get_vfo(my_rig, &vfo); if (retval != RIG_OK) { vfo = RIG_VFO_A; #if 0 // so we work with rigs (like Icom) that have no get_vfo return retval; #endif } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: case RIG_VFO_MAIN_A: case RIG_VFO_SUB_A: vfo = 0; break; case RIG_VFO_B: case RIG_VFO_SUB: case RIG_VFO_MAIN_B: case RIG_VFO_SUB_B: vfo = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected vfo=%d\n", __func__, vfo); } SNPRINTF(response, sizeof(response), fmt, (uint64_t)freq, freq_step, rit, xit, bank1, bank2, ptt, mode, vfo, scan, split, p13, p14, p15); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "MD;") == 0) { rmode_t mode = ts2000_get_mode(); char response[32]; SNPRINTF(response, sizeof(response), "MD%1d;", (int)mode); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "AG0;") == 0) { char response[32]; SNPRINTF(response, sizeof(response), "AG0000;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "FA;") == 0) { freq_t freq = 0; char response[32]; int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get freqA failed: %s\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "FA%011"PRIll";", (uint64_t)freq); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "FB;") == 0) { char response[32]; freq_t freq = 0; int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get freqB failed: %s\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "FB%011"PRIll";", (uint64_t)freq); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "SA;") == 0) { char response[32]; SNPRINTF(response, sizeof(response), "SA0;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "RX;") == 0) { char response[32]; rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), 0); SNPRINTF(response, sizeof(response), "RX0;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } // Now some commands to set things else if (strncmp(arg, "SA", 2) == 0) { if (strcmp(arg, "SA;") == 0) { // should we silently fail with RIG_OK instead? TBD return (-RIG_ENIMPL); } if (strlen(arg) > 3 && ((char *)arg)[2] == '1') { if (my_rig->caps->has_set_func) { int retval = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, ((char *)arg)[2] == '1' ? 1 : 0); return retval; } else { return (-RIG_ENAVAIL); } } return RIG_OK; } else if (strcmp(arg, "TX;") == 0) { return rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), 1); } else if (strcmp(arg, "AI0;") == 0) { // nothing to do return RIG_OK; } else if (strcmp(arg, ";") == 0) { // nothing to do return RIG_OK; } else if (strcmp(arg, "FR0;") == 0) { return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split)); } else if (strcmp(arg, "FR1;") == 0) { return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split)); } else if (strcmp(arg, "FR;") == 0) { char response[32]; vfo_t vfo; int retval = rig_get_vfo(my_rig, &vfo); int nvfo = 0; if (retval != RIG_OK) { vfo = RIG_VFO_A; #if 0 // so we work with rigs (like Icom) that have no get_vfo rig_debug(RIG_DEBUG_ERR, "%s: get vfo failed: %s\n", __func__, rigerror(retval)); return retval; #endif } if (vfo == vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split)) { nvfo = 0; } else if (vfo == vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split)) { nvfo = 1; } else { retval = -RIG_EPROTO; return retval; } SNPRINTF(response, sizeof(response), "FR%c;", nvfo + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); return retval; } else if (strcmp(arg, "FT;") == 0) { char response[32]; vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split); split_t split; int nvfo = 0; int retval = rig_get_split_vfo(my_rig, vfo_curr, &split, &vfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get split vfo failed: %s\n", __func__, rigerror(retval)); return retval; } if (vfo == vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split)) { nvfo = 0; } else if (vfo == vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split)) { nvfo = 1; } else { retval = -RIG_EPROTO; return retval; } SNPRINTF(response, sizeof(response), "FT%c;", nvfo + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); return retval; } else if (strcmp(arg, "TN;") == 0) { char response[32]; tone_t val; int retval = rig_get_ctcss_tone(my_rig, RIG_VFO_CURR, &val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_func XIT failed: %s\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "TN%02d;", val); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "TN", 2) == 0) { tone_t val; int ival = 0; int retval; sscanf(arg, "TN%d", &ival); val = ival; retval = rig_set_ctcss_tone(my_rig, RIG_VFO_CURR, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_ctcss_tone failed: %s\n", __func__, rigerror(retval)); } return retval; } else if (strcmp(arg, "PA;") == 0) { char response[32]; int valA; int retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), RIG_FUNC_AIP, &valA); int valB; if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_func preamp A failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), RIG_FUNC_AIP, &valB); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_func preamp B failed: %s\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "PA%c%c;", valA + '0', valB + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "PA", 2) == 0) { int valA = 0; int valB = 0; int retval; int n = sscanf(arg, "PA%1d%1d", &valA, &valB); if (n != 2) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing preamp cmd '%s'\n", __func__, (char *)arg); } retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), RIG_FUNC_AIP, valA); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_func preamp failed: %s\n", __func__, rigerror(retval)); return retval; } retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), RIG_FUNC_AIP, valB); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_func preamp failed: %s\n", __func__, rigerror(retval)); return retval; } return retval; } else if (strcmp(arg, "XT;") == 0) { char response[32]; int val; int retval = rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_XIT, &val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_func XIT failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } SNPRINTF(response, sizeof(response), "XT%c;", val + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "XT", 2) == 0) { int val = 0; int retval; sscanf(arg, "XT%d", &val); retval = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_XIT, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_func XIT failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *response = "?;"; return write_block2((void *)__func__, &my_com, response, strlen(response)); } } return retval; } else if (strcmp(arg, "NR;") == 0) { char response[32]; int val; int retval = rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NR, &val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get NR failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } SNPRINTF(response, sizeof(response), "NR%c;", val + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "NR", 2) == 0) { int val = 0; int retval; sscanf(arg, "NR%d", &val); retval = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NR, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set NR failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } } return retval; } else if (strcmp(arg, "NB;") == 0) { char response[32]; int val; int retval = rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NB, &val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get func NB failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } SNPRINTF(response, sizeof(response), "NB%c;", val + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "NB", 2) == 0) { int val = 0; int retval = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NB, val); sscanf(arg, "NB%d", &val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_ant failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } } return retval; } else if (strcmp(arg, "AG;") == 0) { value_t val; int retval = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AF, &val); char response[32]; int level; if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_level AF failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } level = val.f * 255; SNPRINTF(response, sizeof(response), "AG0%03d;", level); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "AG", 2) == 0) { int level = 0; int n = sscanf(arg, "AG%d", &level); int retval; value_t val; if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: af level cmd parse failed: %s\n", __func__, (char *)arg); return -RIG_EPROTO; } val.f = level / 255.0; retval = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AF, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_level AF failed: %s\n", __func__, rigerror(retval)); } return retval; } else if (strcmp(arg, "PR;") == 0) { char response[32]; value_t val; int retval = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_COMP, &val); int speechLevel; if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_level speech processor failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } speechLevel = val.f * 255; SNPRINTF(response, sizeof(response), "PR%03d;", speechLevel); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "PR", 2) == 0) { value_t val; int speechLevel = 0; int n = sscanf(arg, "PR%d", &speechLevel); int retval; if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: speech level cmd parse failed: %s\n", __func__, (char *)arg); return -RIG_EPROTO; } val.f = speechLevel / 255.0; retval = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_COMP, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_level AGC failed: %s\n", __func__, rigerror(retval)); } if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } else if (strcmp(arg, "GT;") == 0) { value_t val; int retval = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AGC, &val); char response[32]; int agcLevel; if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_level AGC failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } agcLevel = val.f * 255; SNPRINTF(response, sizeof(response), "GT%03d;", agcLevel); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "GT", 2) == 0) { int agcLevel = 0; int n = sscanf(arg, "GT%d", &agcLevel); int retval; value_t val; if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: AGC cmd parse failed: %s\n", __func__, (char *)arg); return -RIG_EPROTO; } val.f = agcLevel / 255.0; retval = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AGC, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_level AGC failed: %s\n", __func__, rigerror(retval)); } return retval; } else if (strcmp(arg, "SQ;") == 0) { char response[32]; value_t val; int retval = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_SQL, &val); int sqlev; if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_level squelch failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } return retval; } sqlev = val.f * 255; SNPRINTF(response, sizeof(response), "SQ%03d;", sqlev); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "SQ", 2) == 0) { int sqlev = 0; int n = sscanf(arg, "SQ%d", &sqlev); int retval; value_t val; if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: squelch cmd parse failed: %s\n", __func__, (char *)arg); return -RIG_EPROTO; } val.f = sqlev / 255.0; retval = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_SQL, val); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_level squelch failed: %s\n", __func__, rigerror(retval)); if (retval == -RIG_ENIMPL || retval == -RIG_ENAVAIL) { char *responsetmp = "?;"; return write_block2((void *)__func__, &my_com, responsetmp, strlen(responsetmp)); } } return retval; } else if (strcmp(arg, "DC;") == 0) { vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split); split_t split; char response[32]; int retval = rig_get_split_vfo(my_rig, vfo_curr, &split, &vfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get split vfo failed: %s\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "DC%c;", split + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); return retval; } else if (strncmp(arg, "DC", 2) == 0) { vfo_t vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split); split_t split; int isplit; int retval; char response[32]; // Expecting DCnn -- but we don't care about the control param int n = sscanf(arg, "DC%d", &isplit); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing '%s'\n", __func__, (char *)arg); return -RIG_EPROTO; } split = isplit; retval = rig_set_split_vfo(my_rig, vfo_curr, split, RIG_VFO_SUB); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig set split vfo failed '%s'\n", __func__, rigerror(retval)); return retval; } SNPRINTF(response, sizeof(response), "DC%c;", split + '0'); return write_block2((void *)__func__, &my_com, response, strlen(response)); return retval; } else if (strcmp(arg, "FT0;") == 0) { return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), vfo_fixup(my_rig, RIG_VFO_A, CACHE(my_rig)->split), 0); } else if (strcmp(arg, "FT1;") == 0) { return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), 0); } else if (strncmp(arg, "FA0", 3) == 0) { freq_t freq; vfo_t vfo = RIG_VFO_A; if (mapa2b) { vfo = RIG_VFO_B; } sscanf((char *)arg + 2, "%"SCNfreq, &freq); return rig_set_freq(my_rig, vfo_fixup(my_rig, vfo, CACHE(my_rig)->split), freq); } else if (strncmp(arg, "FB0", 3) == 0) { freq_t freq; sscanf((char *)arg + 2, "%"SCNfreq, &freq); return rig_set_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B, CACHE(my_rig)->split), freq); } else if (strncmp(arg, "MD", 2) == 0) { mode_t mode = 0; int imode = 0; sscanf((char *)arg + 2, "%d", &imode); switch (imode) { case 0: mode = RIG_MODE_NONE; break; case 1: mode = RIG_MODE_LSB ; break; case 2: mode = RIG_MODE_USB; break; case 3: mode = RIG_MODE_CW; break; case 4: mode = RIG_MODE_AM; break; case 5: mode = RIG_MODE_FM; break; case 6: mode = RIG_MODE_RTTY; break; case 7: mode = RIG_MODE_CWR; break; case 8: mode = RIG_MODE_NONE; break; case 9: mode = RIG_MODE_RTTYR; break; } rig_set_mode(my_rig, RIG_VFO_A, mode, -1); } else if (strcmp(arg, "PS1;") == 0) { return RIG_OK; } else if (strcmp(arg, "PS0;") == 0) { return RIG_OK; } else if (strncmp(arg, "PS", 2) == 0) { char response[32]; SNPRINTF(response, sizeof(response), "PS1;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "SM0;") == 0) { int retval; value_t value; char response[32]; retval = rig_get_level(my_rig, RIG_VFO_A, RIG_LEVEL_STRENGTH, &value); if (retval != RIG_OK) { SNPRINTF(response, sizeof(response), "SM00000;"); } else { SNPRINTF(response, sizeof(response), "SM0%04d;", value.i * 3); rig_debug(RIG_DEBUG_ERR, "SM response=%d\n", value.i); } return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "SM1;") == 0) { int retval; value_t value; char response[32]; retval = rig_get_level(my_rig, RIG_VFO_B, RIG_LEVEL_STRENGTH, &value); if (retval != RIG_OK) { SNPRINTF(response, sizeof(response), "SM10000;"); } else { SNPRINTF(response, sizeof(response), "SM1%04d;", value.i * 3); rig_debug(RIG_DEBUG_ERR, "SM response=%d\n", value.i); } return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "KS;") == 0) { int retval; value_t value; char response[32]; retval = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_KEYSPD, &value); if (retval != RIG_OK) { SNPRINTF(response, sizeof(response), "KS010;"); } else { rig_debug(RIG_DEBUG_ERR, "KS response=%d\n", value.i); } return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strcmp(arg, "SL;") == 0) { char response[32]; SNPRINTF(response, sizeof(response), "SL%02d;", kwidth); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else if (strncmp(arg, "SB", 2) == 0 || strncmp(arg, "AC", 2) == 0 || strncmp(arg, "AM", 2) == 0 || strncmp(arg, "AN", 2) == 0 || strncmp(arg, "BC", 2) == 0 || strncmp(arg, "CA", 2) == 0 || strncmp(arg, "CT", 2) == 0 || strncmp(arg, "DQ", 2) == 0 || strncmp(arg, "FS", 2) == 0 || strncmp(arg, "LT", 2) == 0 || strncmp(arg, "NL", 2) == 0 || strncmp(arg, "NT", 2) == 0 || strncmp(arg, "LK", 2) == 0 || strncmp(arg, "MF", 2) == 0 || strncmp(arg, "MG", 2) == 0 || strncmp(arg, "PC", 2) == 0 || strncmp(arg, "RA", 2) == 0 || strncmp(arg, "RG", 2) == 0 || strncmp(arg, "RL", 2) == 0 || strncmp(arg, "SC", 2) == 0 || strncmp(arg, "SH", 2) == 0 || strncmp(arg, "TN", 2) == 0 || strncmp(arg, "TO", 2) == 0 || strncmp(arg, "TS", 2) == 0 || strncmp(arg, "VX", 2) == 0 ) { char response[32]; SNPRINTF(response, sizeof(response), "?;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } else { rig_debug(RIG_DEBUG_ERR, "*********************************\n%s: unknown cmd='%s'\n", __func__, (char *)arg); return -RIG_EINVAL; } // Handle all the settings return RIG_OK; } void usage() { char *name = "rigctlcom"; printf("Usage: %s -m rignumber -r comport -s baud -R comport [OPTIONS]...\n\n" "A TS-2000 emulator for rig sharing with programs that don't support Hamlib or FLRig to be able\n" "to use a connected radio transceiver or receiver with FLRig or rigctld via Hamlib.\n\n", name); printf("Example: Using FLRig with virtual COM5/COM6 and other program:\n"); printf("\t%s -m 4 -R COM5 -S 115200\n\n", name); printf("Other program would connect to COM6 and use TS-2000 115200 8N1\n\n"); printf("See the %s.1 manual page for complete details.\n\n", name); printf( " -m, --model=ID select radio model number. See model list (-l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -R, --rig-file2=DEVICE set device of the virtual com port to operate on\n" " -p, --ptt-file=DEVICE set device of the PTT device to operate on\n" " -d, --dcd-file=DEVICE set device of the DCD device to operate on\n" " -P, --ptt-type=TYPE set type of the PTT device to operate on\n" " -D, --dcd-type=TYPE set type of the DCD device to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -S, --serial-speed2=BAUD set serial speed of the virtual com port [default=115200]\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -B, --mapa2b map set_freq on VFOA to VFOB -- useful for CW Skimmer\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n" ); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rigtestmcastrx.c0000664000175000017500000000463215056640443013052 #include #include #include #include #include #ifdef _WIN32 #include #include //#pragma does not work on mingw //#pragma comment(lib, "Ws2_32.lib") #else #include #include #include #include #endif #define MCAST_PORT 4532 #define MCAST_ADDR "224.0.0.1" #define BUFFER_SIZE 4096 int main() { int sock; struct sockaddr_in mcast_addr; char buffer[BUFFER_SIZE]; int bytes_received; #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { fprintf(stderr, "WSAStartup failed: %d\n", WSAGetLastError()); return 1; } #endif if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("socket() failed"); exit(EXIT_FAILURE); } // Set the SO_REUSEADDR option to allow multiple processes to use the same address int optval = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) < 0) { //rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno)); //return -RIG_EIO; return 1; } memset(&mcast_addr, 0, sizeof(mcast_addr)); mcast_addr.sin_family = AF_INET; mcast_addr.sin_port = htons(MCAST_PORT); mcast_addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr)) < 0) { perror("bind() failed"); exit(EXIT_FAILURE); } struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { perror("setsockopt() failed"); exit(EXIT_FAILURE); } while (1) { bytes_received = recvfrom(sock, buffer, BUFFER_SIZE, 0, NULL, 0); if (bytes_received < 0) { perror("recvfrom() failed"); break; } buffer[bytes_received] = '\0'; printf("%s\n", buffer); } // Drop membership before closing the socket if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { perror("setsockopt() failed"); } close(sock); #ifdef _WIN32 WSACleanup(); #endif return 0; } hamlib-4.6.5/tests/testfreq.c0000664000175000017500000000305615056640443011623 /* * Very simple test program to check freq conversion --SF * This is mainly to test kHz, MHz, GHz macros and int64_t support. */ #include #include #include #include #include "misc.h" int main(int argc, char *argv[]) { freq_t f = 0; #if 0 if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } f = atoi(argv[1]); #endif printf("%s\n", hamlib_version); printf("caps size: %lu\n", (long unsigned) sizeof(struct rig_caps)); printf("state size: %lu\n", (long unsigned) sizeof(struct rig_state)); printf("RIG size: %lu\n", (long unsigned) sizeof(RIG)); printf("freq_t size: %lu\n", (long unsigned) sizeof(freq_t)); printf("shortfreq_t size: %lu\n", (long unsigned) sizeof(shortfreq_t)); /* freq on 31bits test */ f = GHz(2); // cppcheck-suppress * printf("GHz(2) = %"PRIll"\n", (int64_t)f); /* freq on 32bits test */ f = GHz(4); printf("GHz(4) = %"PRIll"\n", (int64_t)f); /* freq on >32bits test */ f = GHz(5); printf("GHz(5) = %"PRIll"\n", (int64_t)f); /* floating point to freq conversion test */ f = GHz(1.3); printf("GHz(1.3) = %"PRIll"\n", (int64_t)f); /* floating point to freq conversion precision test */ f = GHz(1.234567890); printf("GHz(1.234567890) = %"PRIll"\n", (int64_t)f); /* floating point to freq conversion precision test, with freq >32bits */ f = GHz(123.456789012); printf("GHz(123.456789012) = %"PRIll"\n", (int64_t)f); return 0; } hamlib-4.6.5/tests/Makefile.in0000664000175000017500000046412515056640454011701 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = rigctl$(EXEEXT) rigctld$(EXEEXT) rigmem$(EXEEXT) \ rigsmtr$(EXEEXT) rigswr$(EXEEXT) rotctl$(EXEEXT) \ rotctld$(EXEEXT) rigctlcom$(EXEEXT) rigctltcp$(EXEEXT) \ rigctlsync$(EXEEXT) ampctl$(EXEEXT) ampctld$(EXEEXT) \ rigtestmcast$(EXEEXT) rigtestmcastrx$(EXEEXT) $(am__EXEEXT_1) \ rigfreqwalk$(EXEEXT) check_PROGRAMS = dumpmem$(EXEEXT) testrig$(EXEEXT) \ testrigopen$(EXEEXT) testrigcaps$(EXEEXT) testtrn$(EXEEXT) \ testbcd$(EXEEXT) testfreq$(EXEEXT) listrigs$(EXEEXT) \ testloc$(EXEEXT) rig_bench$(EXEEXT) testcache$(EXEEXT) \ cachetest$(EXEEXT) cachetest2$(EXEEXT) testcookie$(EXEEXT) \ testgrid$(EXEEXT) hamlibmodels$(EXEEXT) testmW2power$(EXEEXT) \ test2038$(EXEEXT) @HTML_MATRIX_TRUE@EXTRA_PROGRAMS = rigmatrix$(EXEEXT) subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @HAVE_LIBUSB_TRUE@am__EXEEXT_1 = rigtestlibusb$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__objects_1 = ampctl-ampctl_parse.$(OBJEXT) \ ampctl-dumpcaps_amp.$(OBJEXT) am_ampctl_OBJECTS = ampctl-ampctl.$(OBJEXT) $(am__objects_1) ampctl_OBJECTS = $(am_ampctl_OBJECTS) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) ampctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = ampctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ampctl_CFLAGS) $(CFLAGS) \ $(ampctl_LDFLAGS) $(LDFLAGS) -o $@ am__objects_2 = ampctld-ampctl_parse.$(OBJEXT) \ ampctld-dumpcaps_amp.$(OBJEXT) am_ampctld_OBJECTS = ampctld-ampctld.$(OBJEXT) $(am__objects_2) ampctld_OBJECTS = $(am_ampctld_OBJECTS) ampctld_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) ampctld_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ampctld_CFLAGS) \ $(CFLAGS) $(ampctld_LDFLAGS) $(LDFLAGS) -o $@ cachetest_SOURCES = cachetest.c cachetest_OBJECTS = cachetest.$(OBJEXT) cachetest_LDADD = $(LDADD) cachetest_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) cachetest2_SOURCES = cachetest2.c cachetest2_OBJECTS = cachetest2.$(OBJEXT) cachetest2_LDADD = $(LDADD) cachetest2_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) dumpmem_SOURCES = dumpmem.c dumpmem_OBJECTS = dumpmem.$(OBJEXT) dumpmem_LDADD = $(LDADD) dumpmem_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) hamlibmodels_SOURCES = hamlibmodels.c hamlibmodels_OBJECTS = hamlibmodels.$(OBJEXT) hamlibmodels_LDADD = $(LDADD) hamlibmodels_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) listrigs_SOURCES = listrigs.c listrigs_OBJECTS = listrigs.$(OBJEXT) listrigs_LDADD = $(LDADD) listrigs_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rig_bench_SOURCES = rig_bench.c rig_bench_OBJECTS = rig_bench.$(OBJEXT) rig_bench_LDADD = $(LDADD) rig_bench_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am__objects_3 = rigctl-rigctl_parse.$(OBJEXT) \ rigctl-dumpcaps.$(OBJEXT) rigctl-dumpstate.$(OBJEXT) \ rigctl-rig_tests.$(OBJEXT) am_rigctl_OBJECTS = rigctl-rigctl.$(OBJEXT) $(am__objects_3) rigctl_OBJECTS = $(am_rigctl_OBJECTS) rigctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) rigctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rigctl_LDFLAGS) $(LDFLAGS) -o $@ am__objects_4 = rigctlcom-rigctl_parse.$(OBJEXT) \ rigctlcom-dumpcaps.$(OBJEXT) rigctlcom-dumpstate.$(OBJEXT) \ rigctlcom-rig_tests.$(OBJEXT) am_rigctlcom_OBJECTS = rigctlcom-rigctlcom.$(OBJEXT) $(am__objects_4) rigctlcom_OBJECTS = $(am_rigctlcom_OBJECTS) rigctlcom_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) rigctlcom_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigctlcom_CFLAGS) \ $(CFLAGS) $(rigctlcom_LDFLAGS) $(LDFLAGS) -o $@ am__objects_5 = rigctld-rigctl_parse.$(OBJEXT) \ rigctld-dumpcaps.$(OBJEXT) rigctld-dumpstate.$(OBJEXT) \ rigctld-rig_tests.$(OBJEXT) am_rigctld_OBJECTS = rigctld-rigctld.$(OBJEXT) $(am__objects_5) rigctld_OBJECTS = $(am_rigctld_OBJECTS) rigctld_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) rigctld_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigctld_CFLAGS) \ $(CFLAGS) $(rigctld_LDFLAGS) $(LDFLAGS) -o $@ am__objects_6 = rigctlsync-rigctl_parse.$(OBJEXT) \ rigctlsync-dumpcaps.$(OBJEXT) rigctlsync-dumpstate.$(OBJEXT) \ rigctlsync-rig_tests.$(OBJEXT) am_rigctlsync_OBJECTS = rigctlsync-rigctlsync.$(OBJEXT) \ $(am__objects_6) rigctlsync_OBJECTS = $(am_rigctlsync_OBJECTS) rigctlsync_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) rigctlsync_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigctlsync_CFLAGS) \ $(CFLAGS) $(rigctlsync_LDFLAGS) $(LDFLAGS) -o $@ am__objects_7 = rigctltcp-rigctl_parse.$(OBJEXT) \ rigctltcp-dumpcaps.$(OBJEXT) rigctltcp-dumpstate.$(OBJEXT) \ rigctltcp-rig_tests.$(OBJEXT) am_rigctltcp_OBJECTS = rigctltcp-rigctltcp.$(OBJEXT) $(am__objects_7) rigctltcp_OBJECTS = $(am_rigctltcp_OBJECTS) rigctltcp_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) rigctltcp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigctltcp_CFLAGS) \ $(CFLAGS) $(rigctltcp_LDFLAGS) $(LDFLAGS) -o $@ rigfreqwalk_SOURCES = rigfreqwalk.c rigfreqwalk_OBJECTS = rigfreqwalk.$(OBJEXT) rigfreqwalk_LDADD = $(LDADD) rigfreqwalk_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rigmatrix_SOURCES = rigmatrix.c rigmatrix_OBJECTS = rigmatrix.$(OBJEXT) rigmatrix_LDADD = $(LDADD) rigmatrix_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rigmatrix_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rigmatrix_LDFLAGS) $(LDFLAGS) -o $@ am_rigmem_OBJECTS = rigmem-rigmem.$(OBJEXT) rigmem-memsave.$(OBJEXT) \ rigmem-memload.$(OBJEXT) rigmem-memcsv.$(OBJEXT) rigmem_OBJECTS = $(am_rigmem_OBJECTS) rigmem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) rigmem_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigmem_CFLAGS) $(CFLAGS) \ $(rigmem_LDFLAGS) $(LDFLAGS) -o $@ am_rigsmtr_OBJECTS = rigsmtr.$(OBJEXT) rigsmtr_OBJECTS = $(am_rigsmtr_OBJECTS) rigsmtr_LDADD = $(LDADD) rigsmtr_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rigsmtr_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rigsmtr_LDFLAGS) $(LDFLAGS) -o $@ am_rigswr_OBJECTS = rigswr.$(OBJEXT) rigswr_OBJECTS = $(am_rigswr_OBJECTS) rigswr_LDADD = $(LDADD) rigswr_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rigswr_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rigswr_LDFLAGS) $(LDFLAGS) -o $@ am__rigtestlibusb_SOURCES_DIST = rigtestlibusb.c @HAVE_LIBUSB_TRUE@am_rigtestlibusb_OBJECTS = \ @HAVE_LIBUSB_TRUE@ rigtestlibusb-rigtestlibusb.$(OBJEXT) rigtestlibusb_OBJECTS = $(am_rigtestlibusb_OBJECTS) @HAVE_LIBUSB_TRUE@rigtestlibusb_DEPENDENCIES = $(am__DEPENDENCIES_1) rigtestlibusb_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rigtestlibusb_CFLAGS) \ $(CFLAGS) $(rigtestlibusb_LDFLAGS) $(LDFLAGS) -o $@ rigtestmcast_SOURCES = rigtestmcast.c rigtestmcast_OBJECTS = rigtestmcast.$(OBJEXT) rigtestmcast_LDADD = $(LDADD) rigtestmcast_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) rigtestmcastrx_SOURCES = rigtestmcastrx.c rigtestmcastrx_OBJECTS = rigtestmcastrx.$(OBJEXT) rigtestmcastrx_LDADD = $(LDADD) rigtestmcastrx_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am__objects_8 = rotctl-rotctl_parse.$(OBJEXT) \ rotctl-dumpcaps_rot.$(OBJEXT) am_rotctl_OBJECTS = rotctl-rotctl.$(OBJEXT) $(am__objects_8) rotctl_OBJECTS = $(am_rotctl_OBJECTS) rotctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) rotctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rotctl_CFLAGS) $(CFLAGS) \ $(rotctl_LDFLAGS) $(LDFLAGS) -o $@ am__objects_9 = rotctld-rotctl_parse.$(OBJEXT) \ rotctld-dumpcaps_rot.$(OBJEXT) am_rotctld_OBJECTS = rotctld-rotctld.$(OBJEXT) $(am__objects_9) rotctld_OBJECTS = $(am_rotctld_OBJECTS) rotctld_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) rotctld_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rotctld_CFLAGS) \ $(CFLAGS) $(rotctld_LDFLAGS) $(LDFLAGS) -o $@ test2038_SOURCES = test2038.c test2038_OBJECTS = test2038.$(OBJEXT) test2038_LDADD = $(LDADD) test2038_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testbcd_SOURCES = testbcd.c testbcd_OBJECTS = testbcd.$(OBJEXT) testbcd_LDADD = $(LDADD) testbcd_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testcache_SOURCES = testcache.c testcache_OBJECTS = testcache.$(OBJEXT) testcache_LDADD = $(LDADD) testcache_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testcookie_SOURCES = testcookie.c testcookie_OBJECTS = testcookie.$(OBJEXT) testcookie_LDADD = $(LDADD) testcookie_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testfreq_SOURCES = testfreq.c testfreq_OBJECTS = testfreq.$(OBJEXT) testfreq_LDADD = $(LDADD) testfreq_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testgrid_SOURCES = testgrid.c testgrid_OBJECTS = testgrid.$(OBJEXT) testgrid_LDADD = $(LDADD) testgrid_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testloc_SOURCES = testloc.c testloc_OBJECTS = testloc.$(OBJEXT) testloc_LDADD = $(LDADD) testloc_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testmW2power_SOURCES = testmW2power.c testmW2power_OBJECTS = testmW2power.$(OBJEXT) testmW2power_LDADD = $(LDADD) testmW2power_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testrig_SOURCES = testrig.c testrig_OBJECTS = testrig.$(OBJEXT) testrig_LDADD = $(LDADD) testrig_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testrigcaps_SOURCES = testrigcaps.c testrigcaps_OBJECTS = testrigcaps.$(OBJEXT) testrigcaps_LDADD = $(LDADD) testrigcaps_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testrigopen_SOURCES = testrigopen.c testrigopen_OBJECTS = testrigopen.$(OBJEXT) testrigopen_LDADD = $(LDADD) testrigopen_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) testtrn_SOURCES = testtrn.c testtrn_OBJECTS = testtrn.$(OBJEXT) testtrn_LDADD = $(LDADD) testtrn_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ampctl-ampctl.Po \ ./$(DEPDIR)/ampctl-ampctl_parse.Po \ ./$(DEPDIR)/ampctl-dumpcaps_amp.Po \ ./$(DEPDIR)/ampctld-ampctl_parse.Po \ ./$(DEPDIR)/ampctld-ampctld.Po \ ./$(DEPDIR)/ampctld-dumpcaps_amp.Po ./$(DEPDIR)/cachetest.Po \ ./$(DEPDIR)/cachetest2.Po ./$(DEPDIR)/dumpmem.Po \ ./$(DEPDIR)/hamlibmodels.Po ./$(DEPDIR)/listrigs.Po \ ./$(DEPDIR)/rig_bench.Po ./$(DEPDIR)/rigctl-dumpcaps.Po \ ./$(DEPDIR)/rigctl-dumpstate.Po \ ./$(DEPDIR)/rigctl-rig_tests.Po ./$(DEPDIR)/rigctl-rigctl.Po \ ./$(DEPDIR)/rigctl-rigctl_parse.Po \ ./$(DEPDIR)/rigctlcom-dumpcaps.Po \ ./$(DEPDIR)/rigctlcom-dumpstate.Po \ ./$(DEPDIR)/rigctlcom-rig_tests.Po \ ./$(DEPDIR)/rigctlcom-rigctl_parse.Po \ ./$(DEPDIR)/rigctlcom-rigctlcom.Po \ ./$(DEPDIR)/rigctld-dumpcaps.Po \ ./$(DEPDIR)/rigctld-dumpstate.Po \ ./$(DEPDIR)/rigctld-rig_tests.Po \ ./$(DEPDIR)/rigctld-rigctl_parse.Po \ ./$(DEPDIR)/rigctld-rigctld.Po \ ./$(DEPDIR)/rigctlsync-dumpcaps.Po \ ./$(DEPDIR)/rigctlsync-dumpstate.Po \ ./$(DEPDIR)/rigctlsync-rig_tests.Po \ ./$(DEPDIR)/rigctlsync-rigctl_parse.Po \ ./$(DEPDIR)/rigctlsync-rigctlsync.Po \ ./$(DEPDIR)/rigctltcp-dumpcaps.Po \ ./$(DEPDIR)/rigctltcp-dumpstate.Po \ ./$(DEPDIR)/rigctltcp-rig_tests.Po \ ./$(DEPDIR)/rigctltcp-rigctl_parse.Po \ ./$(DEPDIR)/rigctltcp-rigctltcp.Po ./$(DEPDIR)/rigfreqwalk.Po \ ./$(DEPDIR)/rigmatrix.Po ./$(DEPDIR)/rigmem-memcsv.Po \ ./$(DEPDIR)/rigmem-memload.Po ./$(DEPDIR)/rigmem-memsave.Po \ ./$(DEPDIR)/rigmem-rigmem.Po ./$(DEPDIR)/rigsmtr.Po \ ./$(DEPDIR)/rigswr.Po \ ./$(DEPDIR)/rigtestlibusb-rigtestlibusb.Po \ ./$(DEPDIR)/rigtestmcast.Po ./$(DEPDIR)/rigtestmcastrx.Po \ ./$(DEPDIR)/rotctl-dumpcaps_rot.Po \ ./$(DEPDIR)/rotctl-rotctl.Po \ ./$(DEPDIR)/rotctl-rotctl_parse.Po \ ./$(DEPDIR)/rotctld-dumpcaps_rot.Po \ ./$(DEPDIR)/rotctld-rotctl_parse.Po \ ./$(DEPDIR)/rotctld-rotctld.Po ./$(DEPDIR)/test2038.Po \ ./$(DEPDIR)/testbcd.Po ./$(DEPDIR)/testcache.Po \ ./$(DEPDIR)/testcookie.Po ./$(DEPDIR)/testfreq.Po \ ./$(DEPDIR)/testgrid.Po ./$(DEPDIR)/testloc.Po \ ./$(DEPDIR)/testmW2power.Po ./$(DEPDIR)/testrig.Po \ ./$(DEPDIR)/testrigcaps.Po ./$(DEPDIR)/testrigopen.Po \ ./$(DEPDIR)/testtrn.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(ampctl_SOURCES) $(ampctld_SOURCES) cachetest.c \ cachetest2.c dumpmem.c hamlibmodels.c listrigs.c rig_bench.c \ $(rigctl_SOURCES) $(rigctlcom_SOURCES) $(rigctld_SOURCES) \ $(rigctlsync_SOURCES) $(rigctltcp_SOURCES) rigfreqwalk.c \ rigmatrix.c $(rigmem_SOURCES) $(rigsmtr_SOURCES) \ $(rigswr_SOURCES) $(rigtestlibusb_SOURCES) rigtestmcast.c \ rigtestmcastrx.c $(rotctl_SOURCES) $(rotctld_SOURCES) \ test2038.c testbcd.c testcache.c testcookie.c testfreq.c \ testgrid.c testloc.c testmW2power.c testrig.c testrigcaps.c \ testrigopen.c testtrn.c DIST_SOURCES = $(ampctl_SOURCES) $(ampctld_SOURCES) cachetest.c \ cachetest2.c dumpmem.c hamlibmodels.c listrigs.c rig_bench.c \ $(rigctl_SOURCES) $(rigctlcom_SOURCES) $(rigctld_SOURCES) \ $(rigctlsync_SOURCES) $(rigctltcp_SOURCES) rigfreqwalk.c \ rigmatrix.c $(rigmem_SOURCES) $(rigsmtr_SOURCES) \ $(rigswr_SOURCES) $(am__rigtestlibusb_SOURCES_DIST) \ rigtestmcast.c rigtestmcastrx.c $(rotctl_SOURCES) \ $(rotctld_SOURCES) test2038.c testbcd.c testcache.c \ testcookie.c testfreq.c testgrid.c testloc.c testmW2power.c \ testrig.c testrigcaps.c testrigopen.c testtrn.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ $$am__collect_skipped_logs \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(IGNORE_SKIPPED_LOGS)'; then \ am__collect_skipped_logs='--collect-skipped-logs no'; \ else \ am__collect_skipped_logs=''; \ fi; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/test-driver README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @HAVE_LIBUSB_FALSE@TESTLIBUSB = # For some reason this "if" is not working -- rigtestlibusb is still being included # Fix for now is to change rigtestlibusb.c instead @HAVE_LIBUSB_TRUE@TESTLIBUSB = rigtestlibusb DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h dumpcaps.h ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h dumpcaps_rot.h AMPCOMMONSRC = ampctl_parse.c ampctl_parse.h dumpcaps_amp.c uthash.h rigctl_SOURCES = rigctl.c $(RIGCOMMONSRC) rigctld_SOURCES = rigctld.c $(RIGCOMMONSRC) rigctlcom_SOURCES = rigctlcom.c $(RIGCOMMONSRC) rigctltcp_SOURCES = rigctltcp.c $(RIGCOMMONSRC) rigctlsync_SOURCES = rigctlsync.c $(RIGCOMMONSRC) rotctl_SOURCES = rotctl.c $(ROTCOMMONSRC) rotctld_SOURCES = rotctld.c $(ROTCOMMONSRC) ampctl_SOURCES = ampctl.c $(AMPCOMMONSRC) ampctld_SOURCES = ampctld.c $(AMPCOMMONSRC) rigswr_SOURCES = rigswr.c rigsmtr_SOURCES = rigsmtr.c rigmem_SOURCES = rigmem.c memsave.c memload.c memcsv.c @HAVE_LIBUSB_TRUE@rigtestlibusb_SOURCES = rigtestlibusb.c # include generated include files ahead of any in sources rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) -I$(top_builddir)/security $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) -lm rigmem_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src rigctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src -I$(top_builddir)/security rotctl_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src rotctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src ampctl_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src ampctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src rigctlcom_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security rigctltcp_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security rigctlsync_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security @HAVE_LIBUSB_TRUE@rigtestlibusb_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(LIBUSB_CFLAGS) #testsecurity_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src -I$(top_builddir)/security rigctl_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) rigctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rotctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rotctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) ampctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) ampctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigmem_LDADD = $(LIBXML2_LIBS) $(LDADD) rigctlcom_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigctltcp_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigctlsync_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) @HAVE_LIBUSB_TRUE@rigtestlibusb_LDADD = $(LIBUSB_LIBS) # Linker options rigctl_LDFLAGS = $(WINEXELDFLAGS) rigswr_LDFLAGS = $(WINEXELDFLAGS) rigsmtr_LDFLAGS = $(WINEXELDFLAGS) rigmem_LDFLAGS = $(WINEXELDFLAGS) rotctl_LDFLAGS = $(WINEXELDFLAGS) ampctl_LDFLAGS = $(WINEXELDFLAGS) rigctld_LDFLAGS = $(WINEXELDFLAGS) rotctld_LDFLAGS = $(WINEXELDFLAGS) ampctld_LDFLAGS = $(WINEXELDFLAGS) rigctlcom_LDFLAGS = $(WINEXELDFLAGS) rigctltcp_LDFLAGS = $(WINEXELDFLAGS) rigctlsync_LDFLAGS = $(WINEXELDFLAGS) @HAVE_LIBUSB_TRUE@rigtestlibusb_LDFLAGS = $(WINEXELDFLAGS) # rigmatrix needs libgd @HTML_MATRIX_TRUE@rigmatrix_LDFLAGS = -lgd -lz EXTRA_DIST = rigmatrix_head.html rig_split_lst.awk testctld.pl testrotctld.pl # Support 'make check' target for simple tests check_SCRIPTS = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh testgrid.sh test2038.sh TESTS = $(check_SCRIPTS) CLEANFILES = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh rigtestlibusb build-w32.sh build-w64.sh build-w64-jtsdk.sh testgrid.sh testrigcaps.sh test2038.sh tuner_control.log all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: $(am__rm_f) $(bin_PROGRAMS) test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) clean-checkPROGRAMS: $(am__rm_f) $(check_PROGRAMS) test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=) ampctl$(EXEEXT): $(ampctl_OBJECTS) $(ampctl_DEPENDENCIES) $(EXTRA_ampctl_DEPENDENCIES) @rm -f ampctl$(EXEEXT) $(AM_V_CCLD)$(ampctl_LINK) $(ampctl_OBJECTS) $(ampctl_LDADD) $(LIBS) ampctld$(EXEEXT): $(ampctld_OBJECTS) $(ampctld_DEPENDENCIES) $(EXTRA_ampctld_DEPENDENCIES) @rm -f ampctld$(EXEEXT) $(AM_V_CCLD)$(ampctld_LINK) $(ampctld_OBJECTS) $(ampctld_LDADD) $(LIBS) cachetest$(EXEEXT): $(cachetest_OBJECTS) $(cachetest_DEPENDENCIES) $(EXTRA_cachetest_DEPENDENCIES) @rm -f cachetest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cachetest_OBJECTS) $(cachetest_LDADD) $(LIBS) cachetest2$(EXEEXT): $(cachetest2_OBJECTS) $(cachetest2_DEPENDENCIES) $(EXTRA_cachetest2_DEPENDENCIES) @rm -f cachetest2$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cachetest2_OBJECTS) $(cachetest2_LDADD) $(LIBS) dumpmem$(EXEEXT): $(dumpmem_OBJECTS) $(dumpmem_DEPENDENCIES) $(EXTRA_dumpmem_DEPENDENCIES) @rm -f dumpmem$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dumpmem_OBJECTS) $(dumpmem_LDADD) $(LIBS) hamlibmodels$(EXEEXT): $(hamlibmodels_OBJECTS) $(hamlibmodels_DEPENDENCIES) $(EXTRA_hamlibmodels_DEPENDENCIES) @rm -f hamlibmodels$(EXEEXT) $(AM_V_CCLD)$(LINK) $(hamlibmodels_OBJECTS) $(hamlibmodels_LDADD) $(LIBS) listrigs$(EXEEXT): $(listrigs_OBJECTS) $(listrigs_DEPENDENCIES) $(EXTRA_listrigs_DEPENDENCIES) @rm -f listrigs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(listrigs_OBJECTS) $(listrigs_LDADD) $(LIBS) rig_bench$(EXEEXT): $(rig_bench_OBJECTS) $(rig_bench_DEPENDENCIES) $(EXTRA_rig_bench_DEPENDENCIES) @rm -f rig_bench$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rig_bench_OBJECTS) $(rig_bench_LDADD) $(LIBS) rigctl$(EXEEXT): $(rigctl_OBJECTS) $(rigctl_DEPENDENCIES) $(EXTRA_rigctl_DEPENDENCIES) @rm -f rigctl$(EXEEXT) $(AM_V_CCLD)$(rigctl_LINK) $(rigctl_OBJECTS) $(rigctl_LDADD) $(LIBS) rigctlcom$(EXEEXT): $(rigctlcom_OBJECTS) $(rigctlcom_DEPENDENCIES) $(EXTRA_rigctlcom_DEPENDENCIES) @rm -f rigctlcom$(EXEEXT) $(AM_V_CCLD)$(rigctlcom_LINK) $(rigctlcom_OBJECTS) $(rigctlcom_LDADD) $(LIBS) rigctld$(EXEEXT): $(rigctld_OBJECTS) $(rigctld_DEPENDENCIES) $(EXTRA_rigctld_DEPENDENCIES) @rm -f rigctld$(EXEEXT) $(AM_V_CCLD)$(rigctld_LINK) $(rigctld_OBJECTS) $(rigctld_LDADD) $(LIBS) rigctlsync$(EXEEXT): $(rigctlsync_OBJECTS) $(rigctlsync_DEPENDENCIES) $(EXTRA_rigctlsync_DEPENDENCIES) @rm -f rigctlsync$(EXEEXT) $(AM_V_CCLD)$(rigctlsync_LINK) $(rigctlsync_OBJECTS) $(rigctlsync_LDADD) $(LIBS) rigctltcp$(EXEEXT): $(rigctltcp_OBJECTS) $(rigctltcp_DEPENDENCIES) $(EXTRA_rigctltcp_DEPENDENCIES) @rm -f rigctltcp$(EXEEXT) $(AM_V_CCLD)$(rigctltcp_LINK) $(rigctltcp_OBJECTS) $(rigctltcp_LDADD) $(LIBS) rigfreqwalk$(EXEEXT): $(rigfreqwalk_OBJECTS) $(rigfreqwalk_DEPENDENCIES) $(EXTRA_rigfreqwalk_DEPENDENCIES) @rm -f rigfreqwalk$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rigfreqwalk_OBJECTS) $(rigfreqwalk_LDADD) $(LIBS) rigmatrix$(EXEEXT): $(rigmatrix_OBJECTS) $(rigmatrix_DEPENDENCIES) $(EXTRA_rigmatrix_DEPENDENCIES) @rm -f rigmatrix$(EXEEXT) $(AM_V_CCLD)$(rigmatrix_LINK) $(rigmatrix_OBJECTS) $(rigmatrix_LDADD) $(LIBS) rigmem$(EXEEXT): $(rigmem_OBJECTS) $(rigmem_DEPENDENCIES) $(EXTRA_rigmem_DEPENDENCIES) @rm -f rigmem$(EXEEXT) $(AM_V_CCLD)$(rigmem_LINK) $(rigmem_OBJECTS) $(rigmem_LDADD) $(LIBS) rigsmtr$(EXEEXT): $(rigsmtr_OBJECTS) $(rigsmtr_DEPENDENCIES) $(EXTRA_rigsmtr_DEPENDENCIES) @rm -f rigsmtr$(EXEEXT) $(AM_V_CCLD)$(rigsmtr_LINK) $(rigsmtr_OBJECTS) $(rigsmtr_LDADD) $(LIBS) rigswr$(EXEEXT): $(rigswr_OBJECTS) $(rigswr_DEPENDENCIES) $(EXTRA_rigswr_DEPENDENCIES) @rm -f rigswr$(EXEEXT) $(AM_V_CCLD)$(rigswr_LINK) $(rigswr_OBJECTS) $(rigswr_LDADD) $(LIBS) rigtestlibusb$(EXEEXT): $(rigtestlibusb_OBJECTS) $(rigtestlibusb_DEPENDENCIES) $(EXTRA_rigtestlibusb_DEPENDENCIES) @rm -f rigtestlibusb$(EXEEXT) $(AM_V_CCLD)$(rigtestlibusb_LINK) $(rigtestlibusb_OBJECTS) $(rigtestlibusb_LDADD) $(LIBS) rigtestmcast$(EXEEXT): $(rigtestmcast_OBJECTS) $(rigtestmcast_DEPENDENCIES) $(EXTRA_rigtestmcast_DEPENDENCIES) @rm -f rigtestmcast$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rigtestmcast_OBJECTS) $(rigtestmcast_LDADD) $(LIBS) rigtestmcastrx$(EXEEXT): $(rigtestmcastrx_OBJECTS) $(rigtestmcastrx_DEPENDENCIES) $(EXTRA_rigtestmcastrx_DEPENDENCIES) @rm -f rigtestmcastrx$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rigtestmcastrx_OBJECTS) $(rigtestmcastrx_LDADD) $(LIBS) rotctl$(EXEEXT): $(rotctl_OBJECTS) $(rotctl_DEPENDENCIES) $(EXTRA_rotctl_DEPENDENCIES) @rm -f rotctl$(EXEEXT) $(AM_V_CCLD)$(rotctl_LINK) $(rotctl_OBJECTS) $(rotctl_LDADD) $(LIBS) rotctld$(EXEEXT): $(rotctld_OBJECTS) $(rotctld_DEPENDENCIES) $(EXTRA_rotctld_DEPENDENCIES) @rm -f rotctld$(EXEEXT) $(AM_V_CCLD)$(rotctld_LINK) $(rotctld_OBJECTS) $(rotctld_LDADD) $(LIBS) test2038$(EXEEXT): $(test2038_OBJECTS) $(test2038_DEPENDENCIES) $(EXTRA_test2038_DEPENDENCIES) @rm -f test2038$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test2038_OBJECTS) $(test2038_LDADD) $(LIBS) testbcd$(EXEEXT): $(testbcd_OBJECTS) $(testbcd_DEPENDENCIES) $(EXTRA_testbcd_DEPENDENCIES) @rm -f testbcd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testbcd_OBJECTS) $(testbcd_LDADD) $(LIBS) testcache$(EXEEXT): $(testcache_OBJECTS) $(testcache_DEPENDENCIES) $(EXTRA_testcache_DEPENDENCIES) @rm -f testcache$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testcache_OBJECTS) $(testcache_LDADD) $(LIBS) testcookie$(EXEEXT): $(testcookie_OBJECTS) $(testcookie_DEPENDENCIES) $(EXTRA_testcookie_DEPENDENCIES) @rm -f testcookie$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testcookie_OBJECTS) $(testcookie_LDADD) $(LIBS) testfreq$(EXEEXT): $(testfreq_OBJECTS) $(testfreq_DEPENDENCIES) $(EXTRA_testfreq_DEPENDENCIES) @rm -f testfreq$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testfreq_OBJECTS) $(testfreq_LDADD) $(LIBS) testgrid$(EXEEXT): $(testgrid_OBJECTS) $(testgrid_DEPENDENCIES) $(EXTRA_testgrid_DEPENDENCIES) @rm -f testgrid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testgrid_OBJECTS) $(testgrid_LDADD) $(LIBS) testloc$(EXEEXT): $(testloc_OBJECTS) $(testloc_DEPENDENCIES) $(EXTRA_testloc_DEPENDENCIES) @rm -f testloc$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testloc_OBJECTS) $(testloc_LDADD) $(LIBS) testmW2power$(EXEEXT): $(testmW2power_OBJECTS) $(testmW2power_DEPENDENCIES) $(EXTRA_testmW2power_DEPENDENCIES) @rm -f testmW2power$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testmW2power_OBJECTS) $(testmW2power_LDADD) $(LIBS) testrig$(EXEEXT): $(testrig_OBJECTS) $(testrig_DEPENDENCIES) $(EXTRA_testrig_DEPENDENCIES) @rm -f testrig$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testrig_OBJECTS) $(testrig_LDADD) $(LIBS) testrigcaps$(EXEEXT): $(testrigcaps_OBJECTS) $(testrigcaps_DEPENDENCIES) $(EXTRA_testrigcaps_DEPENDENCIES) @rm -f testrigcaps$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testrigcaps_OBJECTS) $(testrigcaps_LDADD) $(LIBS) testrigopen$(EXEEXT): $(testrigopen_OBJECTS) $(testrigopen_DEPENDENCIES) $(EXTRA_testrigopen_DEPENDENCIES) @rm -f testrigopen$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testrigopen_OBJECTS) $(testrigopen_LDADD) $(LIBS) testtrn$(EXEEXT): $(testtrn_OBJECTS) $(testtrn_DEPENDENCIES) $(EXTRA_testtrn_DEPENDENCIES) @rm -f testtrn$(EXEEXT) $(AM_V_CCLD)$(LINK) $(testtrn_OBJECTS) $(testtrn_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctl-ampctl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctl-ampctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctl-dumpcaps_amp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctld-ampctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctld-ampctld.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampctld-dumpcaps_amp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachetest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachetest2.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumpmem.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hamlibmodels.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listrigs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rig_bench.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctl-dumpcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctl-dumpstate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctl-rig_tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctl-rigctl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctl-rigctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlcom-dumpcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlcom-dumpstate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlcom-rig_tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlcom-rigctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlcom-rigctlcom.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctld-dumpcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctld-dumpstate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctld-rig_tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctld-rigctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctld-rigctld.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlsync-dumpcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlsync-dumpstate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlsync-rig_tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlsync-rigctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctlsync-rigctlsync.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctltcp-dumpcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctltcp-dumpstate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctltcp-rig_tests.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctltcp-rigctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigctltcp-rigctltcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigfreqwalk.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigmatrix.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigmem-memcsv.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigmem-memload.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigmem-memsave.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigmem-rigmem.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigsmtr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigswr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigtestlibusb-rigtestlibusb.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigtestmcast.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigtestmcastrx.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctl-dumpcaps_rot.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctl-rotctl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctl-rotctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctld-dumpcaps_rot.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctld-rotctl_parse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotctld-rotctld.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test2038.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbcd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcache.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcookie.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfreq.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testgrid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testloc.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmW2power.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testrig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testrigcaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testrigopen.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testtrn.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< ampctl-ampctl.o: ampctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-ampctl.o -MD -MP -MF $(DEPDIR)/ampctl-ampctl.Tpo -c -o ampctl-ampctl.o `test -f 'ampctl.c' || echo '$(srcdir)/'`ampctl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-ampctl.Tpo $(DEPDIR)/ampctl-ampctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl.c' object='ampctl-ampctl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-ampctl.o `test -f 'ampctl.c' || echo '$(srcdir)/'`ampctl.c ampctl-ampctl.obj: ampctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-ampctl.obj -MD -MP -MF $(DEPDIR)/ampctl-ampctl.Tpo -c -o ampctl-ampctl.obj `if test -f 'ampctl.c'; then $(CYGPATH_W) 'ampctl.c'; else $(CYGPATH_W) '$(srcdir)/ampctl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-ampctl.Tpo $(DEPDIR)/ampctl-ampctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl.c' object='ampctl-ampctl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-ampctl.obj `if test -f 'ampctl.c'; then $(CYGPATH_W) 'ampctl.c'; else $(CYGPATH_W) '$(srcdir)/ampctl.c'; fi` ampctl-ampctl_parse.o: ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-ampctl_parse.o -MD -MP -MF $(DEPDIR)/ampctl-ampctl_parse.Tpo -c -o ampctl-ampctl_parse.o `test -f 'ampctl_parse.c' || echo '$(srcdir)/'`ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-ampctl_parse.Tpo $(DEPDIR)/ampctl-ampctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl_parse.c' object='ampctl-ampctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-ampctl_parse.o `test -f 'ampctl_parse.c' || echo '$(srcdir)/'`ampctl_parse.c ampctl-ampctl_parse.obj: ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-ampctl_parse.obj -MD -MP -MF $(DEPDIR)/ampctl-ampctl_parse.Tpo -c -o ampctl-ampctl_parse.obj `if test -f 'ampctl_parse.c'; then $(CYGPATH_W) 'ampctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/ampctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-ampctl_parse.Tpo $(DEPDIR)/ampctl-ampctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl_parse.c' object='ampctl-ampctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-ampctl_parse.obj `if test -f 'ampctl_parse.c'; then $(CYGPATH_W) 'ampctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/ampctl_parse.c'; fi` ampctl-dumpcaps_amp.o: dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-dumpcaps_amp.o -MD -MP -MF $(DEPDIR)/ampctl-dumpcaps_amp.Tpo -c -o ampctl-dumpcaps_amp.o `test -f 'dumpcaps_amp.c' || echo '$(srcdir)/'`dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-dumpcaps_amp.Tpo $(DEPDIR)/ampctl-dumpcaps_amp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_amp.c' object='ampctl-dumpcaps_amp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-dumpcaps_amp.o `test -f 'dumpcaps_amp.c' || echo '$(srcdir)/'`dumpcaps_amp.c ampctl-dumpcaps_amp.obj: dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -MT ampctl-dumpcaps_amp.obj -MD -MP -MF $(DEPDIR)/ampctl-dumpcaps_amp.Tpo -c -o ampctl-dumpcaps_amp.obj `if test -f 'dumpcaps_amp.c'; then $(CYGPATH_W) 'dumpcaps_amp.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_amp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctl-dumpcaps_amp.Tpo $(DEPDIR)/ampctl-dumpcaps_amp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_amp.c' object='ampctl-dumpcaps_amp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctl_CFLAGS) $(CFLAGS) -c -o ampctl-dumpcaps_amp.obj `if test -f 'dumpcaps_amp.c'; then $(CYGPATH_W) 'dumpcaps_amp.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_amp.c'; fi` ampctld-ampctld.o: ampctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-ampctld.o -MD -MP -MF $(DEPDIR)/ampctld-ampctld.Tpo -c -o ampctld-ampctld.o `test -f 'ampctld.c' || echo '$(srcdir)/'`ampctld.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-ampctld.Tpo $(DEPDIR)/ampctld-ampctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctld.c' object='ampctld-ampctld.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-ampctld.o `test -f 'ampctld.c' || echo '$(srcdir)/'`ampctld.c ampctld-ampctld.obj: ampctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-ampctld.obj -MD -MP -MF $(DEPDIR)/ampctld-ampctld.Tpo -c -o ampctld-ampctld.obj `if test -f 'ampctld.c'; then $(CYGPATH_W) 'ampctld.c'; else $(CYGPATH_W) '$(srcdir)/ampctld.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-ampctld.Tpo $(DEPDIR)/ampctld-ampctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctld.c' object='ampctld-ampctld.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-ampctld.obj `if test -f 'ampctld.c'; then $(CYGPATH_W) 'ampctld.c'; else $(CYGPATH_W) '$(srcdir)/ampctld.c'; fi` ampctld-ampctl_parse.o: ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-ampctl_parse.o -MD -MP -MF $(DEPDIR)/ampctld-ampctl_parse.Tpo -c -o ampctld-ampctl_parse.o `test -f 'ampctl_parse.c' || echo '$(srcdir)/'`ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-ampctl_parse.Tpo $(DEPDIR)/ampctld-ampctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl_parse.c' object='ampctld-ampctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-ampctl_parse.o `test -f 'ampctl_parse.c' || echo '$(srcdir)/'`ampctl_parse.c ampctld-ampctl_parse.obj: ampctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-ampctl_parse.obj -MD -MP -MF $(DEPDIR)/ampctld-ampctl_parse.Tpo -c -o ampctld-ampctl_parse.obj `if test -f 'ampctl_parse.c'; then $(CYGPATH_W) 'ampctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/ampctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-ampctl_parse.Tpo $(DEPDIR)/ampctld-ampctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ampctl_parse.c' object='ampctld-ampctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-ampctl_parse.obj `if test -f 'ampctl_parse.c'; then $(CYGPATH_W) 'ampctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/ampctl_parse.c'; fi` ampctld-dumpcaps_amp.o: dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-dumpcaps_amp.o -MD -MP -MF $(DEPDIR)/ampctld-dumpcaps_amp.Tpo -c -o ampctld-dumpcaps_amp.o `test -f 'dumpcaps_amp.c' || echo '$(srcdir)/'`dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-dumpcaps_amp.Tpo $(DEPDIR)/ampctld-dumpcaps_amp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_amp.c' object='ampctld-dumpcaps_amp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-dumpcaps_amp.o `test -f 'dumpcaps_amp.c' || echo '$(srcdir)/'`dumpcaps_amp.c ampctld-dumpcaps_amp.obj: dumpcaps_amp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -MT ampctld-dumpcaps_amp.obj -MD -MP -MF $(DEPDIR)/ampctld-dumpcaps_amp.Tpo -c -o ampctld-dumpcaps_amp.obj `if test -f 'dumpcaps_amp.c'; then $(CYGPATH_W) 'dumpcaps_amp.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_amp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ampctld-dumpcaps_amp.Tpo $(DEPDIR)/ampctld-dumpcaps_amp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_amp.c' object='ampctld-dumpcaps_amp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ampctld_CFLAGS) $(CFLAGS) -c -o ampctld-dumpcaps_amp.obj `if test -f 'dumpcaps_amp.c'; then $(CYGPATH_W) 'dumpcaps_amp.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_amp.c'; fi` rigctl-rigctl.o: rigctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rigctl.o -MD -MP -MF $(DEPDIR)/rigctl-rigctl.Tpo -c -o rigctl-rigctl.o `test -f 'rigctl.c' || echo '$(srcdir)/'`rigctl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rigctl.Tpo $(DEPDIR)/rigctl-rigctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl.c' object='rigctl-rigctl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rigctl.o `test -f 'rigctl.c' || echo '$(srcdir)/'`rigctl.c rigctl-rigctl.obj: rigctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rigctl.obj -MD -MP -MF $(DEPDIR)/rigctl-rigctl.Tpo -c -o rigctl-rigctl.obj `if test -f 'rigctl.c'; then $(CYGPATH_W) 'rigctl.c'; else $(CYGPATH_W) '$(srcdir)/rigctl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rigctl.Tpo $(DEPDIR)/rigctl-rigctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl.c' object='rigctl-rigctl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rigctl.obj `if test -f 'rigctl.c'; then $(CYGPATH_W) 'rigctl.c'; else $(CYGPATH_W) '$(srcdir)/rigctl.c'; fi` rigctl-rigctl_parse.o: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rigctl_parse.o -MD -MP -MF $(DEPDIR)/rigctl-rigctl_parse.Tpo -c -o rigctl-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rigctl_parse.Tpo $(DEPDIR)/rigctl-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctl-rigctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c rigctl-rigctl_parse.obj: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rigctl_parse.obj -MD -MP -MF $(DEPDIR)/rigctl-rigctl_parse.Tpo -c -o rigctl-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rigctl_parse.Tpo $(DEPDIR)/rigctl-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctl-rigctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` rigctl-dumpcaps.o: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-dumpcaps.o -MD -MP -MF $(DEPDIR)/rigctl-dumpcaps.Tpo -c -o rigctl-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-dumpcaps.Tpo $(DEPDIR)/rigctl-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctl-dumpcaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c rigctl-dumpcaps.obj: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-dumpcaps.obj -MD -MP -MF $(DEPDIR)/rigctl-dumpcaps.Tpo -c -o rigctl-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-dumpcaps.Tpo $(DEPDIR)/rigctl-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctl-dumpcaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` rigctl-dumpstate.o: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-dumpstate.o -MD -MP -MF $(DEPDIR)/rigctl-dumpstate.Tpo -c -o rigctl-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-dumpstate.Tpo $(DEPDIR)/rigctl-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctl-dumpstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c rigctl-dumpstate.obj: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-dumpstate.obj -MD -MP -MF $(DEPDIR)/rigctl-dumpstate.Tpo -c -o rigctl-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-dumpstate.Tpo $(DEPDIR)/rigctl-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctl-dumpstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` rigctl-rig_tests.o: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rig_tests.o -MD -MP -MF $(DEPDIR)/rigctl-rig_tests.Tpo -c -o rigctl-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rig_tests.Tpo $(DEPDIR)/rigctl-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctl-rig_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c rigctl-rig_tests.obj: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rigctl-rig_tests.obj -MD -MP -MF $(DEPDIR)/rigctl-rig_tests.Tpo -c -o rigctl-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctl-rig_tests.Tpo $(DEPDIR)/rigctl-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctl-rig_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rigctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rigctl-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` rigctlcom-rigctlcom.o: rigctlcom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rigctlcom.o -MD -MP -MF $(DEPDIR)/rigctlcom-rigctlcom.Tpo -c -o rigctlcom-rigctlcom.o `test -f 'rigctlcom.c' || echo '$(srcdir)/'`rigctlcom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rigctlcom.Tpo $(DEPDIR)/rigctlcom-rigctlcom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctlcom.c' object='rigctlcom-rigctlcom.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rigctlcom.o `test -f 'rigctlcom.c' || echo '$(srcdir)/'`rigctlcom.c rigctlcom-rigctlcom.obj: rigctlcom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rigctlcom.obj -MD -MP -MF $(DEPDIR)/rigctlcom-rigctlcom.Tpo -c -o rigctlcom-rigctlcom.obj `if test -f 'rigctlcom.c'; then $(CYGPATH_W) 'rigctlcom.c'; else $(CYGPATH_W) '$(srcdir)/rigctlcom.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rigctlcom.Tpo $(DEPDIR)/rigctlcom-rigctlcom.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctlcom.c' object='rigctlcom-rigctlcom.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rigctlcom.obj `if test -f 'rigctlcom.c'; then $(CYGPATH_W) 'rigctlcom.c'; else $(CYGPATH_W) '$(srcdir)/rigctlcom.c'; fi` rigctlcom-rigctl_parse.o: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rigctl_parse.o -MD -MP -MF $(DEPDIR)/rigctlcom-rigctl_parse.Tpo -c -o rigctlcom-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rigctl_parse.Tpo $(DEPDIR)/rigctlcom-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctlcom-rigctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c rigctlcom-rigctl_parse.obj: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rigctl_parse.obj -MD -MP -MF $(DEPDIR)/rigctlcom-rigctl_parse.Tpo -c -o rigctlcom-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rigctl_parse.Tpo $(DEPDIR)/rigctlcom-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctlcom-rigctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` rigctlcom-dumpcaps.o: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-dumpcaps.o -MD -MP -MF $(DEPDIR)/rigctlcom-dumpcaps.Tpo -c -o rigctlcom-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-dumpcaps.Tpo $(DEPDIR)/rigctlcom-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctlcom-dumpcaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c rigctlcom-dumpcaps.obj: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-dumpcaps.obj -MD -MP -MF $(DEPDIR)/rigctlcom-dumpcaps.Tpo -c -o rigctlcom-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-dumpcaps.Tpo $(DEPDIR)/rigctlcom-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctlcom-dumpcaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` rigctlcom-dumpstate.o: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-dumpstate.o -MD -MP -MF $(DEPDIR)/rigctlcom-dumpstate.Tpo -c -o rigctlcom-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-dumpstate.Tpo $(DEPDIR)/rigctlcom-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctlcom-dumpstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c rigctlcom-dumpstate.obj: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-dumpstate.obj -MD -MP -MF $(DEPDIR)/rigctlcom-dumpstate.Tpo -c -o rigctlcom-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-dumpstate.Tpo $(DEPDIR)/rigctlcom-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctlcom-dumpstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` rigctlcom-rig_tests.o: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rig_tests.o -MD -MP -MF $(DEPDIR)/rigctlcom-rig_tests.Tpo -c -o rigctlcom-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rig_tests.Tpo $(DEPDIR)/rigctlcom-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctlcom-rig_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c rigctlcom-rig_tests.obj: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -MT rigctlcom-rig_tests.obj -MD -MP -MF $(DEPDIR)/rigctlcom-rig_tests.Tpo -c -o rigctlcom-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlcom-rig_tests.Tpo $(DEPDIR)/rigctlcom-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctlcom-rig_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlcom_CFLAGS) $(CFLAGS) -c -o rigctlcom-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` rigctld-rigctld.o: rigctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rigctld.o -MD -MP -MF $(DEPDIR)/rigctld-rigctld.Tpo -c -o rigctld-rigctld.o `test -f 'rigctld.c' || echo '$(srcdir)/'`rigctld.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rigctld.Tpo $(DEPDIR)/rigctld-rigctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctld.c' object='rigctld-rigctld.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rigctld.o `test -f 'rigctld.c' || echo '$(srcdir)/'`rigctld.c rigctld-rigctld.obj: rigctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rigctld.obj -MD -MP -MF $(DEPDIR)/rigctld-rigctld.Tpo -c -o rigctld-rigctld.obj `if test -f 'rigctld.c'; then $(CYGPATH_W) 'rigctld.c'; else $(CYGPATH_W) '$(srcdir)/rigctld.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rigctld.Tpo $(DEPDIR)/rigctld-rigctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctld.c' object='rigctld-rigctld.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rigctld.obj `if test -f 'rigctld.c'; then $(CYGPATH_W) 'rigctld.c'; else $(CYGPATH_W) '$(srcdir)/rigctld.c'; fi` rigctld-rigctl_parse.o: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rigctl_parse.o -MD -MP -MF $(DEPDIR)/rigctld-rigctl_parse.Tpo -c -o rigctld-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rigctl_parse.Tpo $(DEPDIR)/rigctld-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctld-rigctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c rigctld-rigctl_parse.obj: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rigctl_parse.obj -MD -MP -MF $(DEPDIR)/rigctld-rigctl_parse.Tpo -c -o rigctld-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rigctl_parse.Tpo $(DEPDIR)/rigctld-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctld-rigctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` rigctld-dumpcaps.o: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-dumpcaps.o -MD -MP -MF $(DEPDIR)/rigctld-dumpcaps.Tpo -c -o rigctld-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-dumpcaps.Tpo $(DEPDIR)/rigctld-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctld-dumpcaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c rigctld-dumpcaps.obj: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-dumpcaps.obj -MD -MP -MF $(DEPDIR)/rigctld-dumpcaps.Tpo -c -o rigctld-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-dumpcaps.Tpo $(DEPDIR)/rigctld-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctld-dumpcaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` rigctld-dumpstate.o: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-dumpstate.o -MD -MP -MF $(DEPDIR)/rigctld-dumpstate.Tpo -c -o rigctld-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-dumpstate.Tpo $(DEPDIR)/rigctld-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctld-dumpstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c rigctld-dumpstate.obj: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-dumpstate.obj -MD -MP -MF $(DEPDIR)/rigctld-dumpstate.Tpo -c -o rigctld-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-dumpstate.Tpo $(DEPDIR)/rigctld-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctld-dumpstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` rigctld-rig_tests.o: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rig_tests.o -MD -MP -MF $(DEPDIR)/rigctld-rig_tests.Tpo -c -o rigctld-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rig_tests.Tpo $(DEPDIR)/rigctld-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctld-rig_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c rigctld-rig_tests.obj: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -MT rigctld-rig_tests.obj -MD -MP -MF $(DEPDIR)/rigctld-rig_tests.Tpo -c -o rigctld-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctld-rig_tests.Tpo $(DEPDIR)/rigctld-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctld-rig_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctld_CFLAGS) $(CFLAGS) -c -o rigctld-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` rigctlsync-rigctlsync.o: rigctlsync.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rigctlsync.o -MD -MP -MF $(DEPDIR)/rigctlsync-rigctlsync.Tpo -c -o rigctlsync-rigctlsync.o `test -f 'rigctlsync.c' || echo '$(srcdir)/'`rigctlsync.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rigctlsync.Tpo $(DEPDIR)/rigctlsync-rigctlsync.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctlsync.c' object='rigctlsync-rigctlsync.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rigctlsync.o `test -f 'rigctlsync.c' || echo '$(srcdir)/'`rigctlsync.c rigctlsync-rigctlsync.obj: rigctlsync.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rigctlsync.obj -MD -MP -MF $(DEPDIR)/rigctlsync-rigctlsync.Tpo -c -o rigctlsync-rigctlsync.obj `if test -f 'rigctlsync.c'; then $(CYGPATH_W) 'rigctlsync.c'; else $(CYGPATH_W) '$(srcdir)/rigctlsync.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rigctlsync.Tpo $(DEPDIR)/rigctlsync-rigctlsync.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctlsync.c' object='rigctlsync-rigctlsync.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rigctlsync.obj `if test -f 'rigctlsync.c'; then $(CYGPATH_W) 'rigctlsync.c'; else $(CYGPATH_W) '$(srcdir)/rigctlsync.c'; fi` rigctlsync-rigctl_parse.o: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rigctl_parse.o -MD -MP -MF $(DEPDIR)/rigctlsync-rigctl_parse.Tpo -c -o rigctlsync-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rigctl_parse.Tpo $(DEPDIR)/rigctlsync-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctlsync-rigctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c rigctlsync-rigctl_parse.obj: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rigctl_parse.obj -MD -MP -MF $(DEPDIR)/rigctlsync-rigctl_parse.Tpo -c -o rigctlsync-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rigctl_parse.Tpo $(DEPDIR)/rigctlsync-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctlsync-rigctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` rigctlsync-dumpcaps.o: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-dumpcaps.o -MD -MP -MF $(DEPDIR)/rigctlsync-dumpcaps.Tpo -c -o rigctlsync-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-dumpcaps.Tpo $(DEPDIR)/rigctlsync-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctlsync-dumpcaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c rigctlsync-dumpcaps.obj: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-dumpcaps.obj -MD -MP -MF $(DEPDIR)/rigctlsync-dumpcaps.Tpo -c -o rigctlsync-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-dumpcaps.Tpo $(DEPDIR)/rigctlsync-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctlsync-dumpcaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` rigctlsync-dumpstate.o: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-dumpstate.o -MD -MP -MF $(DEPDIR)/rigctlsync-dumpstate.Tpo -c -o rigctlsync-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-dumpstate.Tpo $(DEPDIR)/rigctlsync-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctlsync-dumpstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c rigctlsync-dumpstate.obj: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-dumpstate.obj -MD -MP -MF $(DEPDIR)/rigctlsync-dumpstate.Tpo -c -o rigctlsync-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-dumpstate.Tpo $(DEPDIR)/rigctlsync-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctlsync-dumpstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` rigctlsync-rig_tests.o: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rig_tests.o -MD -MP -MF $(DEPDIR)/rigctlsync-rig_tests.Tpo -c -o rigctlsync-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rig_tests.Tpo $(DEPDIR)/rigctlsync-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctlsync-rig_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c rigctlsync-rig_tests.obj: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -MT rigctlsync-rig_tests.obj -MD -MP -MF $(DEPDIR)/rigctlsync-rig_tests.Tpo -c -o rigctlsync-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctlsync-rig_tests.Tpo $(DEPDIR)/rigctlsync-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctlsync-rig_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctlsync_CFLAGS) $(CFLAGS) -c -o rigctlsync-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` rigctltcp-rigctltcp.o: rigctltcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rigctltcp.o -MD -MP -MF $(DEPDIR)/rigctltcp-rigctltcp.Tpo -c -o rigctltcp-rigctltcp.o `test -f 'rigctltcp.c' || echo '$(srcdir)/'`rigctltcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rigctltcp.Tpo $(DEPDIR)/rigctltcp-rigctltcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctltcp.c' object='rigctltcp-rigctltcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rigctltcp.o `test -f 'rigctltcp.c' || echo '$(srcdir)/'`rigctltcp.c rigctltcp-rigctltcp.obj: rigctltcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rigctltcp.obj -MD -MP -MF $(DEPDIR)/rigctltcp-rigctltcp.Tpo -c -o rigctltcp-rigctltcp.obj `if test -f 'rigctltcp.c'; then $(CYGPATH_W) 'rigctltcp.c'; else $(CYGPATH_W) '$(srcdir)/rigctltcp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rigctltcp.Tpo $(DEPDIR)/rigctltcp-rigctltcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctltcp.c' object='rigctltcp-rigctltcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rigctltcp.obj `if test -f 'rigctltcp.c'; then $(CYGPATH_W) 'rigctltcp.c'; else $(CYGPATH_W) '$(srcdir)/rigctltcp.c'; fi` rigctltcp-rigctl_parse.o: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rigctl_parse.o -MD -MP -MF $(DEPDIR)/rigctltcp-rigctl_parse.Tpo -c -o rigctltcp-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rigctl_parse.Tpo $(DEPDIR)/rigctltcp-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctltcp-rigctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rigctl_parse.o `test -f 'rigctl_parse.c' || echo '$(srcdir)/'`rigctl_parse.c rigctltcp-rigctl_parse.obj: rigctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rigctl_parse.obj -MD -MP -MF $(DEPDIR)/rigctltcp-rigctl_parse.Tpo -c -o rigctltcp-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rigctl_parse.Tpo $(DEPDIR)/rigctltcp-rigctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigctl_parse.c' object='rigctltcp-rigctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rigctl_parse.obj `if test -f 'rigctl_parse.c'; then $(CYGPATH_W) 'rigctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rigctl_parse.c'; fi` rigctltcp-dumpcaps.o: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-dumpcaps.o -MD -MP -MF $(DEPDIR)/rigctltcp-dumpcaps.Tpo -c -o rigctltcp-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-dumpcaps.Tpo $(DEPDIR)/rigctltcp-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctltcp-dumpcaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-dumpcaps.o `test -f 'dumpcaps.c' || echo '$(srcdir)/'`dumpcaps.c rigctltcp-dumpcaps.obj: dumpcaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-dumpcaps.obj -MD -MP -MF $(DEPDIR)/rigctltcp-dumpcaps.Tpo -c -o rigctltcp-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-dumpcaps.Tpo $(DEPDIR)/rigctltcp-dumpcaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps.c' object='rigctltcp-dumpcaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-dumpcaps.obj `if test -f 'dumpcaps.c'; then $(CYGPATH_W) 'dumpcaps.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps.c'; fi` rigctltcp-dumpstate.o: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-dumpstate.o -MD -MP -MF $(DEPDIR)/rigctltcp-dumpstate.Tpo -c -o rigctltcp-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-dumpstate.Tpo $(DEPDIR)/rigctltcp-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctltcp-dumpstate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-dumpstate.o `test -f 'dumpstate.c' || echo '$(srcdir)/'`dumpstate.c rigctltcp-dumpstate.obj: dumpstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-dumpstate.obj -MD -MP -MF $(DEPDIR)/rigctltcp-dumpstate.Tpo -c -o rigctltcp-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-dumpstate.Tpo $(DEPDIR)/rigctltcp-dumpstate.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpstate.c' object='rigctltcp-dumpstate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-dumpstate.obj `if test -f 'dumpstate.c'; then $(CYGPATH_W) 'dumpstate.c'; else $(CYGPATH_W) '$(srcdir)/dumpstate.c'; fi` rigctltcp-rig_tests.o: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rig_tests.o -MD -MP -MF $(DEPDIR)/rigctltcp-rig_tests.Tpo -c -o rigctltcp-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rig_tests.Tpo $(DEPDIR)/rigctltcp-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctltcp-rig_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rig_tests.o `test -f 'rig_tests.c' || echo '$(srcdir)/'`rig_tests.c rigctltcp-rig_tests.obj: rig_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -MT rigctltcp-rig_tests.obj -MD -MP -MF $(DEPDIR)/rigctltcp-rig_tests.Tpo -c -o rigctltcp-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigctltcp-rig_tests.Tpo $(DEPDIR)/rigctltcp-rig_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rig_tests.c' object='rigctltcp-rig_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigctltcp_CFLAGS) $(CFLAGS) -c -o rigctltcp-rig_tests.obj `if test -f 'rig_tests.c'; then $(CYGPATH_W) 'rig_tests.c'; else $(CYGPATH_W) '$(srcdir)/rig_tests.c'; fi` rigmem-rigmem.o: rigmem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-rigmem.o -MD -MP -MF $(DEPDIR)/rigmem-rigmem.Tpo -c -o rigmem-rigmem.o `test -f 'rigmem.c' || echo '$(srcdir)/'`rigmem.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-rigmem.Tpo $(DEPDIR)/rigmem-rigmem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigmem.c' object='rigmem-rigmem.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-rigmem.o `test -f 'rigmem.c' || echo '$(srcdir)/'`rigmem.c rigmem-rigmem.obj: rigmem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-rigmem.obj -MD -MP -MF $(DEPDIR)/rigmem-rigmem.Tpo -c -o rigmem-rigmem.obj `if test -f 'rigmem.c'; then $(CYGPATH_W) 'rigmem.c'; else $(CYGPATH_W) '$(srcdir)/rigmem.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-rigmem.Tpo $(DEPDIR)/rigmem-rigmem.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigmem.c' object='rigmem-rigmem.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-rigmem.obj `if test -f 'rigmem.c'; then $(CYGPATH_W) 'rigmem.c'; else $(CYGPATH_W) '$(srcdir)/rigmem.c'; fi` rigmem-memsave.o: memsave.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memsave.o -MD -MP -MF $(DEPDIR)/rigmem-memsave.Tpo -c -o rigmem-memsave.o `test -f 'memsave.c' || echo '$(srcdir)/'`memsave.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memsave.Tpo $(DEPDIR)/rigmem-memsave.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memsave.c' object='rigmem-memsave.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memsave.o `test -f 'memsave.c' || echo '$(srcdir)/'`memsave.c rigmem-memsave.obj: memsave.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memsave.obj -MD -MP -MF $(DEPDIR)/rigmem-memsave.Tpo -c -o rigmem-memsave.obj `if test -f 'memsave.c'; then $(CYGPATH_W) 'memsave.c'; else $(CYGPATH_W) '$(srcdir)/memsave.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memsave.Tpo $(DEPDIR)/rigmem-memsave.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memsave.c' object='rigmem-memsave.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memsave.obj `if test -f 'memsave.c'; then $(CYGPATH_W) 'memsave.c'; else $(CYGPATH_W) '$(srcdir)/memsave.c'; fi` rigmem-memload.o: memload.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memload.o -MD -MP -MF $(DEPDIR)/rigmem-memload.Tpo -c -o rigmem-memload.o `test -f 'memload.c' || echo '$(srcdir)/'`memload.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memload.Tpo $(DEPDIR)/rigmem-memload.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memload.c' object='rigmem-memload.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memload.o `test -f 'memload.c' || echo '$(srcdir)/'`memload.c rigmem-memload.obj: memload.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memload.obj -MD -MP -MF $(DEPDIR)/rigmem-memload.Tpo -c -o rigmem-memload.obj `if test -f 'memload.c'; then $(CYGPATH_W) 'memload.c'; else $(CYGPATH_W) '$(srcdir)/memload.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memload.Tpo $(DEPDIR)/rigmem-memload.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memload.c' object='rigmem-memload.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memload.obj `if test -f 'memload.c'; then $(CYGPATH_W) 'memload.c'; else $(CYGPATH_W) '$(srcdir)/memload.c'; fi` rigmem-memcsv.o: memcsv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memcsv.o -MD -MP -MF $(DEPDIR)/rigmem-memcsv.Tpo -c -o rigmem-memcsv.o `test -f 'memcsv.c' || echo '$(srcdir)/'`memcsv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memcsv.Tpo $(DEPDIR)/rigmem-memcsv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memcsv.c' object='rigmem-memcsv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memcsv.o `test -f 'memcsv.c' || echo '$(srcdir)/'`memcsv.c rigmem-memcsv.obj: memcsv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -MT rigmem-memcsv.obj -MD -MP -MF $(DEPDIR)/rigmem-memcsv.Tpo -c -o rigmem-memcsv.obj `if test -f 'memcsv.c'; then $(CYGPATH_W) 'memcsv.c'; else $(CYGPATH_W) '$(srcdir)/memcsv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigmem-memcsv.Tpo $(DEPDIR)/rigmem-memcsv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memcsv.c' object='rigmem-memcsv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigmem_CFLAGS) $(CFLAGS) -c -o rigmem-memcsv.obj `if test -f 'memcsv.c'; then $(CYGPATH_W) 'memcsv.c'; else $(CYGPATH_W) '$(srcdir)/memcsv.c'; fi` rigtestlibusb-rigtestlibusb.o: rigtestlibusb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigtestlibusb_CFLAGS) $(CFLAGS) -MT rigtestlibusb-rigtestlibusb.o -MD -MP -MF $(DEPDIR)/rigtestlibusb-rigtestlibusb.Tpo -c -o rigtestlibusb-rigtestlibusb.o `test -f 'rigtestlibusb.c' || echo '$(srcdir)/'`rigtestlibusb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigtestlibusb-rigtestlibusb.Tpo $(DEPDIR)/rigtestlibusb-rigtestlibusb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigtestlibusb.c' object='rigtestlibusb-rigtestlibusb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigtestlibusb_CFLAGS) $(CFLAGS) -c -o rigtestlibusb-rigtestlibusb.o `test -f 'rigtestlibusb.c' || echo '$(srcdir)/'`rigtestlibusb.c rigtestlibusb-rigtestlibusb.obj: rigtestlibusb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigtestlibusb_CFLAGS) $(CFLAGS) -MT rigtestlibusb-rigtestlibusb.obj -MD -MP -MF $(DEPDIR)/rigtestlibusb-rigtestlibusb.Tpo -c -o rigtestlibusb-rigtestlibusb.obj `if test -f 'rigtestlibusb.c'; then $(CYGPATH_W) 'rigtestlibusb.c'; else $(CYGPATH_W) '$(srcdir)/rigtestlibusb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rigtestlibusb-rigtestlibusb.Tpo $(DEPDIR)/rigtestlibusb-rigtestlibusb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rigtestlibusb.c' object='rigtestlibusb-rigtestlibusb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rigtestlibusb_CFLAGS) $(CFLAGS) -c -o rigtestlibusb-rigtestlibusb.obj `if test -f 'rigtestlibusb.c'; then $(CYGPATH_W) 'rigtestlibusb.c'; else $(CYGPATH_W) '$(srcdir)/rigtestlibusb.c'; fi` rotctl-rotctl.o: rotctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-rotctl.o -MD -MP -MF $(DEPDIR)/rotctl-rotctl.Tpo -c -o rotctl-rotctl.o `test -f 'rotctl.c' || echo '$(srcdir)/'`rotctl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-rotctl.Tpo $(DEPDIR)/rotctl-rotctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl.c' object='rotctl-rotctl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-rotctl.o `test -f 'rotctl.c' || echo '$(srcdir)/'`rotctl.c rotctl-rotctl.obj: rotctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-rotctl.obj -MD -MP -MF $(DEPDIR)/rotctl-rotctl.Tpo -c -o rotctl-rotctl.obj `if test -f 'rotctl.c'; then $(CYGPATH_W) 'rotctl.c'; else $(CYGPATH_W) '$(srcdir)/rotctl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-rotctl.Tpo $(DEPDIR)/rotctl-rotctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl.c' object='rotctl-rotctl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-rotctl.obj `if test -f 'rotctl.c'; then $(CYGPATH_W) 'rotctl.c'; else $(CYGPATH_W) '$(srcdir)/rotctl.c'; fi` rotctl-rotctl_parse.o: rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-rotctl_parse.o -MD -MP -MF $(DEPDIR)/rotctl-rotctl_parse.Tpo -c -o rotctl-rotctl_parse.o `test -f 'rotctl_parse.c' || echo '$(srcdir)/'`rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-rotctl_parse.Tpo $(DEPDIR)/rotctl-rotctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl_parse.c' object='rotctl-rotctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-rotctl_parse.o `test -f 'rotctl_parse.c' || echo '$(srcdir)/'`rotctl_parse.c rotctl-rotctl_parse.obj: rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-rotctl_parse.obj -MD -MP -MF $(DEPDIR)/rotctl-rotctl_parse.Tpo -c -o rotctl-rotctl_parse.obj `if test -f 'rotctl_parse.c'; then $(CYGPATH_W) 'rotctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rotctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-rotctl_parse.Tpo $(DEPDIR)/rotctl-rotctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl_parse.c' object='rotctl-rotctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-rotctl_parse.obj `if test -f 'rotctl_parse.c'; then $(CYGPATH_W) 'rotctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rotctl_parse.c'; fi` rotctl-dumpcaps_rot.o: dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-dumpcaps_rot.o -MD -MP -MF $(DEPDIR)/rotctl-dumpcaps_rot.Tpo -c -o rotctl-dumpcaps_rot.o `test -f 'dumpcaps_rot.c' || echo '$(srcdir)/'`dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-dumpcaps_rot.Tpo $(DEPDIR)/rotctl-dumpcaps_rot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_rot.c' object='rotctl-dumpcaps_rot.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-dumpcaps_rot.o `test -f 'dumpcaps_rot.c' || echo '$(srcdir)/'`dumpcaps_rot.c rotctl-dumpcaps_rot.obj: dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -MT rotctl-dumpcaps_rot.obj -MD -MP -MF $(DEPDIR)/rotctl-dumpcaps_rot.Tpo -c -o rotctl-dumpcaps_rot.obj `if test -f 'dumpcaps_rot.c'; then $(CYGPATH_W) 'dumpcaps_rot.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_rot.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctl-dumpcaps_rot.Tpo $(DEPDIR)/rotctl-dumpcaps_rot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_rot.c' object='rotctl-dumpcaps_rot.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctl_CFLAGS) $(CFLAGS) -c -o rotctl-dumpcaps_rot.obj `if test -f 'dumpcaps_rot.c'; then $(CYGPATH_W) 'dumpcaps_rot.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_rot.c'; fi` rotctld-rotctld.o: rotctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-rotctld.o -MD -MP -MF $(DEPDIR)/rotctld-rotctld.Tpo -c -o rotctld-rotctld.o `test -f 'rotctld.c' || echo '$(srcdir)/'`rotctld.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-rotctld.Tpo $(DEPDIR)/rotctld-rotctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctld.c' object='rotctld-rotctld.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-rotctld.o `test -f 'rotctld.c' || echo '$(srcdir)/'`rotctld.c rotctld-rotctld.obj: rotctld.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-rotctld.obj -MD -MP -MF $(DEPDIR)/rotctld-rotctld.Tpo -c -o rotctld-rotctld.obj `if test -f 'rotctld.c'; then $(CYGPATH_W) 'rotctld.c'; else $(CYGPATH_W) '$(srcdir)/rotctld.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-rotctld.Tpo $(DEPDIR)/rotctld-rotctld.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctld.c' object='rotctld-rotctld.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-rotctld.obj `if test -f 'rotctld.c'; then $(CYGPATH_W) 'rotctld.c'; else $(CYGPATH_W) '$(srcdir)/rotctld.c'; fi` rotctld-rotctl_parse.o: rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-rotctl_parse.o -MD -MP -MF $(DEPDIR)/rotctld-rotctl_parse.Tpo -c -o rotctld-rotctl_parse.o `test -f 'rotctl_parse.c' || echo '$(srcdir)/'`rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-rotctl_parse.Tpo $(DEPDIR)/rotctld-rotctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl_parse.c' object='rotctld-rotctl_parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-rotctl_parse.o `test -f 'rotctl_parse.c' || echo '$(srcdir)/'`rotctl_parse.c rotctld-rotctl_parse.obj: rotctl_parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-rotctl_parse.obj -MD -MP -MF $(DEPDIR)/rotctld-rotctl_parse.Tpo -c -o rotctld-rotctl_parse.obj `if test -f 'rotctl_parse.c'; then $(CYGPATH_W) 'rotctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rotctl_parse.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-rotctl_parse.Tpo $(DEPDIR)/rotctld-rotctl_parse.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rotctl_parse.c' object='rotctld-rotctl_parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-rotctl_parse.obj `if test -f 'rotctl_parse.c'; then $(CYGPATH_W) 'rotctl_parse.c'; else $(CYGPATH_W) '$(srcdir)/rotctl_parse.c'; fi` rotctld-dumpcaps_rot.o: dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-dumpcaps_rot.o -MD -MP -MF $(DEPDIR)/rotctld-dumpcaps_rot.Tpo -c -o rotctld-dumpcaps_rot.o `test -f 'dumpcaps_rot.c' || echo '$(srcdir)/'`dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-dumpcaps_rot.Tpo $(DEPDIR)/rotctld-dumpcaps_rot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_rot.c' object='rotctld-dumpcaps_rot.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-dumpcaps_rot.o `test -f 'dumpcaps_rot.c' || echo '$(srcdir)/'`dumpcaps_rot.c rotctld-dumpcaps_rot.obj: dumpcaps_rot.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -MT rotctld-dumpcaps_rot.obj -MD -MP -MF $(DEPDIR)/rotctld-dumpcaps_rot.Tpo -c -o rotctld-dumpcaps_rot.obj `if test -f 'dumpcaps_rot.c'; then $(CYGPATH_W) 'dumpcaps_rot.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_rot.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rotctld-dumpcaps_rot.Tpo $(DEPDIR)/rotctld-dumpcaps_rot.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dumpcaps_rot.c' object='rotctld-dumpcaps_rot.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rotctld_CFLAGS) $(CFLAGS) -c -o rotctld-dumpcaps_rot.obj `if test -f 'dumpcaps_rot.c'; then $(CYGPATH_W) 'dumpcaps_rot.c'; else $(CYGPATH_W) '$(srcdir)/dumpcaps_rot.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ output_system_information () \ { \ echo; \ { uname -a | $(AWK) '{ \ printf "System information (uname -a):"; \ for (i = 1; i < NF; ++i) \ { \ if (i != 2) \ printf " %s", $$i; \ } \ printf "\n"; \ }'; } 2>&1; \ if test -r /etc/os-release; then \ echo "Distribution information (/etc/os-release):"; \ sed 8q /etc/os-release; \ elif test -r /etc/issue; then \ echo "Distribution information (/etc/issue):"; \ cat /etc/issue; \ fi; \ }; \ please_report () \ { \ echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \ echo "together with the test-suite.log file (gzipped) and your system"; \ echo "information. Thanks."; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ output_system_information; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\ if test -n "$(PACKAGE_BUGREPORT)"; then \ please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) $(check_SCRIPTS) @$(am__rm_f) $(RECHECK_LOGS) @$(am__rm_f) $(RECHECK_LOGS:.log=.trs) @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(check_SCRIPTS) @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? testrig.sh.log: testrig.sh @p='testrig.sh'; \ b='testrig.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testfreq.sh.log: testfreq.sh @p='testfreq.sh'; \ b='testfreq.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testbcd.sh.log: testbcd.sh @p='testbcd.sh'; \ b='testbcd.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testloc.sh.log: testloc.sh @p='testloc.sh'; \ b='testloc.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testrigcaps.sh.log: testrigcaps.sh @p='testrigcaps.sh'; \ b='testrigcaps.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testcache.sh.log: testcache.sh @p='testcache.sh'; \ b='testcache.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testcookie.sh.log: testcookie.sh @p='testcookie.sh'; \ b='testcookie.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testgrid.sh.log: testgrid.sh @p='testgrid.sh'; \ b='testgrid.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test2038.sh.log: test2038.sh @p='test2038.sh'; \ b='test2038.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -$(am__rm_f) $(TEST_LOGS) -$(am__rm_f) $(TEST_LOGS:.log=.trs) -$(am__rm_f) $(TEST_SUITE_LOG) clean-generic: -$(am__rm_f) $(CLEANFILES) distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ampctl-ampctl.Po -rm -f ./$(DEPDIR)/ampctl-ampctl_parse.Po -rm -f ./$(DEPDIR)/ampctl-dumpcaps_amp.Po -rm -f ./$(DEPDIR)/ampctld-ampctl_parse.Po -rm -f ./$(DEPDIR)/ampctld-ampctld.Po -rm -f ./$(DEPDIR)/ampctld-dumpcaps_amp.Po -rm -f ./$(DEPDIR)/cachetest.Po -rm -f ./$(DEPDIR)/cachetest2.Po -rm -f ./$(DEPDIR)/dumpmem.Po -rm -f ./$(DEPDIR)/hamlibmodels.Po -rm -f ./$(DEPDIR)/listrigs.Po -rm -f ./$(DEPDIR)/rig_bench.Po -rm -f ./$(DEPDIR)/rigctl-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctl-dumpstate.Po -rm -f ./$(DEPDIR)/rigctl-rig_tests.Po -rm -f ./$(DEPDIR)/rigctl-rigctl.Po -rm -f ./$(DEPDIR)/rigctl-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlcom-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctlcom-dumpstate.Po -rm -f ./$(DEPDIR)/rigctlcom-rig_tests.Po -rm -f ./$(DEPDIR)/rigctlcom-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlcom-rigctlcom.Po -rm -f ./$(DEPDIR)/rigctld-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctld-dumpstate.Po -rm -f ./$(DEPDIR)/rigctld-rig_tests.Po -rm -f ./$(DEPDIR)/rigctld-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctld-rigctld.Po -rm -f ./$(DEPDIR)/rigctlsync-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctlsync-dumpstate.Po -rm -f ./$(DEPDIR)/rigctlsync-rig_tests.Po -rm -f ./$(DEPDIR)/rigctlsync-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlsync-rigctlsync.Po -rm -f ./$(DEPDIR)/rigctltcp-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctltcp-dumpstate.Po -rm -f ./$(DEPDIR)/rigctltcp-rig_tests.Po -rm -f ./$(DEPDIR)/rigctltcp-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctltcp-rigctltcp.Po -rm -f ./$(DEPDIR)/rigfreqwalk.Po -rm -f ./$(DEPDIR)/rigmatrix.Po -rm -f ./$(DEPDIR)/rigmem-memcsv.Po -rm -f ./$(DEPDIR)/rigmem-memload.Po -rm -f ./$(DEPDIR)/rigmem-memsave.Po -rm -f ./$(DEPDIR)/rigmem-rigmem.Po -rm -f ./$(DEPDIR)/rigsmtr.Po -rm -f ./$(DEPDIR)/rigswr.Po -rm -f ./$(DEPDIR)/rigtestlibusb-rigtestlibusb.Po -rm -f ./$(DEPDIR)/rigtestmcast.Po -rm -f ./$(DEPDIR)/rigtestmcastrx.Po -rm -f ./$(DEPDIR)/rotctl-dumpcaps_rot.Po -rm -f ./$(DEPDIR)/rotctl-rotctl.Po -rm -f ./$(DEPDIR)/rotctl-rotctl_parse.Po -rm -f ./$(DEPDIR)/rotctld-dumpcaps_rot.Po -rm -f ./$(DEPDIR)/rotctld-rotctl_parse.Po -rm -f ./$(DEPDIR)/rotctld-rotctld.Po -rm -f ./$(DEPDIR)/test2038.Po -rm -f ./$(DEPDIR)/testbcd.Po -rm -f ./$(DEPDIR)/testcache.Po -rm -f ./$(DEPDIR)/testcookie.Po -rm -f ./$(DEPDIR)/testfreq.Po -rm -f ./$(DEPDIR)/testgrid.Po -rm -f ./$(DEPDIR)/testloc.Po -rm -f ./$(DEPDIR)/testmW2power.Po -rm -f ./$(DEPDIR)/testrig.Po -rm -f ./$(DEPDIR)/testrigcaps.Po -rm -f ./$(DEPDIR)/testrigopen.Po -rm -f ./$(DEPDIR)/testtrn.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ampctl-ampctl.Po -rm -f ./$(DEPDIR)/ampctl-ampctl_parse.Po -rm -f ./$(DEPDIR)/ampctl-dumpcaps_amp.Po -rm -f ./$(DEPDIR)/ampctld-ampctl_parse.Po -rm -f ./$(DEPDIR)/ampctld-ampctld.Po -rm -f ./$(DEPDIR)/ampctld-dumpcaps_amp.Po -rm -f ./$(DEPDIR)/cachetest.Po -rm -f ./$(DEPDIR)/cachetest2.Po -rm -f ./$(DEPDIR)/dumpmem.Po -rm -f ./$(DEPDIR)/hamlibmodels.Po -rm -f ./$(DEPDIR)/listrigs.Po -rm -f ./$(DEPDIR)/rig_bench.Po -rm -f ./$(DEPDIR)/rigctl-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctl-dumpstate.Po -rm -f ./$(DEPDIR)/rigctl-rig_tests.Po -rm -f ./$(DEPDIR)/rigctl-rigctl.Po -rm -f ./$(DEPDIR)/rigctl-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlcom-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctlcom-dumpstate.Po -rm -f ./$(DEPDIR)/rigctlcom-rig_tests.Po -rm -f ./$(DEPDIR)/rigctlcom-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlcom-rigctlcom.Po -rm -f ./$(DEPDIR)/rigctld-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctld-dumpstate.Po -rm -f ./$(DEPDIR)/rigctld-rig_tests.Po -rm -f ./$(DEPDIR)/rigctld-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctld-rigctld.Po -rm -f ./$(DEPDIR)/rigctlsync-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctlsync-dumpstate.Po -rm -f ./$(DEPDIR)/rigctlsync-rig_tests.Po -rm -f ./$(DEPDIR)/rigctlsync-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctlsync-rigctlsync.Po -rm -f ./$(DEPDIR)/rigctltcp-dumpcaps.Po -rm -f ./$(DEPDIR)/rigctltcp-dumpstate.Po -rm -f ./$(DEPDIR)/rigctltcp-rig_tests.Po -rm -f ./$(DEPDIR)/rigctltcp-rigctl_parse.Po -rm -f ./$(DEPDIR)/rigctltcp-rigctltcp.Po -rm -f ./$(DEPDIR)/rigfreqwalk.Po -rm -f ./$(DEPDIR)/rigmatrix.Po -rm -f ./$(DEPDIR)/rigmem-memcsv.Po -rm -f ./$(DEPDIR)/rigmem-memload.Po -rm -f ./$(DEPDIR)/rigmem-memsave.Po -rm -f ./$(DEPDIR)/rigmem-rigmem.Po -rm -f ./$(DEPDIR)/rigsmtr.Po -rm -f ./$(DEPDIR)/rigswr.Po -rm -f ./$(DEPDIR)/rigtestlibusb-rigtestlibusb.Po -rm -f ./$(DEPDIR)/rigtestmcast.Po -rm -f ./$(DEPDIR)/rigtestmcastrx.Po -rm -f ./$(DEPDIR)/rotctl-dumpcaps_rot.Po -rm -f ./$(DEPDIR)/rotctl-rotctl.Po -rm -f ./$(DEPDIR)/rotctl-rotctl_parse.Po -rm -f ./$(DEPDIR)/rotctld-dumpcaps_rot.Po -rm -f ./$(DEPDIR)/rotctld-rotctl_parse.Po -rm -f ./$(DEPDIR)/rotctld-rotctld.Po -rm -f ./$(DEPDIR)/test2038.Po -rm -f ./$(DEPDIR)/testbcd.Po -rm -f ./$(DEPDIR)/testcache.Po -rm -f ./$(DEPDIR)/testcookie.Po -rm -f ./$(DEPDIR)/testfreq.Po -rm -f ./$(DEPDIR)/testgrid.Po -rm -f ./$(DEPDIR)/testloc.Po -rm -f ./$(DEPDIR)/testmW2power.Po -rm -f ./$(DEPDIR)/testrig.Po -rm -f ./$(DEPDIR)/testrigcaps.Po -rm -f ./$(DEPDIR)/testrigopen.Po -rm -f ./$(DEPDIR)/testtrn.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-binPROGRAMS clean-checkPROGRAMS \ clean-generic clean-libtool cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS .PRECIOUS: Makefile @HTML_MATRIX_TRUE@rigmatrix.html: rigmatrix_head.html rigmatrix listrigs @HTML_MATRIX_TRUE@ mkdir -p sup-info/support @HTML_MATRIX_TRUE@ ( cat $(srcdir)/rigmatrix_head.html && cd sup-info && ../rigmatrix ) > sup-info/rigmatrix.html @HTML_MATRIX_TRUE@ for f in $$(./listrigs | tail -n +2 | cut -f1) ; do ( ./rigctl -m $$f -u > sup-info/support/model$$f.txt || exit 0 ) ; done @HTML_MATRIX_TRUE@ ./rigctl -l |sort -n | $(srcdir)/rig_split_lst.awk -v lst_dir="sup-info" $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la testrig.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/src/.libs:$(top_builddir)/dummy/.libs ./testrig 1' > testrig.sh chmod +x ./testrig.sh testfreq.sh: echo './testfreq' > testfreq.sh chmod +x ./testfreq.sh testbcd.sh: echo './testbcd 146520000 10' > testbcd.sh chmod +x ./testbcd.sh testloc.sh: echo './testloc EM79UT96LW 5' > testloc.sh chmod +x ./testloc.sh testrigcaps.sh: echo './testrigcaps' > testrigcaps.sh chmod +x ./testrigcaps.sh testcache.sh: echo './testcache 1' > testcache.sh chmod +x ./testcache.sh testcookie.sh: echo './testcookie 1' > testcookie.sh chmod +x ./testcookie.sh testgrid.sh: echo './testgrid' > testgrid.sh chmod +x ./testgrid.sh test2038.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/src/.libs:$(top_builddir)/dummy/.libs ./test2038 1' > test2038.sh chmod +x ./test2038.sh # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/tests/rotctld.c0000664000175000017500000004713415056640443011446 /* * rotctld.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2010,2011,2012,2013 * * This program test/control a rotator using Hamlib. * It takes commands from network connection. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include /* See NOTES */ #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_PTHREAD # include #endif #include #include "rig.h" #include "rotctl_parse.h" #include "rotlist.h" struct handle_data { ROT *rot; int sock; struct sockaddr_storage cli_addr; socklen_t clilen; }; void *handle_socket(void *arg); void usage(); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "m:r:R:s:C:o:O:t:T:LuvhVlZ" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rot-file", 1, 0, 'r'}, {"rot-file2", 1, 0, 'R'}, {"serial-speed", 1, 0, 's'}, {"port", 1, 0, 't'}, {"listen-addr", 1, 0, 'T'}, {"list", 0, 0, 'l'}, {"set-conf", 1, 0, 'C'}, {"set-azoffset", 1, 0, 'o'}, {"set-eloffset", 1, 0, 'O'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"debug-time-stamps", 0, 0, 'Z'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; const char *portno = "4533"; const char *src_addr = NULL; /* INADDR_ANY */ azimuth_t az_offset; elevation_t el_offset; #define MAXCONFLEN 2048 static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, // Default language MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } int main(int argc, char *argv[]) { ROT *my_rot; /* handle to rot (instance) */ rot_model_t my_model = ROT_MODEL_DUMMY; int retcode; /* generic return code from functions */ int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; const char *rot_file = NULL; const char *rot_file2 = NULL; int serial_rate = 0; char conf_parms[MAXCONFLEN] = ""; struct addrinfo hints, *result, *saved_result; int sock_listen; int reuseaddr = 1; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; #ifdef HAVE_PTHREAD pthread_t thread; pthread_attr_t attr; #endif struct handle_data *arg; while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_file = optarg; break; case 'R': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_file2 = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } portno = optarg; break; case 'T': if (!optarg) { usage(); /* wrong arg count */ exit(1); } src_addr = optarg; break; case 'o': if (!optarg) { usage(); /* wrong arg count */ exit(1); } az_offset = atof(optarg); break; case 'O': if (!optarg) { usage(); /* wrong arg count */ exit(1); } el_offset = atof(optarg); case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "rotctld, %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); my_rot = rot_init(my_model); if (!my_rot) { fprintf(stderr, "Unknown rot num %d, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } char *token = strtok(conf_parms, ","); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = rot_token_lookup(my_rot, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s', use -L switch to see\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = rot_set_conf(my_rot, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } token = strtok(NULL, ","); } if (rot_file) { strncpy(ROTPORT(my_rot)->pathname, rot_file, HAMLIB_FILPATHLEN - 1); } if (rot_file2) { strncpy(ROTPORT2(my_rot)->pathname, rot_file2, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { ROTPORT(my_rot)->parm.serial.rate = serial_rate; } /* * print out conf parameters */ if (show_conf) { rot_token_foreach(my_rot, print_conf_list, (rig_ptr_t)my_rot); } /* * Print out conf parameters, and exits immediately as we may be * interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps_rot(my_rot, stdout); rot_cleanup(my_rot); /* if you care about memory */ exit(0); } retcode = rot_open(my_rot); if (retcode != RIG_OK) { fprintf(stderr, "rot_open: error = %s \n", rigerror(retcode)); exit(2); } ROTSTATE(my_rot)->az_offset = az_offset; ROTSTATE(my_rot)->el_offset = el_offset; if (verbose > 0) { printf("Opened rot model %d, '%s'\n", my_rot->caps->rot_model, my_rot->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rot->caps->version, rig_strstatus(my_rot->caps->status)); #ifdef __MINGW32__ # ifndef SO_OPENTYPE # define SO_OPENTYPE 0x7008 # endif # ifndef SO_SYNCHRONOUS_NONALERT # define SO_SYNCHRONOUS_NONALERT 0x20 # endif # ifndef INVALID_SOCKET # define INVALID_SOCKET -1 # endif WSADATA wsadata; if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) { fprintf(stderr, "WSAStartup socket error\n"); exit(1); } { // braced to prevent cppcheck warning int sockopt = SO_SYNCHRONOUS_NONALERT; setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt)); } #endif /* * Prepare listening socket */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* TCP socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ retcode = getaddrinfo(src_addr, portno, &hints, &result); if (retcode != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode)); exit(2); } saved_result = result; do { sock_listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock_listen < 0) { handle_error(RIG_DEBUG_ERR, "socket"); freeaddrinfo(result); /* No longer needed */ exit(1); } if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(result); /* No longer needed */ exit(1); } #ifdef IPV6_V6ONLY if (AF_INET6 == result->ai_family) { /* allow IPv4 mapped to IPv6 clients, MS & BSD default this to 1 i.e. disallowed */ int sockopt = 0; if (setsockopt(sock_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&sockopt, sizeof(sockopt)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } } #endif if (0 == bind(sock_listen, result->ai_addr, result->ai_addrlen)) { break; } handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); #ifdef __MINGW32__ closesocket(sock_listen); #else close(sock_listen); #endif } while ((result = result->ai_next) != NULL); freeaddrinfo(saved_result); /* No longer needed */ if (NULL == result) { rig_debug(RIG_DEBUG_ERR, "%s: bind error - no available interface\n", __func__); exit(1); } if (listen(sock_listen, 4) < 0) { handle_error(RIG_DEBUG_ERR, "listening"); exit(1); } #ifdef SIGPIPE /* Ignore SIGPIPE as we will handle it at the write()/send() calls that will consequently fail with EPIPE. All child threads will inherit this disposition which is what we want. */ #if HAVE_SIGACTION { struct sigaction act; memset(&act, 0, sizeof act); act.sa_handler = SIG_IGN; act.sa_flags = SA_RESTART; if (sigaction(SIGPIPE, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction"); } } #elif HAVE_SIGNAL if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) { handle_error(RIG_DEBUG_ERR, "signal"); } #endif #endif /* * main loop accepting connections */ do { arg = calloc(1, sizeof(struct handle_data)); if (!arg) { rig_debug(RIG_DEBUG_ERR, "calloc: %s\n", strerror(errno)); exit(1); } arg->rot = my_rot; arg->clilen = sizeof(arg->cli_addr); arg->sock = accept(sock_listen, (struct sockaddr *) &arg->cli_addr, &arg->clilen); if (arg->sock < 0) { handle_error(RIG_DEBUG_ERR, "accept"); break; } if ((retcode = getnameinfo((struct sockaddr const *)&arg->cli_addr, arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection opened from %s:%s\n", host, serv); #ifdef HAVE_PTHREAD pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); retcode = pthread_create(&thread, &attr, handle_socket, arg); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "pthread_create: %s\n", strerror(retcode)); break; } #else handle_socket(arg); retcode = 1; #endif } while (retcode == 0); rot_close(my_rot); /* close port */ rot_cleanup(my_rot); /* if you care about memory */ #ifdef __MINGW32__ WSACleanup(); #endif return 0; } /* * This is the function run by the threads */ void *handle_socket(void *arg) { struct handle_data *handle_data_arg = (struct handle_data *)arg; FILE *fsockin; FILE *fsockout; int retcode; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); if (sock_osfhandle == -1) { rig_debug(RIG_DEBUG_ERR, "_open_osfhandle error: %s\n", strerror(errno)); goto handle_exit; } fsockin = _fdopen(sock_osfhandle, "rb"); #elif defined(ANDROID) || defined(__ANDROID__) // fdsan does not allow fdopen the same fd twice in Android fsockin = fdopen(dup(handle_data_arg->sock), "rb"); #else fsockin = fdopen(handle_data_arg->sock, "rb"); #endif if (!fsockin) { rig_debug(RIG_DEBUG_ERR, "fdopen in: %s\n", strerror(errno)); goto handle_exit; } #ifdef __MINGW32__ fsockout = _fdopen(sock_osfhandle, "wb"); #elif defined(ANDROID) || defined(__ANDROID__) // fdsan does not allow fdopen the same fd twice in Android fsockout = fdopen(dup(handle_data_arg->sock), "wb"); #else fsockout = fdopen(handle_data_arg->sock, "wb"); #endif if (!fsockout) { rig_debug(RIG_DEBUG_ERR, "fdopen out: %s\n", strerror(errno)); fclose(fsockin); goto handle_exit; } do { retcode = rotctl_parse(handle_data_arg->rot, fsockin, fsockout, NULL, 0, 1, 0, '\r'); if (ferror(fsockin) || ferror(fsockout)) { retcode = 1; } } while (retcode == 0 || retcode == 2); if ((retcode = getnameinfo((struct sockaddr const *)&handle_data_arg->cli_addr, handle_data_arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection closed from %s:%s\n", host, serv); fclose(fsockin); #ifndef __MINGW32__ fclose(fsockout); #endif handle_exit: #ifdef __MINGW32__ closesocket(handle_data_arg->sock); #else close(handle_data_arg->sock); #endif free(arg); #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif return NULL; } void usage() { printf("Usage: rotctld [OPTION]... [COMMAND]...\n" "Daemon serving COMMANDs to a connected antenna rotator.\n\n"); printf( " -m, --model=ID select rotator model number. See model list (-l)\n" " -r, --rot-file=DEVICE set device of the rotator to operate on\n" " -R, --rot-file2=DEVICE set device of the 2nd rotator controller to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -t, --port=NUM set TCP listening port, default %s\n" " -T, --listen-addr=IPADDR set listening IP address, default ANY\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -o, --set-azoffset=VAL set offset for azimuth\n" " -O, --set-eloffset=VAL set offset for elevation\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n", portno); usage_rot(stdout); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/testcache.c0000664000175000017500000001305315056640443011727 /* This program does a check of cache timing and hit/miss * By Michael Black W9MDB * Used in testing caching effects that have been added * To compile: * gcc -I../src -I../include -g -o cachetest3 cachetest3.c -lhamlib * To run: * ./cachetest3 */ #include #include #include #include #include //#include "misc.h" int main(int argc, char *argv[]) { RIG *my_rig; char *rig_file, *info_buf; int retcode; int model; int cache_timeout = 0; model = 1; // we'll just use the dummy rig by default rig_file = "127.0.0.1:4532"; // default if we use model#2 if (argc == 2) { model = atoi(argv[1]); if (model == 1) { rig_file = ""; } } if (argc == 3) { rig_file = argv[2]; } printf("Model#%d\n", model); rig_set_debug(RIG_DEBUG_CACHE); /* Instantiate a rig */ my_rig = rig_init(model); // your rig model. /* Set up serial port, baud rate */ rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), rig_file); /* Open my rig */ retcode = rig_open(my_rig); if (retcode != RIG_OK) { fprintf(stderr, "%s: rig_open failed %s\n", __func__, rigerror(retcode)); return 1; } rig_set_cache_timeout_ms(my_rig, HAMLIB_CACHE_ALL, cache_timeout); /* Give me ID info, e.g., firmware version. */ info_buf = (char *)rig_get_info(my_rig); if (info_buf) { char *s = strdup(info_buf); strtok(s, "\r\n"); printf("Rig_info: '%s'\n", s); free(s); } vfo_t vfo; retcode = rig_get_vfo(my_rig, &vfo); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_vfo: %s\n", __func__, rigerror(retcode)); return retcode; } if (vfo != RIG_VFO_A) { printf("VFO != VFOA\n"); exit(1); } printf("VFO: %s\n", rig_strvfo(vfo)); freq_t freqA, freqB, freqC; rmode_t modeA, modeB, modeC; pbwidth_t widthA, widthB, widthC; int freq_ms, mode_ms, width_ms; rig_get_cache(my_rig, vfo, &freqA, &freq_ms, &modeA, &mode_ms, &widthA, &width_ms); printf("freq=%.0f cache times=%d,%d,%d\n", freqA, freq_ms, mode_ms, width_ms); rig_get_cache(my_rig, vfo, &freqA, &freq_ms, &modeA, &mode_ms, &widthA, &width_ms); printf("freq=%.0f cache times=%d,%d,%d\n", freqA, freq_ms, mode_ms, width_ms); rig_set_freq(my_rig, RIG_VFO_A, 14074000.0); rig_set_freq(my_rig, RIG_VFO_B, 14075000.0); rig_set_freq(my_rig, RIG_VFO_C, 14076000.0); rig_set_mode(my_rig, RIG_VFO_A, RIG_MODE_USB, 1000); rig_set_mode(my_rig, RIG_VFO_B, RIG_MODE_LSB, 2000); rig_set_mode(my_rig, RIG_VFO_C, RIG_MODE_PKTUSB, 3000); rig_get_cache(my_rig, RIG_VFO_A, &freqA, &freq_ms, &modeA, &mode_ms, &widthA, &width_ms); printf("VFOA freq=%.0f, mode=%s, width=%d, cache times=%d,%d,%d\n", freqA, rig_strrmode(modeA), (int)widthA, freq_ms, mode_ms, width_ms); rig_get_cache(my_rig, RIG_VFO_B, &freqB, &freq_ms, &modeB, &mode_ms, &widthB, &width_ms); printf("VFOB freq=%.0f, mode=%s, width=%d, cache times=%d,%d,%d\n", freqB, rig_strrmode(modeB), (int)widthB, freq_ms, mode_ms, width_ms); rig_get_cache(my_rig, RIG_VFO_C, &freqC, &freq_ms, &modeC, &mode_ms, &widthC, &width_ms); printf("VFOC freq=%.0f, mode=%s, width=%d, cache times=%d,%d,%d\n", freqC, rig_strrmode(modeC), (int)widthC, freq_ms, mode_ms, width_ms); if (freqA != 14074000) { printf("freqA == %.1f\n", freqA); exit(1); } if (modeA != RIG_MODE_USB) { printf("modeA = %s\n", rig_strrmode(modeA)); exit(1); } if (widthA != 1000) { printf("widthA = %d\n", (int)widthA); exit(1); } if (freqB != 14075000) { printf("freqB = %.1f\n", freqB); exit(1); } if (modeB != RIG_MODE_LSB) { printf("modeB = %s\n", rig_strrmode(modeB)); exit(1); } if (widthB != 2000) { printf("widthB = %d\n", (int)widthB); exit(1); } if (freqC != 14076000) { printf("freqC = %.1f\n", freqC); exit(1); } if (modeC != RIG_MODE_PKTUSB) { printf("modeC = %s\n", rig_strrmode(modeC)); exit(1); } if (widthC != 3000) { printf("widthC = %d\n", (int)widthC); exit(1); } #if 0 // PTT does not work for dummy device printf("PTT ON\n"); rig_set_ptt(my_rig, RIG_VFO_CURR, RIG_PTT_ON); ptt_t ptt; printf("PTT get ptt ON\n"); rig_get_ptt(my_rig, RIG_VFO_CURR, &ptt); if (ptt != RIG_PTT_ON) { printf("ptt != ON\n"); exit(1); } hl_usleep(1000 * 1000); rig_get_ptt(my_rig, RIG_VFO_CURR, &ptt); printf("PTT get ptt ON\n"); if (ptt != RIG_PTT_ON) { printf("ptt != ON\n"); exit(1); } printf("PTT ptt OFF\n"); rig_set_ptt(my_rig, RIG_VFO_CURR, RIG_PTT_OFF); if (ptt != RIG_PTT_ON) { printf("ptt != ON\n"); exit(1); } rig_get_ptt(my_rig, RIG_VFO_CURR, &ptt); printf("PTT get ptt OFF\n"); #endif vfo_t tx_vfo; split_t split; rig_get_split_vfo(my_rig, RIG_VFO_A, &split, &tx_vfo); printf("split=%d, tx_vfo=%s\n", split, rig_strvfo(tx_vfo)); if (split != 0 || tx_vfo != RIG_VFO_NONE) { printf("split#1 failed\n"); exit(1); } rig_set_split_vfo(my_rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); hl_usleep(1000 * 1000); rig_get_split_vfo(my_rig, RIG_VFO_A, &split, &tx_vfo); printf("split=%d, tx_vfo=%s\n", split, rig_strvfo(tx_vfo)); if (split != RIG_SPLIT_ON || (tx_vfo != RIG_VFO_B && tx_vfo != RIG_VFO_SUB)) { printf("split#2 failed\n"); exit(1); } printf("All OK\n"); rig_close(my_rig); return 0 ; }; hamlib-4.6.5/tests/rigctlsync.c0000664000175000017500000004143215056640443012147 /* * rigctlsync.c - (C) Stephane Fillod 2000-2011 * (C) The Hamlib Group 2012 * (C) Nate Bargmann 2008,2010,2011,2012,2013 * (C) Michael Black W9MDB 2023 - derived from rigctlcom.c * * This program will synchronize frequency from one rig to another * Implemented for AirSpy SDR# to keep freq synced with a real rig * It simply polls the real rig and when freq changes sends it to SDR# (or whatever rig is hooked up) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #ifdef WIN32 #define WIN32_LEAN_AND_MEAN // cppcheck-suppress * #include #endif // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include #ifdef HAVE_NETINET_IN_H // cppcheck-suppress * # include #endif #ifdef HAVE_ARPA_INET_H // cppcheck-suppress * # include #endif #ifdef HAVE_SYS_SOCKET_H // cppcheck-suppress * # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #include #include "rigctl_parse.h" #include "riglist.h" #include "sleep.h" /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "Bm:M:r:R:p:d:P:D:s:S:c:C:lLuvhVZ" static struct option long_options[] = { {"mapa2b", 0, 0, 'B'}, {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"rig-file2", 1, 0, 'R'}, {"ptt-file", 1, 0, 'p'}, {"dcd-file", 1, 0, 'd'}, {"ptt-type", 1, 0, 'P'}, {"dcd-type", 1, 0, 'D'}, {"serial-speed", 1, 0, 's'}, {"serial-speed2", 1, 0, 'S'}, {"civaddr", 1, 0, 'c'}, {"set-conf", 1, 0, 'C'}, {"list", 0, 0, 'l'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"debug-time-stamps", 0, 0, 'Z'}, {0, 0, 0, 0} }; void usage(); static RIG *my_rig; /* handle to rig */ static RIG *my_rig_sync; /* rig the gets synchronized -- freq only for now */ static int verbose; /* CW Skimmer can only set VFOA */ /* IC7300 for example can run VFOA on FM and VFOB on CW */ /* So -A/--mapa2b changes set_freq on VFOA to VFOB */ /* This allows working CW Skimmer in split mode and transmit on VFOB */ static int mapa2b; /* maps set_freq on VFOA to VFOB instead */ #ifdef HAVE_SIG_ATOMIC_T static sig_atomic_t volatile ctrl_c; #else static int volatile ctrl_c; #endif #define MAXCONFLEN 2048 #if 0 # ifdef WIN32 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { rig_debug(RIG_DEBUG_VERBOSE, "CtrlHandler called\n"); switch (fdwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: ctrl_c = 1; return TRUE; default: return FALSE; } } # else static void signal_handler(int sig) { switch (sig) { case SIGINT: ctrl_c = 1; break; default: /* do nothing */ break; } } # endif /* ifdef WIN32 */ #endif /* if 0 */ #if 0 static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; # ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } # else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); # endif /* ifdef __MINGW32__ */ } #endif /* if 0 */ int main(int argc, char *argv[]) { rig_model_t my_model[] = { RIG_MODEL_DUMMY, RIG_MODEL_SDRSHARP }; int retcode; /* generic return code from functions */ int show_conf = 0; int dump_caps_opt = 0; const char *rig_file = NULL, *rig_file2 = "127.0.0.1:4532"; //const char **ptt_file = NULL, *dcd_file = NULL; //ptt_type_t ptt_type = RIG_PTT_NONE; //dcd_type_t dcd_type = RIG_DCD_NONE; int serial_rate = 0; int serial_rate2 = 0; /* virtual com port default speed */ char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; printf("rigctlsync Version 1.0\n"); while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': rig_version(); exit(0); case 'B': mapa2b = 1; break; case 'm': case 'M': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (c == 'm') { my_model[0] = atoi(optarg); } else { my_model[1] = atoi(optarg); } break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'R': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file2 = optarg; break; #if 0 case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; #endif #if 0 case 'd': if (!optarg) { usage(); /* wrong arg count */ exit(1); } dcd_file = optarg; break; #endif #if 0 case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "CM108")) { ptt_type = RIG_PTT_CM108; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { ptt_type = atoi(optarg); } break; #endif #if 0 case 'D': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { dcd_type = RIG_DCD_RIG; } else if (!strcmp(optarg, "DSR")) { dcd_type = RIG_DCD_SERIAL_DSR; } else if (!strcmp(optarg, "CTS")) { dcd_type = RIG_DCD_SERIAL_CTS; } else if (!strcmp(optarg, "CD")) { dcd_type = RIG_DCD_SERIAL_CAR; } else if (!strcmp(optarg, "PARALLEL")) { dcd_type = RIG_DCD_PARALLEL; } else if (!strcmp(optarg, "NONE")) { dcd_type = RIG_DCD_NONE; } else { dcd_type = atoi(optarg); } break; #endif case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'S': if (!optarg) { usage(); /* wrong arg count */ exit(1); } serial_rate2 = atoi(optarg); break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': rig_set_debug(verbose); list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "%s, %s\n", "rigctlsync", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); if (argc < 3) { usage(); exit(1); } my_rig = rig_init(my_model[0]); if (!my_rig) { fprintf(stderr, "Unknown rig num %d, or initialization error.\n", my_model[0]); fprintf(stderr, "Please check with --list option.\n"); exit(2); } my_rig_sync = rig_init(my_model[1]); if (!my_rig_sync) { fprintf(stderr, "Unknown rig num %d, or initialization error.\n", my_model[1]); fprintf(stderr, "Please check with --list option.\n"); exit(2); } #if 0 retcode = set_conf(my_rig, conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } #endif if (my_model[0] > 5 && !rig_file) { fprintf(stderr, "-r rig com port not provided\n"); exit(2); } if (rig_file) { strncpy(RIGPORT(my_rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } fprintf(stderr, "rig to send frequency to: %s\n", rig_file2); strncpy(RIGPORT(my_rig_sync)->pathname, rig_file2, HAMLIB_FILPATHLEN - 1); #if 0 /* * ex: RIG_PTT_PARALLEL and /dev/parport0 */ if (ptt_type != RIG_PTT_NONE) { PTTPORT(my_rig)->type.ptt = ptt_type; } if (dcd_type != RIG_DCD_NONE) { DCDPORT(my_rig)->type.dcd = dcd_type; } if (ptt_file) { strncpy(PTTPORT(my_rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); } if (dcd_file) { strncpy(DCDPORT(my_rig)->pathname, dcd_file, HAMLIB_FILPATHLEN - 1); } #endif /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(my_rig)->parm.serial.rate = serial_rate; } if (serial_rate2 != 0) { RIGPORT(my_rig_sync)->parm.serial.rate = serial_rate2; } if (civaddr) { rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); } /* * print out conf parameters */ if (show_conf) { rig_token_foreach(my_rig, print_conf_list, (rig_ptr_t)my_rig); } /* * print out conf parameters, and exits immediately * We may be interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps(my_rig, stdout); rig_cleanup(my_rig); /* if you care about memory */ exit(0); } /* open and close rig connection to check early for issues */ retcode = rig_open(my_rig); if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s \n", rigerror(retcode)); exit(2); } retcode = rig_open(my_rig_sync); if (retcode != RIG_OK) { fprintf(stderr, "rig_open sync: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened rig model %u, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); /* * main loop */ do { freq_t freq; retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Error in rig_get_freq: %s\n", __func__, rigerror(retcode)); } retcode = rig_set_freq(my_rig_sync, RIG_VFO_CURR, freq); hl_usleep(400 * 1000); // fairly fast to keep up } while (retcode == 0 && !ctrl_c); rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ return 0; } void usage() { const char *name = "rigctlsync"; printf("Usage: %s -m rignumber -r comport -s baud -M rignumber -R comport [OPTIONS]...\n\n" "Will copy frequency from -m rig to -M rig\n" "e.g. will keep SDR# synchronized to a rig.\n\n", name); printf("Example: Sync freq from rigctld to SDR#\n"); printf("\t%s -m 2 -M 9 -R 127.0.0.1:4532\n\n", name); printf("See the %s.1 manual page for complete details.\n\n", name); printf( " -m, --model=ID select radio model number. See model list (-l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -R, --rig-file2=DEVICE set device of the virtual com port to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -S, --serial-speed2=BAUD set serial speed of the virtual com port [default=115200]\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n" ); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rigtestlibusb.c0000664000175000017500000002717615056640443012661 /* * To compile on linux ensure you have libusb-1.0 installed * e.g. apt install libusb-1.0-0-dev * Also works on MinGW with both static build and DLLs from MSVC builds * gcc -o testlibusb testlibusb.c -lusb-1.0 * * Test suite program based of libusb-0.1-compat testlibusb * Copyright (c) 2013 Nathan Hjelm * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "config.h" #if defined(HAVE_LIBUSB_H) #include #elif defined(HAVE_LIBUSB_1_0_LIBUSB_H) #include #endif #if HAVE_LIBUSB int verbose = 0; static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp) { printf(" USB 3.0 Endpoint Companion:\n"); printf(" bMaxBurst: %u\n", ep_comp->bMaxBurst); printf(" bmAttributes: %02xh\n", ep_comp->bmAttributes); printf(" wBytesPerInterval: %u\n", ep_comp->wBytesPerInterval); } static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint) { int i, ret; printf(" Endpoint:\n"); printf(" bEndpointAddress: %02xh\n", endpoint->bEndpointAddress); printf(" bmAttributes: %02xh\n", endpoint->bmAttributes); printf(" wMaxPacketSize: %u\n", endpoint->wMaxPacketSize); printf(" bInterval: %u\n", endpoint->bInterval); printf(" bRefresh: %u\n", endpoint->bRefresh); printf(" bSynchAddress: %u\n", endpoint->bSynchAddress); for (i = 0; i < endpoint->extra_length;) { if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) { struct libusb_ss_endpoint_companion_descriptor *ep_comp; ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp); if (LIBUSB_SUCCESS != ret) { continue; } print_endpoint_comp(ep_comp); libusb_free_ss_endpoint_companion_descriptor(ep_comp); } i += endpoint->extra[i]; } } static void print_altsetting(const struct libusb_interface_descriptor *interface) { uint8_t i; printf(" Interface:\n"); printf(" bInterfaceNumber: %u\n", interface->bInterfaceNumber); printf(" bAlternateSetting: %u\n", interface->bAlternateSetting); printf(" bNumEndpoints: %u\n", interface->bNumEndpoints); printf(" bInterfaceClass: %u\n", interface->bInterfaceClass); printf(" bInterfaceSubClass: %u\n", interface->bInterfaceSubClass); printf(" bInterfaceProtocol: %u\n", interface->bInterfaceProtocol); printf(" iInterface: %u\n", interface->iInterface); for (i = 0; i < interface->bNumEndpoints; i++) { print_endpoint(&interface->endpoint[i]); } } static void print_2_0_ext_cap(const struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap) { printf(" USB 2.0 Extension Capabilities:\n"); printf(" bDevCapabilityType: %u\n", usb_2_0_ext_cap->bDevCapabilityType); printf(" bmAttributes: %08xh\n", usb_2_0_ext_cap->bmAttributes); } static void print_ss_usb_cap(const struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap) { printf(" USB 3.0 Capabilities:\n"); printf(" bDevCapabilityType: %u\n", ss_usb_cap->bDevCapabilityType); printf(" bmAttributes: %02xh\n", ss_usb_cap->bmAttributes); printf(" wSpeedSupported: %u\n", ss_usb_cap->wSpeedSupported); printf(" bFunctionalitySupport: %u\n", ss_usb_cap->bFunctionalitySupport); printf(" bU1devExitLat: %u\n", ss_usb_cap->bU1DevExitLat); printf(" bU2devExitLat: %u\n", ss_usb_cap->bU2DevExitLat); } static void print_bos(libusb_device_handle *handle) { struct libusb_bos_descriptor *bos; uint8_t i; int ret; ret = libusb_get_bos_descriptor(handle, &bos); if (ret < 0) { return; } printf(" Binary Object Store (BOS):\n"); printf(" wTotalLength: %u\n", bos->wTotalLength); printf(" bNumDeviceCaps: %u\n", bos->bNumDeviceCaps); for (i = 0; i < bos->bNumDeviceCaps; i++) { struct libusb_bos_dev_capability_descriptor *dev_cap = bos->dev_capability[i]; if (dev_cap->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) { struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension; ret = libusb_get_usb_2_0_extension_descriptor(NULL, dev_cap, &usb_2_0_extension); if (ret < 0) { return; } print_2_0_ext_cap(usb_2_0_extension); libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension); } else if (dev_cap->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) { struct libusb_ss_usb_device_capability_descriptor *ss_dev_cap; ret = libusb_get_ss_usb_device_capability_descriptor(NULL, dev_cap, &ss_dev_cap); if (ret < 0) { return; } print_ss_usb_cap(ss_dev_cap); libusb_free_ss_usb_device_capability_descriptor(ss_dev_cap); } } libusb_free_bos_descriptor(bos); } static void print_interface(const struct libusb_interface *interface) { int i; for (i = 0; i < interface->num_altsetting; i++) { print_altsetting(&interface->altsetting[i]); } } static void print_configuration(struct libusb_config_descriptor *config) { uint8_t i; printf(" Configuration:\n"); printf(" wTotalLength: %u\n", config->wTotalLength); printf(" bNumInterfaces: %u\n", config->bNumInterfaces); printf(" bConfigurationValue: %u\n", config->bConfigurationValue); printf(" iConfiguration: %u\n", config->iConfiguration); printf(" bmAttributes: %02xh\n", config->bmAttributes); printf(" MaxPower: %u\n", config->MaxPower); for (i = 0; i < config->bNumInterfaces; i++) { print_interface(&config->interface[i]); } } static void print_device(libusb_device *dev, libusb_device_handle *handle) { struct libusb_device_descriptor desc; unsigned char string[256]; const char *speed; int ret; uint8_t i; switch (libusb_get_device_speed(dev)) { case LIBUSB_SPEED_LOW: speed = "1.5M"; break; case LIBUSB_SPEED_FULL: speed = "12M"; break; case LIBUSB_SPEED_HIGH: speed = "480M"; break; case LIBUSB_SPEED_SUPER: speed = "5G"; break; #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107) case LIBUSB_SPEED_SUPER_PLUS: speed = "10G"; break; #endif default: speed = "Unknown"; } ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { fprintf(stderr, "failed to get device descriptor"); return; } printf("Dev (bus %u, device %u): %04X - %04X speed: %s\n", libusb_get_bus_number(dev), libusb_get_device_address(dev), desc.idVendor, desc.idProduct, speed); if (!handle) { libusb_open(dev, &handle); } if (handle) { if (desc.iManufacturer) { ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string)); if (ret > 0) { printf(" Manufacturer: %s\n", (char *)string); } } if (desc.iProduct) { ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string)); if (ret > 0) { printf(" Product: %s\n", (char *)string); } } if (desc.iSerialNumber && verbose) { ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string)); if (ret > 0) { printf(" Serial Number: %s\n", (char *)string); } } } if (verbose) { for (i = 0; i < desc.bNumConfigurations; i++) { struct libusb_config_descriptor *config; ret = libusb_get_config_descriptor(dev, i, &config); if (LIBUSB_SUCCESS != ret) { printf(" Couldn't retrieve descriptors\n"); continue; } print_configuration(config); libusb_free_config_descriptor(config); } if (handle && desc.bcdUSB >= 0x0201) { print_bos(handle); } } if (handle) { libusb_close(handle); } } #if defined(ANDROID) && defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION < 0x01000107) #warning LIBUSB-1.0.23 or greater is required for Android devices #include #include #include static int test_wrapped_device(const char *device_name) { libusb_device_handle *handle; int r, fd; fd = open(device_name, O_RDWR); if (fd < 0) { printf("Error could not open %s: %s\n", device_name, strerror(errno)); return 1; } r = libusb_wrap_sys_device(NULL, fd, &handle); if (r) { printf("Error wrapping device: %s: %s\n", device_name, libusb_strerror(r)); close(fd); return 1; } print_device(libusb_get_device(handle), handle); close(fd); return 0; } #else static int test_wrapped_device(const char *device_name) { (void)device_name; printf("Testing wrapped devices is not supported on your platform\n"); return 1; } #endif int main(int argc, const char *argv[]) { const char *device_name = NULL; libusb_device **devs; int r, i; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-v")) { verbose = 1; } else if (!strcmp(argv[i], "-d") && (i + 1) < argc) { i++; device_name = argv[i]; } else { printf("Usage %s [-v] [-d ]\n", argv[0]); printf("Note use -d to test libusb_wrap_sys_device()\n"); return 1; } } r = libusb_init(NULL); if (r < 0) { return r; } if (device_name) { r = test_wrapped_device(device_name); } else { ssize_t cnt; cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) { libusb_exit(NULL); return 1; } for (i = 0; devs[i]; i++) { print_device(devs[i], NULL); } libusb_free_device_list(devs, 1); } libusb_exit(NULL); return r; } #else int main() { puts("libusb not installed"); return 0; } #endif hamlib-4.6.5/tests/memcsv.c0000664000175000017500000005400515056640443011260 /* * memcsv.c - (C) Stephane Fillod 2003-2005 * * This program exercises the backup and restore of a radio * using Hamlib. CSV primitives * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include "misc.h" /* * external prototype */ extern int all; char csv_sep = ','; /* CSV separator */ /* * Prototypes */ static int dump_csv_chan(RIG *rig, vfo_t vfo, channel_t **chan, int channel_num, const chan_t *chan_list, rig_ptr_t arg); static void dump_csv_name(const channel_cap_t *mem_caps, FILE *f); static int set_channel_data(RIG *rig, channel_t *chan, char **line_key, char **line_data); static char *mystrtok(char *s, char delim); static int tokenize_line(char *line, char **token_list, size_t siz, char delim); static int find_on_list(char **list, const char *what); int csv_save(RIG *rig, const char *outfilename); int csv_load(RIG *rig, const char *infilename); int csv_parm_save(RIG *rig, const char *outfilename); int csv_parm_load(RIG *rig, const char *infilename); int csv_save(RIG *rig, const char *outfilename) { int status; FILE *f; f = fopen(outfilename, "w"); if (!f) { return -1; } if (rig->caps->clone_combo_get) { printf("About to save data, enter cloning mode: %s\n", rig->caps->clone_combo_get); } status = rig_get_chan_all_cb(rig, RIG_VFO_NONE, dump_csv_chan, f); fclose(f); return status; } /** csv_load assumes the first line in a csv file is a key line, defining entries and their number. First line should not contain 'empty column', i.e. two adjacent commas. Each next line should contain the same number of entries. However, empty columns (two adjacent commas) are allowed. \param rig - a pointer to the rig \param infilename - a string with a file name to write to */ int csv_load(RIG *rig, const char *infilename) { int status = RIG_OK; FILE *f; char *key_list[ 64 ]; char *value_list[ 64 ]; char keys[ 256 ]; char line[ 256 ]; channel_t chan; f = fopen(infilename, "r"); if (!f) { return -1; } /* First read the first line, containing the key */ if (fgets(keys, sizeof(keys), f) != NULL) { /* fgets stores '\n' in a buffer, get rid of it */ keys[ strlen(keys) - 1 ] = '\0'; printf("Read the key: %s\n", keys); /* Tokenize the key list */ if (!tokenize_line(keys, key_list, sizeof(key_list) / sizeof(char *), ',')) { fprintf(stderr, "Invalid (possibly too long or empty) key line, cannot continue.\n"); fclose(f); return -1; } } else { /* File exists, but is empty */ fclose(f); return -1; } /* Next, read the file line by line */ while (fgets(line, sizeof line, f) != NULL) { /* Tokenize the line */ if (!tokenize_line(line, value_list, sizeof(value_list) / sizeof(char *), ',')) { fprintf(stderr, "Invalid (possibly too long or empty) line ignored\n"); continue; } /* Parse a line, write channel data into chan */ set_channel_data(rig, &chan, key_list, value_list); /* Write a rig memory */ status = rig_set_channel(rig, RIG_VFO_NONE, &chan); if (status != RIG_OK) { fprintf(stderr, "rig_get_channel: error = %s \n", rigerror(status)); fclose(f); return status; } } fclose(f); return status; } /** Function to break a line into a list of tokens. Delimiters are replaced by end-of-string characters ('\0'), and a list of pointers to thus created substrings is created. \param line (input) - a line to be tokenized, the line will be modified! \param token_list (output) - a resulting table containing pointers to tokens, or NULLs (the table will be initially nulled ) all the pointers should point to addresses within the line \param siz (input) - size of the table \param delim (input) - delimiter character \return number of tokens on success, 0 if \param token_list is too small to contain all the tokens, or if line was empty. */ static int tokenize_line(char *line, char **token_list, size_t siz, char delim) { size_t i; char *tok; /* Erase the table */ for (i = 0; i < siz; i++) { token_list[i] = NULL; } /* Empty line passed? */ if (line == NULL) { return 0; } /* Reinitialize, find the first token */ i = 0; tok = mystrtok(line, delim); /* Line contains no delim */ if (tok == NULL) { return 0; } token_list[ i++ ] = tok; /* Find the remaining tokens */ while (i < siz) { tok = mystrtok(NULL, delim); /* If NULL, no more tokens left */ if (tok == NULL) { break; } /* Add token to the list */ token_list[ i++ ] = tok; } /* Any tokens left? */ if (i == siz) { return 0; } else { return i; } } /** Tokenizer that handles two delimiters by returning an empty string. First param (input) is a string to be tokenized, second is a delimiter (input) This tokenizer accepts only one delimiter! \param s - string to divide on first run, NULL on each next \param delim - delimiter \return pointer to token, or NULL if there are no more tokens \sa "man strtok" */ static char *mystrtok(char *s, char delim) { static size_t pos = 0, length = 0; static char *str = 0; size_t i, ent_pos; if (s != NULL) { str = s; pos = 0; length = strlen(str); } else { return NULL; } if (str && str[ pos + 1 ] == '\0') { return NULL; } ent_pos = pos; for (i = pos; i < length;) { if (str[i] == delim) { str[i] = '\0'; pos = i + 1; return str + ent_pos; } else { i++; } } return str + ent_pos; } static int print_parm_name(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { fprintf((FILE *)ptr, "%s%c", cfp->name, csv_sep); return 1; /* process them all */ } static int print_parm_val(RIG *rig, const struct confparams *cfp, rig_ptr_t ptr) { value_t val; FILE *f = (FILE *)ptr; rig_get_ext_parm(rig, cfp->token, &val); switch (cfp->type) { case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(f, "%d%c", val.i, csv_sep); break; case RIG_CONF_NUMERIC: fprintf(f, "%f%c", val.f, csv_sep); break; case RIG_CONF_STRING: fprintf(f, "%s%c", val.s, csv_sep); break; default: fprintf(f, "unknown%c", csv_sep); } return 1; /* process them all */ } int csv_parm_save(RIG *rig, const char *outfilename) { int i, ret; FILE *f; setting_t get_parm = all ? 0x7fffffff : STATE(rig)->has_get_parm; f = fopen(outfilename, "w"); if (!f) { return -1; } for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms = rig_strparm(get_parm & rig_idx2setting(i)); if (!ms || !ms[0]) { continue; } fprintf(f, "%s%c", ms, csv_sep); } rig_ext_parm_foreach(rig, print_parm_name, f); fprintf(f, "\n"); for (i = 0; i < RIG_SETTING_MAX; i++) { const char *ms; value_t val; setting_t parm; parm = get_parm & rig_idx2setting(i); ms = rig_strparm(parm); if (!ms || !ms[0]) { continue; } ret = rig_get_parm(rig, parm, &val); if (ret != RIG_OK) { return ret; } if (RIG_PARM_IS_FLOAT(parm)) { fprintf(f, "%f%c", val.f, csv_sep); } else { fprintf(f, "%d%c", val.i, csv_sep); } } rig_ext_parm_foreach(rig, print_parm_val, f); fprintf(f, "\n"); fclose(f); return 0; } int csv_parm_load(RIG *rig, const char *infilename) { return -RIG_ENIMPL; /* for every parm/ext_parm, fscanf, parse, set_parm's */ } /* *********************** */ /* Caution! Keep the function consistent with dump_csv_chan and set_channel_data! */ void dump_csv_name(const channel_cap_t *mem_caps, FILE *f) { fprintf(f, "num%c", csv_sep); if (mem_caps->bank_num) { fprintf(f, "bank_num%c", csv_sep); } if (mem_caps->channel_desc) { fprintf(f, "channel_desc%c", csv_sep); } if (mem_caps->vfo) { fprintf(f, "vfo%c", csv_sep); } if (mem_caps->ant) { fprintf(f, "ant%c", csv_sep); } if (mem_caps->freq) { fprintf(f, "freq%c", csv_sep); } if (mem_caps->mode) { fprintf(f, "mode%c", csv_sep); } if (mem_caps->width) { fprintf(f, "width%c", csv_sep); } if (mem_caps->tx_freq) { fprintf(f, "tx_freq%c", csv_sep); } if (mem_caps->tx_mode) { fprintf(f, "tx_mode%c", csv_sep); } if (mem_caps->tx_width) { fprintf(f, "tx_width%c", csv_sep); } if (mem_caps->split) { fprintf(f, "split%c", csv_sep); } if (mem_caps->tx_vfo) { fprintf(f, "tx_vfo%c", csv_sep); } if (mem_caps->rptr_shift) { fprintf(f, "rptr_shift%c", csv_sep); } if (mem_caps->rptr_offs) { fprintf(f, "rptr_offs%c", csv_sep); } if (mem_caps->tuning_step) { fprintf(f, "tuning_step%c", csv_sep); } if (mem_caps->rit) { fprintf(f, "rit%c", csv_sep); } if (mem_caps->xit) { fprintf(f, "xit%c", csv_sep); } if (mem_caps->funcs) { fprintf(f, "funcs%c", csv_sep); } if (mem_caps->ctcss_tone) { fprintf(f, "ctcss_tone%c", csv_sep); } if (mem_caps->ctcss_sql) { fprintf(f, "ctcss_sql%c", csv_sep); } if (mem_caps->dcs_code) { fprintf(f, "dcs_code%c", csv_sep); } if (mem_caps->dcs_sql) { fprintf(f, "dcs_sql%c", csv_sep); } if (mem_caps->scan_group) { fprintf(f, "scan_group%c", csv_sep); } if (mem_caps->flags) { fprintf(f, "flags%c", csv_sep); } if (mem_caps->tag) { fprintf(f, "tag%c", csv_sep); } fprintf(f, "\n"); } /* Caution! Keep the function consistent with dump_csv_name and set_channel_data! */ int dump_csv_chan(RIG *rig, vfo_t vfo, channel_t **chan_pp, int channel_num, const chan_t *chan_list, rig_ptr_t arg) { FILE *f = arg; static channel_t chan; static int first_time = 1; const channel_cap_t *mem_caps = &chan_list->mem_caps; if (first_time) { dump_csv_name(mem_caps, f); first_time = 0; } if (*chan_pp == NULL) { /* * Hamlib frontend demand application an allocated * channel_t pointer for next round. */ *chan_pp = &chan; return RIG_OK; } fprintf(f, "%d%c", chan.channel_num, csv_sep); if (mem_caps->bank_num) { fprintf(f, "%d%c", chan.bank_num, csv_sep); } if (mem_caps->channel_desc) { fprintf(f, "%s%c", chan.channel_desc, csv_sep); } if (mem_caps->vfo) { fprintf(f, "%s%c", rig_strvfo(chan.vfo), csv_sep); } if (mem_caps->ant) { fprintf(f, "%u%c", chan.ant, csv_sep); } if (mem_caps->freq) { fprintf(f, "%"PRIfreq"%c", chan.freq, csv_sep); } if (mem_caps->mode) { fprintf(f, "%s%c", rig_strrmode(chan.mode), csv_sep); } if (mem_caps->width) { fprintf(f, "%d%c", (int)chan.width, csv_sep); } if (mem_caps->tx_freq) { fprintf(f, "%"PRIfreq"%c", chan.tx_freq, csv_sep); } if (mem_caps->tx_mode) { fprintf(f, "%s%c", rig_strrmode(chan.tx_mode), csv_sep); } if (mem_caps->tx_width) { fprintf(f, "%d%c", (int)chan.tx_width, csv_sep); } if (mem_caps->split) { fprintf(f, "%s%c", chan.split == RIG_SPLIT_ON ? "on" : "off", csv_sep); } if (mem_caps->tx_vfo) { fprintf(f, "%s%c", rig_strvfo(chan.tx_vfo), csv_sep); } if (mem_caps->rptr_shift) { fprintf(f, "%s%c", rig_strptrshift(chan.rptr_shift), csv_sep); } if (mem_caps->rptr_offs) { fprintf(f, "%d%c", (int)chan.rptr_offs, csv_sep); } if (mem_caps->tuning_step) { fprintf(f, "%d%c", (int)chan.tuning_step, csv_sep); } if (mem_caps->rit) { fprintf(f, "%d%c", (int)chan.rit, csv_sep); } if (mem_caps->xit) { fprintf(f, "%d%c", (int)chan.xit, csv_sep); } if (mem_caps->funcs) { fprintf(f, "%"PRXll"%c", chan.funcs, csv_sep); } if (mem_caps->ctcss_tone) { fprintf(f, "%u%c", chan.ctcss_tone, csv_sep); } if (mem_caps->ctcss_sql) { fprintf(f, "%u%c", chan.ctcss_sql, csv_sep); } if (mem_caps->dcs_code) { fprintf(f, "%u%c", chan.dcs_code, csv_sep); } if (mem_caps->dcs_sql) { fprintf(f, "%u%c", chan.dcs_sql, csv_sep); } if (mem_caps->scan_group) { fprintf(f, "%d%c", chan.scan_group, csv_sep); } if (mem_caps->flags) { if (chan.tag[0] != 0) // then we need the separator { fprintf(f, "%x%c", chan.flags, csv_sep); } else { fprintf(f, "%x", chan.flags); } } if (chan.tag[0] != 0) { fprintf(f, "%s", chan.tag); } fprintf(f, "\n"); /* * keep the same *chan_pp for next round, thanks * to chan being static */ return RIG_OK; } /** Function to parse a line read from csv file and store the data into appropriate fields of channel_t. The function must be consistent with dump_csv_name and dump_csv_chan. \param rig - a pointer to the rig \param chan - a pointer to channel_t structure with channel data \param line_key_list - a pointer to a table of strings with "keys" \param line_data_list - a pointer to a table of strings with values \return 0 on success, negative value on error */ int set_channel_data(RIG *rig, channel_t *chan, char **line_key_list, char **line_data_list) { int i, j, n; const channel_cap_t *mem_caps; struct rig_state *rs = STATE(rig); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_CURR; i = find_on_list(line_key_list, "num"); if (i < 0) { fprintf(stderr, "No channel number\n"); return -1; } n = chan->channel_num = atoi(line_data_list[ i ]); /* find channel caps of appropriate memory group? */ for (j = 0; j < HAMLIB_CHANLSTSIZ; j++) { if (rs->chan_list[j].startc <= n && rs->chan_list[j].endc >= n) { break; } } if (j == HAMLIB_CHANLSTSIZ) { return -RIG_EINVAL; } printf("Requested channel number %d, list number %d\n", n, j); mem_caps = &rs->chan_list[j].mem_caps; if (mem_caps->bank_num) { i = find_on_list(line_key_list, "bank_num"); if (i >= 0) { chan->bank_num = atoi(line_data_list[ i ]); } } if (mem_caps->channel_desc) { i = find_on_list(line_key_list, "channel_desc"); if (i >= 0) { strncpy(chan->channel_desc, line_data_list[ i ], rig->caps->chan_desc_sz - 1); chan->channel_desc[ rig->caps->chan_desc_sz ] = '\0'; } } if (mem_caps->ant) { i = find_on_list(line_key_list, "ant"); if (i >= 0) { chan->ant = atoi(line_data_list[ i ]); } } if (mem_caps->freq) { i = find_on_list(line_key_list, "freq"); if (i >= 0) { chan->freq = atoi(line_data_list[ i ]); } } if (mem_caps->mode) { i = find_on_list(line_key_list, "mode"); if (i >= 0) { chan->mode = rig_parse_mode(line_data_list[ i ]); } } if (mem_caps->width) { i = find_on_list(line_key_list, "width"); if (i >= 0) { chan->width = atoi(line_data_list[ i ]); } } if (mem_caps->tx_freq) { i = find_on_list(line_key_list, "tx_freq"); if (i >= 0) { sscanf(line_data_list[i], "%"SCNfreq, &chan->tx_freq); } } if (mem_caps->tx_mode) { i = find_on_list(line_key_list, "tx_mode"); if (i >= 0) { chan->tx_mode = rig_parse_mode(line_data_list[ i ]); } } if (mem_caps->tx_width) { i = find_on_list(line_key_list, "tx_width"); if (i >= 0) { chan->tx_width = atoi(line_data_list[ i ]); } } if (mem_caps->split) { chan->split = RIG_SPLIT_OFF; i = find_on_list(line_key_list, "split"); if (i >= 0) { if (strcmp(line_data_list[i], "on") == 0) { chan->split = RIG_SPLIT_ON; if (mem_caps->tx_vfo) { i = find_on_list(line_key_list, "tx_vfo"); if (i >= 0) { sscanf(line_data_list[i], "%x", &chan->tx_vfo); } } } } } if (mem_caps->rptr_shift) { i = find_on_list(line_key_list, "rptr_shift"); if (i >= 0) { switch (line_data_list[i][0]) { case '=': chan->rptr_shift = RIG_RPT_SHIFT_NONE; break; case '+': chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break; case '-': chan->rptr_shift = RIG_RPT_SHIFT_MINUS; break; } if (mem_caps->rptr_offs && chan->rptr_shift != RIG_RPT_SHIFT_NONE) { i = find_on_list(line_key_list, "rptr_offs"); if (i >= 0) { chan->rptr_offs = atoi(line_data_list[ i ]); } } } } if (mem_caps->tuning_step) { i = find_on_list(line_key_list, "tuning_step"); if (i >= 0) { chan->tuning_step = atoi(line_data_list[ i ]); } } if (mem_caps->rit) { i = find_on_list(line_key_list, "rit"); if (i >= 0) { chan->rit = atoi(line_data_list[ i ]); } } if (mem_caps->xit) { i = find_on_list(line_key_list, "xit"); if (i >= 0) { chan->xit = atoi(line_data_list[ i ]); } } if (mem_caps->funcs) { i = find_on_list(line_key_list, "funcs"); if (i >= 0) { sscanf(line_data_list[i], "%"SCNXll, &chan->funcs); } } if (mem_caps->ctcss_tone) { i = find_on_list(line_key_list, "ctcss_tone"); if (i >= 0) { chan->ctcss_tone = atoi(line_data_list[ i ]); } } if (mem_caps->ctcss_sql) { i = find_on_list(line_key_list, "ctcss_sql"); if (i >= 0) { chan->ctcss_sql = atoi(line_data_list[ i ]); } } if (mem_caps->dcs_code) { i = find_on_list(line_key_list, "dcs_code"); if (i >= 0) { chan->dcs_code = atoi(line_data_list[ i ]); } } if (mem_caps->dcs_sql) { i = find_on_list(line_key_list, "dcs_sql"); if (i >= 0) { chan->dcs_sql = atoi(line_data_list[ i ]); } } if (mem_caps->scan_group) { i = find_on_list(line_key_list, "scan_group"); if (i >= 0) { chan->scan_group = atoi(line_data_list[ i ]); } } if (mem_caps->flags) { i = find_on_list(line_key_list, "flags"); if (i >= 0) { sscanf(line_data_list[i], "%x", &chan->flags); } } return 0; } /** Find a string on the list. Assumes the last element on the list is NULL \param list - a list \param what - a string to find \return string position on the list on success, -1 if string not found or if string is empty */ int find_on_list(char **list, const char *what) { int i = 0; if (!what) { return -1; } if (!list[i]) { return -1; } while (list[i] != NULL) { if (strcmp(list[i], what) == 0) { return i; } else { i++; } } return i; } hamlib-4.6.5/tests/testloc.c0000664000175000017500000001630215056640443011441 /* * Very simple test program to check locator conversion against some other --SF * This is mainly to test longlat2locator and locator2longlat functions. * * Takes at least two arguments, which is a locator and desired locater * precision in pairs, e.g. EM19ov is three pairs. precision is limited * to >= 1 or <= 6. If two locators are given, then the qrb is also * calculated. * * */ #include #include #include #include #include int main(int argc, char *argv[]) { char recodedloc[13], *loc1, *loc2, sign; double lon1, lat1, lon2, lat2; double distance, az, mmm, sec; int deg, min, retcode, loc_len, nesw = 0; if (argc < 2) { fprintf(stderr, "Usage: %s []\n", argv[0]); exit(1); } loc1 = argv[1]; loc_len = argc > 2 ? atoi(argv[2]) : strlen(loc1) / 2; loc2 = argc > 3 ? argv[3] : NULL; printf("Locator1:\t%s\n", loc1); /* hamlib function to convert maidenhead to decimal degrees */ retcode = locator2longlat(&lon1, &lat1, loc1); if (retcode != RIG_OK) { fprintf(stderr, "locator2longlat() failed with malformed input.\n"); exit(2); } /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lon1, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" Longitude:\t%f\t%c%d %d' %.2f\"\n", lon1, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lon1 = dms2dec(deg, min, sec, nesw); printf(" Recoded lon:\t%f\n", lon1); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lon1, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" GPS lon:\t%f\t%c%d %.3f'\n", lon1, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lon1 = dmmm2dec(deg, mmm, nesw, 0.0); printf(" Recoded GPS:\t%f\n", lon1); /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lat1, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" Latitude:\t%f\t%c%d %d' %.2f\"\n", lat1, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lat1 = dms2dec(deg, min, sec, nesw); printf(" Recoded lat:\t%f\n", lat1); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lat1, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" GPS lat:\t%f\t%c%d %.3f'\n", lat1, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lat1 = dmmm2dec(deg, mmm, nesw, 0.0); printf(" Recoded GPS:\t%f\n", lat1); /* hamlib function to convert decimal degrees to maidenhead */ retcode = longlat2locator(lon1, lat1, recodedloc, loc_len); if (retcode != RIG_OK) { fprintf(stderr, "longlat2locator() failed, precision out of range.\n"); exit(2); } printf(" Recoded:\t%s\n", recodedloc); if (loc2 == NULL) { exit(0); } /* Now work on the second locator */ printf("\nLocator2:\t%s\n", loc2); retcode = locator2longlat(&lon2, &lat2, loc2); if (retcode != RIG_OK) { fprintf(stderr, "locator2longlat() failed with malformed input.\n"); exit(2); } /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lon2, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" Longitude:\t%f\t%c%d %d' %.2f\"\n", lon2, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lon2 = dms2dec(deg, min, sec, nesw); printf(" Recoded lon:\t%f\n", lon2); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lon2, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" GPS lon:\t%f\t%c%d %.3f'\n", lon2, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lon2 = dmmm2dec(deg, mmm, nesw, 0.0); printf(" Recoded GPS:\t%f\n", lon2); /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lat2, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" Latitude:\t%f\t%c%d %d' %.2f\"\n", lat2, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lat2 = dms2dec(deg, min, sec, nesw); printf(" Recoded lat:\t%f\n", lat2); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lat2, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid parameter address.\n"); exit(2); } if (nesw == 1) { sign = '-'; } else { sign = '\0'; } printf(" GPS lat:\t%f\t%c%d %.3f'\n", lat2, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lat2 = dmmm2dec(deg, mmm, nesw, 0.0); printf(" Recoded GPS:\t%f\n", lat2); /* hamlib function to convert decimal degrees to maidenhead */ retcode = longlat2locator(lon2, lat2, recodedloc, loc_len); if (retcode != RIG_OK) { fprintf(stderr, "longlat2locator() failed, precision out of range.\n"); exit(2); } printf(" Recoded:\t%s\n", recodedloc); retcode = qrb(lon1, lat1, lon2, lat2, &distance, &az); if (retcode != RIG_OK) { fprintf(stderr, "QRB error: %d\n", retcode); exit(2); } dec2dms(az, °, &min, &sec, &nesw); printf("\nDistance: %.6fkm\n", distance); if (nesw == 1) { sign = '-'; } else { sign = '\0'; } /* Beware printf() rounding error! */ printf("Bearing: %.2f, %c%d %d' %.2f\"\n", az, sign, deg, min, sec); exit(0); } hamlib-4.6.5/tests/rotctl.c0000664000175000017500000003522515056640443011300 /* * rotctl.c - (C) Stephane Fillod 2000-2010 * (C) Nate Bargmann 2003,2007,2010,2011,2012,2013 * (C) The Hamlib Group 2002,2006 * * This program test/control a rotator using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # include # define HST_SHRT_OPTS "iI" # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ #else /* no history */ # define HST_SHRT_OPTS "" #endif /* HAVE_READLINE_HISTORY */ #include #include "rig.h" #include "rotctl_parse.h" #include "rotlist.h" /* * Prototypes */ void usage(); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "+m:r:R:s:C:o:O:t:LvhVluZ" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rot-file", 1, 0, 'r'}, {"rot-file2", 1, 0, 'R'}, {"serial-speed", 1, 0, 's'}, {"send-cmd-term", 1, 0, 't'}, {"list", 0, 0, 'l'}, {"set-conf", 1, 0, 'C'}, {"set-azoffset", 1, 0, 'o'}, {"set-eloffset", 1, 0, 'O'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"debug-time-stamps", 0, 0, 'Z'}, #ifdef HAVE_READLINE_HISTORY {"read-history", 0, 0, 'i'}, {"save-history", 0, 0, 'I'}, #endif {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; #define MAXCONFLEN 2048 /* variable for readline support */ #ifdef HAVE_LIBREADLINE static const int have_rl = 1; #endif int main(int argc, char *argv[]) { ROT *my_rot; /* handle to rot (instance) */ rot_model_t my_model = ROT_MODEL_DUMMY; int retcode; /* generic return code from functions */ int exitcode; int verbose = 0; int show_conf = 0; int dump_caps_opt = 0; #ifdef HAVE_READLINE_HISTORY int rd_hist = 0; int sv_hist = 0; const char *hist_dir = NULL; const char hist_file[] = "/.rotctl_history"; char *hist_path = NULL; #endif /* HAVE_READLINE_HISTORY */ const char *rot_file = NULL; const char *rot_file2 = NULL; // for 2nd controller for RT21 int serial_rate = 0; char conf_parms[MAXCONFLEN] = ""; int interactive = 1; /* if no cmd on command line, switch to interactive */ int prompt = 1; /* Print prompt in rotctl */ char send_cmd_term = '\r'; /* send_cmd termination char */ azimuth_t az_offset = 0; elevation_t el_offset = 0; while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS HST_SHRT_OPTS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_file = optarg; break; case 'R': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_file2 = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (strlen(optarg) > 1) { send_cmd_term = strtol(optarg, NULL, 0); } else { send_cmd_term = optarg[0]; } break; case 'o': if (!optarg) { usage(); /* wrong arg count */ exit(1); } az_offset = atof(optarg); break; case 'O': if (!optarg) { usage(); /* wrong arg count */ exit(1); } el_offset = atof(optarg); break; #ifdef HAVE_READLINE_HISTORY case 'i': rd_hist++; break; case 'I': sv_hist++; break; #endif /* HAVE_READLINE_HISTORY */ case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': rig_set_debug(0); list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose); rig_debug(RIG_DEBUG_VERBOSE, "rotctl %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); /* * at least one command on command line, * disable interactive mode */ if (optind < argc) { interactive = 0; } my_rot = rot_init(my_model); if (!my_rot) { fprintf(stderr, "Unknown rot num %d, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } char *token = strtok(conf_parms, ","); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = rot_token_lookup(my_rot, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s', use -L switch to see\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = rot_set_conf(my_rot, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } token = strtok(NULL, ","); } hamlib_port_t *rotp = ROTPORT(my_rot); hamlib_port_t *rotp2 = ROTPORT2(my_rot); if (rot_file) { strncpy(rotp->pathname, rot_file, HAMLIB_FILPATHLEN - 1); } if (rot_file2) { strncpy(rotp2->pathname, rot_file2, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ rotp2->parm.serial.rate = rotp->parm.serial.rate; rotp2->parm.serial.data_bits = rotp->parm.serial.data_bits; if (serial_rate != 0) { rotp->parm.serial.rate = serial_rate; rotp2->parm.serial.rate = serial_rate; } /* * print out conf parameters */ if (show_conf) { rot_token_foreach(my_rot, print_conf_list, (rig_ptr_t)my_rot); } retcode = rot_open(my_rot); if (retcode != RIG_OK) { fprintf(stderr, "rot_open: error = %s \n", rigerror(retcode)); exit(2); } /* * Print out capabilities, and exits immediately as we may be interested * only in caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps_rot(my_rot, stdout); rot_cleanup(my_rot); /* if you care about memory */ exit(0); } ROTSTATE(my_rot)->az_offset = az_offset; ROTSTATE(my_rot)->el_offset = el_offset; if (verbose > 0) { printf("Opened rot model %d, '%s'\n", my_rot->caps->rot_model, my_rot->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rot->caps->version, rig_strstatus(my_rot->caps->status)); exitcode = 0; #ifdef HAVE_LIBREADLINE // cppcheck-suppress knownConditionTrueFalse if (interactive && prompt && have_rl) { rl_readline_name = "rotctl"; #ifdef HAVE_READLINE_HISTORY using_history(); /* Initialize Readline History */ if (rd_hist || sv_hist) { int hist_path_size; struct stat hist_dir_stat; if (!(hist_dir = getenv("ROTCTL_HIST_DIR"))) { hist_dir = getenv("HOME"); } if (((stat(hist_dir, &hist_dir_stat) == -1) && (errno == ENOENT)) || !(S_ISDIR(hist_dir_stat.st_mode))) { fprintf(stderr, "Warning: %s is not a directory!\n", hist_dir); } hist_path_size = sizeof(char) * (strlen(hist_dir) + strlen(hist_file) + 1); hist_path = (char *)calloc(hist_path_size, sizeof(char)); SNPRINTF(hist_path, hist_path_size, "%s%s", hist_dir, hist_file); } if (rd_hist && hist_path) { if (read_history(hist_path) == ENOENT) { fprintf(stderr, "Warning: Could not read history from %s\n", hist_path); } } #endif /* HAVE_READLINE_HISTORY */ } #endif /* HAVE_LIBREADLINE */ do { retcode = rotctl_parse(my_rot, stdin, stdout, (const char **)argv, argc, interactive, prompt, send_cmd_term); if (retcode == 2) { exitcode = 2; } } // cppcheck-suppress knownConditionTrueFalse while (retcode == 0 || retcode == 2); #ifdef HAVE_LIBREADLINE if (interactive && prompt && have_rl) { #ifdef HAVE_READLINE_HISTORY if (sv_hist && hist_path) { if (write_history(hist_path) == ENOENT) { fprintf(stderr, "\nWarning: Could not write history to %s\n", hist_path); } } if ((rd_hist || sv_hist) && hist_path) { free(hist_path); hist_path = (char *)NULL; } #endif /* HAVE_READLINE_HISTORY */ } #endif /* HAVE_LIBREADLINE */ rot_close(my_rot); /* close port */ rot_cleanup(my_rot); /* if you care about memory */ return exitcode; } void usage() { printf("Usage: rotctl [OPTION]... [COMMAND]...\n" "Send COMMANDs to a connected antenna rotator.\n\n"); printf( " -m, --model=ID select rotator model number. See model list (-l)\n" " -r, --rot-file=DEVICE set device of the rotator to operate on\n" " -R, --rot-file2=DEVICE set device of the 2nd rotator controller to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -t, --send-cmd-term=CHAR set send_cmd command termination char\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -o, --set-azoffset=VAL set offset for azimuth\n" " -O, --set-eloffset=VAL set offset for elevation\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" #ifdef HAVE_READLINE_HISTORY " -i, --read-history read prior interactive session history\n" " -I, --save-history save current interactive session history\n" #endif " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" " - read commands from standard input\n" "\n" ); usage_rot(stdout); printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/rotctl_parse.h0000664000175000017500000000302315056640443012466 /* * rotctl_parse.h - (C) Stephane Fillod 2000-2008 * * This program test/control a radio using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef ROTCTL_PARSE_H #define ROTCTL_PARSE_H #include #include /* * external prototype */ int dumpcaps_rot(ROT *, FILE *); /* * Prototypes */ void usage_rot(FILE *); void version(); void list_models(); int print_conf_list(const struct confparams *cfp, rig_ptr_t data); int print_conf_list2(const struct confparams *cfp, rig_ptr_t data, FILE *fout); int set_conf(ROT *my_rot, char *conf_parms); int rotctl_parse(ROT *my_rot, FILE *fin, FILE *fout, const char **argv, int argc, int interactive, int prompt, char send_cmd_term); #endif /* ROTCTL_PARSE_H */ hamlib-4.6.5/tests/memsave.c0000664000175000017500000002046315056640443011424 /* * memsave.c - Copyright (C) 2003-2005 Thierry Leconte * Copyright (C) 2008-2010 Stephane Fillod * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #ifdef HAVE_XML2 # include # include static int dump_xml_chan(RIG *rig, vfo_t vfo, channel_t **chan, int channel_num, const chan_t *chan_list, rig_ptr_t arg); #endif int xml_save(RIG *rig, const char *outfilename) { #ifdef HAVE_XML2 int retval; xmlDocPtr Doc; xmlNodePtr root; /* create xlm Doc */ Doc = xmlNewDoc((unsigned char *) "1.0"); root = xmlNewNode(NULL, (unsigned char *) "hamlib"); xmlDocSetRootElement(Doc, root); root = xmlNewChild(root, NULL, (unsigned char *) "channels", NULL); if (rig->caps->clone_combo_get) printf("About to save data, enter cloning mode: %s\n", rig->caps->clone_combo_get); retval = rig_get_chan_all_cb(rig, RIG_VFO_NONE, dump_xml_chan, root); if (retval != RIG_OK) { return retval; } /* write xml File */ xmlSaveFormatFileEnc(outfilename, Doc, "UTF-8", 1); xmlFreeDoc(Doc); xmlCleanupParser(); return 0; #else return -RIG_ENAVAIL; #endif } int xml_parm_save(RIG *rig, const char *outfilename) { return -RIG_ENIMPL; } #ifdef HAVE_XML2 int dump_xml_chan(RIG *rig, vfo_t vfo, channel_t **chan_pp, int chan_num, const chan_t *chan_list, rig_ptr_t arg) { char attrbuf[20]; xmlNodePtr root = arg; xmlNodePtr node = NULL; int i; const char *mtype; static channel_t chan; const channel_cap_t *mem_caps = &chan_list->mem_caps; if (*chan_pp == NULL) { /* * Hamlib frontend demand application an allocated * channel_t pointer for next round. */ *chan_pp = &chan; return RIG_OK; } if (chan_list->type == RIG_MTYPE_NONE) { return RIG_OK; } mtype = rig_strmtype(chan_list->type); for (i = 0; i < strlen(mtype); i++) { attrbuf[i] = tolower(mtype[i]); } attrbuf[i] = '\0'; node = xmlNewChild(root, NULL, (unsigned char *)attrbuf, NULL); if (mem_caps->bank_num) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", chan.bank_num); xmlNewProp(node, (unsigned char *) "bank_num", (unsigned char *) attrbuf); } SNPRINTF(attrbuf, sizeof(attrbuf), "%d", chan.channel_num); xmlNewProp(node, (unsigned char *) "num", (unsigned char *) attrbuf); if (mem_caps->channel_desc && chan.channel_desc[0] != '\0') { xmlNewProp(node, (unsigned char *) "channel_desc", (unsigned char *) chan.channel_desc); } if (mem_caps->vfo) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.vfo); xmlNewProp(node, (unsigned char *) "vfo", (unsigned char *) attrbuf); } if (mem_caps->ant && chan.ant != RIG_ANT_NONE) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.ant); xmlNewProp(node, (unsigned char *) "ant", (unsigned char *) attrbuf); } if (mem_caps->freq && chan.freq != RIG_FREQ_NONE) { // cppcheck-suppress * char *fmt = "%"PRIll; // cppcheck-suppress * SNPRINTF(attrbuf, sizeof(attrbuf), fmt, (int64_t)chan.freq); xmlNewProp(node, (unsigned char *) "freq", (unsigned char *) attrbuf); } if (mem_caps->mode && chan.mode != RIG_MODE_NONE) { xmlNewProp(node, (unsigned char *) "mode", (unsigned char *) rig_strrmode(chan.mode)); } if (mem_caps->width && chan.width != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.width); xmlNewProp(node, (unsigned char *) "width", (unsigned char *) attrbuf); } if (mem_caps->tx_freq && chan.tx_freq != RIG_FREQ_NONE) { SNPRINTF(attrbuf, sizeof(attrbuf), "%"PRIll, (int64_t)chan.tx_freq); xmlNewProp(node, (unsigned char *) "tx_freq", (unsigned char *) attrbuf); } if (mem_caps->tx_mode && chan.tx_mode != RIG_MODE_NONE) { xmlNewProp(node, (unsigned char *) "tx_mode", (unsigned char *) rig_strrmode(chan.tx_mode)); } if (mem_caps->tx_width && chan.tx_width != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.tx_width); xmlNewProp(node, (unsigned char *) "tx_width", (unsigned char *) attrbuf); } if (mem_caps->split && chan.split != RIG_SPLIT_OFF) { xmlNewProp(node, (unsigned char *) "split", (unsigned char *) "on"); if (mem_caps->tx_vfo) { SNPRINTF(attrbuf, sizeof(attrbuf), "%x", chan.tx_vfo); xmlNewProp(node, (unsigned char *) "tx_vfo", (unsigned char *) attrbuf); } } if (mem_caps->rptr_shift && chan.rptr_shift != RIG_RPT_SHIFT_NONE) { xmlNewProp(node, (unsigned char *) "rptr_shift", (unsigned char *) rig_strptrshift(chan.rptr_shift)); if (mem_caps->rptr_offs && (int)chan.rptr_offs != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.rptr_offs); xmlNewProp(node, (unsigned char *) "rptr_offs", (unsigned char *) attrbuf); } } if (mem_caps->tuning_step && chan.tuning_step != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.tuning_step); xmlNewProp(node, (unsigned char *) "tuning_step", (unsigned char *) attrbuf); } if (mem_caps->rit && chan.rit != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.rit); xmlNewProp(node, (unsigned char *) "rit", (unsigned char *) attrbuf); } if (mem_caps->xit && chan.xit != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", (int)chan.xit); xmlNewProp(node, (unsigned char *) "xit", (unsigned char *) attrbuf); } if (mem_caps->funcs) { SNPRINTF(attrbuf, sizeof(attrbuf), "%lx", chan.funcs); xmlNewProp(node, (unsigned char *) "funcs", (unsigned char *) attrbuf); } if (mem_caps->ctcss_tone && chan.ctcss_tone != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.ctcss_tone); xmlNewProp(node, (unsigned char *) "ctcss_tone", (unsigned char *) attrbuf); } if (mem_caps->ctcss_sql && chan.ctcss_sql != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.ctcss_sql); xmlNewProp(node, (unsigned char *) "ctcss_sql", (unsigned char *) attrbuf); } if (mem_caps->dcs_code && chan.dcs_code != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.dcs_code); xmlNewProp(node, (unsigned char *) "dcs_code", (unsigned char *) attrbuf); } if (mem_caps->dcs_sql && chan.dcs_sql != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%u", chan.dcs_sql); xmlNewProp(node, (unsigned char *) "dcs_sql", (unsigned char *) attrbuf); } if (mem_caps->scan_group) { SNPRINTF(attrbuf, sizeof(attrbuf), "%d", chan.scan_group); xmlNewProp(node, (unsigned char *) "scan_group", (unsigned char *) attrbuf); } if (mem_caps->flags) { SNPRINTF(attrbuf, sizeof(attrbuf), "%x", chan.flags); xmlNewProp(node, (unsigned char *) "flags", (unsigned char *) attrbuf); } if (mem_caps->tag[0] != 0) { SNPRINTF(attrbuf, sizeof(attrbuf), "%s", chan.tag); xmlNewProp(node, (unsigned char *) "tag", (unsigned char *) attrbuf); } return 0; } #endif hamlib-4.6.5/tests/listrigs.c0000664000175000017500000000505615056640443011630 /* * listrigs.c - Copyright (C) 2000-2008 Stephane Fillod * This programs list all the available the rig capabilities. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include int print_caps_sum(const struct rig_caps *caps, void *data) { const char *fmt1 = "%-13s"; printf("%6u \t%-22s \t%-23s\t%-8s \t", caps->rig_model, caps->mfg_name, caps->model_name, caps->version); printf("%-8s \t", rig_strstatus(caps->status)); switch (caps->rig_type & RIG_TYPE_MASK) { case RIG_TYPE_TRANSCEIVER: printf(fmt1, "Transceiver"); break; case RIG_TYPE_HANDHELD: printf(fmt1, "Handheld"); break; case RIG_TYPE_MOBILE: printf(fmt1, "Mobile"); break; case RIG_TYPE_RECEIVER: printf(fmt1, "Receiver"); break; case RIG_TYPE_PCRECEIVER: printf(fmt1, "PC Receiver"); break; case RIG_TYPE_SCANNER: printf(fmt1, "Scanner"); break; case RIG_TYPE_TRUNKSCANNER: printf(fmt1, "Trunk scanner"); break; case RIG_TYPE_COMPUTER: printf(fmt1, "Computer"); break; case RIG_TYPE_OTHER: printf(fmt1, "Other"); break; default: printf(fmt1, "Unknown"); } printf("\t%s\n", caps->macro_name == NULL ? "Unknown" : caps->macro_name); return -1; /* !=0, we want them all ! */ } int main(int argc, char *argv[]) { int status; rig_load_all_backends(); printf(" Rig# \tMfg \tModel \tVersion \tStatus \tType \tMacro\n"); status = rig_list_foreach(print_caps_sum, NULL); if (status != RIG_OK) { printf("rig_list_foreach: error = %s \n", rigerror(status)); exit(3); } return 0; } hamlib-4.6.5/tests/rigmatrix_head.html0000664000175000017500000000022015056640443013465 Hamlib rig matrix

hamlib-4.6.5/tests/rigsmtr.c0000664000175000017500000003004015056640443011446 /* * rigsmtr.c - (C) Stephane Fillod 2007 * * This program output S-meter vs. Azimuth curve using Hamlib. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include "misc.h" #include "riglist.h" #include "rotlist.h" /* * Prototypes */ static void usage(); static void version(); static int set_conf_rig(RIG *rig, char *conf_parms); static int set_conf_rot(ROT *rot, char *conf_parms); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. */ #define SHORT_OPTIONS "m:r:s:c:C:M:R:S:N:vhV" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"serial-speed", 1, 0, 's'}, {"civaddr", 1, 0, 'c'}, {"set-conf", 1, 0, 'C'}, {"rot-model", 1, 0, 'M'}, {"rot-file", 1, 0, 'R'}, {"rot-serial-speed", 1, 0, 'S'}, {"rot-set-conf", 1, 0, 'N'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; #define MAXCONFLEN 2048 int main(int argc, char *argv[]) { RIG *rig; /* handle to rig (instance) */ ROT *rot; /* handle to rotator (instance) */ rig_model_t rig_model = RIG_MODEL_DUMMY; rot_model_t rot_model = ROT_MODEL_DUMMY; int retcode; /* generic return code from functions */ int verbose = 0; const char *rig_file = NULL, *rot_file = NULL; int serial_rate = 0; int rot_serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char rig_conf_parms[MAXCONFLEN] = ""; char rot_conf_parms[MAXCONFLEN] = ""; /* int with_rot = 1; */ azimuth_t azimuth; elevation_t elevation; unsigned step = 1000000; /* 1e6 us */ while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*rig_conf_parms != '\0') { strcat(rig_conf_parms, ","); } if (strlen(rig_conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(rig_conf_parms, optarg, MAXCONFLEN - strlen(rig_conf_parms) - 1); break; case 'M': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_model = atoi(optarg); break; case 'R': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_file = optarg; break; case 'S': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rot_serial_rate = atoi(optarg); break; case 'N': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*rot_conf_parms != '\0') { strcat(rot_conf_parms, ","); } strncat(rot_conf_parms, optarg, MAXCONFLEN - strlen(rot_conf_parms) - 1); break; case 'v': verbose++; break; default: usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose < 2 ? RIG_DEBUG_WARN : verbose); rig_debug(RIG_DEBUG_VERBOSE, "rigsmtr, %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); /* * The radio */ rig = rig_init(rig_model); if (!rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", rig_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } retcode = set_conf_rig(rig, rig_conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } if (rig_file) { strncpy(RIGPORT(rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(rig)->parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(rig, rig_token_lookup(rig, "civaddr"), civaddr); } if (!rig_has_get_level(rig, RIG_LEVEL_STRENGTH)) { fprintf(stderr, "rig backend for %s could not get S-Meter" "or has insufficient capability\nSorry\n", rig->caps->model_name); exit(3); } retcode = rig_open(rig); if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened rig model %u, '%s'\n", rig->caps->rig_model, rig->caps->model_name); } /* * The rotator */ rot = rot_init(rot_model); if (!rot) { fprintf(stderr, "Unknown rot num %d, or initialization error.\n", rot_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } retcode = set_conf_rot(rot, rot_conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } if (rot_file) { strncpy(ROTPORT(rot)->pathname, rot_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (rot_serial_rate != 0) { ROTPORT(rot)->parm.serial.rate = rot_serial_rate; } retcode = rot_open(rot); if (retcode != RIG_OK && rot_model != ROT_MODEL_DUMMY) { fprintf(stderr, "rot_open: error = %s \n", rigerror(retcode)); exit(2); } /* Commenting out to quell "set but not used" warning. * Enable when needed for further functionality. -N0NB */ /* if (rot_model == ROT_MODEL_DUMMY) */ /* with_rot = 1; */ if (verbose > 0) { printf("Opened rotator model %d, '%s'\n", rot->caps->rot_model, rot->caps->model_name); } /*******************************/ if (optind < argc) { step = atof(argv[optind]) * 1e6; } fprintf(stderr, "Setting rotator to azimuth %.1f°\n", ROTSTATE(rot)->min_az); rot_set_position(rot, ROTSTATE(rot)->min_az, 0); fprintf(stderr, "Wait for rotator to move...\n"); rot_get_position(rot, &azimuth, &elevation); while (fabs(azimuth - ROTSTATE(rot)->min_az) > 1.) { rot_get_position(rot, &azimuth, &elevation); hl_usleep(step); } fprintf(stderr, "Now initiating full 360° rotation...\n"); rot_set_position(rot, ROTSTATE(rot)->max_az, 0); /* TODO: check CW or CCW */ /* disable AGC? */ while (fabs(ROTSTATE(rot)->max_az - azimuth) > 1.) { value_t strength; rig_get_level(rig, RIG_VFO_CURR, RIG_LEVEL_STRENGTH, &strength); rot_get_position(rot, &azimuth, &elevation); printf("%.1f %d\n", azimuth, strength.i); } rig_close(rig); rot_close(rot); return 0; } void version() { printf("rigsmtr, %s\n\n", hamlib_version2); printf("%s\n", hamlib_copyright); } void usage() { printf("Usage: rigsmtr [OPTION]... [time]\n" "Input S-Meter vs Azimuth.\n\n"); printf( " -m, --model=ID select radio model number. See model list (rigctl -l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -M, --rot-model=ID select rotator model number. See model list (rotctl -l)\n" " -R, --rot-file=DEVICE set device of the rotator to operate on\n" " -S, --rot-serial-speed=BAUD set serial speed of the serial port\n" " -N, --rot-set-conf=PARM=VAL set rotator config parameters\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n" ); printf("\nReport bugs to .\n"); } int set_conf_rig(RIG *rig, char *conf_parms) { char *p; p = conf_parms; while (p && *p != '\0') { int ret; char *q, *n = NULL; /* FIXME: left hand value of = cannot be null */ q = strchr(p, '='); if (!q) { return RIG_EINVAL; *q++ = '\0'; n = strchr(q, ','); if (n) { *n++ = '\0'; } } ret = rig_set_conf(rig, rig_token_lookup(rig, p), q); if (ret != RIG_OK) { return ret; } p = n; } return RIG_OK; } int set_conf_rot(ROT *rot, char *conf_parms) { char *p; p = conf_parms; while (p && *p != '\0') { char *q, *n = NULL; int ret; /* FIXME: left hand value of = cannot be null */ q = strchr(p, '='); if (q) { *q++ = '\0'; n = strchr(q, ','); if (n) { *n++ = '\0'; } } ret = rot_set_conf(rot, rot_token_lookup(rot, p), q); if (ret != RIG_OK) { return ret; } p = n; } return RIG_OK; } hamlib-4.6.5/tests/testtrn.c0000664000175000017500000000416715056640443011475 /* * Hamlib sample program to test transceive mode (async event) */ #include #include #include #include #include #include #define SERIAL_PORT "/dev/ttyS0" int myfreq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg) { int *count_ptr = (int *) arg; printf("Rig changed freq to %"PRIfreq"Hz\n", freq); *count_ptr += 1; return 0; } int main(int argc, const char *argv[]) { RIG *my_rig; /* handle to rig (nstance) */ int retcode; /* generic return code from functions */ int i, count = 0; if (argc != 2) { fprintf(stderr, "%s \n", argv[0]); exit(1); } printf("testrig: Hello, I am your main() !\n"); /* * allocate memory, setup & open port */ my_rig = rig_init(atoi(argv[1])); if (!my_rig) { fprintf(stderr, "Unknown rig num: %d\n", atoi(argv[1])); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), SERIAL_PORT); if (rig_open(my_rig)) { exit(2); } printf("Port %s opened ok\n", SERIAL_PORT); /* * Below are examples of set/get routines. * Must add checking of functionality map prior to command execution -- FS * */ retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 439700000); if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } rig_set_freq_callback(my_rig, myfreq_event, (rig_ptr_t)&count); retcode = rig_set_trn(my_rig, RIG_TRN_RIG); if (retcode != RIG_OK) { printf("rig_set_trn: error = %s \n", rigerror(retcode)); } for (i = 0; i < 12; i++) { printf("Loop count: %d\n", i); sleep(10); /* or anything smarter */ } printf("Frequency changed %d times\n", count); rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ printf("port %s closed ok \n", SERIAL_PORT); return 0; } hamlib-4.6.5/tests/rigfreqwalk.c0000664000175000017500000000760215056640443012305 /* * Hamlib sample program */ #include #include #include #include #include #include #include #define HISTORYSIZE 10 double history[HISTORYSIZE]; int nhistory; int historyinit = 1; double compute_mean(const double arr[], int length) { double sum = 0.0; for (int i = 0; i < length; i++) { sum += arr[i]; } return sum / length; } double sigma(double arr[], int length) { double mean = compute_mean(arr, length); double sum_of_squares = 0.0; for (int i = 0; i < length; i++) { sum_of_squares += pow(arr[i] - mean, 2); } return sqrt(sum_of_squares / length); } int main(int argc, const char *argv[]) { RIG *my_rig; /* handle to rig (nstance) */ int strength; /* S-Meter level */ int retcode; /* generic return code from functions */ rig_model_t myrig_model; if (argc != 8) { fprintf(stderr, "%s: version 1.0\n", argv[0]); fprintf(stderr, "Usage: %s [model#] [comport] [baud] [start freq] [stop_freq] [stepsize] [seconds/step]\n", argv[0]); return 1; } /* Turn off backend debugging output */ rig_set_debug_level(RIG_DEBUG_NONE); /* * allocate memory, setup & open port */ // hamlib_port_t myport; myrig_model = atoi(argv[1]); // strncpy(myport.pathname, argv[2], HAMLIB_FILPATHLEN - 1); // myport.parm.serial.rate = atoi(argv[3]); my_rig = rig_init(myrig_model); if (!my_rig) { fprintf(stderr, "Unknown rig num: %u\n", myrig_model); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), argv[2]); retcode = rig_open(my_rig); if (retcode != RIG_OK) { printf("rig_open: error = %s\n", rigerror(retcode)); exit(2); } // printf("Port %s opened ok\n", SERIAL_PORT); long freq1, freq2; int stepsize, seconds; int n = sscanf(argv[4], "%ld", &freq1); n += sscanf(argv[5], "%ld", &freq2); n += sscanf(argv[6], "%d", &stepsize); n += sscanf(argv[7], "%d", &seconds); if (n != 4) { fprintf(stderr, "Error parsing %s/%s/%s/%s as start/stop/step/seconds\n", argv[4], argv[5], argv[6], argv[7]); return 1; } printf("Start:%ld Stop:%ld Step:%d Wait:%d\n", freq1, freq2, stepsize, seconds); while (1) { for (long f = freq1; f <= freq2; f += stepsize) { retcode = rig_set_freq(my_rig, RIG_VFO_CURR, (freq_t)f); if (retcode != RIG_OK) { fprintf(stderr, "%s: Error rig_set_freq: %s\n", __func__, rigerror(retcode)); return 1; } sleep(seconds); retcode = rig_get_strength(my_rig, RIG_VFO_CURR, &strength); if (retcode != RIG_OK) { int static once = 1; if (once) { once = 0; fprintf(stderr, "rig_get_strength error: %s\n", rigerror(retcode)); } strength = 1; } history[nhistory++] = strength; if (historyinit) { for (int i = 0; i < HISTORYSIZE; ++i) { history[i] = strength; } historyinit = 0; } nhistory %= HISTORYSIZE; double s = sigma(history, HISTORYSIZE); char timebuf[64]; rig_date_strget(timebuf, sizeof(timebuf), 1); printf("%s\t%ld\t%d\t%f\n", timebuf, f, strength, s); fflush(stdout); } } rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ printf("port %s closed ok \n", argv[2]); return 0; } hamlib-4.6.5/tests/rigmem.c0000664000175000017500000002760215056640443011251 /* * rigmem.c - (C) Thierry Leconte 2003-2005 * (C) Stephane Fillod 2003-2009 * * This program exercises the backup and restore of a radio * using Hamlib. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include "riglist.h" #define MAXNAMSIZ 32 #define MAXNBOPT 100 /* max number of different options */ /* * external prototype */ extern int xml_save(RIG *rig, const char *outfilename); extern int xml_load(RIG *rig, const char *infilename); extern int xml_parm_save(RIG *rig, const char *outfilename); extern int xml_parm_load(RIG *rig, const char *infilename); extern int csv_save(RIG *rig, const char *outfilename); extern int csv_load(RIG *rig, const char *infilename); extern int csv_parm_save(RIG *rig, const char *outfilename); extern int csv_parm_load(RIG *rig, const char *infilename); /* * Prototypes */ void usage(); void version(); static int set_conf(RIG *rig, char *conf_parms); int clear_chans(RIG *rig, const char *infilename); /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * NB: do NOT use -W since it's reserved by POSIX. */ #define SHORT_OPTIONS "m:r:s:c:C:p:axvhV" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"serial-speed", 1, 0, 's'}, {"civaddr", 1, 0, 'c'}, {"set-conf", 1, 0, 'C'}, {"set-separator", 1, 0, 'p'}, {"all", 0, 0, 'a'}, #ifdef HAVE_XML2 {"xml", 0, 0, 'x'}, #endif {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; #define MAXCONFLEN 2048 int all; int main(int argc, char *argv[]) { RIG *rig; /* handle to rig (nstance) */ rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int verbose = 0; #ifdef HAVE_XML2 int xml = 0; #endif const char *rig_file = NULL; int serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; extern char csv_sep; while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } csv_sep = optarg[0]; break; case 'a': all++; break; #ifdef HAVE_XML2 case 'x': printf("xml\n"); xml++; break; #endif case 'v': verbose++; break; default: fprintf(stderr, "Unknown option '%c'\n", c); usage(); /* unknown option? */ exit(1); } } rig_set_debug(verbose < 2 ? RIG_DEBUG_WARN : verbose); rig_debug(RIG_DEBUG_VERBOSE, "rigmem, %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to " "\n\n"); if (optind + 1 >= argc) { usage(); exit(1); } rig = rig_init(my_model); if (!rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } retcode = set_conf(rig, conf_parms); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } /* check channel support */ if (rig->caps->set_channel == NULL && rig->caps->get_channel == NULL && rig->caps->set_chan_all_cb == NULL && rig->caps->get_chan_all_cb == NULL && (rig->caps->set_mem == NULL || rig->caps->set_vfo == NULL)) { fprintf(stderr, "Error: rig num %u has no memory support implemented/available.\n", my_model); exit(3); } /* check channel description */ if (rig->caps->chan_list[0].type == 0) { fprintf(stderr, "Error: rig num %u has no channel list.\n", my_model); exit(3); } if (rig_file) { strncpy(RIGPORT(rig)->pathname, rig_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(rig)->parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(rig, rig_token_lookup(rig, "civaddr"), civaddr); } retcode = rig_open(rig); if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s \n", rigerror(retcode)); exit(2); } if (verbose > 0) { printf("Opened rig model %u, '%s'\n", rig->caps->rig_model, rig->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", rig->caps->version, rig_strstatus(rig->caps->status)); /* on some rigs, this accelerates the backup/restore */ rig_set_vfo(rig, RIG_VFO_MEM); if (!strcmp(argv[optind], "save")) { #ifdef HAVE_XML2 if (xml) { retcode = xml_save(rig, argv[optind + 1]); } else #endif { retcode = csv_save(rig, argv[optind + 1]); } } else if (!strcmp(argv[optind], "load")) { #ifdef HAVE_XML2 if (xml) { retcode = xml_load(rig, argv[optind + 1]); } else #endif { retcode = csv_load(rig, argv[optind + 1]); } } else if (!strcmp(argv[optind], "save_parm")) { #ifdef HAVE_XML2 if (xml) { retcode = xml_parm_save(rig, argv[optind + 1]); } else #endif { retcode = csv_parm_save(rig, argv[optind + 1]); } } else if (!strcmp(argv[optind], "load_parm")) { #ifdef HAVE_XML2 if (xml) { retcode = xml_parm_load(rig, argv[optind + 1]); } else #endif { retcode = csv_parm_load(rig, argv[optind + 1]); } } else if (!strcmp(argv[optind], "clear")) { retcode = clear_chans(rig, argv[optind + 1]); } else { usage(); exit(1); } rig_close(rig); /* close port */ rig_cleanup(rig); /* if you care about memory */ if (retcode != 0) { fprintf(stderr, "Hamlib error: %s\n", rigerror(retcode)); exit(2); } return 0; } void version() { printf("rigmem, %s\n\n", hamlib_version2); printf("%s\n", hamlib_copyright); } void usage() { printf("Usage: rigmem [OPTION]... COMMAND... FILE\n" "Backup/restore COMMANDs to a connected radio transceiver or receiver.\n\n"); printf( " -m, --model=ID select radio model number. See model list (rigctl -l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -C, --set-conf=PARM=VAL set config parameters\n" " -p, --set-separator=CHAR set character separator instead of the CSV comma\n" " -a, --all bypass mem_caps, apply to all fields of channel_t\n" #ifdef HAVE_XML2 " -x, --xml use XML format instead of CSV\n" #endif " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n" ); printf( "COMMANDs:\n" " load\n" " save\n" " load_parm\n" " save_parm\n" " clear\n\n" ); printf("\nReport bugs to .\n"); } static int set_conf(RIG *rig, char *conf_parms) { char *p, *n; p = conf_parms; while (p && *p != '\0') { int ret; /* FIXME: left hand value of = cannot be null */ char *q = strchr(p, '='); if (!q) { return RIG_EINVAL; } *q++ = '\0'; n = strchr(q, ','); if (n) { *n++ = '\0'; } ret = rig_set_conf(rig, rig_token_lookup(rig, p), q); if (ret != RIG_OK) { return ret; } p = n; } return RIG_OK; } /* * Pretty nasty, clears everything you have in rig memory */ int clear_chans(RIG *rig, const char *infilename) { int i, j, ret; channel_t chan; struct rig_state *rs = STATE(rig); memset(&chan, 0, sizeof(chan)); chan.freq = RIG_FREQ_NONE; chan.tx_freq = RIG_FREQ_NONE; chan.mode = RIG_MODE_NONE; chan.tx_mode = RIG_MODE_NONE; chan.vfo = RIG_VFO_MEM; for (i = 0; rs->chan_list[i].type; i++) { for (j = rs->chan_list[i].startc; j <= rs->chan_list[i].endc; j++) { chan.channel_num = j; ret = rig_set_channel(rig, RIG_VFO_NONE, &chan); if (ret != RIG_OK) { return ret; } } } return 0; } hamlib-4.6.5/tests/testrig.c0000664000175000017500000003246315056640443011453 /* * Hamlib sample program */ #include #include #include #include #include #include #define SERIAL_PORT "/dev/pts/2" int main(int argc, const char *argv[]) { RIG *my_rig; /* handle to rig (nstance) */ freq_t freq; /* frequency */ rmode_t rmode; /* radio mode of operation */ pbwidth_t width; vfo_t vfo; /* vfo selection */ int strength; /* S-Meter level */ int rit = 0; /* RIT status */ int xit = 0; /* XIT status */ int retcode; /* generic return code from functions */ rig_model_t myrig_model; printf("testrig: Hello, I am your main() !\n"); /* Turn off backend debugging output */ rig_set_debug_level(RIG_DEBUG_NONE); /* * allocate memory, setup & open port */ hamlib_port_t myport; if (argc < 2) { /* may be overridden by backend probe */ myport.type.rig = RIG_PORT_SERIAL; myport.parm.serial.rate = 9600; myport.parm.serial.data_bits = 8; myport.parm.serial.stop_bits = 1; myport.parm.serial.parity = RIG_PARITY_NONE; myport.parm.serial.handshake = RIG_HANDSHAKE_NONE; rig_load_all_backends(); myrig_model = rig_probe(&myport); } else { myrig_model = atoi(argv[1]); } my_rig = rig_init(myrig_model); rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), SERIAL_PORT); if (!my_rig) { fprintf(stderr, "Unknown rig num: %u\n", myrig_model); fprintf(stderr, "Please check riglist.h\n"); exit(1); /* whoops! something went wrong (mem alloc?) */ } //strncpy(RIGPORT(my_rig)->pathname, SERIAL_PORT, HAMLIB_FILPATHLEN - 1); retcode = rig_open(my_rig); if (retcode != RIG_OK) { printf("rig_open: error = %s\n", rigerror(retcode)); exit(2); } uint64_t levels = rig_get_caps_int(my_rig->caps->rig_model, RIG_CAPS_HAS_GET_LEVEL); printf("HAS_GET_LEVEL=0x%8llx, SWR=%8llx,true=%d\n", (unsigned long long)levels, (unsigned long long)(levels & RIG_LEVEL_SWR), (levels & RIG_LEVEL_SWR) == RIG_LEVEL_SWR); char val[256]; retcode = rig_get_conf2(my_rig, rig_token_lookup(my_rig, "write_delay"), val, sizeof(val)); if (retcode != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_conf2: %s\n", __func__, rigerror(retcode)); } printf("write_delay=%s\n", val); // printf("Port %s opened ok\n", SERIAL_PORT); /* * Below are examples of set/get routines. * Must add checking of functionality map prior to command execution -- FS * */ /* * Example of setting rig paameters * and some error checking on the return code. */ retcode = rig_set_vfo(my_rig, RIG_VFO_B); if (retcode != RIG_OK) { printf("rig_set_vfo: error = %s \n", rigerror(retcode)); } /* * Lets try some frequencies and modes. Return code is not checked. * Examples of checking return code are further down. * */ /* 10m FM Narrow */ printf("\nSetting 10m FM Narrow...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 29620000); /* 10m */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_FM, rig_passband_narrow(my_rig, RIG_MODE_FM)); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.6f MHz, Mode: %s, Passband: %.3f kHz\n\n", freq / 1000000, rig_strrmode(rmode), width / 1000.0); if (freq != 29620000) { printf("rig_set_freq: error expect %.0f got %.0f\n", 296290000.0, freq); } if (rmode != RIG_MODE_FM || width != rig_passband_narrow(my_rig, RIG_MODE_FM)) { printf("rig_set_mode: error expected FM/%d, got %s/%d\n", (int)rig_passband_narrow(my_rig, RIG_MODE_FM), rig_strrmode(rmode), (int)width); } sleep(1); /* so you can see it -- FS */ /* 15m USB */ printf("Setting 15m USB...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 21235175); /* 15m */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_USB, rig_passband_normal(my_rig, RIG_MODE_USB)); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.6f MHz, Mode: %s, Passband: %.3f kHz\n\n", freq / 1000000, rig_strrmode(rmode), width / 1000.0); sleep(1); /* 40m LSB */ printf("Setting 40m LSB...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 7250100); /* 40m */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_LSB, RIG_PASSBAND_NORMAL); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.6f MHz, Mode: %s, Passband: %.3f kHz\n\n", freq / 1000000, rig_strrmode(rmode), width / 1000.0); sleep(1); /* 80m AM Narrow */ printf("Setting 80m AM Narrow...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 3885000); /* 80m */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_AM, rig_passband_narrow(my_rig, RIG_MODE_AM)); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.6f MHz, Mode: %s, Passband: %.3f kHz\n\n", freq / 1000000, rig_strrmode(rmode), width / 1000.0); sleep(1); /* 160m CW Normal */ printf("Setting 160m CW...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 1875000); /* 160m */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_CW, RIG_PASSBAND_NORMAL); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.3f kHz, Mode: %s, Passband: %li Hz\n\n", freq / 1000, rig_strrmode(rmode), width); sleep(1); /* 160m CW Narrow -- The band is noisy tonight -- FS*/ printf("Setting 160m CW Narrow...\n"); retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_CW, rig_passband_narrow(my_rig, RIG_MODE_CW)); if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.3f kHz, Mode: %s, Passband: %li Hz\n\n", freq / 1000, rig_strrmode(rmode), width); sleep(1); /* AM Broadcast band */ printf("Setting Medium Wave AM...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 770000); /* KAAM */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_AM, RIG_PASSBAND_NORMAL); if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); printf(" Freq: %.3f kHz, Mode: %s, Passband: %.3f kHz\n\n", freq / 1000, rig_strrmode(rmode), width / 1000.0); sleep(1); /* 20m USB on VFO_A */ printf("Setting 20m on VFO A with two functions...\n"); retcode = rig_set_vfo(my_rig, RIG_VFO_A); if (retcode != RIG_OK) { printf("rig_set_vfo: error = %s \n", rigerror(retcode)); } retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 14250375); /* cq de vk3fcs */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_vfo(my_rig, &vfo); printf(" Freq: %.6f MHz, VFO: %s\n\n", freq / 1000000, rig_strvfo(vfo)); sleep(1); /* 20m USB on VFO_A , with only 1 call */ printf("Setting 20m on VFO A with one function...\n"); retcode = rig_set_freq(my_rig, RIG_VFO_A, 14295125); /* cq de vk3fcs */ if (retcode != RIG_OK) { printf("rig_set_freq: error = %s \n", rigerror(retcode)); } rig_get_freq(my_rig, RIG_VFO_CURR, &freq); rig_get_vfo(my_rig, &vfo); printf(" Freq: %.6f MHz, VFO: %s\n\n", freq / 1000000, rig_strvfo(vfo)); sleep(1); #if 0 retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 145100000); /* 2m */ sleep(2); retcode = rig_set_freq(my_rig, RIG_VFO_CURR, 435125000); /* 70cm */ sleep(2); #endif printf("Setting rig Mode to LSB.\n"); retcode = rig_set_mode(my_rig, RIG_VFO_CURR, RIG_MODE_LSB, RIG_PASSBAND_NORMAL); if (retcode != RIG_OK) { printf("rig_set_mode: error = %s \n", rigerror(retcode)); } sleep(1); printf("Setting rig PTT ON.\n"); retcode = rig_set_ptt(my_rig, RIG_VFO_A, RIG_PTT_ON); /* stand back ! */ if (retcode != RIG_OK) { printf("rig_set_ptt: error = %s \n", rigerror(retcode)); } sleep(1); printf("Setting rig PTT OFF.\n"); retcode = rig_set_ptt(my_rig, RIG_VFO_A, RIG_PTT_OFF); /* phew ! */ if (retcode != RIG_OK) { printf("rig_set_ptt: error = %s \n", rigerror(retcode)); } sleep(1); /* * Simple examples of getting rig information -- FS * */ printf("\nGet various raw rig values:\n"); retcode = rig_get_vfo(my_rig, &vfo); /* try to get vfo info */ if (retcode == RIG_OK) { printf("rig_get_vfo: vfo = %u \n", vfo); } else { printf("rig_get_vfo: error = %s \n", rigerror(retcode)); } retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq); if (retcode == RIG_OK) { printf("rig_get_freq: freq = %"PRIfreq"\n", freq); } else { printf("rig_get_freq: error = %s \n", rigerror(retcode)); } retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &rmode, &width); if (retcode == RIG_OK) { printf("rig_get_mode: mode = %s\n", rig_strrmode(rmode)); } else { printf("rig_get_mode: error = %s \n", rigerror(retcode)); } retcode = rig_get_strength(my_rig, RIG_VFO_CURR, &strength); if (retcode == RIG_OK) { printf("rig_get_strength: strength = %i \n", strength); } else { printf("rig_get_strength: error = %s \n", rigerror(retcode)); } if (rig_has_set_func(my_rig, RIG_FUNC_RIT)) { retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_RIT, 1); if (retcode != RIG_OK) { printf("rig_set_func RIT error: %s\n", rigerror(retcode)); } printf("rig_set_func: Setting RIT ON\n"); } if (rig_has_get_func(my_rig, RIG_FUNC_RIT)) { retcode = rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_RIT, &rit); if (retcode != RIG_OK) { printf("rig_get_func RIT error: %s\n", rigerror(retcode)); } printf("rig_get_func: RIT: %d\n", rit); } if (rig_has_set_func(my_rig, RIG_FUNC_XIT)) { retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_XIT, 1); if (retcode != RIG_OK) { printf("rig_set_func XIT error: %s\n", rigerror(retcode)); } printf("rig_set_func: Setting XIT ON\n"); } if (rig_has_get_func(my_rig, RIG_FUNC_XIT)) { retcode = rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_XIT, &xit); if (retcode != RIG_OK) { printf("rig_get_func XIT error: %s\n", rigerror(retcode)); } printf("rig_get_func: XIT: %d\n", xit); } rig_close(my_rig); /* close port */ rig_cleanup(my_rig); /* if you care about memory */ printf("port %s closed ok \n", SERIAL_PORT); for (unsigned long i = 1; i < 0x80000000; i = i << 1) { const char *vfostr = rig_strvfo(i); if (strlen(vfostr) > 0) { printf("0x%08lx=%s\n", i, vfostr); } } return 0; } hamlib-4.6.5/tests/rotctl_parse.c0000664000175000017500000021214515056640443012470 /* * rotctl_parse.c - (C) Stephane Fillod 2000-2010 * (C) Nate Bargmann 2003,2007,2010,2011,2012,2013 * (C) The Hamlib Group 2002,2006,2011 * * This program test/control a rotator using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ /* no history */ #endif /* HAVE_READLINE_HISTORY */ #include #include "iofunc.h" #include "misc.h" #include "dumpcaps_rot.h" /* HAVE_SSLEEP is defined when Windows Sleep is found * HAVE_SLEEP is defined when POSIX sleep is found * _WIN32 is defined when compiling with MinGW * * When cross-compiling from POSIX to Windows using MinGW, HAVE_SLEEP * will often be defined by configure although it is not supported by * MinGW. So substitute the sleep definition below in such a case and * when compiling on Windows using MinGW where HAVE_SLEEP will be * undefined. * * FIXME: Needs better handling for all versions of MinGW. * */ #if (defined(HAVE_SSLEEP) || defined(_WIN32)) && (!defined(HAVE_SLEEP)) # include "hl_sleep.h" #endif #include "rotctl_parse.h" #include "rotlist.h" #include "sprintflst.h" /* Hash table implementation See: http://uthash.sourceforge.net/ */ #include "uthash.h" #ifdef HAVE_PTHREAD # include static pthread_mutex_t rot_mutex = PTHREAD_MUTEX_INITIALIZER; #endif #define STR1(S) #S #define STR(S) STR1(S) #define MAXNAMSIZ 32 #define MAXNBOPT 100 /* max number of different options */ #define MAXARGSZ 127 #define ARG_IN1 0x01 #define ARG_OUT1 0x02 #define ARG_IN2 0x04 #define ARG_OUT2 0x08 #define ARG_IN3 0x10 #define ARG_OUT3 0x20 #define ARG_IN4 0x40 #define ARG_OUT4 0x80 #define ARG_IN_LINE 0x4000 #define ARG_NONE 0 #define ARG_IN (ARG_IN1|ARG_IN2|ARG_IN3|ARG_IN4) #define ARG_OUT (ARG_OUT1|ARG_OUT2|ARG_OUT3|ARG_OUT4) /* variables for readline support */ #ifdef HAVE_LIBREADLINE static char *input_line = (char *)NULL; static char *result = (char *)NULL; static char *parsed_input[sizeof(char *) * 7]; static const int have_rl = 1; #endif #ifdef HAVE_READLINE_HISTORY static char *rp_hist_buf = (char *)NULL; #endif struct test_table { unsigned char cmd; const char *name; int (*rot_routine)(ROT *, FILE *, int, int, char, int, char, const struct test_table *, const char *, const char *, const char *, const char *, const char *, const char *); int flags; const char *arg1; const char *arg2; const char *arg3; const char *arg4; const char *arg5; const char *arg6; }; #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EINVAL; else do {} while(0) #define ACTION(f) rotctl_##f #define declare_proto_rot(f) static int (ACTION(f))(ROT *rot, \ FILE *fout, \ int interactive, \ int prompt, \ char send_cmd_term, \ int ext_resp, \ char resp_sep, \ const struct test_table *cmd, \ const char *arg1, \ const char *arg2, \ const char *arg3, \ const char *arg4, \ const char *arg5, \ const char *arg6) declare_proto_rot(set_position); declare_proto_rot(get_position); declare_proto_rot(stop); declare_proto_rot(park); declare_proto_rot(reset); declare_proto_rot(move); declare_proto_rot(set_level); declare_proto_rot(get_level); declare_proto_rot(set_func); declare_proto_rot(get_func); declare_proto_rot(set_parm); declare_proto_rot(get_parm); declare_proto_rot(get_info); declare_proto_rot(get_status); declare_proto_rot(set_conf); declare_proto_rot(get_conf); declare_proto_rot(send_cmd); declare_proto_rot(dump_state); declare_proto_rot(dump_caps); declare_proto_rot(dump_conf); /* Follows are functions from locator.c */ declare_proto_rot(loc2lonlat); declare_proto_rot(lonlat2loc); declare_proto_rot(d_m_s2dec); declare_proto_rot(dec2d_m_s); declare_proto_rot(d_mm2dec); declare_proto_rot(dec2d_mm); declare_proto_rot(coord2qrb); declare_proto_rot(az_sp2az_lp); declare_proto_rot(dist_sp2dist_lp); declare_proto_rot(pause); /* * convention: upper case cmd is set, lowercase is get * * NB: 'q' 'Q' '?' are reserved by interactive mode interface */ struct test_table test_list[] = { { 'P', "set_pos", ACTION(set_position), ARG_IN, "Azimuth", "Elevation" }, { 'p', "get_pos", ACTION(get_position), ARG_OUT, "Azimuth", "Elevation" }, { 'K', "park", ACTION(park), ARG_NONE, }, { 'S', "stop", ACTION(stop), ARG_NONE, }, { 'R', "reset", ACTION(reset), ARG_IN, "Reset" }, { 'M', "move", ACTION(move), ARG_IN, "Direction", "Speed" }, { 'V', "set_level", ACTION(set_level), ARG_IN, "Level", "Level Value" }, { 'v', "get_level", ACTION(get_level), ARG_IN1 | ARG_OUT2, "Level", "Level Value" }, { 'U', "set_func", ACTION(set_func), ARG_IN, "Func", "Func Status" }, { 'u', "get_func", ACTION(get_func), ARG_IN1 | ARG_OUT2, "Func", "Func Status" }, { 'X', "set_parm", ACTION(set_parm), ARG_IN, "Parm", "Parm Value" }, { 'x', "get_parm", ACTION(get_parm), ARG_IN1 | ARG_OUT2, "Parm", "Parm Value" }, { 'C', "set_conf", ACTION(set_conf), ARG_IN, "Token", "Value" }, { '_', "get_info", ACTION(get_info), ARG_OUT, "Info" }, { 's', "get_status", ACTION(get_status), ARG_OUT, "Status flags" }, { 'w', "send_cmd", ACTION(send_cmd), ARG_IN1 | ARG_IN_LINE | ARG_OUT2, "Cmd", "Reply" }, { '1', "dump_caps", ACTION(dump_caps), }, { '3', "dump_conf", ACTION(dump_conf), }, { 0x8f, "dump_state", ACTION(dump_state), ARG_OUT }, { 'L', "lonlat2loc", ACTION(lonlat2loc), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_OUT1, "Longitude", "Latitude", "Loc Len [2-12]", "Locator" }, { 'l', "loc2lonlat", ACTION(loc2lonlat), ARG_IN1 | ARG_OUT1 | ARG_OUT2, "Locator", "Longitude", "Latitude" }, { 'D', "dms2dec", ACTION(d_m_s2dec), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_IN4 | ARG_OUT1, "Degrees", "Minutes", "Seconds", "S/W", "Dec Degrees" }, { 'd', "dec2dms", ACTION(dec2d_m_s), ARG_IN1 | ARG_OUT1 | ARG_OUT2 | ARG_OUT3 | ARG_OUT4, "Dec Degrees", "Degrees", "Minutes", "Seconds", "S/W" }, { 'E', "dmmm2dec", ACTION(d_mm2dec), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_OUT1, "Degrees", "Dec Minutes", "S/W", "Dec Deg" }, { 'e', "dec2dmmm", ACTION(dec2d_mm), ARG_IN1 | ARG_OUT1 | ARG_OUT2 | ARG_OUT3, "Dec Deg", "Degrees", "Dec Minutes", "S/W" }, { 'B', "qrb", ACTION(coord2qrb), ARG_IN1 | ARG_IN2 | ARG_IN3 | ARG_IN4 | ARG_OUT1 | ARG_OUT2, "Lon 1", "Lat 1", "Lon 2", "Lat 2", "QRB Distance", "QRB Azimuth" }, { 'A', "a_sp2a_lp", ACTION(az_sp2az_lp), ARG_IN1 | ARG_OUT1, "Short Path Deg", "Long Path Deg" }, { 'a', "d_sp2d_lp", ACTION(dist_sp2dist_lp), ARG_IN1 | ARG_OUT1, "Short Path km", "Long Path km" }, { 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" }, { 0xad, "get_conf", ACTION(get_conf), ARG_IN1 | ARG_OUT2, "Token", "Value"}, { 0x00, "", NULL }, }; struct test_table *find_cmd_entry(int cmd) { int i; for (i = 0; test_list[i].cmd != 0x00; i++) if (test_list[i].cmd == cmd) { break; } if (test_list[i].cmd == 0x00) { return NULL; } return &test_list[i]; } /* Structure for hash table provided by uthash.h * * Structure and hash functions patterned after/copied from example.c * distributed with the uthash package. See: http://uthash.sourceforge.net/ */ struct mod_lst { int id; /* caps->rot_model This is the hash key */ char mfg_name[32]; /* caps->mfg_name */ char model_name[32]; /* caps->model_name */ char version[32]; /* caps->version */ char status[32]; /* caps->status */ char macro_name[64]; /* caps->macro_name */ UT_hash_handle hh; /* makes this structure hashable */ }; /* Hash declaration. Must be initialized to NULL */ struct mod_lst *models = NULL; /* Add model information to the hash */ void hash_add_model(int id, const char *mfg_name, const char *model_name, const char *version, const char *status, const char *macro_name) { struct mod_lst *s; s = (struct mod_lst *)calloc(1, sizeof(struct mod_lst)); s->id = id; SNPRINTF(s->mfg_name, sizeof(s->mfg_name), "%s", mfg_name); SNPRINTF(s->model_name, sizeof(s->model_name), "%s", model_name); SNPRINTF(s->version, sizeof(s->version), "%s", version); SNPRINTF(s->status, sizeof(s->status), "%s", status); SNPRINTF(s->macro_name, sizeof(s->macro_name), "%s", macro_name); HASH_ADD_INT(models, id, s); /* id: name of key field */ } /* Hash sorting functions */ int hash_model_id_sort(const struct mod_lst *a, const struct mod_lst *b) { return (a->id > b->id); } void hash_sort_by_model_id() { HASH_SORT(models, hash_model_id_sort); } /* Delete hash */ void hash_delete_all() { struct mod_lst *current_model, *tmp = NULL; HASH_ITER(hh, models, current_model, tmp) { /* delete it (models advances to next) */ HASH_DEL(models, current_model); free(current_model); /* free it */ } } #ifdef HAVE_LIBREADLINE /* Frees allocated memory and sets pointers to NULL before calling readline * and then parses the input into space separated tokens. */ static void rp_getline(const char *s) { int i; /* free allocated memory and set pointers to NULL */ if (input_line) { free(input_line); input_line = (char *)NULL; } if (result) { result = (char *)NULL; } /* cmd, arg1, arg2, arg3, arg4, arg5, arg6 * arg5 and arg 6 are currently unused. */ for (i = 0; i < 7; i++) { parsed_input[i] = NULL; } /* Action! Returns typed line with newline stripped. */ input_line = readline(s); } #endif /* * TODO: use Lex? */ char parse_arg(const char *arg) { int i; for (i = 0; test_list[i].cmd != 0; i++) { if (!strncmp(arg, test_list[i].name, MAXNAMSIZ)) { return test_list[i].cmd; } } return 0; } /* * This scanf works even in presence of signals (timer, SIGIO, ..) */ static int scanfc(FILE *fin, const char *format, void *p) { do { int ret; ret = fscanf(fin, format, p); if (ret < 0) { if (errno == EINTR) { continue; } if (!feof(fin)) { rig_debug(RIG_DEBUG_TRACE, "%s fscanf of:", __func__); dump_hex((unsigned char *)p, strlen(p)); rig_debug(RIG_DEBUG_TRACE, " failed with format '%s'\n", format); } } if (ferror(fin)) { rig_debug(RIG_DEBUG_ERR, "%s: errno=%d, %s\n", __func__, errno, strerror(errno)); clearerr(fin); } if (errno == EINVAL) // invalid arg we will continue { continue; } return ret; } while (1); } /* * function to get the next word from the command line or from stdin * until stdin exhausted. stdin is read if the special token '-' is * found on the command line. * * returns EOF when words exhausted * returns <0 is error number * returns >=0 when successful */ static int next_word(char *buffer, int argc, const char **argv, int newline) { int ret; char c; static int reading_stdin; if (!reading_stdin) { if (optind >= argc) { return EOF; } else if (newline && '-' == argv[optind][0] && 1 == strlen(argv[optind])) { ++optind; reading_stdin = 1; } } if (reading_stdin) { do { do { ret = scanf(" %c%" STR(MAXARGSZ) "[^ \t\n#]", &c, &buffer[1]); } while (EINTR == ret); if (ret > 0 && '#' == c) { do { ret = scanf("%*[^\n]"); } while (EINTR == ret); /* consume comments */ ret = 0; } } while (!ret); if (EOF == ret) { reading_stdin = 0; } else if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "scanf: %s\n", strerror(errno)); reading_stdin = 0; } else { buffer[0] = c; buffer[1 == ret ? 1 : MAXARGSZ] = '\0'; if (newline) { putchar('\n'); } fputs(buffer, stdout); putchar(' '); } } if (!reading_stdin) { if (optind < argc) { strncpy(buffer, argv[optind++], MAXARGSZ); buffer[MAXARGSZ] = '\0'; ret = 1; } else { ret = EOF; } } return ret; } #define fprintf_flush(f, a...) \ ({ int __ret; \ __ret = fprintf((f), a); \ fflush((f)); \ __ret; \ }) int rotctl_parse(ROT *my_rot, FILE *fin, FILE *fout, const char *argv[], int argc, int interactive, int prompt, char send_cmd_term) { int retcode; /* generic return code from functions */ unsigned char cmd; struct test_table *cmd_entry = NULL; int ext_resp = 0; char resp_sep = '\n'; char command[MAXARGSZ + 1]; char arg1[MAXARGSZ + 1], *p1 = NULL; char arg2[MAXARGSZ + 1], *p2 = NULL; char arg3[MAXARGSZ + 1], *p3 = NULL; char arg4[MAXARGSZ + 1], *p4 = NULL; #ifdef __USEP5P6__ char *p5 = NULL; char *p6 = NULL; #endif /* cmd, internal, rotctld */ #ifdef HAVE_LIBREADLINE if (!(interactive && prompt && have_rl)) #endif { if (interactive) { static int last_was_ret = 1; if (prompt) { fprintf_flush(fout, "\nRotator command: "); } do { if (scanfc(fin, "%c", &cmd) < 1) { return -1; } /* Extended response protocol requested with leading '+' on command * string--rotctld only! */ if (cmd == '+' && !prompt) { ext_resp = 1; if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } else if (cmd == '+' && prompt) { return 0; } if (cmd != '\\' && cmd != '_' && cmd != '#' && ispunct(cmd) && !prompt) { ext_resp = 1; resp_sep = cmd; if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } else if (cmd != '\\' && cmd != '?' && cmd != '_' && cmd != '#' && ispunct(cmd) && prompt) { return 0; } /* command by name */ if (cmd == '\\') { unsigned char cmd_name[MAXNAMSIZ], *pcmd = cmd_name; int c_len = MAXNAMSIZ; if (scanfc(fin, "%c", pcmd) < 1) { return -1; } while (c_len-- && (isalnum(*pcmd) || *pcmd == '_')) { if (scanfc(fin, "%c", ++pcmd) < 1) { return -1; } } *pcmd = '\0'; cmd = parse_arg((char *) cmd_name); break; } if (cmd == 0x0a || cmd == 0x0d) { if (last_was_ret) { if (prompt) { fprintf_flush(fout, "? for help, q to quit.\n"); } return 0; } last_was_ret = 1; } } while (cmd == 0x0a || cmd == 0x0d); last_was_ret = 0; /* comment line */ if (cmd == '#') { while (cmd != '\n' && cmd != '\r') { if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } return 0; } if (cmd == 'Q' || cmd == 'q') { return 1; } if (cmd == '?') { usage_rot(fout); fflush(fout); return 0; } } else { /* parse rest of command line */ retcode = next_word(command, argc, argv, 1); if (EOF == retcode) { return 1; } else if (retcode < 0) { return retcode; } else if ('\0' == command[1]) { cmd = command[0]; } else { cmd = parse_arg(command); } } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { fprintf_flush(stderr, "Command '%c' not found!\n", cmd); return 0; } if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (interactive) { char *nl; if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (fgets(arg1, MAXARGSZ, fin) == NULL) { return -1; } if (arg1[0] == 0xa) { if (fgets(arg1, MAXARGSZ, fin) == NULL) { return -1; } } nl = strchr(arg1, 0xa); if (nl) { *nl = '\0'; /* chomp */ } p1 = arg1[0] == ' ' ? arg1 + 1 : arg1; } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p1 = arg1; } } else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (scanfc(fin, "%s", arg1) < 1) { return -1; } p1 = arg1; } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p1 = arg1; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg2); } if (scanfc(fin, "%s", arg2) < 1) { return -1; } p2 = arg2; } else { retcode = next_word(arg2, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p2 = arg2; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg3); } if (scanfc(fin, "%s", arg3) < 1) { return -1; } p3 = arg3; } else { retcode = next_word(arg3, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p3 = arg3; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN4) && cmd_entry->arg4) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg4); } if (scanfc(fin, "%s", arg4) < 1) { return -1; } p4 = arg4; } else { retcode = next_word(arg4, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p4 = arg4; } } } #ifdef HAVE_LIBREADLINE if (interactive && prompt && have_rl) { int j, x; #ifdef HAVE_READLINE_HISTORY /* Minimum space for 32+1+128+1+128+1+128+1+128+1+128+1+128+1 = 807 * chars, so allocate 896 chars cleared to zero for safety. */ rp_hist_buf = (char *)calloc(896, sizeof(char)); #endif rp_getline("\nRotator command: "); /* EOF (Ctl-D) received on empty input line, bail out gracefully. */ if (!input_line) { fprintf_flush(fout, "\n"); return 1; } /* Q or q to quit */ if (!(strncasecmp(input_line, "q", 1))) { return 1; } /* '?' for help */ if (!(strncmp(input_line, "?", 1))) { usage_rot(fout); fflush(fout); return 0; } /* '#' for comment */ if (!(strncmp(input_line, "#", 1))) { return 0; } /* Blank line entered */ if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } rig_debug(RIG_DEBUG_BUG, "%s: input_line: %s\n", __func__, input_line); /* Split input_line on any number of spaces to get the command token * Tabs are intercepted by readline for completion and a newline * causes readline to return the typed text. If more than one * argument is given, it will be parsed out later. */ result = strtok(input_line, " "); /* parsed_input stores pointers into input_line where the token strings * start. */ if (result) { parsed_input[0] = result; } else { /* Oops! Invoke GDB!! */ fprintf_flush(fout, "\n"); return 1; } /* At this point parsed_input contains the typed text of the command * with surrounding space characters removed. If Readline History is * available, copy the command string into a history buffer. */ /* Single character command */ if ((strlen(parsed_input[0]) == 1) && (*parsed_input[0] != '\\')) { cmd = *parsed_input[0]; #ifdef HAVE_READLINE_HISTORY /* Store what is typed, not validated, for history. */ if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], 1); } #endif } /* Test the command token, parsed_input[0] */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) > 1)) { char cmd_name[MAXNAMSIZ]; /* if there is no terminating '\0' character in the source string, * srncpy() doesn't add one even if the supplied length is less * than the destination array. Truncate the source string here. */ if (strlen(parsed_input[0] + 1) >= MAXNAMSIZ) { *(parsed_input[0] + MAXNAMSIZ) = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], MAXNAMSIZ); } #endif /* The starting position of the source string is the first * character past the initial '\'. */ SNPRINTF(cmd_name, sizeof(cmd_name), "%s", parsed_input[0] + 1); /* Sanity check as valid multiple character commands consist of * alphanumeric characters and the underscore ('_') character. */ for (j = 0; cmd_name[j] != '\0'; j++) { if (!(isalnum((int)cmd_name[j]) || cmd_name[j] == '_')) { fprintf(stderr, "Valid multiple character command names contain alphanumeric characters plus '_'\n"); return 0; } } cmd = parse_arg(cmd_name); } /* Single '\' entered, prompt again */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) == 1)) { return 0; } /* Multiple characters but no leading '\' */ else { fprintf(stderr, "Precede multiple character command names with '\\'\n"); return 0; } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { if (cmd == '\0') { fprintf(stderr, "Command '%s' not found!\n", parsed_input[0]); } else { fprintf(stderr, "Command '%c' not found!\n", cmd); } return 0; } /* \send_cmd */ if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { /* Check for a non-existent delimiter so as to not break up * remaining line into separate tokens (spaces OK). */ result = strtok(NULL, "\0"); if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); if (input_line == NULL) { fprintf_flush(fout, "\n"); return 1; } /* Blank line entered */ else if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } else { parsed_input[x] = input_line; } } /* The arg1 array size is MAXARGSZ + 1 so truncate it to fit if larger. */ if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } /* Normal argument parsing. */ else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { result = strtok(NULL, " "); if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { result = strtok(NULL, " "); if (result) { x = 2; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg2) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg2); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg2, parsed_input[x]); p2 = arg2; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { result = strtok(NULL, " "); if (result) { x = 3; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg3) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg3); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg3, parsed_input[x]); p3 = arg3; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN4) && cmd_entry->arg4) { result = strtok(NULL, " "); if (result) { x = 4; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg4) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg4); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg4, parsed_input[x]); p4 = arg4; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { add_history(rp_hist_buf); free(rp_hist_buf); rp_hist_buf = (char *)NULL; } #endif } #endif // HAVE_LIBREADLINE /* * mutex locking needed because rotctld is multithreaded * and hamlib is not MT-safe */ #ifdef HAVE_PTHREAD pthread_mutex_lock(&rot_mutex); #endif if (!prompt) { rig_debug(RIG_DEBUG_TRACE, "rotctl(d): %c '%s' '%s' '%s' '%s'\n", cmd, p1 ? p1 : "", p2 ? p2 : "", p3 ? p3 : "", p4 ? p4 : ""); } /* * Extended Response protocol: output received command name and arguments * response. */ if (interactive && ext_resp && !prompt) { char a1[MAXARGSZ + 2]; char a2[MAXARGSZ + 2]; char a3[MAXARGSZ + 2]; char a4[MAXARGSZ + 2]; p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1); p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2); p3 == NULL ? a3[0] = '\0' : snprintf(a3, sizeof(a3), " %s", p3); p4 == NULL ? a4[0] = '\0' : snprintf(a4, sizeof(a4), " %s", p4); fprintf(fout, "%s:%s%s%s%s%c", cmd_entry->name, a1, a2, a3, a4, resp_sep); } retcode = (*cmd_entry->rot_routine)(my_rot, fout, interactive, prompt, send_cmd_term, ext_resp, resp_sep, cmd_entry, p1, p2 ? p2 : "", p3 ? p3 : "", p4 ? p4 : "", #ifdef __USEP5P6__ p5 ? p5 : "", p6 ? p6 : ""); #else "", ""); #endif #ifdef HAVE_PTHREAD pthread_mutex_unlock(&rot_mutex); #endif if (retcode == RIG_EIO) { return retcode; } if (retcode != RIG_OK) { /* only for rotctld */ if (interactive && !prompt) { rot_debug(RIG_DEBUG_TRACE, "%s: NETROTCTL_RET %d\n", __func__, retcode); fprintf(fout, NETROTCTL_RET "%d\n", retcode); // ext_resp = 0; // not used ? // cppcheck-suppress unreadVariable resp_sep = '\n'; } else { if (cmd_entry->name != NULL) { //fprintf(fout, "%s: error = %s\n", cmd_entry->name, rigerror(retcode)); fprintf(fout, "error = %s\n", rigerror(retcode)); } } } else { /* only for rotctld */ if (interactive && !prompt) { /* netrotctl RIG_OK */ if (!(cmd_entry->flags & ARG_OUT) && !ext_resp) { rot_debug(RIG_DEBUG_TRACE, "%s: NETROTCTL_RET 0\n", __func__); fprintf(fout, NETROTCTL_RET "0\n"); } /* Extended Response protocol */ else if (ext_resp && cmd != 0xf0) { rot_debug(RIG_DEBUG_TRACE, "%s: NETROTCTL_RET 0\n", __func__); fprintf(fout, NETROTCTL_RET "0\n"); // cppcheck-suppress unreadVariable resp_sep = '\n'; } } } fflush(fout); return retcode != RIG_OK ? 2 : 0; } void version() { printf("rotctl(d), %s\n\n", hamlib_version2); printf("%s\n", hamlib_copyright); } void usage_rot(FILE *fout) { int i; fprintf(fout, "Commands (some may not be available for this rotator):\n"); for (i = 0; test_list[i].cmd != 0; i++) { fprintf(fout, "%c: %-12s(", isprint(test_list[i].cmd) ? test_list[i].cmd : '?', test_list[i].name); if (test_list[i].arg1 && (test_list[i].flags & ARG_IN1)) { fprintf(fout, "%s", test_list[i].arg1); } if (test_list[i].arg2 && (test_list[i].flags & ARG_IN2)) { fprintf(fout, ", %s", test_list[i].arg2); } if (test_list[i].arg3 && (test_list[i].flags & ARG_IN3)) { fprintf(fout, ", %s", test_list[i].arg3); } if (test_list[i].arg4 && (test_list[i].flags & ARG_IN4)) { fprintf(fout, ", %s", test_list[i].arg4); } fprintf(fout, ")\n"); } fprintf(fout, "\n\nIn interactive mode prefix long command names with '\\', e.g. '\\dump_state'\n\n" "The special command '-' is used to read further commands from standard input\n" "Commands and arguments read from standard input must be white space separated,\n" "comments are allowed, comments start with the # character and continue to the\n" "end of the line.\n"); } int print_conf_list(const struct confparams *cfp, rig_ptr_t data) { ROT *rot = (ROT *) data; int i; char buf[128] = ""; rot_get_conf2(rot, cfp->token, buf, sizeof(buf)); fprintf(stdout, "%s: \"%s\"\n" "\tDefault: %s, Value: %s\n", cfp->name, cfp->tooltip, cfp->dflt, buf); switch (cfp->type) { case RIG_CONF_NUMERIC: fprintf(stdout, "\tRange: %.1f..%.1f, step %.1f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; case RIG_CONF_CHECKBUTTON: fprintf(stdout, "\tCheckbox: 0,1\n"); break; case RIG_CONF_COMBO: if (!cfp->u.c.combostr[0]) { break; } fprintf(stdout, "\tCombo: %s", cfp->u.c.combostr[0]); for (i = 1 ; i < RIG_COMBO_MAX && cfp->u.c.combostr[i]; i++) { fprintf(stdout, ", %s", cfp->u.c.combostr[i]); } fprintf(stdout, "\n"); break; default: break; } return 1; /* != 0, we want them all ! */ } static int hash_model_list(const struct rot_caps *caps, void *data) { hash_add_model(caps->rot_model, caps->mfg_name, caps->model_name, caps->version, rig_strstatus(caps->status), caps->macro_name); return 1; /* !=0, we want them all ! */ } void print_model_list() { struct mod_lst *s; for (s = models; s != NULL; s = (struct mod_lst *)(s->hh.next)) { printf("%6d %-23s%-24s%-16s%-14s%s\n", s->id, s->mfg_name, s->model_name, s->version, s->status, s->macro_name); } } void list_models() { int status; rot_load_all_backends(); printf(" Rot # Mfg Model Version Status Macro\n"); status = rot_list_foreach(hash_model_list, NULL); if (status != RIG_OK) { printf("rot_list_foreach: error = %s \n", rigerror(status)); exit(2); } hash_sort_by_model_id(); print_model_list(); hash_delete_all(); } declare_proto_rot(get_conf) { int ret; rig_debug(RIG_DEBUG_ERR, "%s: \n", __func__); if (arg1 == NULL || arg1[0] == '?') { dumpconf_list(rot, fout); debugmsgsave[0] = 0; debugmsgsave2[0] = 0; return RIG_OK; } hamlib_token_t mytoken = rot_token_lookup(rot, arg1); if (mytoken == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rot\n", __func__, arg1); ret = -RIG_EINVAL; } else { char value[4096]; ret = rot_get_conf(rot, rot_token_lookup(rot, arg1), value); if (ret != RIG_OK) { return ret; } fprintf(fout, "%s=%s\n", arg1, value); } return (ret); } /* 'C' */ declare_proto_rot(set_conf) { int ret; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (arg1[0] == '?') { dumpconf_list(rot, fout); debugmsgsave[0] = 0; debugmsgsave2[0] = 0; return RIG_OK; } hamlib_token_t mytoken = rot_token_lookup(rot, arg1); if (mytoken == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unknown token '%s' for this rot\n", __func__, arg1); ret = -RIG_EINVAL; } else { ret = rot_set_conf(rot, rot_token_lookup(rot, arg1), arg2); } return (ret); } /* * static int (f)(ROT *rot, int interactive, const void *arg1, const void *arg2, const void *arg3, const void *arg4) */ /* 'P' */ declare_proto_rot(set_position) { azimuth_t az; elevation_t el; char *comma_pos; /* Fixing args with an invalid decimal separator. */ comma_pos = strchr(arg1, ','); if (comma_pos) { *comma_pos = '.'; } comma_pos = strchr(arg2, ','); if (comma_pos) { *comma_pos = '.'; } CHKSCN1ARG(sscanf(arg1, "%f", &az)); CHKSCN1ARG(sscanf(arg2, "%f", &el)); return rot_set_position(rot, az, el); } /* 'p' */ declare_proto_rot(get_position) { int status; azimuth_t az; elevation_t el; status = rot_get_position(rot, &az, &el); if (status != RIG_OK) { return status; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%.2f%c", az, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%.2f%c", el, resp_sep); return status; } /* 'S' */ declare_proto_rot(stop) { return rot_stop(rot); } /* 'K' */ declare_proto_rot(park) { return rot_park(rot); } /* 'R' */ declare_proto_rot(reset) { rot_reset_t reset; CHKSCN1ARG(sscanf(arg1, "%d", &reset)); return rot_reset(rot, reset); } /* '_' */ declare_proto_rot(get_info) { const char *s; s = rot_get_info(rot); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", s ? s : "None", resp_sep); return RIG_OK; } /* 's' */ declare_proto_rot(get_status) { int result; rot_status_t status; char s[SPRINTF_MAX_SIZE]; result = rot_get_status(rot, &status); if (result != RIG_OK) { return result; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } rot_sprintf_status(s, sizeof(s), status); fprintf(fout, "%s%c", s, resp_sep); return RIG_OK; } /* 'M' */ declare_proto_rot(move) { int direction; int speed; if (!strcmp(arg1, "LEFT") || !strcmp(arg1, "CCW")) { direction = ROT_MOVE_LEFT; } else if (!strcmp(arg1, "RIGHT") || !strcmp(arg1, "CW")) { direction = ROT_MOVE_RIGHT; } else if (!strcmp(arg1, "UP")) { direction = ROT_MOVE_UP; } else if (!strcmp(arg1, "DOWN")) { direction = ROT_MOVE_DOWN; } else if (!strcmp(arg1, "DOWN_RIGHT") || !strcmp(arg1, "DOWN_CW")) { direction = ROT_MOVE_DOWN_CW; } else if (!strcmp(arg1, "DOWN_LEFT") || !strcmp(arg1, "DOWN_CCW")) { direction = ROT_MOVE_DOWN_CCW; } else if (!strcmp(arg1, "UP_RIGHT") || !strcmp(arg1, "UP_CW")) { direction = ROT_MOVE_UP_CW; } else if (!strcmp(arg1, "UP_LEFT") || !strcmp(arg1, "UP_CCW")) { direction = ROT_MOVE_UP_CCW; } else { CHKSCN1ARG(sscanf(arg1, "%d", &direction)); } CHKSCN1ARG(sscanf(arg2, "%d", &speed)); return rot_move(rot, direction, speed); } /* * 'V' */ declare_proto_rot(set_level) { setting_t level; value_t val; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_level(s, sizeof(s), ROTSTATE(rot)->has_set_level); fputs(s, fout); if (rot->caps->set_ext_level) { sprintf_level_ext(s, sizeof(s), rot->caps->extlevels); fputs(s, fout); } fputc('\n', fout); return RIG_OK; } level = rot_parse_level(arg1); if (!rot_has_set_level(rot, level)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_ENAVAIL; /* no such parameter */ } switch (cfp->type) { case RIG_CONF_BUTTON: /* arg is ignored */ val.i = 0; // avoid passing uninitialized data break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); break; case RIG_CONF_NUMERIC: CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); break; case RIG_CONF_STRING: val.cs = arg2; break; default: return -RIG_ECONF; } return rot_set_ext_level(rot, cfp->token, val); } if (ROT_LEVEL_IS_FLOAT(level)) { CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); } else { CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); } return rot_set_level(rot, level, val); } /* 'v' */ declare_proto_rot(get_level) { int status; setting_t level; value_t val; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_level(s, sizeof(s), ROTSTATE(rot)->has_get_level); fputs(s, fout); if (rot->caps->get_ext_level) { sprintf_level_ext(s, sizeof(s), rot->caps->extlevels); fputs(s, fout); } fputc('\n', fout); return RIG_OK; } level = rot_parse_level(arg1); if (!rot_has_get_level(rot, level)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_EINVAL; /* no such parameter */ } status = rot_get_ext_level(rot, cfp->token, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } switch (cfp->type) { case RIG_CONF_BUTTON: /* there's no sense in retrieving value of stateless button */ return -RIG_EINVAL; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(fout, "%d\n", val.i); break; case RIG_CONF_NUMERIC: fprintf(fout, "%f\n", val.f); break; case RIG_CONF_STRING: fprintf(fout, "%s\n", val.s); break; default: return -RIG_ECONF; } return status; } status = rot_get_level(rot, level, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } if (ROT_LEVEL_IS_FLOAT(level)) { fprintf(fout, "%f\n", val.f); } else { fprintf(fout, "%d\n", val.i); } return status; } /* 'U' */ declare_proto_rot(set_func) { setting_t func; int func_stat; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_func(s, sizeof(s), ROTSTATE(rot)->has_set_func); fprintf(fout, "%s\n", s); return RIG_OK; } func = rot_parse_func(arg1); if (!rot_has_set_func(rot, func)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_ENAVAIL; /* no such parameter */ } CHKSCN1ARG(sscanf(arg2, "%d", &func_stat)); return rot_set_ext_func(rot, cfp->token, func_stat); } CHKSCN1ARG(sscanf(arg2, "%d", &func_stat)); return rot_set_func(rot, func, func_stat); } /* 'u' */ declare_proto_rot(get_func) { int status; setting_t func; int func_stat; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_func(s, sizeof(s), ROTSTATE(rot)->has_get_func); fprintf(fout, "%s\n", s); return RIG_OK; } func = rot_parse_func(arg1); if (!rot_has_get_func(rot, func)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_EINVAL; /* no such parameter */ } status = rot_get_ext_func(rot, cfp->token, &func_stat); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d\n", func_stat); return status; } status = rot_get_func(rot, func, &func_stat); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d\n", func_stat); return status; } /* 'R' */ declare_proto_rot(set_parm) { setting_t parm; value_t val; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_parm(s, sizeof(s), ROTSTATE(rot)->has_set_parm); fprintf(fout, "%s\n", s); return RIG_OK; } parm = rot_parse_parm(arg1); if (!rot_has_set_parm(rot, parm)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_EINVAL; /* no such parameter */ } switch (cfp->type) { case RIG_CONF_BUTTON: /* arg is ignored */ val.i = 0; // avoid passing uninitialized data break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); break; case RIG_CONF_NUMERIC: CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); break; case RIG_CONF_STRING: val.cs = arg2; break; case RIG_CONF_BINARY: val.b.d = (unsigned char *)arg2; break; default: return -RIG_ECONF; } return rot_set_ext_parm(rot, cfp->token, val); } if (ROT_PARM_IS_FLOAT(parm)) { CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); } else { CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); } return rot_set_parm(rot, parm, val); } /* 'r' */ declare_proto_rot(get_parm) { int status; setting_t parm; value_t val; char buffer[RIG_BIN_MAX]; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rot_sprintf_parm(s, sizeof(s), ROTSTATE(rot)->has_get_parm); fprintf(fout, "%s\n", s); return RIG_OK; } parm = rot_parse_parm(arg1); if (!rot_has_get_parm(rot, parm)) { const struct confparams *cfp; cfp = rot_ext_lookup(rot, arg1); if (!cfp) { return -RIG_EINVAL; /* no such parameter */ } switch (cfp->type) { case RIG_CONF_STRING: memset(buffer, '0', sizeof(buffer)); buffer[sizeof(buffer) - 1] = 0; val.s = buffer; break; case RIG_CONF_BINARY: memset(buffer, 0, sizeof(buffer)); val.b.d = (unsigned char *)buffer; val.b.l = RIG_BIN_MAX; break; default: break; } status = rot_get_ext_parm(rot, cfp->token, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } switch (cfp->type) { case RIG_CONF_BUTTON: /* there's not sense in retrieving value of stateless button */ return -RIG_EINVAL; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(fout, "%d\n", val.i); break; case RIG_CONF_NUMERIC: fprintf(fout, "%f\n", val.f); break; case RIG_CONF_STRING: fprintf(fout, "%s\n", val.s); break; case RIG_CONF_BINARY: dump_hex((unsigned char *)buffer, val.b.l); break; default: return -RIG_ECONF; } return status; } status = rot_get_parm(rot, parm, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } if (ROT_PARM_IS_FLOAT(parm)) { fprintf(fout, "%f\n", val.f); } else { fprintf(fout, "%d\n", val.i); } return status; } #if 0 // replace by set_conf /* 'C' */ declare_proto_rot(inter_set_conf) { char buf[256]; rot_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (!arg2 || arg2[0] == '\0') { rot_debug(RIG_DEBUG_ERR, "%s: arg1=='%s', arg2=='%s'\n", __func__, arg1, arg2); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "%s=%s", arg1, arg2); return set_conf(rot, buf); } #endif /* '1' */ declare_proto_rot(dump_caps) { dumpcaps_rot(rot, fout); return RIG_OK; } declare_proto_rot(dump_conf) { ENTERFUNC2; dumpconf_list(rot, fout); RETURNFUNC2(RIG_OK); } /* For rotctld internal use * '0x8f' */ declare_proto_rot(dump_state) { struct rot_state *rs = ROTSTATE(rot); char *tag; /* * - Protocol version */ #define ROTCTLD_PROT_VER 1 if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "rotctld Protocol Ver: "); } fprintf(fout, "%d%c", ROTCTLD_PROT_VER, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "Rotor Model: "); } fprintf(fout, "%d%c", rot->caps->rot_model, resp_sep); tag = "min_az="; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { tag = "Minimum Azimuth: "; } fprintf(fout, "%s%lf%c", tag, rs->min_az + rs->az_offset, resp_sep); tag = "max_az="; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { tag = "Maximum Azimuth: "; } fprintf(fout, "%s%lf%c", tag, rs->max_az + rs->az_offset, resp_sep); tag = "min_el="; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { tag = "Minimum Elevation: "; } fprintf(fout, "%s%lf%c", tag, rs->min_el + rs->el_offset, resp_sep); tag = "max_el="; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { tag = "Maximum Elevation: "; } fprintf(fout, "%s%lf%c", tag, rs->max_el + rs->el_offset, resp_sep); tag = "south_zero="; if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { tag = "South Zero: "; } fprintf(fout, "%s%d%c", tag, rs->south_zero, resp_sep); char *rtype = "Unknown"; switch (rot->caps->rot_type) { case ROT_TYPE_OTHER: rtype = "Other"; break; case ROT_TYPE_AZIMUTH : rtype = "Az"; break; case ROT_TYPE_ELEVATION : rtype = "El"; break; case ROT_TYPE_AZEL : rtype = "AzEl"; break; } fprintf(fout, "rot_type=%s%c", rtype, resp_sep); fprintf(fout, "done%c", resp_sep); return RIG_OK; } /* * Special debugging purpose send command display reply until there's a * timeout. * * 'w' */ declare_proto_rot(send_cmd) { int retval; hamlib_port_t *rotp = ROTPORT(rot); int backend_num, cmd_len; #define BUFSZ 128 unsigned char bufcmd[BUFSZ]; unsigned char buf[BUFSZ]; char eom_buf[4] = { 0xa, 0xd, 0, 0 }; /* * binary protocols enter values as \0xZZ\0xYY.. * * Rem: no binary protocol for rotator as of now */ backend_num = ROT_BACKEND_NUM(rot->caps->rot_model); if (send_cmd_term == -1 || backend_num == -1) { const char *p = arg1, *pp = NULL; int i; for (i = 0; i < BUFSZ - 1 && p != pp; i++) { pp = p + 1; bufcmd[i] = strtol(p + 1, (char **) &p, 0); } /* must save length to allow 0x00 to be sent as part of a command */ cmd_len = i - 1; /* no End Of Message chars */ eom_buf[0] = '\0'; } else { /* text protocol */ strncpy((char *) bufcmd, arg1, BUFSZ); bufcmd[BUFSZ - 2] = '\0'; cmd_len = strlen((char *) bufcmd); /* Automatic termination char */ if (send_cmd_term != 0) { bufcmd[cmd_len++] = send_cmd_term; } eom_buf[2] = send_cmd_term; } rig_flush(rotp); retval = write_block(rotp, bufcmd, cmd_len); if (retval != RIG_OK) { return retval; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } do { /* * assumes CR or LF is end of line char * for all ascii protocols */ retval = read_string(rotp, buf, BUFSZ, eom_buf, strlen(eom_buf), 0, 1); if (retval < 0) { break; } if (retval < BUFSZ) { buf[retval] = '\0'; } else { buf[BUFSZ - 1] = '\0'; } fprintf(fout, "%s\n", buf); } while (retval > 0); if (retval > 0 || retval == -RIG_ETIMEOUT) { retval = RIG_OK; } return retval; } /* 'L' */ declare_proto_rot(lonlat2loc) { unsigned char loc[MAXARGSZ + 1]; double lat, lon; int err, pair; CHKSCN1ARG(sscanf(arg1, "%lf", &lon)); CHKSCN1ARG(sscanf(arg2, "%lf", &lat)); CHKSCN1ARG(sscanf(arg3, "%d", &pair)); pair /= 2; err = longlat2locator(lon, lat, (char *)&loc, pair); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%s%c", loc, resp_sep); return err; } /* 'l' */ declare_proto_rot(loc2lonlat) { unsigned char loc[MAXARGSZ + 1]; double lat, lon; int status; CHKSCN1ARG(sscanf(arg1, "%s", (char *)&loc)); status = locator2longlat(&lon, &lat, (const char *)loc); if (status != RIG_OK) { return status; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%f%c", lon, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%f%c", lat, resp_sep); return status; } /* 'D' */ declare_proto_rot(d_m_s2dec) { int deg, min, sw; double sec, dec_deg; CHKSCN1ARG(sscanf(arg1, "%d", °)); CHKSCN1ARG(sscanf(arg2, "%d", &min)); CHKSCN1ARG(sscanf(arg3, "%lf", &sec)); CHKSCN1ARG(sscanf(arg4, "%d", &sw)); dec_deg = dms2dec(deg, min, sec, sw); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%lf%c", dec_deg, resp_sep); return RIG_OK; } /* 'd' */ declare_proto_rot(dec2d_m_s) { int deg, min, sw, err; double sec, dec_deg; CHKSCN1ARG(sscanf(arg1, "%lf", &dec_deg)); err = dec2dms(dec_deg, °, &min, &sec, &sw); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", deg, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%d%c", min, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%lf%c", sec, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%d%c", sw, resp_sep); return err; } /* 'E' */ declare_proto_rot(d_mm2dec) { int deg, sw; double dec_deg, min; CHKSCN1ARG(sscanf(arg1, "%d", °)); CHKSCN1ARG(sscanf(arg2, "%lf", &min)); CHKSCN1ARG(sscanf(arg3, "%d", &sw)); dec_deg = dmmm2dec(deg, min, sw, 0.0); // we'll add real seconds when somebody asks for it if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%lf%c", dec_deg, resp_sep); return RIG_OK; } /* 'e' */ declare_proto_rot(dec2d_mm) { int deg, sw, err; double min, dec_deg; CHKSCN1ARG(sscanf(arg1, "%lf", &dec_deg)); err = dec2dmmm(dec_deg, °, &min, &sw); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", deg, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%lf%c", min, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%d%c", sw, resp_sep); return err; } /* 'B' */ declare_proto_rot(coord2qrb) { double lon1, lat1, lon2, lat2, dist, az; int err; CHKSCN1ARG(sscanf(arg1, "%lf", &lon1)); CHKSCN1ARG(sscanf(arg2, "%lf", &lat1)); CHKSCN1ARG(sscanf(arg3, "%lf", &lon2)); CHKSCN1ARG(sscanf(arg4, "%lf", &lat2)); err = qrb(lon1, lat1, lon2, lat2, &dist, &az); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%lf%c", dist, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg6); } fprintf(fout, "%lf%c", az, resp_sep); return err; } /* 'A' */ declare_proto_rot(az_sp2az_lp) { double az_sp, az_lp; CHKSCN1ARG(sscanf(arg1, "%lf", &az_sp)); az_lp = azimuth_long_path(az_sp); if (az_lp < 0) { return -RIG_EINVAL; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%lf%c", az_lp, resp_sep); return RIG_OK; } /* 'a' */ declare_proto_rot(dist_sp2dist_lp) { double dist_sp, dist_lp; CHKSCN1ARG(sscanf(arg1, "%lf", &dist_sp)); dist_lp = distance_long_path(dist_sp); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%lf%c", dist_lp, resp_sep); return RIG_OK; } /* '0x8c'--pause processing */ declare_proto_rot(pause) { unsigned seconds; CHKSCN1ARG(sscanf(arg1, "%u", &seconds)); sleep(seconds); return RIG_OK; } // short list for rigctl/rigctld display int print_conf_list2(const struct confparams *cfp, rig_ptr_t data, FILE *fout) { ROT *rot = (ROT *) data; char buf[128] = ""; rot_get_conf(rot, cfp->token, buf); fprintf(fout, "%s: \"%s\"\n" "\t" "Default: %s, Value: %s\n", cfp->name, cfp->tooltip, cfp->dflt, buf); return 1; /* !=0, we want them all ! */ } hamlib-4.6.5/tests/memload.c0000664000175000017500000002123415056640443011402 /* * memload.c - Copyright (C) 2003 Thierry Leconte * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #ifdef HAVE_XML2 # include # include static int set_chan(RIG *rig, channel_t *chan, xmlNodePtr node); #endif int xml_load(RIG *my_rig, const char *infilename) { #ifdef HAVE_XML2 xmlDocPtr Doc; xmlNodePtr node; /* load xlm Doc */ Doc = xmlParseFile(infilename); if (Doc == NULL) { fprintf(stderr, "xmlParse failed\n"); exit(2); } node = xmlDocGetRootElement(Doc); if (node == NULL) { fprintf(stderr, "get root failed\n"); exit(2); } if (strcmp((char *) node->name, "hamlib")) { fprintf(stderr, "no hamlib tag found\n"); exit(2); } for (node = node->xmlChildrenNode; node != NULL; node = node->next) { if (xmlNodeIsText(node)) { continue; } if (strcmp((char *) node->name, "channels") == 0) { break; } } if (node == NULL) { fprintf(stderr, "no channels\n"); exit(2); } for (node = node->xmlChildrenNode; node != NULL; node = node->next) { channel_t chan; int status; if (xmlNodeIsText(node)) { continue; } set_chan(my_rig, &chan, node); status = rig_set_channel(my_rig, RIG_VFO_NONE, &chan); if (status != RIG_OK) { printf("rig_get_channel: error = %s \n", rigerror(status)); return status; } } xmlFreeDoc(Doc); xmlCleanupParser(); return 0; #else return -RIG_ENAVAIL; #endif } int xml_parm_load(RIG *my_rig, const char *infilename) { return -RIG_ENIMPL; } #ifdef HAVE_XML2 int set_chan(RIG *rig, channel_t *chan, xmlNodePtr node) { xmlChar *prop; int i, n; struct rig_state *rs = STATE(rig); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; prop = xmlGetProp(node, (unsigned char *) "num"); if (prop == NULL) { fprintf(stderr, "no num\n"); return -1; } n = chan->channel_num = atoi((char *) prop); /* find channel caps */ for (i = 0; i < HAMLIB_CHANLSTSIZ ; i++) { if (rs->chan_list[i].startc <= n && rs->chan_list[i].endc >= n) { break; } } if (i == HAMLIB_CHANLSTSIZ) { return -RIG_EINVAL; } fprintf(stderr, "node %d %d\n", n, i); if (rs->chan_list[i].mem_caps.bank_num) { prop = xmlGetProp(node, (unsigned char *) "bank_num"); if (prop != NULL) { chan->bank_num = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.channel_desc) { prop = xmlGetProp(node, (unsigned char *) "channel_desc"); if (prop != NULL) { strncpy(chan->channel_desc, (char *) prop, 7); } } if (rs->chan_list[i].mem_caps.ant) { prop = xmlGetProp(node, (unsigned char *) "ant"); if (prop != NULL) { chan->ant = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.freq) { prop = xmlGetProp(node, (unsigned char *) "freq"); if (prop != NULL) { sscanf((char *) prop, "%"SCNfreq, &chan->freq); } } if (rs->chan_list[i].mem_caps.mode) { prop = xmlGetProp(node, (unsigned char *) "mode"); if (prop != NULL) { chan->mode = rig_parse_mode((char *) prop); } } if (rs->chan_list[i].mem_caps.width) { prop = xmlGetProp(node, (unsigned char *) "width"); if (prop != NULL) { chan->width = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.tx_freq) { prop = xmlGetProp(node, (unsigned char *) "tx_freq"); if (prop != NULL) { sscanf((char *) prop, "%"SCNfreq, &chan->tx_freq); } } if (rs->chan_list[i].mem_caps.tx_mode) { prop = xmlGetProp(node, (unsigned char *)"tx_mode"); if (prop != NULL) { chan->tx_mode = rig_parse_mode((char *) prop); } } if (rs->chan_list[i].mem_caps.tx_width) { prop = xmlGetProp(node, (unsigned char *)"tx_width"); if (prop != NULL) { chan->tx_width = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.split) { chan->split = RIG_SPLIT_OFF; prop = xmlGetProp(node, (unsigned char *)"split"); if (prop != NULL) { if (strcmp((char *) prop, "on") == 0) { chan->split = RIG_SPLIT_ON; if (rs->chan_list[i].mem_caps.tx_vfo) { prop = xmlGetProp(node, (unsigned char *)"tx_vfo"); if (prop != NULL) { sscanf((char *) prop, "%x", &chan->tx_vfo); } } } } } if (rs->chan_list[i].mem_caps.rptr_shift) { prop = xmlGetProp(node, (unsigned char *)"rptr_shift"); if (prop) { switch (prop[0]) { case '=': chan->rptr_shift = RIG_RPT_SHIFT_NONE; break; case '+': chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break; case '-': chan->rptr_shift = RIG_RPT_SHIFT_MINUS; break; } } if (rs->chan_list[i].mem_caps.rptr_offs && chan->rptr_shift != RIG_RPT_SHIFT_NONE) { prop = xmlGetProp(node, (unsigned char *)"rptr_offs"); if (prop != NULL) { chan->rptr_offs = atoi((char *) prop); } } } if (rs->chan_list[i].mem_caps.tuning_step) { prop = xmlGetProp(node, (unsigned char *)"tuning_step"); if (prop != NULL) { chan->tuning_step = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.rit) { prop = xmlGetProp(node, (unsigned char *)"rit"); if (prop != NULL) { chan->rit = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.xit) { prop = xmlGetProp(node, (unsigned char *)"xit"); if (prop != NULL) { chan->xit = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.funcs) { prop = xmlGetProp(node, (unsigned char *)"funcs"); if (prop != NULL) { sscanf((char *) prop, "%lx", &chan->funcs); } } if (rs->chan_list[i].mem_caps.ctcss_tone) { prop = xmlGetProp(node, (unsigned char *)"ctcss_tone"); if (prop != NULL) { chan->ctcss_tone = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.ctcss_sql) { prop = xmlGetProp(node, (unsigned char *)"ctcss_sql"); if (prop != NULL) { chan->ctcss_sql = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.dcs_code) { prop = xmlGetProp(node, (unsigned char *)"dcs_code"); if (prop != NULL) { chan->dcs_code = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.dcs_sql) { prop = xmlGetProp(node, (unsigned char *)"dcs_sql"); if (prop != NULL) { chan->dcs_sql = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.scan_group) { prop = xmlGetProp(node, (unsigned char *)"scan_group"); if (prop != NULL) { chan->scan_group = atoi((char *) prop); } } if (rs->chan_list[i].mem_caps.flags) { prop = xmlGetProp(node, (unsigned char *)"flags"); if (prop != NULL) { sscanf((char *) prop, "%x", &chan->flags); } } return 0; } #endif hamlib-4.6.5/tests/testctld.pl0000775000175000017500000005642215056640443012015 #! /usr/bin/perl # testctld.pl - (C) 2008,2010 Nate Bargmann, n0nb@arrl.net # A Perl test script for the rigctld program. # # # It connects to the rigctld TCP port (default 4532) and queries the daemon # for some common rig information and sets some values. It also aims to # provide a bit of example code for Perl scripting. # # This program utilizes the Extended Response protocol of rigctld in line # response mode. See the rigctld(1) man page for details. ############################################################################# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # See the file 'COPYING' in the main Hamlib distribution directory for the # complete text of the GNU Public License version 2. # ############################################################################# # Perl modules this script uses use warnings; use strict; use IO::Socket; use Getopt::Long; use Pod::Usage; # Global variables my $socket; my $host = 'localhost'; my $port = 4532; my $vfo = ''; my %rig_state = (); # State of the rig--freq, mode, passband, ptt, etc. my %rig_caps = (); # Rig capabilities from \dump_caps my $man = 0; my $help = 0; my $debug = 0; my $user_in; my $ret_val; # Error values returned from rigctld by Hamlib name my %errstr = ( RIG_OK => "0", # No error, operation completed successfully RIG_EINVAL => "-1", # invalid parameter RIG_ECONF => "-2", # invalid configuration (serial,..) RIG_ENOMEM => "-3", # memory shortage RIG_ENIMPL => "-4", # function not implemented, but will be RIG_ETIMEOUT => "-5", # communication timed out RIG_EIO => "-6", # IO error, including open failed RIG_EINTERNAL => "-7", # Internal Hamlib error, huh?! RIG_EPROTO => "-8", # Protocol error RIG_ERJCTED => "-9", # Command rejected by the rig RIG_ETRUNC => "-10", # Command performed, but arg truncated RIG_ENAVAIL => "-11", # function not available RIG_ENTARGET => "-12", # VFO not targetable RIG_BUSERROR => "-13", # Error talking on the bus RIG_BUSBUSY => "-14", # Collision on the bus RIG_EARG => "-15", # NULL RIG handle or any invalid pointer parameter in get arg RIG_EVFO => "-16", # Invalid VFO RIG_EDOM => "-17", # Argument out of domain of func # testctld specific error values from -100 onward CTLD_OK => "-100", # testctld -- No error CTLD_ENIMPL => "-103", # testctld -- %rig_caps reports backend function not implemented CTLD_EPROTO => "-108", # testctld -- Echoed command mismatch or other error ); # Error values returned from rigctld by Hamlib value my %errval = reverse %errstr; ############################################################################# # Main program # ############################################################################# # Parse command line options argv_opts(); # Create the new socket. # 'localhost' may be replaced by any hostname or IP address where a # rigctld instance is running. # Timeout is set to 5 seconds. $socket = new IO::Socket::INET (PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Type => SOCK_STREAM, Timeout => 5 ) or die $@; print "Welcome to testctld.pl a program to test 'rigctld'\n"; print "Type '?' or 'help' for commands help.\n\n"; # Populate %rig_caps from \dump_caps $ret_val = dump_caps(); # Tell user what radio rigctld is working with if ($ret_val eq $errstr{'RIG_OK'}) { print "Hamlib Model: " . $rig_caps{'Caps dump for model'} . "\t"; print "Common Name: " . $rig_caps{'Mfg name'} . ' ' . $rig_caps{'Model name'} . "\n\n\n"; } else { errmsg ($ret_val); } # Check rigctld's response to the \chk_vfo command to see if it was # invoked with the -o|--vfo option. If true, all commands must include VFO as # first parameter after the command if (chk_opt($socket, 'CHKVFO')) { $vfo = 'currVFO'; # KISS--One could use the VFO key from %rig_state after calling the \get_vfo command... } # Interactive loop do { print "rigctld command: "; chomp($user_in = <>); # F, \set_freq if ($user_in =~ /^(F|\\set_freq)\s+(\d+)\b$/) { if ($rig_caps{'Can set Frequency'} eq 'Y') { # Get the entered frequency value print "Freq = $2\n" if $debug; $ret_val = rig_cmd('set_freq', $vfo, $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # f, \get_freq elsif ($user_in =~ /^(f|\\get_freq)\b$/) { if ($rig_caps{'Can get Frequency'} eq 'Y') { # Query rig and process result $ret_val = rig_cmd('get_freq', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "Frequency: " . $rig_state{Frequency} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # M, \set_mode elsif ($user_in =~ /^(M|\\set_mode)\s+([A-Z]+)\s+(\d+)\b$/) { if ($rig_caps{'Can set Mode'} eq 'Y') { # Get the entered mode and passband values print "Mode = $2, Passband = $3\n" if $debug; $ret_val = rig_cmd('set_mode', $vfo, $2, $3); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # m, \get_mode elsif ($user_in =~ /^(m|\\get_mode)\b$/) { if ($rig_caps{'Can get Mode'} eq 'Y') { # Do the same for the mode (reading the mode also returns the bandwidth) $ret_val = rig_cmd('get_mode', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "Mode: " . $rig_state{Mode} . "\n"; print "Passband: " . $rig_state{Passband} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # V, \set_vfo elsif ($user_in =~ /^(V|\\set_vfo)\s+([A-Za-z]+)\b$/) { if ($rig_caps{'Can set VFO'} eq 'Y') { print "VFO = $2\n" if $debug; $ret_val = rig_cmd('set_vfo', $2); # $vfo not used! unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # v, \get_vfo elsif ($user_in =~ /^(v|\\get_vfo)\b$/) { if ($rig_caps{'Can get VFO'} eq 'Y') { $ret_val = rig_cmd('get_vfo', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "VFO: " . $rig_state{VFO} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # J, \set_rit elsif ($user_in =~ /^(J|\\set_rit)\s+([+-]?\d+)\b$/) { if ($rig_caps{'Can set RIT'} eq 'Y') { print "RIT freq = $2\n" if $debug; $ret_val = rig_cmd('set_rit', $vfo, $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # j, \get_rit elsif ($user_in =~ /^(j|\\get_rit)\b$/) { if ($rig_caps{'Can get RIT'} eq 'Y') { $ret_val = rig_cmd('get_rit', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "RIT: " . $rig_state{RIT} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # Z, \set_xit elsif ($user_in =~ /^(Z|\\set_xit)\s+([+-]?\d+)\b$/) { if ($rig_caps{'Can set XIT'} eq 'Y') { print "XIT freq = $2\n" if $debug; $ret_val = rig_cmd('set_xit', $vfo, $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # z, \get_xit elsif ($user_in =~ /^(z|\\get_xit)\b$/) { if ($rig_caps{'Can get XIT'} eq 'Y') { $ret_val = rig_cmd('get_xit', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "XIT: " . $rig_state{XIT} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # T, \set_ptt elsif ($user_in =~ /^(T|\\set_ptt)\s+(\d)\b$/) { if ($rig_caps{'Can set PTT'} eq 'Y') { print "PTT = $2\n" if $debug; $ret_val = rig_cmd('set_ptt', $vfo, $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # t, \get_ptt elsif ($user_in =~ /^(t|\\get_ptt)\b$/) { if ($rig_caps{'Can get PTT'} eq 'Y') { $ret_val = rig_cmd('get_ptt', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "PTT: " . $rig_state{PTT} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # S, \set_split_vfo elsif ($user_in =~ /^(S|\\set_split_vfo)\s+(\d)\s+([A-Za-z]+)\b$/) { if ($rig_caps{'Can set Split VFO'} eq 'Y') { print "split = $2, VFO = $3\n" if $debug; $ret_val = rig_cmd('set_split_vfo', $vfo, $2, $3); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # s, \get_split_vfo elsif ($user_in =~ /^(s|\\get_split_vfo)\b$/) { if ($rig_caps{'Can get Split VFO'} eq 'Y') { $ret_val = rig_cmd('get_split_vfo', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "Split: " . $rig_state{Split} . "\n"; print "TX VFO: " . $rig_state{'TX VFO'} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # I, \set_split_freq elsif ($user_in =~ /^(I|\\set_split_freq)\s+(\d+)\b$/) { if ($rig_caps{'Can set Split Freq'} eq 'Y') { print "TX VFO freq = $2\n" if $debug; $ret_val = rig_cmd('set_split_freq', $vfo, $2); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # i, \get_split_freq elsif ($user_in =~ /^(i|\\get_split_freq)\b$/) { if ($rig_caps{'Can get Split Freq'} eq 'Y') { $ret_val = rig_cmd('get_split_freq', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "TX Frequency: " . $rig_state{'TX Frequency'} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # X, \set_split_mode elsif ($user_in =~ /^(X|\\set_split_mode)\s+([A-Z]+)\s+(\d+)\b$/) { if ($rig_caps{'Can set Split Mode'} eq 'Y') { # Get the entered mode and passband values print "TX Mode = $2, TX Passband = $3\n" if $debug; $ret_val = rig_cmd('set_split_mode', $vfo, $2, $3); unless ($ret_val eq $errstr{'RIG_OK'}) { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # x, \get_split_mode elsif ($user_in =~ /^(x|\\get_split_mode)\b$/) { if ($rig_caps{'Can get Split Mode'} eq 'Y') { # Do the same for the mode (reading the mode also returns the bandwidth) $ret_val = rig_cmd('get_split_mode', $vfo); if ($ret_val eq $errstr{'RIG_OK'}) { print "TX Mode: " . $rig_state{'TX Mode'} . "\n"; print "TX Passband: " . $rig_state{'TX Passband'} . "\n\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # 2, \power2mW elsif ($user_in =~ /^(2|\\power2mW)\s+(\d\.\d+)\s+(\d+)\s+([A-Za-z]+)\b$/) { if ($rig_caps{'Can get power2mW'} eq 'Y') { print "Power = $2, freq = $3, VFO = $4\n" if $debug; $ret_val = rig_cmd('power2mW', $2, $3, $4); if ($ret_val eq $errstr{'RIG_OK'}) { print "Power mW: " . $rig_state{'Power mW'} . "\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # 4, \mW2power elsif ($user_in =~ /^(4|\\mW2power)\s+(\d+)\s+(\d+)\s+([A-Za-z]+)\b$/) { if ($rig_caps{'Can get mW2power'} eq 'Y') { print "mW = $2, freq = $3, VFO = $4\n" if $debug; $ret_val = rig_cmd('mW2power', $2, $3, $4); if ($ret_val eq $errstr{'RIG_OK'}) { print "Power [0.0..1.0]: " . $rig_state{'Power [0.0..1.0]'} . "\n"; } else { errmsg ($ret_val); } } else { errmsg($errstr{'CTLD_ENIMPL'}); } } # 1, \dump_caps elsif ($user_in =~ /^(1|\\dump_caps)\b$/) { $ret_val = dump_caps(); if ($ret_val eq $errstr{'RIG_OK'}) { print "Model: " . $rig_caps{'Caps dump for model'} . "\n"; print "Manufacturer: " . $rig_caps{'Mfg name'} . "\n"; print "Name: " . $rig_caps{'Model name'} . "\n\n"; } else { errmsg ($ret_val); } } # ?, help elsif ($user_in =~ /^\?|^help\b$/) { print <) { # rigctld terminates each line with '\n' chomp; push @lines, $_; return @lines if $_ =~ /^RPRT/; } } # Builds the %rig_state hash from the lines returned by rigctld which are of the # form "Frequency: 14250000", "Mode: USB", "Passband: 2400", etc. sub get_state { my ($key, $val); foreach (@_) { ($key, $val) = split(/: /, $_); $rig_state{$key} = $val; } } # Parse the (large) \dump_caps command response into %rig_caps. # TODO: process all lines of output sub get_caps { my ($key, $val); foreach (@_) { if (($_ =~ /^Caps .*:/) or ($_ =~ /^Model .*:/) or ($_ =~ /^Mfg .*:/) or ($_ =~ /^Can .*:/) ) { ($key, $val) = split(/:\s+/, $_); $rig_caps{$key} = $val; } } } # Extract the Hamlib error value returned with the last line from rigctld sub get_errno { chomp @_; my @errno = split(/ /, $_[0]); return $errno[1]; } # check for VFO mode from rigctld sub chk_opt { my $sock = shift @_; my @lines; if ($_[0] =~ /^CHKVFO/) { print $sock "\\chk_vfo\n"; } while (<$sock>) { # rigctld terminates each line with '\n' chomp; push @lines, $_; # Should only be one line, but be sure last if $_ =~ /^$_[0]/; } # The CHK* line will have a space separated integer of 0 or 1 # for 'rigctld' invocation without and with -b|--block or # -o|--vfo options respectively foreach (@lines) { if ($_ =~ /^$_[0]\s(\d)/) { return $1; } } } # FIXME: Better argument handling sub errmsg { unless (($_[0] eq $errstr{'CTLD_EPROTO'}) or ($_[0] eq $errstr{'CTLD_ENIMPL'})) { print "rigctld returned Hamlib $errval{$_[0]}\n\n"; } elsif ($_[0] eq $errstr{'CTLD_EPROTO'}) { print "Echoed command mismatch\n\n"; } elsif ($_[0] eq $errstr{'CTLD_ENIMPL'}) { print "Function not yet implemented in Hamlib rig backend\n\n"; } } # Parse the command line for supported options. Print help text as needed. sub argv_opts { # Parse options and print usage if there is a syntax error, # or if usage was explicitly requested. GetOptions('help|?' => \$help, man => \$man, "port=i" => \$port, "host=s" => \$host, debug => \$debug ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-verbose => 2) if $man; } # POD for pod2usage __END__ =head1 NAME testctld.pl - A test and example program for 'rigctld' written in Perl. =head1 SYNOPSIS testctld.pl [options] Options: --host Hostname or IP address of target 'rigctld' process --port TCP Port of target 'rigctld' process --help Brief help message --man Full documentation --debug Enable debugging output =head1 DESCRIPTION B provides a set of functions to interactively test the Hamlib I TCP/IP network daemon. It also aims to be an example of programming code to control a radio via TCP/IP in Hamlib. =head1 OPTIONS =over 8 =item B<--host> Hostname or IP address of the target I process. Default is I which should resolve to 127.0.0.1 if I is configured correctly. =item B<--port> TCP port of the target I process. Default is 4532. Multiple instances of I will require unique port numbers. =item B<--help> Prints a brief help message and exits. =item B<--man> Prints this manual page and exits. =item B<--debug> Enables debugging output to the console. =back =head1 COMMANDS Commands are the same as described in the rigctld(1) man page. This is only a brief summary. F, \set_freq Set frequency in Hz f, \get_freq Get frequency in Hz M, \set_mode Set mode including passband in Hz m, \get_mode Get mode including passband in Hz V, \set_vfo Set VFO (VFOA, VFOB, etc.) v, \get_vfo Get VFO (VFOA, VFOB, etc.) J, \set_rit Set RIT in +/-Hz, '0' to clear j, \get_rit Get RIT in +/-Hz, '0' indicates Off Z, \set_xit Set XIT in +/-Hz, '0' to clear z, \get_rit Get XIT in +/-Hz, '0' indicates Off T, \set_ptt Set PTT, '1' On, '0' Off t, \get_ptt Get PTT, '1' indicates On, '0' indicates Off S, \set_split_vfo Set rig into "split" VFO mode, '1' On, '0' Off s, \get_split_vfo Get status of :split" VFO mode, '1' On, '0' Off I, \set_split_freq Set TX VFO frequency in Hz i, \get_split_freq Get TX VFO frequency in Hz X, \set_split_mode Set TX VFO mode including passband in Hz x, \get_split_mode Get TX VFO mode including passband in Hz 2, \power2mW Translate a power value [0.0..1.0] to milliWatts 4, \mW2power Translate milliWatts to a power value [0.0..1.0] 1, \dump_caps Get the rig capabilities and display select values. =cut hamlib-4.6.5/tests/rigctld.c0000664000175000017500000012075215056640443011421 /* * rigctld.c - (C) Stephane Fillod 2000-2011 * (C) Nate Bargmann 2008,2010,2011,2012,2013 * (C) The Hamlib Group 2012 * * This program test/control a radio using Hamlib. * It takes commands from network connection. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include #endif #include #include #include #include #include #include #include #include /* See NOTES */ #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include # include # if defined(HAVE_WSPIAPI_H) # include # endif #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_PTHREAD # include #endif #include #include "misc.h" #include "network.h" #include "rigctl_parse.h" #include "riglist.h" #include "token.h" /* * Reminder: when adding long options, * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. * TODO: add an option to read from a file */ #define SHORT_OPTIONS "m:r:p:d:P:D:s:S:c:T:t:C:W:w:x:lLuovhVZRA:b" static struct option long_options[] = { {"model", 1, 0, 'm'}, {"rig-file", 1, 0, 'r'}, {"ptt-file", 1, 0, 'p'}, {"dcd-file", 1, 0, 'd'}, {"ptt-type", 1, 0, 'P'}, {"dcd-type", 1, 0, 'D'}, {"serial-speed", 1, 0, 's'}, {"separator", 1, 0, 'S'}, {"civaddr", 1, 0, 'c'}, {"listen-addr", 1, 0, 'T'}, {"port", 1, 0, 't'}, {"set-conf", 1, 0, 'C'}, {"list", 0, 0, 'l'}, {"show-conf", 0, 0, 'L'}, {"dump-caps", 0, 0, 'u'}, {"vfo", 0, 0, 'o'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"twiddle_timeout", 1, 0, 'W'}, {"twiddle_rit", 1, 0, 'w'}, {"uplink", 1, 0, 'x'}, {"debug-time-stamps", 0, 0, 'Z'}, {"password", 1, 0, 'A'}, {"rigctld-idle", 0, 0, 'R'}, {"bind-all", 0, 0, 'b'}, {0, 0, 0, 0} }; struct handle_data { RIG *rig; int sock; struct sockaddr_storage cli_addr; socklen_t clilen; int vfo_mode; int use_password; }; void *handle_socket(void *arg); void usage(void); #ifdef HAVE_PTHREAD static unsigned client_count; #endif static RIG *my_rig; /* handle to rig (instance) */ static volatile int rig_opened = 0; static int verbose; #ifdef HAVE_SIG_ATOMIC_T static sig_atomic_t volatile ctrl_c = 0; #else static int volatile ctrl_c = 0; #endif const char *portno = "4532"; const char *src_addr = NULL; /* INADDR_ANY */ extern char rigctld_password[65]; char resp_sep = '\n'; extern int lock_mode; extern powerstat_t rig_powerstat; static int rigctld_idle = 0; // if true then rig will close when no clients are connected static int skip_open = 0; static int bind_all = 0; #define MAXCONFLEN 2048 void mutex_rigctld(int lock) { #ifdef HAVE_PTHREAD static pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER; if (lock) { pthread_mutex_lock(&client_lock); rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock engaged\n", __func__); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: client lock disengaged\n", __func__); pthread_mutex_unlock(&client_lock); } #endif } #ifdef WIN32 static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (fdwCtrlType) { case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: ctrl_c = 1; return TRUE; default: return FALSE; } } #else static void signal_handler(int sig) { switch (sig) { case SIGINT: case SIGTERM: fprintf(stderr, "\nTerminating application, caught signal %d\n", sig); // Close stdin to stop reading input fclose(stdin); ctrl_c = 1; break; default: /* do nothing */ break; } } #endif static void handle_error(enum rig_debug_level_e lvl, const char *msg) { int e; #ifdef __MINGW32__ LPVOID lpMsgBuf; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf); LocalFree(lpMsgBuf); } else { rig_debug(lvl, "%s: Network error %d\n", msg, e); } #else e = errno; rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e)); #endif } int main(int argc, char *argv[]) { rig_model_t my_model = RIG_MODEL_DUMMY; int retcode; /* generic return code from functions */ int show_conf = 0; int dump_caps_opt = 0; const char *rig_file = NULL, *ptt_file = NULL, *dcd_file = NULL; ptt_type_t ptt_type = RIG_PTT_NONE; dcd_type_t dcd_type = RIG_DCD_NONE; int serial_rate = 0; char *civaddr = NULL; /* NULL means no need to set conf */ char conf_parms[MAXCONFLEN] = ""; struct addrinfo hints, *result, *saved_result; int sock_listen; // int reuseaddr = 1; int twiddle_timeout = 0; int twiddle_rit = 0; int uplink = 0; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; char rigstartup[1024]; char vbuf[1024]; #if HAVE_SIGACTION struct sigaction act; #endif #ifdef HAVE_PTHREAD pthread_t thread; pthread_attr_t attr; #endif struct handle_data *arg; int vfo_mode = 0; /* vfo_mode=0 means target VFO is current VFO */ int i; extern int is_rigctld; is_rigctld = 1; int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf)); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: setvbuf err=%s\n", __func__, strerror(err)); } while (1) { int c; int option_index = 0; char dummy[2]; c = getopt_long(argc, argv, SHORT_OPTIONS, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'h': usage(); exit(0); case 'V': printf("rigctld %s\n", hamlib_version2); exit(0); case 'R': rigctld_idle = 1; break; case 'b': bind_all = 1; break; case 'A': strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1); //char *md5 = rig_make_m d5(rigctld_password); char md5[HAMLIB_SECRET_LENGTH + 1]; rig_password_generate_secret(rigctld_password, md5); printf("Secret key: %s\n", md5); rig_settings_save("sharedkey", md5, e_CHAR); break; case 'm': if (!optarg) { usage(); /* wrong arg count */ exit(1); } my_model = atoi(optarg); break; case 'r': if (!optarg) { usage(); /* wrong arg count */ exit(1); } rig_file = optarg; break; case 'p': if (!optarg) { usage(); /* wrong arg count */ exit(1); } ptt_file = optarg; break; case 'd': if (!optarg) { usage(); /* wrong arg count */ exit(1); } dcd_file = optarg; break; case 'P': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { ptt_type = RIG_PTT_RIG; } else if (!strcmp(optarg, "DTR")) { ptt_type = RIG_PTT_SERIAL_DTR; } else if (!strcmp(optarg, "RTS")) { ptt_type = RIG_PTT_SERIAL_RTS; } else if (!strcmp(optarg, "PARALLEL")) { ptt_type = RIG_PTT_PARALLEL; } else if (!strcmp(optarg, "CM108")) { ptt_type = RIG_PTT_CM108; } else if (!strcmp(optarg, "GPIO")) { ptt_type = RIG_PTT_GPIO; } else if (!strcmp(optarg, "GPION")) { ptt_type = RIG_PTT_GPION; } else if (!strcmp(optarg, "NONE")) { ptt_type = RIG_PTT_NONE; } else { puts("Unrecognised PTT type, using NONE"); ptt_type = RIG_PTT_NONE; } break; case 'D': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (!strcmp(optarg, "RIG")) { dcd_type = RIG_DCD_RIG; } else if (!strcmp(optarg, "DSR")) { dcd_type = RIG_DCD_SERIAL_DSR; } else if (!strcmp(optarg, "CTS")) { dcd_type = RIG_DCD_SERIAL_CTS; } else if (!strcmp(optarg, "CD")) { dcd_type = RIG_DCD_SERIAL_CAR; } else if (!strcmp(optarg, "PARALLEL")) { dcd_type = RIG_DCD_PARALLEL; } else if (!strcmp(optarg, "CM108")) { dcd_type = RIG_DCD_CM108; } else if (!strcmp(optarg, "GPIO")) { dcd_type = RIG_DCD_GPIO; } else if (!strcmp(optarg, "GPION")) { dcd_type = RIG_DCD_GPION; } else if (!strcmp(optarg, "NONE")) { dcd_type = RIG_DCD_NONE; } else { puts("Unrecognised DCD type, using NONE"); dcd_type = RIG_DCD_NONE; } break; case 'c': if (!optarg) { usage(); /* wrong arg count */ exit(1); } civaddr = optarg; break; case 'S': if (!optarg) { usage(); /* wrong arg count */ exit(1); } resp_sep = *optarg; rig_debug(RIG_DEBUG_VERBOSE, "%s: resp_sep=%c\n", __func__, resp_sep); break; case 's': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (sscanf(optarg, "%d%1s", &serial_rate, dummy) != 1) { fprintf(stderr, "Invalid baud rate of %s\n", optarg); exit(1); } break; case 'C': if (!optarg) { usage(); /* wrong arg count */ exit(1); } if (strcmp(optarg, "auto_power_on=0") == 0) { rig_debug(RIG_DEBUG_ERR, "%s: skipping rig_open\n", __func__); skip_open = 1; } else { if (*conf_parms != '\0') { strcat(conf_parms, ","); } if (strlen(conf_parms) + strlen(optarg) > MAXCONFLEN - 24) { printf("Length of conf_parms exceeds internal maximum of %d\n", MAXCONFLEN - 24); return 1; } strncat(conf_parms, optarg, MAXCONFLEN - strlen(conf_parms) - 1); } break; case 't': if (!optarg) { usage(); /* wrong arg count */ exit(1); } portno = optarg; break; case 'T': if (!optarg) { usage(); /* wrong arg count */ exit(1); } src_addr = optarg; break; case 'o': vfo_mode++; //rig_debug(RIG_DEBUG_ERR, "%s: #0 vfo_mode=%d\n", __func__, vfo_mode); break; case 'v': verbose++; break; case 'L': show_conf++; break; case 'l': list_models(); exit(0); case 'u': dump_caps_opt++; break; case 'W': if (!optarg) { usage(); /* wrong arg count */ exit(1); } twiddle_timeout = atoi(optarg); fprintf(stderr, "twiddle_timeout is deprecated...use e.g. --set-conf=twiddle_timeout=5\n"); break; case 'w': if (!optarg) { usage(); /* wrong arg count */ exit(1); } twiddle_rit = atoi(optarg); fprintf(stderr, "twiddle_rit is deprecated...use e.g. --set-conf=twiddle_rit=1\n"); break; case 'x': if (!optarg) { usage(); /* wrong arg count */ exit(1); } uplink = atoi(optarg); break; case 'Z': rig_set_debug_time_stamp(1); break; default: usage(); /* unknown option? */ exit(1); } } #if 0 if (!vfo_mode) { printf("Recommend using --vfo switch for rigctld if client supports it\n"); printf("rigctl and netrigctl will automatically detect vfo mode\n"); } #endif rig_set_debug(verbose); SNPRINTF(rigstartup, sizeof(rigstartup), "%s(%d) Startup:", __FILE__, __LINE__); for (i = 0; i < argc; ++i) { strcat(rigstartup, " "); strcat(rigstartup, argv[i]); } rig_debug(RIG_DEBUG_VERBOSE, "%s\n", rigstartup); rig_debug(RIG_DEBUG_VERBOSE, "rigctld %s\n", hamlib_version2); rig_debug(RIG_DEBUG_VERBOSE, "%s", "Report bugs to \n\n"); rig_debug(RIG_DEBUG_VERBOSE, "Max# of rigctld client services=%d\n", NI_MAXSERV); my_rig = rig_init(my_model); if (!my_rig) { fprintf(stderr, "Unknown rig num %u, or initialization error.\n", my_model); fprintf(stderr, "Please check with --list option.\n"); exit(2); } my_rig->caps->ptt_type = ptt_type; char *token = strtok(conf_parms, ","); struct rig_state *rs = STATE(my_rig); while (token) { char mytoken[100], myvalue[100]; hamlib_token_t lookup; sscanf(token, "%99[^=]=%99s", mytoken, myvalue); //printf("mytoken=%s,myvalue=%s\n",mytoken, myvalue); lookup = rig_token_lookup(my_rig, mytoken); if (lookup == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no such token as '%s'\n", __func__, mytoken); token = strtok(NULL, ","); continue; } retcode = rig_set_conf(my_rig, lookup, myvalue); if (retcode != RIG_OK) { fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); exit(2); } token = strtok(NULL, ","); ptt_type = my_rig->caps->ptt_type; // in case we set the ptt_type with set_conf } if (rig_file) { rig_set_conf(my_rig, TOK_PATHNAME, rig_file); } rs->twiddle_timeout = twiddle_timeout; rs->twiddle_rit = twiddle_rit; rs->uplink = uplink; rig_debug(RIG_DEBUG_TRACE, "%s: twiddle=%d, uplink=%d, twiddle_rit=%d\n", __func__, rs->twiddle_timeout, rs->uplink, rs->twiddle_rit); /* * ex: RIG_PTT_PARALLEL and /dev/parport0 */ if (ptt_type != RIG_PTT_NONE) { PTTPORT(my_rig)->type.ptt = ptt_type; rs->pttport_deprecated.type.ptt = ptt_type; // This causes segfault since backend rig_caps are const // rigctld will use the STATE(rig) version of this for clients //my_rig->caps->ptt_type = ptt_type; } if (dcd_type != RIG_DCD_NONE) { DCDPORT(my_rig)->type.dcd = dcd_type; rs->dcdport_deprecated.type.dcd = dcd_type; } if (ptt_file) { strncpy(PTTPORT(my_rig)->pathname, ptt_file, HAMLIB_FILPATHLEN - 1); strncpy(rs->pttport_deprecated.pathname, ptt_file, HAMLIB_FILPATHLEN - 1); // default to RTS when ptt_type is not specified if (ptt_type == RIG_PTT_NONE) { rig_debug(RIG_DEBUG_VERBOSE, "%s: defaulting to RTS PTT\n", __func__); my_rig->caps->ptt_type = ptt_type = RIG_PTT_SERIAL_RTS; } } if (dcd_file) { strncpy(DCDPORT(my_rig)->pathname, dcd_file, HAMLIB_FILPATHLEN - 1); strncpy(rs->dcdport_deprecated.pathname, dcd_file, HAMLIB_FILPATHLEN - 1); } /* FIXME: bound checking and port type == serial */ if (serial_rate != 0) { RIGPORT(my_rig)->parm.serial.rate = serial_rate; rs->rigport_deprecated.parm.serial.rate = serial_rate; } if (civaddr) { rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); } /* * print out conf parameters */ if (show_conf) { rig_token_foreach(my_rig, print_conf_list, (rig_ptr_t)my_rig); if (rig_file == NULL) { fflush(stdout); exit(0); } } /* * print out conf parameters, and exits immediately * We may be interested only in only caps, and rig_open may fail. */ if (dump_caps_opt) { dumpcaps(my_rig, stdout); rig_cleanup(my_rig); /* if you care about memory */ exit(0); } /* attempt to open rig to check early for issues */ if (skip_open) { rig_opened = 0; } else { retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; } if (retcode != RIG_OK) { fprintf(stderr, "rig_open: error = %s %s %s \n", rigerror(retcode), rig_file, strerror(errno)); // continue even if opening the rig fails, because it may be powered off } if (verbose > RIG_DEBUG_ERR) { printf("Opened rig model %u, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } rig_debug(RIG_DEBUG_VERBOSE, "Backend version: %s, Status: %s\n", my_rig->caps->version, rig_strstatus(my_rig->caps->status)); // Normally we keep the rig open to speed up the 1st client connect // But some rigs like the FT-736 have to lock the rig for CAT control // So they need to release the rig when no clients are connected if (rigctld_idle) { rig_close(my_rig); /* we will reopen for clients */ if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %u, '%s - will reopen for clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } #ifdef __MINGW32__ # ifndef SO_OPENTYPE # define SO_OPENTYPE 0x7008 # endif # ifndef SO_SYNCHRONOUS_NONALERT # define SO_SYNCHRONOUS_NONALERT 0x20 # endif # ifndef INVALID_SOCKET # define INVALID_SOCKET -1 # endif WSADATA wsadata; if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) { fprintf(stderr, "WSAStartup socket error\n"); exit(1); } { int sockopt = SO_SYNCHRONOUS_NONALERT; setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&sockopt, sizeof(sockopt)); } #endif /* * Prepare listening socket */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM;/* TCP socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ retcode = getaddrinfo(src_addr, portno, &hints, &result); if (retcode == 0 && result->ai_family == AF_INET6) { rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV6\n", __func__); } else if (retcode == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV4\n", __func__); } else { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retcode)); exit(2); } saved_result = result; do { sock_listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock_listen < 0) { handle_error(RIG_DEBUG_ERR, "socket"); freeaddrinfo(saved_result); /* No longer needed */ exit(2); } const int optval = 1; #ifdef __MINGW32__ if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, (PCHAR)&optval, sizeof(optval)) < 0) #else if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) #endif { rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP address reuse: %s\n", __func__, strerror(errno)); } // Windows does not have SO_REUSEPORT. However, SO_REUSEADDR works in a similar way. #if defined(SO_REUSEPORT) if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error enabling UDP port reuse: %s\n", __func__, strerror(errno)); } #endif #if 0 if (setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } #endif #ifdef IPV6_V6ONLY if (AF_INET6 == result->ai_family) { /* allow IPv4 mapped to IPv6 clients Windows and BSD default this to 1 (i.e. disallowed) and we prefer it off */ int sockopt = 0; if (setsockopt(sock_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&sockopt, sizeof(sockopt)) < 0) { handle_error(RIG_DEBUG_ERR, "setsockopt"); freeaddrinfo(saved_result); /* No longer needed */ exit(1); } } #endif int retval = bind(sock_listen, result->ai_addr, result->ai_addrlen); if (retval == 0) { break; } { rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno)); } if (bind_all) { handle_error(RIG_DEBUG_WARN, "binding failed (trying next interface)"); } else { handle_error(RIG_DEBUG_WARN, "binding failed"); } #ifdef __MINGW32__ closesocket(sock_listen); #else close(sock_listen); #endif } while (bind_all && ((result = result->ai_next) != NULL)); freeaddrinfo(saved_result); /* No longer needed */ if (NULL == result) { rig_debug(RIG_DEBUG_ERR, "%s: bind error - no available interface\n", __func__); exit(1); } if (listen(sock_listen, 4) < 0) { handle_error(RIG_DEBUG_ERR, "listening"); exit(1); } #if HAVE_SIGACTION #ifdef SIGPIPE /* Ignore SIGPIPE as we will handle it at the write()/send() calls that will consequently fail with EPIPE. All child threads will inherit this disposition which is what we want. */ memset(&act, 0, sizeof act); act.sa_handler = SIG_IGN; act.sa_flags = SA_RESTART; if (sigaction(SIGPIPE, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE"); } #endif #ifdef SIGINT memset(&act, 0, sizeof act); act.sa_handler = signal_handler; if (sigaction(SIGINT, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGINT"); } #endif #ifdef SIGTERM memset(&act, 0, sizeof act); act.sa_handler = signal_handler; if (sigaction(SIGTERM, &act, NULL)) { handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM"); } #endif #elif defined (WIN32) if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) { handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler"); } #elif HAVE_SIGNAL #ifdef SIGPIPE if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) { handle_error(RIG_DEBUG_ERR, "signal SIGPIPE"); } #endif #ifdef SIGINT if (SIG_ERR == signal(SIGINT, signal_handler)) { handle_error(RIG_DEBUG_ERR, "signal SIGINT"); } #endif #ifdef SIGTERM if (SIG_ERR == signal(SIGTERM, signal_handler)) { handle_error(RIG_DEBUG_ERR, "signal SIGTERM"); } #endif #endif /* * main loop accepting connections */ rig_debug(RIG_DEBUG_TRACE, "%s: rigctld listening on port %s\n", __func__, portno); do { fd_set set; struct timeval timeout; arg = calloc(1, sizeof(struct handle_data)); if (!arg) { rig_debug(RIG_DEBUG_ERR, "calloc: %s\n", strerror(errno)); exit(1); } if (rigctld_password[0] != 0) { arg->use_password = 1; } /* use select to allow for periodic checks for CTRL+C */ FD_ZERO(&set); FD_SET(sock_listen, &set); timeout.tv_sec = 5; timeout.tv_usec = 0; retcode = select(sock_listen + 1, &set, NULL, NULL, &timeout); if (retcode == -1) { int errno_stored = errno; rig_debug(RIG_DEBUG_ERR, "%s: select() failed: %s\n", __func__, strerror(errno_stored)); if (ctrl_c) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ctrl_c when retcode==-1\n", __func__); break; } if (errno == EINTR) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ignoring interrupted system call\n", __func__); //retcode = 0; // not used? } } else if (retcode == 0) { if (ctrl_c) { rig_debug(RIG_DEBUG_VERBOSE, "%s: ctrl_c when retcode==0\n", __func__); break; } } else { arg->rig = my_rig; arg->clilen = sizeof(arg->cli_addr); arg->vfo_mode = vfo_mode; arg->sock = accept(sock_listen, (struct sockaddr *)&arg->cli_addr, &arg->clilen); if (arg->sock < 0) { handle_error(RIG_DEBUG_ERR, "accept"); break; } if ((retcode = getnameinfo((struct sockaddr const *)&arg->cli_addr, arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection opened from %s:%s\n", host, serv); #ifdef HAVE_PTHREAD pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); retcode = pthread_create(&thread, &attr, handle_socket, arg); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "pthread_create: %s\n", strerror(retcode)); break; } #else handle_socket(arg); #endif } } while (!ctrl_c); rig_debug(RIG_DEBUG_VERBOSE, "%s: while loop done\n", __func__); #ifdef HAVE_PTHREAD /* allow threads to finish current action */ mutex_rigctld(1); if (client_count) { rig_debug(RIG_DEBUG_WARN, "%u outstanding client(s)\n", client_count); } #ifdef __MINGW__ closesocket(sock_listen); #else close(sock_listen); #endif rig_close(my_rig); mutex_rigctld(0); #else rig_close(my_rig); /* close port */ #endif rig_cleanup(my_rig); /* if you care about memory */ #ifdef __MINGW32__ WSACleanup(); #endif return 0; } static FILE *get_fsockout(struct handle_data *handle_data_arg) { #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); return _fdopen(sock_osfhandle, "wb"); #else return fdopen(handle_data_arg->sock, "wb"); #endif } static FILE *get_fsockin(struct handle_data *handle_data_arg) { #ifdef __MINGW32__ int sock_osfhandle = _open_osfhandle(handle_data_arg->sock, _O_RDONLY); if (sock_osfhandle == -1) { rig_debug(RIG_DEBUG_ERR, "_open_osfhandle error: %s\n", strerror(errno)); return NULL; } return _fdopen(sock_osfhandle, "rb"); #else return fdopen(handle_data_arg->sock, "rb"); #endif } /* * This is the function run by the threads */ void *handle_socket(void *arg) { struct handle_data *handle_data_arg = (struct handle_data *)arg; FILE *fsockin = NULL; FILE *fsockout = NULL; int retcode = RIG_OK; char host[NI_MAXHOST]; char serv[NI_MAXSERV]; char send_cmd_term = '\r'; /* send_cmd termination char */ int ext_resp = 0; char my_resp_sep = resp_sep; // Separator for this connection, initial default rig_powerstat = RIG_POWER_ON; // defaults to power on struct timespec powerstat_check_time; fsockin = get_fsockin(handle_data_arg); if (!fsockin) { rig_debug(RIG_DEBUG_ERR, "%s: fdopen(0x%d) in: %s\n", __func__, handle_data_arg->sock, strerror(errno)); goto handle_exit; } fsockout = get_fsockout(handle_data_arg); if (!fsockout) { rig_debug(RIG_DEBUG_ERR, "%s: fdopen out: %s\n", __func__, strerror(errno)); fclose(fsockin); fsockin = NULL; goto handle_exit; } #ifdef HAVE_PTHREAD mutex_rigctld(1); ++client_count; #if 0 if (!client_count++) { retcode = rig_open(my_rig); if (RIG_OK == retcode && verbose > RIG_DEBUG_ERR) { printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } #endif mutex_rigctld(0); #else mutex_rigctld(1); retcode = rig_open(my_rig); mutex_rigctld(0); if (RIG_OK == retcode && verbose > RIG_DEBUG_ERR) { printf("Opened rig model %d, '%s'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } #endif if (my_rig->caps->get_powerstat) { mutex_rigctld(1); rig_get_powerstat(my_rig, &rig_powerstat); mutex_rigctld(0); STATE(my_rig)->powerstat = rig_powerstat; } elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_SET); do { mutex_rigctld(1); if (!rig_opened) { retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; rig_debug(RIG_DEBUG_ERR, "%s: rig_open reopened retcode=%d\n", __func__, retcode); } mutex_rigctld(0); if (rig_opened) // only do this if rig is open { rig_debug(RIG_DEBUG_TRACE, "%s: doing rigctl_parse vfo_mode=%d, secure=%d\n", __func__, handle_data_arg->vfo_mode, handle_data_arg->use_password); retcode = rigctl_parse(handle_data_arg->rig, fsockin, fsockout, NULL, 0, mutex_rigctld, 1, 0, &handle_data_arg->vfo_mode, send_cmd_term, &ext_resp, &my_resp_sep, handle_data_arg->use_password); if (retcode != 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rigctl_parse retcode=%d\n", __func__, retcode); } // If we get a timeout, the rig might be powered off // Update our power status in case power gets turned off // Check power status if rig is powered off, but not more often than once per second if (my_rig->caps->get_powerstat && (retcode == -RIG_ETIMEOUT || (retcode == -RIG_EPOWER && elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_GET) >= 1000))) { powerstat_t powerstat; rig_get_powerstat(my_rig, &powerstat); rig_powerstat = powerstat; if (powerstat == RIG_POWER_OFF || powerstat == RIG_POWER_STANDBY) { retcode = -RIG_EPOWER; } elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_SET); } } else { retcode = -RIG_EIO; } // if we get a hard error we try to reopen the rig again // this should cover short dropouts that can occur if (retcode < 0 && !RIG_IS_SOFT_ERRCODE(-retcode)) { int retry = 3; rig_debug(RIG_DEBUG_ERR, "%s: i/o error\n", __func__); do { mutex_rigctld(1); retcode = rig_close(my_rig); rig_opened = 0; mutex_rigctld(0); rig_debug(RIG_DEBUG_ERR, "%s: rig_close retcode=%d\n", __func__, retcode); hl_usleep(1000 * 1000); mutex_rigctld(1); if (!rig_opened) { retcode = rig_open(my_rig); rig_opened = retcode == RIG_OK ? 1 : 0; rig_debug(RIG_DEBUG_ERR, "%s: rig_open retcode=%d, opened=%d\n", __func__, retcode, rig_opened); } mutex_rigctld(0); } while (!ctrl_c && !rig_opened && retry-- > 0 && retcode != RIG_OK); } } while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode))); #if defined(HAVE_PTHREAD) if (rigctld_idle && client_count == 1) #else if (rigctld_idle) #endif { rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %s. Will reopen for new clients\n", my_rig->caps->model_name); } } #ifdef HAVE_PTHREAD --client_count; if (rigctld_idle && client_count > 0) { printf("%u client%s still connected so rig remains open\n", client_count, client_count > 1 ? "s" : ""); } #if 0 mutex_rigctld(1); /* Release rig if there are no clients */ if (!--client_count) { rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %d, '%s - no clients, will reopen for new clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } } mutex_rigctld(0); #endif #else rig_close(my_rig); if (verbose > RIG_DEBUG_ERR) { printf("Closed rig model %d, '%s - will reopen for new clients'\n", my_rig->caps->rig_model, my_rig->caps->model_name); } #endif if ((retcode = getnameinfo((struct sockaddr const *)&handle_data_arg->cli_addr, handle_data_arg->clilen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) < 0) { rig_debug(RIG_DEBUG_WARN, "Peer lookup error: %s", gai_strerror(retcode)); } rig_debug(RIG_DEBUG_VERBOSE, "Connection closed from %s:%s\n", host, serv); handle_exit: // for MINGW we close the handle before fclose #ifdef __MINGW32__ retcode = closesocket(handle_data_arg->sock); if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "%s: fclose(fsockin) %s\n", __func__, strerror(retcode)); } #endif if (fsockin) { fclose(fsockin); } if (fsockout) { fclose(fsockout); } // for everybody else we close the handle after fclose #ifndef __MINGW32__ retcode = close(handle_data_arg->sock); if (retcode != 0 && errno != EBADF) { rig_debug(RIG_DEBUG_ERR, "%s: close(handle_data_arg->sock) %s\n", __func__, strerror(errno)); } #endif free(arg); #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif return NULL; } void usage(void) { printf("Usage: rigctld [OPTION]...\n" "Daemon serving COMMANDs to a connected radio transceiver or receiver.\n\n"); printf( " -m, --model=ID select radio model number. See model list (-l)\n" " -r, --rig-file=DEVICE set device of the radio to operate on\n" " -p, --ptt-file=DEVICE set device of the PTT device to operate on\n" " -d, --dcd-file=DEVICE set device of the DCD device to operate on\n" " -P, --ptt-type=TYPE set type of the PTT device to operate on\n" " -D, --dcd-type=TYPE set type of the DCD device to operate on\n" " -s, --serial-speed=BAUD set serial speed of the serial port\n" " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" " -t, --port=NUM set TCP listening port, default %s\n" " -S, --separator=CHAR set char as rigctld response separator, default is \\n\n" " -T, --listen-addr=IPADDR set listening IP address, default ANY\n" " -C, --set-conf=PARM=VAL[,...] set config parameters\n" " -L, --show-conf list all config parameters\n" " -l, --list list all model numbers and exit\n" " -u, --dump-caps dump capabilities and exit\n" " -o, --vfo do not default to VFO_CURR, require extra vfo arg\n" " -v, --verbose set verbose mode, cumulative (-v to -vvvvv)\n" " -W, --twiddle_timeout=SECONDS timeout after detecting vfo manual change\n" " -w, --twiddle_rit=SECONDS suppress VFOB getfreq so RIT can be twiddled\n" " -x, --uplink=OPTION set uplink get_freq ignore: option 1=Sub, 2=Main\n" " -Z, --debug-time-stamps enable time stamps for debug messages\n" " -A, --password=PASSWORD set password for rigctld access (NOT IMPLEMENTED)\n" " -R, --rigctld-idle make rigctld close the rig when no clients are connected\n" " -b, --bind-all make rigctld bind to first network device available\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n\n", portno); usage_rig(stdout); printf("\nError codes and messages\n"); for (enum rig_errcode_e e = 0; e < RIG_EEND; ++e) { printf("-%d - %s", e, rigerror2(e)); } printf("\nReport bugs to .\n"); } hamlib-4.6.5/tests/ampctl_parse.c0000664000175000017500000015656715056640443012460 /* * ampctl_parse.c - (C) Stephane Fillod 2000-2010 * (C) Nate Bargmann 2003,2007,2010,2011,2012,2013 * (C) The Hamlib Group 2002,2006,2011 * Derived from rotctl_parse.c by Michael Black 2019 * * This program test/control an amplifier using Hamlib. * It takes commands in interactive mode as well as * from command line options. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBREADLINE # if defined(HAVE_READLINE_READLINE_H) # include # elif defined(HAVE_READLINE_H) /* !defined(HAVE_READLINE_READLINE_H) */ # include # else /* !defined(HAVE_READLINE_H) */ extern char *readline(); # endif /* HAVE_READLINE_H */ #else /* no readline */ #endif /* HAVE_LIBREADLINE */ #ifdef HAVE_READLINE_HISTORY # if defined(HAVE_READLINE_HISTORY_H) # include # elif defined(HAVE_HISTORY_H) # include # else /* !defined(HAVE_HISTORY_H) */ extern void add_history(); extern int write_history(); extern int read_history(); # endif /* defined(HAVE_READLINE_HISTORY_H) */ /* no history */ #endif /* HAVE_READLINE_HISTORY */ #include #include "amplist.h" #include "iofunc.h" #include "misc.h" #include "sprintflst.h" #include "ampctl_parse.h" /* Hash table implementation See: http://uthash.sourceforge.net/ */ #include "uthash.h" #ifdef HAVE_PTHREAD # include static pthread_mutex_t amp_mutex = PTHREAD_MUTEX_INITIALIZER; #endif #define STR1(S) #S #define STR(S) STR1(S) #define MAXNAMSIZ 32 #define MAXNBOPT 100 /* max number of different options */ #define MAXARGSZ 127 #define ARG_IN1 0x01 #define ARG_OUT1 0x02 #define ARG_IN2 0x04 #define ARG_OUT2 0x08 #define ARG_IN3 0x10 #define ARG_OUT3 0x20 #define ARG_IN4 0x40 #define ARG_OUT4 0x80 #define ARG_IN_LINE 0x4000 #define ARG_NONE 0 #define ARG_IN (ARG_IN1|ARG_IN2|ARG_IN3|ARG_IN4) #define ARG_OUT (ARG_OUT1|ARG_OUT2|ARG_OUT3|ARG_OUT4) /* variables for readline support */ #ifdef HAVE_LIBREADLINE static char *input_line = (char *)NULL; static char *result = (char *)NULL; static char *parsed_input[sizeof(char *) * 7]; static const int have_rl = 1; #ifdef HAVE_READLINE_HISTORY static char *rp_hist_buf = (char *)NULL; #endif #else static const int have_rl = 0; #endif struct test_table { unsigned char cmd; const char *name; int (*amp_routine)(AMP *, FILE *, int, const struct test_table *, const char *, const char *, const char *, const char *, const char *, const char *); int flags; const char *arg1; const char *arg2; const char *arg3; const char *arg4; const char *arg5; const char *arg6; }; #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EINVAL; else do {} while(0) #define ACTION(f) ampctl_##f #define declare_proto_amp(f) static int (ACTION(f))(AMP *amp, \ FILE *fout, \ int interactive, \ const struct test_table *cmd, \ const char *arg1, \ const char *arg2, \ const char *arg3, \ const char *arg4, \ const char *arg5, \ const char *arg6) declare_proto_amp(set_freq); declare_proto_amp(get_freq); declare_proto_amp(send_cmd); declare_proto_amp(dump_state); declare_proto_amp(dump_caps); declare_proto_amp(get_info); declare_proto_amp(reset); declare_proto_amp(set_level); declare_proto_amp(get_level); declare_proto_amp(set_powerstat); declare_proto_amp(get_powerstat); //declare_proto_amp(dump_caps); /* * convention: upper case cmd is set, lowercase is get * * NB: 'q' 'Q' '?' are reserved by interactive mode interface */ struct test_table test_list[] = { { 'F', "set_freq", ACTION(set_freq), ARG_IN, "Frequency(Hz)" }, { 'f', "get_freq", ACTION(get_freq), ARG_OUT, "Frequency(Hz)" }, { 'l', "get_level", ACTION(get_level), ARG_IN1 | ARG_OUT2, "Level", "Level Value" }, { 'L', "set_level", ACTION(set_level), ARG_IN, "Level", "Level Value" }, { 'w', "send_cmd", ACTION(send_cmd), ARG_IN1 | ARG_IN_LINE | ARG_OUT2, "Cmd", "Reply" }, { 0x8f, "dump_state", ACTION(dump_state), ARG_OUT }, { '1', "dump_caps", ACTION(dump_caps), }, { '_', "get_info", ACTION(get_info), ARG_OUT, "Info" }, { 'R', "reset", ACTION(reset), ARG_IN, "Reset" }, { 0x87, "set_powerstat", ACTION(set_powerstat), ARG_IN, "Power Status" }, { 0x88, "get_powerstat", ACTION(get_powerstat), ARG_OUT, "Power Status" }, { 0x00, "", NULL }, }; struct test_table *find_cmd_entry(int cmd) { int i; for (i = 0; test_list[i].cmd != 0; i++) if (test_list[i].cmd == cmd) { break; } if (test_list[i].cmd == 0x00) { return NULL; } return &test_list[i]; } /* Structure for hash table provided by uthash.h * * Structure and hash functions patterned after/copied from example.c * distributed with the uthash package. See: http://uthash.sourceforge.net/ */ struct mod_lst { unsigned int id; /* caps->amp_model This is the hash key */ char mfg_name[32]; /* caps->mfg_name */ char model_name[32]; /* caps->model_name */ char version[32]; /* caps->version */ char status[32]; /* caps->status */ char macro_name[32]; /* caps->macro_name */ UT_hash_handle hh; /* makes this structure hashable */ }; /* Hash declaration. Must be initialized to NULL */ struct mod_lst *models = NULL; /* Add model information to the hash */ void hash_add_model(int id, const char *mfg_name, const char *model_name, const char *version, const char *status, const char *macro_name) { struct mod_lst *s; s = (struct mod_lst *)calloc(1, sizeof(struct mod_lst)); s->id = id; SNPRINTF(s->mfg_name, sizeof(s->mfg_name), "%s", mfg_name); SNPRINTF(s->model_name, sizeof(s->model_name), "%s", model_name); SNPRINTF(s->version, sizeof(s->version), "%s", version); SNPRINTF(s->status, sizeof(s->status), "%s", status); SNPRINTF(s->macro_name, sizeof(s->macro_name), "%s", macro_name); HASH_ADD_INT(models, id, s); /* id: name of key field */ } /* Hash sorting functions */ int hash_model_id_sort(struct mod_lst *a, struct mod_lst *b) { return (a->id > b->id); } void hash_sort_by_model_id() { HASH_SORT(models, hash_model_id_sort); } /* Delete hash */ void hash_delete_all() { struct mod_lst *current_model, *tmp; HASH_ITER(hh, models, current_model, tmp) { /* delete it (models advances to next) */ HASH_DEL(models, current_model); free(current_model); /* free it */ } } #ifdef HAVE_LIBREADLINE /* Frees allocated memory and sets pointers to NULL before calling readline * and then parses the input into space separated tokens. */ static void rp_getline(const char *s) { int i; /* free allocated memory and set pointers to NULL */ if (input_line) { free(input_line); input_line = (char *)NULL; } if (result) { result = (char *)NULL; } /* cmd, arg1, arg2, arg3, arg4, arg5, arg6 * arg5 and arg 6 are currently unused. */ for (i = 0; i < 7; i++) { parsed_input[i] = NULL; } /* Action! Returns typed line with newline stripped. */ input_line = readline(s); } #endif /* * TODO: use Lex? */ char parse_arg(const char *arg) { int i; for (i = 0; test_list[i].cmd != 0; i++) { if (!strncmp(arg, test_list[i].name, MAXNAMSIZ)) { return test_list[i].cmd; } } return 0; } /* * This scanf works even in presence of signals (timer, SIGIO, ..) */ static int scanfc(FILE *fin, const char *format, void *p) { do { int ret = fscanf(fin, format, p); if (ret < 0) { if (errno == EINTR) { continue; } rig_debug(RIG_DEBUG_ERR, "fscanf: %s\n", strerror(errno)); rig_debug(RIG_DEBUG_ERR, "fscanf: parsing '%s' with '%s'\n", (char *)p, format); } return ret; } while (1); } /* * function to get the next word from the command line or from stdin * until stdin exhausted. stdin is read if the special token '-' is * found on the command line. * * returns EOF when words exhausted * returns <0 is error number * returns >=0 when successful */ static int next_word(char *buffer, int argc, char *argv[], int newline) { int ret; char c; static int reading_stdin; if (!reading_stdin) { if (optind >= argc) { return EOF; } else if (newline && '-' == argv[optind][0] && 1 == strlen(argv[optind])) { ++optind; reading_stdin = 1; } } if (reading_stdin) { do { do { ret = scanf(" %c%" STR(MAXARGSZ) "[^ \t\n#]", &c, &buffer[1]); } while (EINTR == ret); if (ret > 0 && '#' == c) { do { ret = scanf("%*[^\n]"); } while (EINTR == ret); /* consume comments */ ret = 0; } } while (!ret); if (EOF == ret) { reading_stdin = 0; } else if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "scanf: %s\n", strerror(errno)); reading_stdin = 0; } else { buffer[0] = c; buffer[1 == ret ? 1 : MAXARGSZ] = '\0'; if (newline) { putchar('\n'); } fputs(buffer, stdout); putchar(' '); } } if (!reading_stdin) { if (optind < argc) { strncpy(buffer, argv[optind++], MAXARGSZ); buffer[MAXARGSZ] = '\0'; ret = 1; } else { ret = EOF; } } return ret; } #define fprintf_flush(f, a...) \ ({ int __ret; \ __ret = fprintf((f), a); \ fflush((f)); \ __ret; \ }) extern int interactive; extern int prompt; extern char send_cmd_term; int ext_resp = 0; unsigned char resp_sep = '\n'; /* Default response separator */ int ampctl_parse(AMP *my_amp, FILE *fin, FILE *fout, char *argv[], int argc) { int retcode; /* generic return code from functions */ unsigned char cmd; struct test_table *cmd_entry; char command[MAXARGSZ + 1]; char arg1[MAXARGSZ + 1], *p1 = NULL; char arg2[MAXARGSZ + 1], *p2 = NULL; char arg3[MAXARGSZ + 1], *p3 = NULL; char arg4[MAXARGSZ + 1], *p4 = NULL; #ifdef __USEP5P6__ // to avoid cppcheck warning char *p5 = NULL; char *p6 = NULL; #endif /* cmd, internal, ampctld */ if (!(interactive && prompt && have_rl)) { if (interactive) { static int last_was_ret = 1; if (prompt) { fprintf_flush(fout, "\nAmplifier command: "); } do { if (scanfc(fin, "%c", &cmd) < 1) { return -1; } /* Extended response protocol requested with leading '+' on command * string--ampctld only! */ if (cmd == '+' && !prompt) { ext_resp = 1; if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } else if (cmd == '+' && prompt) { return 0; } if (cmd != '\\' && cmd != '_' && cmd != '#' && ispunct(cmd) && !prompt) { ext_resp = 1; resp_sep = cmd; if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } else if (cmd != '\\' && cmd != '?' && cmd != '_' && cmd != '#' && ispunct(cmd) && prompt) { return 0; } /* command by name */ if (cmd == '\\') { unsigned char cmd_name[MAXNAMSIZ], *pcmd = cmd_name; int c_len = MAXNAMSIZ; if (scanfc(fin, "%c", pcmd) < 1) { return -1; } while (c_len-- && (isalnum(*pcmd) || *pcmd == '_')) { if (scanfc(fin, "%c", ++pcmd) < 1) { return -1; } } *pcmd = '\0'; cmd = parse_arg((char *) cmd_name); break; } if (cmd == 0x0a || cmd == 0x0d) { if (last_was_ret) { if (prompt) { fprintf_flush(fout, "? for help, q to quit.\n"); } return 0; } last_was_ret = 1; } } while (cmd == 0x0a || cmd == 0x0d); last_was_ret = 0; /* comment line */ if (cmd == '#') { while (cmd != '\n' && cmd != '\r') { if (scanfc(fin, "%c", &cmd) < 1) { return -1; } } return 0; } if (cmd == 'Q' || cmd == 'q') { return 1; } if (cmd == '?') { usage_amp(fout); fflush(fout); return 0; } } else { /* parse rest of command line */ retcode = next_word(command, argc, argv, 1); if (EOF == retcode) { return 1; } else if (retcode < 0) { return retcode; } else if ('\0' == command[1]) { cmd = command[0]; } else { cmd = parse_arg(command); } } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { fprintf_flush(stderr, "Command '%c' not found!\n", cmd); return 0; } if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (interactive) { char *nl; if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (fgets(arg1, MAXARGSZ, fin) == NULL) { return -1; } if (arg1[0] == 0xa) { if (fgets(arg1, MAXARGSZ, fin) == NULL) { return -1; } } nl = strchr(arg1, 0xa); if (nl) { *nl = '\0'; /* chomp */ } p1 = arg1[0] == ' ' ? arg1 + 1 : arg1; } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p1 = arg1; } } else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg1); } if (scanfc(fin, "%s", arg1) < 1) { return -1; } p1 = arg1; } else { retcode = next_word(arg1, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p1 = arg1; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg2); } if (scanfc(fin, "%s", arg2) < 1) { return -1; } p2 = arg2; } else { retcode = next_word(arg2, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p2 = arg2; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg3); } if (scanfc(fin, "%s", arg3) < 1) { return -1; } p3 = arg3; } else { retcode = next_word(arg3, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p3 = arg3; } } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN4) && cmd_entry->arg4) { if (interactive) { if (prompt) { fprintf_flush(fout, "%s: ", cmd_entry->arg4); } if (scanfc(fin, "%s", arg4) < 1) { return -1; } p4 = arg4; } else { retcode = next_word(arg4, argc, argv, 0); if (EOF == retcode) { fprintf(stderr, "Invalid arg for command '%s'\n", cmd_entry->name); return 1; } else if (retcode < 0) { return retcode; } p4 = arg4; } } } #ifdef HAVE_LIBREADLINE if (interactive && prompt && have_rl) { int j, x; #ifdef HAVE_READLINE_HISTORY /* Minimum space for 32+1+128+1+128+1+128+1+128+1+128+1+128+1 = 807 * chars, so allocate 896 chars cleared to zero for safety. */ rp_hist_buf = (char *)calloc(896, sizeof(char)); #endif rp_getline("\nAmplifier command: "); /* EOF (Ctrl-D) received on empty input line, bail out gracefully. */ if (!input_line) { fprintf_flush(fout, "\n"); return 1; } /* Q or q to quit */ if (!(strncasecmp(input_line, "q", 1))) { return 1; } /* '?' for help */ if (!(strncmp(input_line, "?", 1))) { usage_amp(fout); fflush(fout); return 0; } /* '#' for comment */ if (!(strncmp(input_line, "#", 1))) { return 0; } /* Blank line entered */ if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } rig_debug(RIG_DEBUG_BUG, "%s: input_line: %s\n", __func__, input_line); /* Split input_line on any number of spaces to get the command token * Tabs are intercepted by readline for completion and a newline * causes readline to return the typed text. If more than one * argument is given, it will be parsed out later. */ result = strtok(input_line, " "); /* parsed_input stores pointers into input_line where the token strings * start. */ if (result) { parsed_input[0] = result; } else { /* Oops! Invoke GDB!! */ fprintf_flush(fout, "\n"); return 1; } /* At this point parsed_input contains the typed text of the command * with surrounding space characters removed. If Readline History is * available, copy the command string into a history buffer. */ /* Single character command */ if ((strlen(parsed_input[0]) == 1) && (*parsed_input[0] != '\\')) { cmd = *parsed_input[0]; #ifdef HAVE_READLINE_HISTORY /* Store what is typed, not validated, for history. */ if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], 1); } #endif } /* Test the command token, parsed_input[0] */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) > 1)) { char cmd_name[MAXNAMSIZ]; /* if there is no terminating '\0' character in the source string, * strncpy() doesn't add one even if the supplied length is less * than the destination array. Truncate the source string here. */ if (strlen(parsed_input[0] + 1) >= MAXNAMSIZ) { *(parsed_input[0] + MAXNAMSIZ) = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncpy(rp_hist_buf, parsed_input[0], MAXNAMSIZ); } #endif /* The starting position of the source string is the first * character past the initial '\'. */ SNPRINTF(cmd_name, sizeof(cmd_name), "%s", parsed_input[0] + 1); /* Sanity check as valid multiple character commands consist of * alphanumeric characters and the underscore ('_') character. */ for (j = 0; cmd_name[j] != '\0'; j++) { if (!(isalnum((int)cmd_name[j]) || cmd_name[j] == '_')) { fprintf(stderr, "Valid multiple character command names contain alphanumeric characters plus '_'\n"); return 0; } } cmd = parse_arg(cmd_name); } /* Single '\' entered, prompt again */ else if ((*parsed_input[0] == '\\') && (strlen(parsed_input[0]) == 1)) { return 0; } /* Multiple characters but no leading '\' */ else { fprintf(stderr, "Precede multiple character command names with '\\'\n"); return 0; } cmd_entry = find_cmd_entry(cmd); if (!cmd_entry) { if (cmd == '\0') { fprintf(stderr, "Command '%s' not found!\n", parsed_input[0]); } else { fprintf(stderr, "Command '%c' not found!\n", cmd); } return 0; } /* \send_cmd */ if ((cmd_entry->flags & ARG_IN_LINE) && (cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { /* Check for a non-existent delimiter so as to not break up * remaining line into separate tokens (spaces OK). */ result = strtok(NULL, "\0"); if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); /* Blank line entered */ if (input_line && !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } if (input_line) { parsed_input[x] = input_line; } else { fprintf_flush(fout, "\n"); return 1; } } /* The arg1 array size is MAXARGSZ + 1 so truncate it to fit if larger. */ if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } /* Normal argument parsing. */ else if ((cmd_entry->flags & ARG_IN1) && cmd_entry->arg1) { result = strtok(NULL, " "); if (result) { x = 1; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg1) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg1); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg1, parsed_input[x]); p1 = arg1; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN2) && cmd_entry->arg2) { result = strtok(NULL, " "); if (result) { x = 2; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg2) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg2); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!input_line || !(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg2, parsed_input[x]); p2 = arg2; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN3) && cmd_entry->arg3) { result = strtok(NULL, " "); if (result) { x = 3; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg3) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg3); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg3, parsed_input[x]); p3 = arg3; } if (p1 && p1[0] != '?' && (cmd_entry->flags & ARG_IN4) && cmd_entry->arg4) { result = strtok(NULL, " "); if (result) { x = 4; parsed_input[x] = result; } else { char pmptstr[(strlen(cmd_entry->arg4) + 3)]; x = 0; strcpy(pmptstr, cmd_entry->arg4); strcat(pmptstr, ": "); rp_getline(pmptstr); if (!(strcmp(input_line, ""))) { fprintf(fout, "? for help, q to quit.\n"); fflush(fout); return 0; } result = strtok(input_line, " "); if (result) { parsed_input[x] = result; } else { fprintf_flush(fout, "\n"); return 1; } } if (strlen(parsed_input[x]) > MAXARGSZ) { parsed_input[x][MAXARGSZ] = '\0'; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { strncat(rp_hist_buf, " ", 2); strncat(rp_hist_buf, parsed_input[x], MAXARGSZ); } #endif strcpy(arg4, parsed_input[x]); p4 = arg4; } #ifdef HAVE_READLINE_HISTORY if (rp_hist_buf) { add_history(rp_hist_buf); free(rp_hist_buf); rp_hist_buf = (char *)NULL; } #endif } #endif // HAVE_LIBREADLINE /* * mutex locking needed because ampctld is multithreaded * and hamlib is not MT-safe */ #ifdef HAVE_PTHREAD pthread_mutex_lock(&_mutex); #endif if (!prompt) { rig_debug(RIG_DEBUG_TRACE, "ampctl(d): %c '%s' '%s' '%s' '%s'\n", cmd, p1 ? p1 : "", p2 ? p2 : "", p3 ? p3 : "", p4 ? p4 : ""); } /* * Extended Response protocol: output received command name and arguments * response. */ if (interactive && ext_resp && !prompt) { char a1[MAXARGSZ + 2]; char a2[MAXARGSZ + 2]; char a3[MAXARGSZ + 2]; char a4[MAXARGSZ + 2]; p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1); p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2); p3 == NULL ? a3[0] = '\0' : snprintf(a3, sizeof(a3), " %s", p3); p4 == NULL ? a4[0] = '\0' : snprintf(a4, sizeof(a4), " %s", p4); fprintf(fout, "%s:%s%s%s%s%c", cmd_entry->name, a1, a2, a3, a4, resp_sep); } retcode = (*cmd_entry->amp_routine)(my_amp, fout, interactive, cmd_entry, p1, p2 ? p2 : "", p3 ? p3 : "", p4 ? p4 : "", #ifdef __USEP5P6__ p5 ? p5 : "", p6 ? p6 : ""); #else "", ""); #endif #ifdef HAVE_PTHREAD pthread_mutex_unlock(&_mutex); #endif if (retcode == RIG_EIO) { return retcode; } if (retcode != RIG_OK) { /* only for ampctld */ if (interactive && !prompt) { fprintf(fout, NETAMPCTL_RET "%d\n", retcode); ext_resp = 0; resp_sep = '\n'; } else { fprintf(fout, "error = %s\n", rigerror(retcode)); //fprintf(fout, "%s: error = %s\n", cmd_entry->name, rigerror(retcode)); } } else { /* only for ampctld */ if (interactive && !prompt) { /* netampctl RIG_OK */ if (!(cmd_entry->flags & ARG_OUT) && !ext_resp) { fprintf(fout, NETAMPCTL_RET "0\n"); } /* Extended Response protocol */ else if (ext_resp && cmd != 0xf0) { fprintf(fout, NETAMPCTL_RET "0\n"); ext_resp = 0; resp_sep = '\n'; } } } fflush(fout); return retcode != RIG_OK ? 2 : 0; } void version() { printf("ampctl(d), %s\n\n", hamlib_version2); printf("%s\n", hamlib_copyright); } void usage_amp(FILE *fout) { int i; fprintf(fout, "Commands (some may not be available for this amplifier):\n"); for (i = 0; test_list[i].cmd != 0; i++) { int nbspaces; fprintf(fout, "%c: %-12s(", isprint(test_list[i].cmd) ? test_list[i].cmd : '?', test_list[i].name); nbspaces = 16; if (test_list[i].arg1 && (test_list[i].flags & ARG_IN1)) { nbspaces -= fprintf(fout, "%s", test_list[i].arg1); } if (test_list[i].arg2 && (test_list[i].flags & ARG_IN2)) { nbspaces -= fprintf(fout, ", %s", test_list[i].arg2); } if (test_list[i].arg3 && (test_list[i].flags & ARG_IN3)) { nbspaces -= fprintf(fout, ", %s", test_list[i].arg3); } if (test_list[i].arg4 && (test_list[i].flags & ARG_IN4)) { nbspaces -= fprintf(fout, ", %s", test_list[i].arg4); } rig_debug(RIG_DEBUG_VERBOSE, "%s: nbspace left=%d\n", __func__, nbspaces); fprintf(fout, ")\n"); } fprintf(fout, "\n\nIn interactive mode prefix long command names with '\\', e.g. '\\dump_state'\n\n" "The special command '-' is used to read further commands from standard input\n" "Commands and arguments read from standard input must be white space separated,\n" "comments are allowed, comments start with the # character and continue to the\n" "end of the line.\n"); } int print_conf_list(const struct confparams *cfp, rig_ptr_t data) { AMP *amp = (AMP *) data; int i; char buf[128] = ""; amp_get_conf(amp, cfp->token, buf); printf("%s: \"%s\"\n" "\tDefault: %s, Value: %s\n", cfp->name, cfp->tooltip, cfp->dflt, buf); switch (cfp->type) { case RIG_CONF_NUMERIC: printf("\tRange: %.1f..%.1f, step %.1f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; case RIG_CONF_COMBO: if (!cfp->u.c.combostr[0]) { break; } printf("\tCombo: %s", cfp->u.c.combostr[0]); for (i = 1 ; i < RIG_COMBO_MAX && cfp->u.c.combostr[i]; i++) { printf(", %s", cfp->u.c.combostr[i]); } printf("\n"); break; default: break; } return 1; /* != 0, we want them all ! */ } static int hash_model_list(const struct amp_caps *caps, void *data) { hash_add_model(caps->amp_model, caps->mfg_name, caps->model_name, caps->version, rig_strstatus(caps->status), caps->macro_name); return 1; /* !=0, we want them all ! */ } void print_model_list() { struct mod_lst *s; for (s = models; s != NULL; s = (struct mod_lst *)(s->hh.next)) { printf("%6u %-23s%-24s%-16s%-14s%s\n", s->id, s->mfg_name, s->model_name, s->version, s->status, s->macro_name); } } void list_models() { int status; amp_load_all_backends(); printf(" Amp # Mfg Model Version Status Macro\n"); status = amp_list_foreach(hash_model_list, NULL); if (status != RIG_OK) { printf("amp_list_foreach: error = %s \n", rigerror(status)); exit(2); } hash_sort_by_model_id(); print_model_list(); hash_delete_all(); } int set_conf(AMP *my_amp, char *conf_parms) { char *p, *n; int token; amp_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); p = conf_parms; while (p && *p != '\0') { char *q; int ret; /* FIXME: left hand value of = cannot be null */ q = strchr(p, '='); if (!q) { return RIG_EINVAL; } *q++ = '\0'; n = strchr(q, ','); if (n) { *n++ = '\0'; } token = amp_token_lookup(my_amp, p); if (token != 0) { ret = amp_set_conf(my_amp, token, q); if (ret != RIG_OK) { return ret; } } else { rig_debug(RIG_DEBUG_WARN, "%s: invalid token %s for this amp\n", __func__, p); } p = n; } return RIG_OK; } /* * static int (f)(AMP *amp, int interactive, const void *arg1, const void *arg2, const void *arg3, const void *arg4) */ /* 'f' */ declare_proto_amp(get_freq) { int status; freq_t freq; // cppcheck-suppress * char *fmt = "%"PRIll"%c"; status = amp_get_freq(amp, &freq); if (status != RIG_OK) { return status; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); /* i.e. "Frequency" */ } fprintf(fout, fmt, (int64_t)freq, resp_sep); return status; } /* 'F' */ declare_proto_amp(set_freq) { freq_t freq; CHKSCN1ARG(sscanf(arg1, "%"SCNfreq, &freq)); return amp_set_freq(amp, freq); } /* * RIG_CONF_ extparm's type: * NUMERIC: val.f * COMBO: val.i, starting from 0 * STRING: val.s * CHECKBUTTON: val.i 0/1 * * 'L' */ declare_proto_amp(set_level) { setting_t level; value_t val; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; rig_sprintf_level(s, sizeof(s), AMPSTATE(amp)->has_set_level); fputs(s, fout); if (amp->caps->set_ext_level) { sprintf_level_ext(s, sizeof(s), amp->caps->extlevels); fputs(s, fout); } fputc('\n', fout); return (RIG_OK); } level = rig_parse_level(arg1); // some Java apps send comma in international setups so substitute period char *p = strchr(arg2, ','); if (p) { *p = '.'; } if (!amp_has_set_level(amp, level)) { const struct confparams *cfp; cfp = amp_ext_lookup(amp, arg1); if (!cfp) { return (-RIG_ENAVAIL); /* no such parameter */ } switch (cfp->type) { case RIG_CONF_BUTTON: /* arg is ignored */ val.i = 0; // avoid passing uninitialized data break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); break; case RIG_CONF_NUMERIC: CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); break; case RIG_CONF_STRING: val.cs = arg2; break; default: return (-RIG_ECONF); } return (amp_set_ext_level(amp, cfp->token, val)); } if (RIG_LEVEL_IS_FLOAT(level)) { CHKSCN1ARG(sscanf(arg2, "%f", &val.f)); } else { CHKSCN1ARG(sscanf(arg2, "%d", &val.i)); } return (amp_set_level(amp, level, val)); } /* 'l' */ declare_proto_amp(get_level) { int status; setting_t level; value_t val; if (!strcmp(arg1, "?")) { char s[SPRINTF_MAX_SIZE]; amp_sprintf_level(s, sizeof(s), AMPSTATE(amp)->has_get_level); fputs(s, fout); if (amp->caps->get_ext_level) { sprintf_level_ext(s, sizeof(s), amp->caps->extlevels); fputs(s, fout); } fputc('\n', fout); return RIG_OK; } level = amp_parse_level(arg1); if (!amp_has_get_level(amp, level)) { const struct confparams *cfp; cfp = amp_ext_lookup(amp, arg1); if (!cfp) { return -RIG_EINVAL; /* no such parameter */ } status = amp_get_ext_level(amp, cfp->token, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } printf("cfp->type=%d\n", cfp->type); switch (cfp->type) { case RIG_CONF_BUTTON: /* there's no sense in retrieving value of stateless button */ return -RIG_EINVAL; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: fprintf(fout, "%d\n", val.i); break; case RIG_CONF_NUMERIC: fprintf(fout, "%f\n", val.f); break; case RIG_CONF_STRING: fprintf(fout, "%s\n", val.s); break; default: return -RIG_ECONF; } return status; } status = amp_get_level(amp, level, &val); if (status != RIG_OK) { return status; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } if (AMP_LEVEL_IS_FLOAT(level)) { fprintf(fout, "%f\n", val.f); } else if (AMP_LEVEL_IS_STRING(level)) { fprintf(fout, "%s\n", val.s); } else { fprintf(fout, "%d\n", val.i); } return status; } /* 'R' */ declare_proto_amp(reset) { amp_reset_t reset; CHKSCN1ARG(sscanf(arg1, "%d", (int *)&reset)); return amp_reset(amp, reset); } /* '_' */ declare_proto_amp(get_info) { const char *s; s = amp_get_info(amp); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%s%c", s ? s : "None", resp_sep); return RIG_OK; } /* '1' */ declare_proto_amp(dump_caps) { dumpcaps_amp(amp, fout); return RIG_OK; } /* For ampctld internal use * '0x8f' */ declare_proto_amp(dump_state) { /* * - Protocol version */ #define AMPCTLD_PROT_VER 0 if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "ampctld Protocol Ver: "); } fprintf(fout, "%d%c", AMPCTLD_PROT_VER, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "Amplifier Model: "); switch (amp->caps->amp_model) { case AMP_MODEL_DUMMY: fprintf(fout, "dummy\n"); break; case AMP_MODEL_ELECRAFT_KPA1500: fprintf(fout, "Elecraft KPA1500\n"); break; default: fprintf(fout, "unknown=%02x\n", amp->caps->amp_model); break; } } return RIG_OK; } /* '0x87' */ declare_proto_amp(set_powerstat) { int stat; CHKSCN1ARG(sscanf(arg1, "%d", &stat)); return amp_set_powerstat(amp, (powerstat_t) stat); } /* '0x88' */ declare_proto_amp(get_powerstat) { int status; powerstat_t stat; status = amp_get_powerstat(amp, &stat); if (status != RIG_OK) { return status; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg1); } fprintf(fout, "%d\n", stat); return status; } /* * Special debugging purpose send command display reply until there's a * timeout. * * 'w' */ declare_proto_amp(send_cmd) { int retval; hamlib_port_t *ampp = AMPPORT(amp); int backend_num, cmd_len; #define BUFSZ 128 unsigned char bufcmd[BUFSZ]; unsigned char buf[BUFSZ]; char eom_buf[4] = { 0xa, 0xd, 0, 0 }; /* * binary protocols enter values as \0xZZ\0xYY.. * * Rem: no binary protocol for amplifier as of now */ backend_num = AMP_BACKEND_NUM(amp->caps->amp_model); if (send_cmd_term == -1 || backend_num == -1) { const char *p = arg1, *pp = NULL; int i; for (i = 0; i < BUFSZ - 1 && p != pp; i++) { pp = p + 1; bufcmd[i] = strtol(p + 1, (char **) &p, 0); } /* must save length to allow 0x00 to be sent as part of a command */ cmd_len = i - 1; /* no End Of Message chars */ eom_buf[0] = '\0'; } else { /* text protocol */ strncpy((char *) bufcmd, arg1, BUFSZ); bufcmd[BUFSZ - 2] = '\0'; cmd_len = strlen((char *) bufcmd); /* Automatic termination char */ if (send_cmd_term != 0) { bufcmd[cmd_len++] = send_cmd_term; } eom_buf[2] = send_cmd_term; } rig_flush(ampp); retval = write_block(ampp, bufcmd, cmd_len); if (retval != RIG_OK) { return retval; } if (interactive && prompt) { fprintf(fout, "%s: ", cmd->arg2); } do { /* * assumes CR or LF is end of line char * for all ascii protocols */ retval = read_string(ampp, buf, BUFSZ, eom_buf, strlen(eom_buf), 0, 1); if (retval < 0) { break; } if (retval < BUFSZ) { buf[retval] = '\0'; } else { buf[BUFSZ - 1] = '\0'; } fprintf(fout, "%s\n", buf); } while (retval > 0); if (retval > 0 || retval == -RIG_ETIMEOUT) { retval = RIG_OK; } return retval; } /* 'L' */ /* declare_proto_amp(lonlat2loc) { unsigned char loc[MAXARGSZ + 1]; double lat, lon; int err, pair; CHKSCN1ARG(sscanf(arg1, "%lf", &lon)); CHKSCN1ARG(sscanf(arg2, "%lf", &lat)); CHKSCN1ARG(sscanf(arg3, "%d", &pair)); pair /= 2; err = longlat2locator(lon, lat, (char *)&loc, pair); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%s%c", loc, resp_sep); return err; } */ /* 'l' */ /* declare_proto_amp(loc2lonlat) { unsigned char loc[MAXARGSZ + 1]; double lat, lon; int status; CHKSCN1ARG(sscanf(arg1, "%s", (char *)&loc)); status = locator2longlat(&lon, &lat, (const char *)loc); if (status != RIG_OK) { return status; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%f%c", lon, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%f%c", lat, resp_sep); return status; } */ /* 'D' */ /* declare_proto_amp(d_m_s2dec) { int deg, min, sw; double sec, dec_deg; CHKSCN1ARG(sscanf(arg1, "%d", °)); CHKSCN1ARG(sscanf(arg2, "%d", &min)); CHKSCN1ARG(sscanf(arg3, "%lf", &sec)); CHKSCN1ARG(sscanf(arg4, "%d", &sw)); dec_deg = dms2dec(deg, min, sec, sw); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%lf%c", dec_deg, resp_sep); return RIG_OK; } */ /* 'd' */ /* declare_proto_amp(dec2d_m_s) { int deg, min, sw, err; double sec, dec_deg; CHKSCN1ARG(sscanf(arg1, "%lf", &dec_deg)); err = dec2dms(dec_deg, °, &min, &sec, &sw); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", deg, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%d%c", min, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%lf%c", sec, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%d%c", sw, resp_sep); return err; } */ /* 'E' */ /* declare_proto_amp(d_mm2dec) { int deg, sw; double dec_deg, min; CHKSCN1ARG(sscanf(arg1, "%d", °)); CHKSCN1ARG(sscanf(arg2, "%lf", &min)); CHKSCN1ARG(sscanf(arg3, "%d", &sw)); dec_deg = dmmm2dec(deg, min, sw); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%lf%c", dec_deg, resp_sep); return RIG_OK; } */ /* 'e' */ /* declare_proto_amp(dec2d_mm) { int deg, sw, err; double min, dec_deg; CHKSCN1ARG(sscanf(arg1, "%lf", &dec_deg)); err = dec2dmmm(dec_deg, °, &min, &sw); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%d%c", deg, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg3); } fprintf(fout, "%lf%c", min, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg4); } fprintf(fout, "%d%c", sw, resp_sep); return err; } */ /* 'B' */ /* declare_proto_amp(coord2qrb) { double lon1, lat1, lon2, lat2, dist, az; int err; CHKSCN1ARG(sscanf(arg1, "%lf", &lon1)); CHKSCN1ARG(sscanf(arg2, "%lf", &lat1)); CHKSCN1ARG(sscanf(arg3, "%lf", &lon2)); CHKSCN1ARG(sscanf(arg4, "%lf", &lat2)); err = qrb(lon1, lat1, lon2, lat2, &dist, &az); if (err != RIG_OK) { return err; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg5); } fprintf(fout, "%lf%c", dist, resp_sep); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg6); } fprintf(fout, "%lf%c", az, resp_sep); return err; } */ /* 'A' */ /* declare_proto_amp(az_sp2az_lp) { double az_sp, az_lp; CHKSCN1ARG(sscanf(arg1, "%lf", &az_sp)); az_lp = azimuth_long_path(az_sp); if (az_lp < 0) { return -RIG_EINVAL; } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%lf%c", az_lp, resp_sep); return RIG_OK; } */ /* 'a' */ /* declare_proto_amp(dist_sp2dist_lp) { double dist_sp, dist_lp; CHKSCN1ARG(sscanf(arg1, "%lf", &dist_sp)); dist_lp = distance_long_path(dist_sp); if ((interactive && prompt) || (interactive && !prompt && ext_resp)) { fprintf(fout, "%s: ", cmd->arg2); } fprintf(fout, "%lf%c", dist_lp, resp_sep); return RIG_OK; } */ /* '0x8c'--pause processing */ /* declare_proto_amp(pause) { unsigned seconds; CHKSCN1ARG(sscanf(arg1, "%u", &seconds)); sleep(seconds); return RIG_OK; } */ hamlib-4.6.5/tests/Makefile.am0000664000175000017500000001374515056640443011664 # Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl # For some reason this "if" is not working -- rigtestlibusb is still being included # Fix for now is to change rigtestlibusb.c instead if HAVE_LIBUSB TESTLIBUSB = rigtestlibusb else TESTLIBUSB = endif DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom rigctltcp rigctlsync ampctl ampctld rigtestmcast rigtestmcastrx $(TESTLIBUSB) rigfreqwalk #check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid testsecurity check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie testgrid hamlibmodels testmW2power test2038 RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c dumpstate.c uthash.h rig_tests.c rig_tests.h dumpcaps.h ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h dumpcaps_rot.h AMPCOMMONSRC = ampctl_parse.c ampctl_parse.h dumpcaps_amp.c uthash.h rigctl_SOURCES = rigctl.c $(RIGCOMMONSRC) rigctld_SOURCES = rigctld.c $(RIGCOMMONSRC) rigctlcom_SOURCES = rigctlcom.c $(RIGCOMMONSRC) rigctltcp_SOURCES = rigctltcp.c $(RIGCOMMONSRC) rigctlsync_SOURCES = rigctlsync.c $(RIGCOMMONSRC) rotctl_SOURCES = rotctl.c $(ROTCOMMONSRC) rotctld_SOURCES = rotctld.c $(ROTCOMMONSRC) ampctl_SOURCES = ampctl.c $(AMPCOMMONSRC) ampctld_SOURCES = ampctld.c $(AMPCOMMONSRC) rigswr_SOURCES = rigswr.c rigsmtr_SOURCES = rigsmtr.c rigmem_SOURCES = rigmem.c memsave.c memload.c memcsv.c if HAVE_LIBUSB rigtestlibusb_SOURCES = rigtestlibusb.c endif # include generated include files ahead of any in sources rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) -I$(top_builddir)/security $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) -lm rigmem_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src rigctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src -I$(top_builddir)/security rotctl_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src rotctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src ampctl_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src ampctld_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src rigctlcom_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security rigctltcp_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security rigctlsync_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/security if HAVE_LIBUSB rigtestlibusb_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(LIBUSB_CFLAGS) endif #testsecurity_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src -I$(top_builddir)/security rigctl_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) rigctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rotctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rotctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) ampctl_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) ampctld_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigmem_LDADD = $(LIBXML2_LIBS) $(LDADD) rigctlcom_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigctltcp_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) rigctlsync_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) if HAVE_LIBUSB rigtestlibusb_LDADD = $(LIBUSB_LIBS) endif # Linker options rigctl_LDFLAGS = $(WINEXELDFLAGS) rigswr_LDFLAGS = $(WINEXELDFLAGS) rigsmtr_LDFLAGS = $(WINEXELDFLAGS) rigmem_LDFLAGS = $(WINEXELDFLAGS) rotctl_LDFLAGS = $(WINEXELDFLAGS) ampctl_LDFLAGS = $(WINEXELDFLAGS) rigctld_LDFLAGS = $(WINEXELDFLAGS) rotctld_LDFLAGS = $(WINEXELDFLAGS) ampctld_LDFLAGS = $(WINEXELDFLAGS) rigctlcom_LDFLAGS = $(WINEXELDFLAGS) rigctltcp_LDFLAGS = $(WINEXELDFLAGS) rigctlsync_LDFLAGS = $(WINEXELDFLAGS) if HAVE_LIBUSB rigtestlibusb_LDFLAGS = $(WINEXELDFLAGS) endif if HTML_MATRIX EXTRA_PROGRAMS = rigmatrix # rigmatrix needs libgd rigmatrix_LDFLAGS = -lgd -lz rigmatrix.html: rigmatrix_head.html rigmatrix listrigs mkdir -p sup-info/support ( cat $(srcdir)/rigmatrix_head.html && cd sup-info && ../rigmatrix ) > sup-info/rigmatrix.html for f in $$(./listrigs | tail -n +2 | cut -f1) ; do ( ./rigctl -m $$f -u > sup-info/support/model$$f.txt || exit 0 ) ; done ./rigctl -l |sort -n | $(srcdir)/rig_split_lst.awk -v lst_dir="sup-info" endif EXTRA_DIST = rigmatrix_head.html rig_split_lst.awk testctld.pl testrotctld.pl # Support 'make check' target for simple tests check_SCRIPTS = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh testgrid.sh test2038.sh TESTS = $(check_SCRIPTS) $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la testrig.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/src/.libs:$(top_builddir)/dummy/.libs ./testrig 1' > testrig.sh chmod +x ./testrig.sh testfreq.sh: echo './testfreq' > testfreq.sh chmod +x ./testfreq.sh testbcd.sh: echo './testbcd 146520000 10' > testbcd.sh chmod +x ./testbcd.sh testloc.sh: echo './testloc EM79UT96LW 5' > testloc.sh chmod +x ./testloc.sh testrigcaps.sh: echo './testrigcaps' > testrigcaps.sh chmod +x ./testrigcaps.sh testcache.sh: echo './testcache 1' > testcache.sh chmod +x ./testcache.sh testcookie.sh: echo './testcookie 1' > testcookie.sh chmod +x ./testcookie.sh testgrid.sh: echo './testgrid' > testgrid.sh chmod +x ./testgrid.sh test2038.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/src/.libs:$(top_builddir)/dummy/.libs ./test2038 1' > test2038.sh chmod +x ./test2038.sh CLEANFILES = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh rigtestlibusb build-w32.sh build-w64.sh build-w64-jtsdk.sh testgrid.sh testrigcaps.sh test2038.sh tuner_control.log hamlib-4.6.5/tests/README0000664000175000017500000000430615056640443010501 You will find in the tests/ subdirectory various programs to exercise the Hamlib library. Most of the time, you will have to make sure that the backend for your rig is loaded by passing the model number of your rig by argument. If you don't know the number, listrigs can give it to you, "rigctl --list" will also output something like this: Rig# Mfg Model Vers. 1 Hamlib Dummy 0.1 105 Yaesu FT-747GX 0.1 210 Kenwood TS-870S 0.1 311 Icom IC-706MkIIG 0.2 1506 Winradio WR-3500 0.6 [etc.] In any case, you are encouraged to check for correct initialization by reading the source code, at the beginning of the main(). Check also that the program is setup for your rig path strncpy(HAMLIB_RIGPORT(my_rig)->pathname... dumpcaps - Output the caps contents of a rig dumpmem - Dump the memory contents of the rig listrigs - Condensed list of all the models supported by backends rigmatrix - Output the HTML table of supported rigs, with .png files for freqs (Better call 'make rigmatrix.html' which builds the HTML table and additional information in sup-info subdirectory.) testbcd - Simple program to test BCD conversion, takes a number as arg. testfreq - Simple program to test Freq conversion, takes a number as arg. testrig - Sample program calling common API calls, uses rig_probe testtrn - Sample program using event notification (transceive mode) rigctl - Combined tool to execute any call of the API, see man page rigmem - Combined tool to load/save content of rig memory, see man page rotctl - Similar to 'rigctl' but for rotators, see man page rigctld - A simple daemon to process 'rigctl' commands received over a network socket. Useful for scripting languages or remote access via an SSH tunnel (insecure program). See man page. rotctld - A simple daemon to process 'rotctl' commands received over a network socket. Useful for scripting languages or remote access via an SSH tunnel (insecure program). See man page. testctld.pl A Perl program to test 'rigctld' and provide some example code. hamlib-4.6.5/aclocal.m40000664000175000017500000020327315056640446010326 # generated automatically by aclocal 1.17 -*- Autoconf -*- # Copyright (C) 1996-2024 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.72],, [m4_warning([this file was generated for autoconf 2.72. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.17' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.17], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.17])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_BEFORE([$0], [AC_PROG_AR])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} : ${ARFLAGS=cr} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR $ARFLAGS libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([_AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl AC_REQUIRE([_AM_PROG_RM_F]) AC_REQUIRE([_AM_PROG_XARGS_N]) dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python3 dnl python3.20 python3.19 python3.18 python3.17 python3.16 dnl python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 dnl python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl python3.2 python3.1 python3.0 dnl python2 dnl python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Although site.py simply uses dnl sys.version[:3], printing that failed with Python 3.10, since the dnl trailing zero was eliminated. So now we output just the major dnl and minor version numbers, as numbers. Apparently the tertiary dnl version is not of interest. dnl AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl At times, e.g., when building shared libraries, you may want dnl to know which OS platform Python thinks this is. dnl AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) dnl emacs-page dnl If --with-python-sys-prefix is given, use the values of sys.prefix dnl and sys.exec_prefix for the corresponding values of PYTHON_PREFIX dnl and PYTHON_EXEC_PREFIX. Otherwise, use the GNU ${prefix} and dnl ${exec_prefix} variables. dnl dnl The two are made distinct variables so they can be overridden if dnl need be, although general consensus is that you shouldn't need dnl this separation. dnl dnl Also allow directly setting the prefixes via configure options, dnl overriding any default. dnl if test "x$prefix" = xNONE; then am__usable_prefix=$ac_default_prefix else am__usable_prefix=$prefix fi # Allow user to request using sys.* values from Python, # instead of the GNU $prefix values. AC_ARG_WITH([python-sys-prefix], [AS_HELP_STRING([--with-python-sys-prefix], [use Python's sys.prefix and sys.exec_prefix values])], [am_use_python_sys=:], [am_use_python_sys=false]) # Allow user to override whatever the default Python prefix is. AC_ARG_WITH([python_prefix], [AS_HELP_STRING([--with-python_prefix], [override the default PYTHON_PREFIX])], [am_python_prefix_subst=$withval am_cv_python_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_cv_python_prefix])], [ if $am_use_python_sys; then # using python sys.prefix value, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON prefix], [am_cv_python_prefix], [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`]) dnl If sys.prefix is a subdir of $prefix, replace the literal value of dnl $prefix with a variable reference so it can be overridden. case $am_cv_python_prefix in $am__usable_prefix*) am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` ;; *) am_python_prefix_subst=$am_cv_python_prefix ;; esac else # using GNU prefix value, not python sys.prefix am_python_prefix_subst='${prefix}' am_python_prefix=$am_python_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_python_prefix]) fi]) # Substituting python_prefix_subst value. AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst]) # emacs-page Now do it all over again for Python exec_prefix, but with yet # another conditional: fall back to regular prefix if that was specified. AC_ARG_WITH([python_exec_prefix], [AS_HELP_STRING([--with-python_exec_prefix], [override the default PYTHON_EXEC_PREFIX])], [am_python_exec_prefix_subst=$withval am_cv_python_exec_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # no explicit --with-python_exec_prefix, but if # --with-python_prefix was given, use its value for python_exec_prefix too. AS_IF([test -n "$with_python_prefix"], [am_python_exec_prefix_subst=$with_python_prefix am_cv_python_exec_prefix=$with_python_prefix AC_MSG_CHECKING([for python_prefix-given $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # Set am__usable_exec_prefix whether using GNU or Python values, # since we use that variable for pyexecdir. if test "x$exec_prefix" = xNONE; then am__usable_exec_prefix=$am__usable_prefix else am__usable_exec_prefix=$exec_prefix fi # if $am_use_python_sys; then # using python sys.exec_prefix, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON exec_prefix], [am_cv_python_exec_prefix], [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`]) dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the dnl literal value of $exec_prefix with a variable reference so it can dnl be overridden. case $am_cv_python_exec_prefix in $am__usable_exec_prefix*) am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` ;; *) am_python_exec_prefix_subst=$am_cv_python_exec_prefix ;; esac else # using GNU $exec_prefix, not python sys.exec_prefix am_python_exec_prefix_subst='${exec_prefix}' am_python_exec_prefix=$am_python_exec_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_python_exec_prefix]) fi])]) # Substituting python_exec_prefix_subst. AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst]) # Factor out some code duplication into this shell variable. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" # end of am_python_setup_sysconfig # More repeated code, for figuring out the installation scheme to use. am_python_setup_scheme="if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': if '$am_py_prefix' == '/usr': scheme = 'deb_system' # should only happen during Debian package builds else: # Debian's default scheme installs to /usr/local/ but we want to # follow the prefix, as we always have. # See bugs#54412, #64837, et al. scheme = 'posix_prefix'" # end of am_python_setup_scheme dnl emacs-page Set up 4 directories: dnl 1. pythondir: where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory as in early automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query sysconfig or distutils (per above) for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)], [am_cv_python_pythondir], [if test "x$am_cv_python_prefix" = x; then am_py_prefix=$am__usable_prefix else am_py_prefix=$am_cv_python_prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: try: $am_python_setup_scheme sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) except: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl 2. pkgpythondir: $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. dnl AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl 3. pyexecdir: directory for installing python extension modules dnl (shared libraries). dnl Query sysconfig or distutils for this directory. dnl Much of this is the same as for prefix setup above. dnl AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)], [am_cv_python_pyexecdir], [if test "x$am_cv_python_exec_prefix" = x; then am_py_exec_prefix=$am__usable_exec_prefix else am_py_exec_prefix=$am_cv_python_exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: try: $am_python_setup_scheme sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) except: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl 4. pkgpyexecdir: $(pyexecdir)/$(PACKAGE) dnl AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2022-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_RM_F # --------------- # Check whether 'rm -f' without any arguments works. # https://bugs.gnu.org/10828 AC_DEFUN([_AM_PROG_RM_F], [am__rm_f_notfound= AS_IF([(rm -f && rm -fr && rm -rf) 2>/dev/null], [], [am__rm_f_notfound='""']) AC_SUBST(am__rm_f_notfound) ]) # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SLEEP_FRACTIONAL_SECONDS # ---------------------------- AC_DEFUN([_AM_SLEEP_FRACTIONAL_SECONDS], [dnl AC_CACHE_CHECK([whether sleep supports fractional seconds], am_cv_sleep_fractional_seconds, [dnl AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=yes], [am_cv_sleep_fractional_seconds=no]) ])]) # _AM_FILESYSTEM_TIMESTAMP_RESOLUTION # ----------------------------------- # Determine the filesystem's resolution for file modification # timestamps. The coarsest we know of is FAT, with a resolution # of only two seconds, even with the most recent "exFAT" extensions. # The finest (e.g. ext4 with large inodes, XFS, ZFS) is one # nanosecond, matching clock_gettime. However, it is probably not # possible to delay execution of a shell script for less than one # millisecond, due to process creation overhead and scheduling # granularity, so we don't check for anything finer than that. (See below.) AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS]) AC_CACHE_CHECK([filesystem timestamp resolution], am_cv_filesystem_timestamp_resolution, [dnl # Default to the worst case. am_cv_filesystem_timestamp_resolution=2 # Only try to go finer than 1 sec if sleep can do it. # Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, # - 1 sec is not much of a win compared to 2 sec, and # - it takes 2 seconds to perform the test whether 1 sec works. # # Instead, just use the default 2s on platforms that have 1s resolution, # accept the extra 1s delay when using $sleep in the Automake tests, in # exchange for not incurring the 2s delay for running the test for all # packages. # am_try_resolutions= if test "$am_cv_sleep_fractional_seconds" = yes; then # Even a millisecond often causes a bunch of false positives, # so just try a hundredth of a second. The time saved between .001 and # .01 is not terribly consequential. am_try_resolutions="0.01 0.1 $am_try_resolutions" fi # In order to catch current-generation FAT out, we must *modify* files # that already exist; the *creation* timestamp is finer. Use names # that make ls -t sort them differently when they have equal # timestamps than when they have distinct timestamps, keeping # in mind that ls -t prints the *newest* file first. rm -f conftest.ts? : > conftest.ts1 : > conftest.ts2 : > conftest.ts3 # Make sure ls -t actually works. Do 'set' in a subshell so we don't # clobber the current shell's arguments. (Outer-level square brackets # are removed by m4; they're present so that m4 does not expand # ; be careful, easy to get confused.) if ( set X `[ls -t conftest.ts[12]]` && { test "$[]*" != "X conftest.ts1 conftest.ts2" || test "$[]*" != "X conftest.ts2 conftest.ts1"; } ); then :; else # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". _AS_ECHO_UNQUOTED( ["Bad output from ls -t: \"`[ls -t conftest.ts[12]]`\""], [AS_MESSAGE_LOG_FD]) AC_MSG_FAILURE([ls -t produces unexpected output. Make sure there is not a broken ls alias in your environment.]) fi for am_try_res in $am_try_resolutions; do # Any one fine-grained sleep might happen to cross the boundary # between two values of a coarser actual resolution, but if we do # two fine-grained sleeps in a row, at least one of them will fall # entirely within a coarse interval. echo alpha > conftest.ts1 sleep $am_try_res echo beta > conftest.ts2 sleep $am_try_res echo gamma > conftest.ts3 # We assume that 'ls -t' will make use of high-resolution # timestamps if the operating system supports them at all. if (set X `ls -t conftest.ts?` && test "$[]2" = conftest.ts3 && test "$[]3" = conftest.ts2 && test "$[]4" = conftest.ts1); then # # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, # because we don't need to test make. make_ok=true if test $am_try_res != 1; then # But if we've succeeded so far with a subsecond resolution, we # have one more thing to check: make. It can happen that # everything else supports the subsecond mtimes, but make doesn't; # notably on macOS, which ships make 3.81 from 2006 (the last one # released under GPLv2). https://bugs.gnu.org/68808 # # We test $MAKE if it is defined in the environment, else "make". # It might get overridden later, but our hope is that in practice # it does not matter: it is the system "make" which is (by far) # the most likely to be broken, whereas if the user overrides it, # probably they did so with a better, or at least not worse, make. # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html # # Create a Makefile (real tab character here): rm -f conftest.mk echo 'conftest.ts1: conftest.ts2' >conftest.mk echo ' touch conftest.ts2' >>conftest.mk # # Now, running # touch conftest.ts1; touch conftest.ts2; make # should touch ts1 because ts2 is newer. This could happen by luck, # but most often, it will fail if make's support is insufficient. So # test for several consecutive successes. # # (We reuse conftest.ts[12] because we still want to modify existing # files, not create new ones, per above.) n=0 make=${MAKE-make} until test $n -eq 3; do echo one > conftest.ts1 sleep $am_try_res echo two > conftest.ts2 # ts2 should now be newer than ts1 if $make -f conftest.mk | grep 'up to date' >/dev/null; then make_ok=false break # out of $n loop fi n=`expr $n + 1` done fi # if $make_ok; then # Everything we know to check worked out, so call this resolution good. am_cv_filesystem_timestamp_resolution=$am_try_res break # out of $am_try_res loop fi # Otherwise, we'll go on to check the next resolution. fi done rm -f conftest.ts? # (end _am_filesystem_timestamp_resolution) ])]) # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION]) # This check should not be cached, as it may vary across builds of # different projects. AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). am_build_env_is_sane=no am_has_slept=no rm -f conftest.file for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[]*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi test "$[]2" = conftest.file ); then am_build_env_is_sane=yes break fi # Just in case. sleep "$am_cv_filesystem_timestamp_resolution" am_has_slept=yes done AC_MSG_RESULT([$am_build_env_is_sane]) if test "$am_build_env_is_sane" = no; then AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= AS_IF([test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1],, [dnl ( sleep "$am_cv_filesystem_timestamp_resolution" ) & am_sleep_pid=$! ]) AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SILENT_RULES # ---------------- # Enable less verbose build rules support. AC_DEFUN([_AM_SILENT_RULES], [AM_DEFAULT_VERBOSITY=1 AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl dnl Delay evaluation of AM_DEFAULT_VERBOSITY to the end to allow multiple calls dnl to AM_SILENT_RULES to change the default value. AC_CONFIG_COMMANDS_PRE([dnl case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; esac if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi ])dnl ]) # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Set the default verbosity level to DEFAULT ("yes" being less verbose, "no" or # empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_REQUIRE([_AM_SILENT_RULES]) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1])]) # Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test x$am_uid = xunknown; then AC_MSG_WARN([ancient id detected; assuming current UID is ok, but dist-ustar might not work]) elif test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test x$gm_gid = xunknown; then AC_MSG_WARN([ancient id detected; assuming current GID is ok, but dist-ustar might not work]) elif test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR # Copyright (C) 2022-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_XARGS_N # ---------------- # Check whether 'xargs -n' works. It should work everywhere, so the fallback # is not optimized at all as we never expect to use it. AC_DEFUN([_AM_PROG_XARGS_N], [AC_CACHE_CHECK([xargs -n works], am_cv_xargs_n_works, [dnl AS_IF([test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 3"], [am_cv_xargs_n_works=yes], [am_cv_xargs_n_works=no])]) AS_IF([test "$am_cv_xargs_n_works" = yes], [am__xargs_n='xargs -n'], [dnl am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "$@" "$am__xargs_n_arg"; done; }' ])dnl AC_SUBST(am__xargs_n) ]) m4_include([macros/ax_append_flag.m4]) m4_include([macros/ax_cflags_warn_all.m4]) m4_include([macros/ax_cxx_compile_stdcxx.m4]) m4_include([macros/ax_lib_indi.m4]) m4_include([macros/ax_lib_nova.m4]) m4_include([macros/ax_lib_readline.m4]) m4_include([macros/ax_lua.m4]) m4_include([macros/ax_pkg_swig.m4]) m4_include([macros/ax_pthread.m4]) m4_include([macros/ax_python_devel.m4]) m4_include([macros/gr_pwin32.m4]) m4_include([macros/hl_getaddrinfo.m4]) m4_include([macros/libtool.m4]) m4_include([macros/ltoptions.m4]) m4_include([macros/ltsugar.m4]) m4_include([macros/ltversion.m4]) m4_include([macros/lt~obsolete.m4]) m4_include([macros/perl.m4]) m4_include([macros/pkg.m4]) m4_include([macros/tcl.m4]) hamlib-4.6.5/Makefile.in0000664000175000017500000010442315056640452010525 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = hamlib.pc CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(aclocaldir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(pkgconfigdir)" DATA = $(aclocal_DATA) $(doc_DATA) $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/hamlib.pc.in \ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.sub \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing \ $(top_srcdir)/include/hamlib/config.h.in AUTHORS COPYING \ COPYING.LIB ChangeLog INSTALL NEWS README THANKS \ build-aux/ar-lib build-aux/compile build-aux/config.guess \ build-aux/config.sub build-aux/install-sh build-aux/ltmain.sh \ build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \ ; rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = -9 DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = \ find . \( -type f -a \! \ \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = -D_TIME_BITS=64 -Winitializer-overrides AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ aclocaldir = $(datadir)/aclocal aclocal_DATA = hamlib.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = hamlib.pc EXTRA_DIST = PLAN LICENSE hamlib.m4 hamlib.pc.in README.md README.developer \ README.betatester README.freqranges README.multicast README.osx \ Android.mk doc_DATA = ChangeLog COPYING COPYING.LIB LICENSE \ README.md README.betatester README.developer SUBDIRS = macros include lib security \ $(BACKEND_LIST) \ $(RIG_BACKEND_LIST) \ $(ROT_BACKEND_LIST) \ $(AMP_BACKEND_LIST) \ security \ src \ $(BINDINGS) \ tests doc DIST_SUBDIRS = macros include lib src c++ bindings tests doc android scripts rotators/indi simulators\ security $(BACKEND_LIST) $(RIG_BACKEND_LIST) $(ROT_BACKEND_LIST) $(AMP_BACKEND_LIST) # Install any third party macros into our tree for distribution ACLOCAL_AMFLAGS = -I macros --install all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): include/hamlib/config.h: include/hamlib/stamp-h1 @test -f $@ || rm -f include/hamlib/stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) include/hamlib/stamp-h1 include/hamlib/stamp-h1: $(top_srcdir)/include/hamlib/config.h.in $(top_builddir)/config.status $(AM_V_at)rm -f include/hamlib/stamp-h1 $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status include/hamlib/config.h $(top_srcdir)/include/hamlib/config.h.in: $(am__configure_deps) $(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER)) $(AM_V_at)rm -f include/hamlib/stamp-h1 $(AM_V_at)touch $@ distclean-hdr: -rm -f include/hamlib/config.h include/hamlib/stamp-h1 hamlib.pc: $(top_builddir)/config.status $(srcdir)/hamlib.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-aclocalDATA: $(aclocal_DATA) @$(NORMAL_INSTALL) @list='$(aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(aclocaldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(aclocaldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(aclocaldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(aclocaldir)" || exit $$?; \ done uninstall-aclocalDATA: @$(NORMAL_UNINSTALL) @list='$(aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(aclocaldir)'; $(am__uninstall_files_from_dir) install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) $(AM_V_at)$(MKDIR_P) "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(aclocaldir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-aclocalDATA install-docDATA \ install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-aclocalDATA uninstall-docDATA \ uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-aclocalDATA \ install-am install-data install-data-am install-docDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-aclocalDATA uninstall-am uninstall-docDATA \ uninstall-pkgconfigDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/README.betatester0000664000175000017500000003155415056640442011504 Hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) (C) Stephane Fillod 2000-2011 (C) The Hamlib Group 2000-2013 Why does Hamlib need beta-testers? ================================== Hamlib is developed by a team of radio enthusiasts around the world, for fun, much in the spirit of ham radio. (Note that it is not restricted for ham usage only). There are a great deal of protocols and rigs around the world developers may not own. However, protocols may be available, so backends can be implemented, but cannot always be tested by developers. That's where beta-testers are so precious. On top of that, I've been told that there's no such sure thing like bug free code. Feedback and improvement requests are also valuable. Okay, you volunteer as beta-tester, how to proceed? =================================================== First of all, you can start testing official releases. They are easier to test because they come in precompiled and packaged (.rpm, .deb, etc.) but they have the drawback of being older than the Git repository. Reports from these versions are still very appreciated. Please send them to the hamlib-developer@lists.sourceforge.net mailing list. However, the development of Hamlib is still very active, so it's better to test from the latest Git version of the code. And, depending on feedback you make, developers can commit a fix, so you can try out the change soon after, without waiting for the next official version. To proceed, you will have first to obtain either a daily snapshot or a check out the latest sources from the Git repository, then rebuild the Hamlib package and finally test it with your rig. Don't worry, it's much simpler than it looks, despite the size of the package. Pre-requisite: - some kind of internet access - POSIXish compiler toolchain (gcc, make, C library development headers, etc., see README.developer for a complete list and building from a Git checkout) So here we go: Daily Git master branch snapshots: ================================== Download the latest Git master branch snapshot from: http://n0nb.users.sourceforge.net You'll find a tarball with a name like hamlib-3.0~git-30e58df-20121009.tar.gz, i.e. a check out made 09 Oct 2012 With a Git SHA1 of 30e58df (The SHA1 is a signature of each commit. Each is unique and as our project is small, the first seven characters for the full 40 character SHA1 are likely unique. The shorthand SHA1 is automatically generated and may become longer in the future.), ready for building using the familiar "three step" (see below). Each morning by about 1130z a new snapshot is generated and uploaded and the prior day's version is removed. The advantage of the Git snapshot is that you won't need as many tools installed to build Hamlib as the work of the GNU Build System has already been done. Most of the other packages listed below will be needed. If you tell the 'configure' script to build certain parts of Hamlib like documentation or scripting language bindings the relevant optional packages will be needed. See 'configure --help' for more information. Here is a list of development packages needed for a complete build of the library (Debian package names are listed, other distributions may differ): * Gnu C (gcc) or any C99 compliant compiler # gcc --version * Gnu make (or any modern one, BSD okay) # make --version N.B. The Debian and derivatives (Ubuntu and friends) 'build-essentials' package will install a number of tools and minimize the number of packages that need to be installed manually. Optional, but highly recommended for a complete build: * GNU C++ (g++) # g++ --version * swig (for bindings) 1.3.14+ # swig -version * perl devel # h2xs * tcl devel # tcltk-depends * python devel # python-config * zlib devel # Needed by configure's test for Python * libxml2 devel # xml2-config --version * libgd2 devel # gdlib-config --version * libusb-1.0 devel # ver 1.0 or newer (not 0.1!) * libreadline devel # ver 5.2 or newer N.B The libusb package is required for building most of the 'kit' backend. The newer version is needed, not 0.1. Debian and derivatives package libusb-1.0 which is what is needed. Documentation: * Doxygen Git master branch daily snapshot build: ======================================= Reading the INSTALL file in top directory will explain in more detail how to do the following commands. ./configure [--prefix=$HOME/local] make make check make install The prefix argument is optional. Convention is that local packages be placed in /usr/local away from distribution installed packages This is the default location for the snapshots so it may be disregarded unless you wish to install Hamlib elsewhere. The example above would install Hamlib to the user's home directory under the 'local' subdirectory. Other useful options are '--with-perl-binding' or '--with-python-binding' or '--with-tcl-binding' if you are interested in Swig binding support for those scripting languages If you are unsure it is safe to ignore these options. 'make' will run the C and, optionally, the C++ compiler building all of the binary object files and finally linking all of them together to form the Hamlib "frontend" and "backend" libraries. The 'make check' target will run a few predetermined tests using the 'dummy' (rig model 1) backend and some other Hamlib functions in the build tree. This is a basic sanity check and cannot test all backends. The 'make install' target will require super user (root/administrator) privileges when installing to the system directories as a normal user. Some Linux distributions offer the 'sudo' command to grant temporary root privileges or the 'su' command to login as "root". Consult your distribution's documentation. NOTE! If Hamlib has not been previously installed as a locally built package you will need to make sure that 'ldconfig' is configured correctly and run after 'make install'. Most modern distributions have an /etc/ld.so.conf.d/ directory where local configuration can be made. Later versions of Debian and derivatives have a file named 'libc.conf' in this directory. The contents of libc.conf are: # libc default configuration /usr/local/lib If your system does not have such a file, one will need to be created and then 'ldconfig' will need to be run as the root user so that applications using the Hamlib libraries can find them. To delete the binary files from the source directory after compiling: make clean To also remove the Makefiles and other build files generated by 'configure', along with the binary files as with 'make clean' above: make distclean The 'configure' script will need to be run again as above. The above commands will clean things up so Hamlib can be compiled with other configure script options. To remove Hamlib from your system: sudo make uninstall Note that due to a limitation in a Perl support script that if the Perl binding is built and installed that not all of the files under /usr/local/lib/perl/PERL_VERSION will not be removed. Git checkout: ============= Please read the beginning of README.developer file, especially Section 1 which details the Git checkout, the required tools and versions (very important or make won't even work!), and how to use the bootstrap script. Structure: ========== For the brave who want to peruse the contents, here are what all the subdirectories are for (these are just a sample as more are added from time to time): rigs: rig backends rotors: rotator backends rigs/dummy: virtual dummy rig and rotator and other non-rig devices, for testing use. lib: library for functions missing on your system bindings Perl, Python, Tcl, and Visual Basic bindings c++: C++ bindings doc: documentation base and scripts to extract from src include/hamlib: exported header files go here include: non-distributed header files go there src: Hamlib frontend source directory tests: rigctl/rotctl and various C programs for testing Testing Hamlib: =============== Don't attempt to test Hamlib from the source directory unless you're a developer and you understand the side effects of *not* installing freshly generated objects (basically having to mess with LD_LIBRARY_PATH and .libs). Do an 'sudo make install' to install the libraries in the system area. (You did run 'sudo ldconfig' after 'sudo make install', right?) So here we go. First of all, identify your rig model id. Make sure /usr/local/bin (or the path you set --prefix to above) is in your $PATH, as your shell has to be able to locate rigctl. Run 'rigctl -l' to get a list of rigs supported by Hamlib. If you cannot find your radio in the list, please report to the hamlib-developer mailing list. The protocol manual and rig specifications will help us a lot. You found your rig's ID? Good! You're almost ready to use rigctl. Have a quick look at its manual page: man rigctl or: man -M /usr/local/man rigctl or simply: rigctl --help Let's say you own an Icom IC-756: rigctl -vvvvv -r /dev/ttyS0 -m 326 The -vvvvv is very important since this will increase verbosity, and give precious traces to developers if something goes wrong. At this level, the protocol data exchanged will also be dumped to the screen. Some backends produce a useful amount of data regarding function calls and critical variables with the -vvvv option without all the protocol data. Unless some problem shows up, you should be presented with a menu like "Rig command: ". Enter "?" followed by return to have the list of available commands. 'Q' or 'q' quits rigctl immediately. Most wanted functions to be tested are: '_' get misc information on the rig 'f' get frequency 'F' set frequency, in Hz 'm' get mode 'M' set mode (AM,FM,CW,USB,etc. and passband width in Hz) 'v' get vfo 'V' set vfo (VFOA, VFOB, etc.) f,F get_freq/set_freq try various (<1MHz, <30Mhz and >1GHz) v,V get_vfo/set_vfo VFOA, VFOB m,M get_mode/set_mode FM, USB, LSB, CW, WFM, etc. passband is in Hz (pass 0 for default) G vfo_op UP, DOWN _ get_info should give remote Id and firmware vers NB: some functions may not be implemented in the backend or simply not available on this rig. When reporting to the hamlib-developer mailing list, please include traces and also comments to tell developers if the action performed correctly on the rig. Tip: Traces can be hard to cut and paste sometimes. In that case, there's a handy tool for you: script(1) (the (1) is not a part of the command, rather it is a Unix convention telling which section of the manual it is found, in this case section 1, user commands. e.g. 'man 1 script'). It will make a typescript of everything printed on your terminal and save it to the file you give it. $ script my_rig_traces.txt Script started, file is my_rig_traces.txt $ rigctl -vvvvv -r /dev/ttyS0 -m 326 rig:rig_init called rig: loading backend icom icom: _init called rig_register (309) rig_register (326) rig:rig_open called Opened rig model 326, 'IC-756' Rig command: q rig:rig_close called rig:rig_cleanup called $ exit exit Script done, file is my_rig_traces.txt $ And then send my_rig_traces.txt to the hamlib-developer mailing list. Some models need S-meter calibration, because the rig only returns raw measurement. It's easy, it takes only 10mn. Here's how to proceed: 1. Fire up the rigctl program released with the Hamlib package, and pass along options as needed (serial speed, etc.). 2. Tune to some frequency reporting S0 to the radio S-Meter. 3. At rigctl prompt, issue "get_level" ('l' in short) of the level RAWSTR. 4. Write down the S-level read on radio front panel, and the RAWSTR value retrieved. 5. Repeat from step 2 with S9 and S9+60dB. Actually the more plots, the better, otherwise Hamlib does interpolation. 6. Send the table to the hamlib-developer mailing list and it will be added in the next release of Hamlib. NB: It is well known the S-Meter of any given radio is far from being accurate. For owners with a fully equipped lab, you may want to make the above-mentioned measurements with a good signal generator and a set of calibrated attenuators. Greg W8WWV has an insightful page about S-Meter calibration: http://www.seed-solutions.com/gregordy/Amateur%20Radio/Experimentation/SMeterBlues.htm Okay folks, test as much as you can, in the weirdest situations if possible. There is a special prize for those who find 'Segmentation fault' and other nasty bugs. Needless to say, patches are also very welcome (see README.developer). :-) Stephane - F8CFE and The Hamlib Group hamlib-4.6.5/c++/0000775000175000017500000000000015056640475007111 5hamlib-4.6.5/c++/ampclass.cc0000664000175000017500000000512015056640442011133 /** * \file src/ampclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2002 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2002 by Stephane Fillod * Copyright (c) 2019 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include //#include #include #include #define CHECK_AMP(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } Amplifier::Amplifier(amp_model_t amp_model) { theAmp = amp_init(amp_model); if (!theAmp) THROW(new RigException ("Amplifier initialization error")); caps = theAmp->caps; theAmp->state.obj = (amp_ptr_t)this; } Amplifier::~Amplifier() { theAmp->state.obj = NULL; CHECK_AMP( amp_cleanup(theAmp) ); caps = NULL; } void Amplifier::open(void) { CHECK_AMP( amp_open(theAmp) ); } void Amplifier::close(void) { CHECK_AMP( amp_close(theAmp) ); } void Amplifier::setConf(hamlib_token_t token, const char *val) { CHECK_AMP( amp_set_conf(theAmp, token, val) ); } void Amplifier::setConf(const char *name, const char *val) { CHECK_AMP( amp_set_conf(theAmp, tokenLookup(name), val) ); } void Amplifier::getConf(hamlib_token_t token, char *val) { CHECK_AMP( amp_get_conf(theAmp, token, val) ); } void Amplifier::getConf(const char *name, char *val) { CHECK_AMP( amp_get_conf(theAmp, tokenLookup(name), val) ); } hamlib_token_t Amplifier::tokenLookup(const char *name) { return amp_token_lookup(theAmp, name); } void Amplifier::reset (amp_reset_t reset) { CHECK_AMP( amp_reset(theAmp, reset) ); } void Amplifier::setFreq(freq_t freq) { CHECK_AMP( amp_set_freq(theAmp, freq) ); } freq_t Amplifier::getFreq() { freq_t freq; CHECK_AMP( amp_get_freq(theAmp, &freq) ); return freq; } hamlib-4.6.5/c++/rotclass.cc0000664000175000017500000000536715056640442011177 /** * \file src/rotclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2002 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2002 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #define CHECK_ROT(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } Rotator::Rotator(rot_model_t rot_model) { theRot = rot_init(rot_model); if (!theRot) THROW(new RigException ("Rotator initialization error")); caps = theRot->caps; theRot->state.obj = (rig_ptr_t)this; } Rotator::~Rotator() { theRot->state.obj = NULL; CHECK_ROT( rot_cleanup(theRot) ); caps = NULL; } void Rotator::open(void) { CHECK_ROT( rot_open(theRot) ); } void Rotator::close(void) { CHECK_ROT( rot_close(theRot) ); } void Rotator::setConf(hamlib_token_t token, const char *val) { CHECK_ROT( rot_set_conf(theRot, token, val) ); } void Rotator::setConf(const char *name, const char *val) { CHECK_ROT( rot_set_conf(theRot, tokenLookup(name), val) ); } void Rotator::getConf(hamlib_token_t token, char *val) { CHECK_ROT( rot_get_conf(theRot, token, val) ); } void Rotator::getConf(const char *name, char *val) { CHECK_ROT( rot_get_conf(theRot, tokenLookup(name), val) ); } hamlib_token_t Rotator::tokenLookup(const char *name) { return rot_token_lookup(theRot, name); } void Rotator::setPosition(azimuth_t az, elevation_t el) { CHECK_ROT( rot_set_position(theRot, az, el) ); } void Rotator::getPosition(azimuth_t& az, elevation_t& el) { CHECK_ROT( rot_get_position(theRot, &az, &el) ); } void Rotator::stop() { CHECK_ROT(rot_stop(theRot)); } void Rotator::park() { CHECK_ROT(rot_park(theRot)); } void Rotator::reset (rot_reset_t reset) { CHECK_ROT( rot_reset(theRot, reset) ); } void Rotator::move (int direction, int speed) { CHECK_ROT( rot_move(theRot, direction, speed) ); } hamlib-4.6.5/c++/testcpp.cc0000664000175000017500000000077615056640442011026 /* * Hamlib sample C++ program */ #include #include int main(int argc, char* argv[]) { Rig myRig {RIG_MODEL_DUMMY}; try { myRig.setConf("rig_pathname", "/dev/pts/4"); myRig.open(); myRig.setFreq(MHz(144)); std::cout << myRig.getLevelI(RIG_LEVEL_STRENGTH) << "dB" << std::endl; std::cout << "Modes for freq 14.332: " << myRig.RngRxModes(MHz(14.332)) << std::endl; myRig.close(); } catch (const RigException &Ex) { Ex.print(); return 1; } return 0; } hamlib-4.6.5/c++/rigclass.cc0000664000175000017500000003205715056640442011150 /** * \file src/rigclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2001-2003 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2001-2003 by Stephane Fillod * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #define CHECK_RIG(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg); static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg) { if (!rig || !rig->state.obj) return -RIG_EINVAL; /* assert rig == ((Rig*)rig->state.obj).theRig */ return (static_cast(rig->state.obj))->FreqEvent(vfo, freq, arg); } Rig::Rig(rig_model_t rig_model) { theRig = rig_init(rig_model); if (!theRig) THROW(new RigException ("Rig initialization error")); caps = theRig->caps; theRig->callbacks.freq_event = &hamlibpp_freq_event; theRig->state.obj = (rig_ptr_t)this; } Rig::~Rig() { theRig->state.obj = NULL; CHECK_RIG( rig_cleanup(theRig) ); caps = NULL; } void Rig::open(void) { CHECK_RIG( rig_open(theRig) ); } void Rig::close(void) { CHECK_RIG( rig_close(theRig) ); } void Rig::setConf(hamlib_token_t token, const char *val) { CHECK_RIG( rig_set_conf(theRig, token, val) ); } void Rig::setConf(const char *name, const char *val) { CHECK_RIG( rig_set_conf(theRig, tokenLookup(name), val) ); } void Rig::getConf(hamlib_token_t token, char *val) { CHECK_RIG( rig_get_conf(theRig, token, val) ); } void Rig::getConf(const char *name, char *val) { CHECK_RIG( rig_get_conf(theRig, tokenLookup(name), val) ); } hamlib_token_t Rig::tokenLookup(const char *name) { return rig_token_lookup(theRig, name); } void Rig::setFreq(freq_t freq, vfo_t vfo) { CHECK_RIG( rig_set_freq(theRig, vfo, freq) ); } freq_t Rig::getFreq(vfo_t vfo) { freq_t freq; CHECK_RIG( rig_get_freq(theRig, vfo, &freq) ); return freq; } void Rig::setMode(rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG(rig_set_mode(theRig, vfo, mode, width)); } rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) { rmode_t mode; CHECK_RIG( rig_get_mode(theRig, vfo, &mode, &width) ); return mode; } void Rig::setVFO(vfo_t vfo) { CHECK_RIG( rig_set_vfo(theRig, vfo) ); } vfo_t Rig::getVFO() { vfo_t vfo; CHECK_RIG( rig_get_vfo(theRig, &vfo) ); return vfo; } void Rig::setPTT(ptt_t ptt, vfo_t vfo) { CHECK_RIG( rig_set_ptt(theRig, vfo, ptt) ); } ptt_t Rig::getPTT(vfo_t vfo) { ptt_t ptt; CHECK_RIG( rig_get_ptt(theRig, vfo, &ptt) ); return ptt; } dcd_t Rig::getDCD(vfo_t vfo) { dcd_t dcd; CHECK_RIG( rig_get_dcd(theRig, vfo, &dcd) ); return dcd; } void Rig::setLevel(setting_t level, int vali, vfo_t vfo) { value_t val; val.i = vali; CHECK_RIG( rig_set_level(theRig, vfo, level, val) ); } void Rig::setLevel(setting_t level, float valf, vfo_t vfo) { value_t val; val.f = valf; CHECK_RIG( rig_set_level(theRig, vfo, level, val) ); } void Rig::getLevel(setting_t level, int& vali, vfo_t vfo) { value_t val; if (RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); vali = val.i; } void Rig::getLevel(setting_t level, float& valf, vfo_t vfo) { value_t val; if (!RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); valf = val.f; } int Rig::getLevelI(setting_t level, vfo_t vfo) { value_t val; if (RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); return val.i; } float Rig::getLevelF(setting_t level, vfo_t vfo) { value_t val; if (!RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); return val.f; } void Rig::setParm(setting_t parm, int vali) { value_t val; val.i = vali; CHECK_RIG( rig_set_parm(theRig, parm, val) ); } void Rig::setParm(setting_t parm, float valf) { value_t val; val.f = valf; CHECK_RIG( rig_set_parm(theRig, parm, val) ); } void Rig::getParm(setting_t parm, int& vali) { value_t val; if (RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); vali = val.i; } void Rig::getParm(setting_t parm, float& valf) { value_t val; if (!RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); valf = val.f; } int Rig::getParmI(setting_t parm) { value_t val; if (RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); return val.i; } float Rig::getParmF(setting_t parm) { value_t val; if (!RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); return val.f; } void Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) { CHECK_RIG( rig_set_split_freq(theRig, vfo, tx_freq) ); } freq_t Rig::getSplitFreq(vfo_t vfo) { freq_t freq; CHECK_RIG( rig_get_split_freq(theRig, vfo, &freq) ); return freq; } void Rig::setSplitMode(rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG(rig_set_split_mode(theRig, vfo, mode, width)); } rmode_t Rig::getSplitMode(pbwidth_t& width, vfo_t vfo) { rmode_t mode; CHECK_RIG( rig_get_split_mode(theRig, vfo, &mode, &width) ); return mode; } void Rig::setSplitFreqMode(freq_t tx_freq, rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG (rig_set_split_freq_mode (theRig, vfo, tx_freq, mode, width)); } freq_t Rig::getSplitFreqMode(rmode_t& mode, pbwidth_t& width, vfo_t vfo) { freq_t freq; CHECK_RIG (rig_get_split_freq_mode (theRig, vfo, &freq, &mode, &width)); return freq; } void Rig::setSplitVFO(split_t split, vfo_t vfo, vfo_t tx_vfo) { CHECK_RIG(rig_set_split_vfo(theRig, vfo, split, tx_vfo)); } split_t Rig::getSplitVFO(vfo_t &tx_vfo, vfo_t vfo) { split_t split; CHECK_RIG( rig_get_split_vfo(theRig, vfo, &split, &tx_vfo) ); return split; } bool Rig::hasGetLevel (setting_t level) { return rig_has_get_level(theRig, level) == level; } bool Rig::hasSetLevel (setting_t level) { return rig_has_set_level(theRig, level) == level; } bool Rig::hasGetParm (setting_t parm) { return rig_has_get_parm(theRig, parm) == parm; } bool Rig::hasSetParm (setting_t parm) { return rig_has_set_parm(theRig, parm) == parm; } const char *Rig::getInfo (void) { return rig_get_info(theRig); } pbwidth_t Rig::passbandNormal (rmode_t mode) { return rig_passband_normal(theRig, mode); } pbwidth_t Rig::passbandNarrow (rmode_t mode) { return rig_passband_narrow(theRig, mode); } pbwidth_t Rig::passbandWide (rmode_t mode) { return rig_passband_wide(theRig, mode); } void Rig::setRptrShift (rptr_shift_t rptr_shift, vfo_t vfo) { CHECK_RIG( rig_set_rptr_shift(theRig, vfo, rptr_shift) ); } rptr_shift_t Rig::getRptrShift (vfo_t vfo) { rptr_shift_t rptr_shift; CHECK_RIG( rig_get_rptr_shift(theRig, vfo, &rptr_shift) ); return rptr_shift; } void Rig::setRptrOffs (shortfreq_t rptr_offs, vfo_t vfo) { CHECK_RIG( rig_set_rptr_offs(theRig, vfo, rptr_offs) ); } shortfreq_t Rig::getRptrOffs (vfo_t vfo) { shortfreq_t rptr_offs; CHECK_RIG( rig_get_rptr_offs(theRig, vfo, &rptr_offs) ); return rptr_offs; } void Rig::setTs (shortfreq_t ts, vfo_t vfo) { CHECK_RIG( rig_set_ts(theRig, vfo, ts) ); } shortfreq_t Rig::getTs (vfo_t vfo) { shortfreq_t ts; CHECK_RIG( rig_get_ts(theRig, vfo, &ts) ); return ts; } void Rig::setCTCSS (tone_t tone, vfo_t vfo) { CHECK_RIG( rig_set_ctcss_tone(theRig, vfo, tone) ); } tone_t Rig::getCTCSS (vfo_t vfo) { tone_t tone; CHECK_RIG( rig_get_ctcss_tone(theRig, vfo, &tone) ); return tone; } void Rig::setDCS (tone_t code, vfo_t vfo) { CHECK_RIG( rig_set_dcs_code(theRig, vfo, code) ); } tone_t Rig::getDCS (vfo_t vfo) { tone_t code; CHECK_RIG( rig_get_dcs_code(theRig, vfo, &code) ); return code; } void Rig::setCTCSSsql (tone_t tone, vfo_t vfo) { CHECK_RIG( rig_set_ctcss_sql(theRig, vfo, tone) ); } tone_t Rig::getCTCSSsql (vfo_t vfo) { tone_t tone; CHECK_RIG( rig_get_ctcss_sql(theRig, vfo, &tone) ); return tone; } void Rig::setDCSsql (tone_t code, vfo_t vfo) { CHECK_RIG( rig_set_dcs_sql(theRig, vfo, code) ); } tone_t Rig::getDCSsql (vfo_t vfo) { tone_t code; CHECK_RIG( rig_get_dcs_sql(theRig, vfo, &code) ); return code; } void Rig::setFunc (setting_t func, bool status, vfo_t vfo) { CHECK_RIG( rig_set_func(theRig, vfo, func, status? 1:0) ); } bool Rig::getFunc (setting_t func, vfo_t vfo) { int status; CHECK_RIG( rig_get_func(theRig, vfo, func, &status) ); return status ? true : false; } void Rig::VFOop (vfo_op_t op, vfo_t vfo) { CHECK_RIG( rig_vfo_op(theRig, vfo, op) ); } bool Rig::hasVFOop (vfo_op_t op) { return rig_has_vfo_op(theRig, op)==op; } void Rig::scan (scan_t scan, int ch, vfo_t vfo) { CHECK_RIG( rig_scan(theRig, vfo, scan, ch) ); } bool Rig::hasScan (scan_t scan) { return rig_has_scan(theRig, scan)==scan; } void Rig::setRit(shortfreq_t rit, vfo_t vfo) { CHECK_RIG(rig_set_rit(theRig, vfo, rit)); } shortfreq_t Rig::getRit(vfo_t vfo) { shortfreq_t rit; CHECK_RIG( rig_get_rit(theRig, vfo, &rit) ); return rit; } void Rig::setXit(shortfreq_t xit, vfo_t vfo) { CHECK_RIG(rig_set_xit(theRig, vfo, xit)); } shortfreq_t Rig::getXit(vfo_t vfo) { shortfreq_t xit; CHECK_RIG( rig_get_xit(theRig, vfo, &xit) ); return xit; } void Rig::setAnt(const value_t option, ant_t ant, vfo_t vfo) { CHECK_RIG(rig_set_ant(theRig, vfo, ant, option)); } ant_t Rig::getAnt(ant_t &ant_rx, ant_t &ant_tx, ant_t ant, value_t &option, ant_t &ant_curr, vfo_t vfo) { CHECK_RIG( rig_get_ant(theRig, vfo, ant, &option, &ant_curr, &ant_tx, &ant_rx) ); return ant; } void Rig::sendDtmf(const char *digits, vfo_t vfo) { CHECK_RIG(rig_send_dtmf(theRig, vfo, digits)); } int Rig::recvDtmf(char *digits, vfo_t vfo) { int len; CHECK_RIG( rig_recv_dtmf(theRig, vfo, digits, &len) ); return len; } void Rig::sendMorse(const char *msg, vfo_t vfo) { CHECK_RIG(rig_send_morse(theRig, vfo, msg)); } shortfreq_t Rig::getResolution (rmode_t mode) { shortfreq_t res; res = rig_get_resolution(theRig, mode); if (res < 0) THROW(new RigException (res)); return res; } void Rig::reset (reset_t reset) { CHECK_RIG( rig_reset(theRig, reset) ); } bool Rig::hasGetFunc (setting_t func) { return rig_has_get_func(theRig, func)==func; } bool Rig::hasSetFunc (setting_t func) { return rig_has_set_func(theRig, func)==func; } unsigned int Rig::power2mW (float power, freq_t freq, rmode_t mode) { unsigned int mwpower; CHECK_RIG( rig_power2mW(theRig, &mwpower, power, freq, mode) ); return mwpower; } float Rig::mW2power (unsigned int mwpower, freq_t freq, rmode_t mode) { float power; CHECK_RIG( rig_mW2power(theRig, &power, mwpower, freq, mode) ); return power; } void Rig::setTrn (int trn) { CHECK_RIG( rig_set_trn(theRig, trn) ); } int Rig::getTrn () { int trn; CHECK_RIG( rig_get_trn(theRig, &trn) ); return trn; } void Rig::setBank (int bank, vfo_t vfo) { CHECK_RIG( rig_set_ts(theRig, vfo, bank) ); } void Rig::setMem (int ch, vfo_t vfo) { CHECK_RIG( rig_set_mem(theRig, vfo, ch) ); } int Rig::getMem (vfo_t vfo) { int mem; CHECK_RIG( rig_get_mem(theRig, vfo, &mem) ); return mem; } void Rig::setChannel (const channel_t *chan, vfo_t vfo) { CHECK_RIG( rig_set_channel(theRig, vfo, chan) ); } void Rig::getChannel (channel_t *chan,vfo_t vfo, int readOnly) { CHECK_RIG( rig_get_channel(theRig, vfo, chan, readOnly) ); } void Rig::setPowerStat (powerstat_t status) { CHECK_RIG( rig_set_powerstat(theRig, status) ); } powerstat_t Rig::getPowerStat (void) { powerstat_t status; CHECK_RIG( rig_get_powerstat(theRig, &status) ); return status; } rmode_t Rig::RngRxModes (freq_t freq) { unsigned modes = RIG_MODE_NONE; int i; for (i=0; istate.rx_range_list[i]; if (RIG_IS_FRNG_END(*rng)) { return (rmode_t)modes; } if (freq >= rng->startf && freq <= rng->endf) modes |= (unsigned)rng->modes; } return (rmode_t)modes; } rmode_t Rig::RngTxModes (freq_t freq) { unsigned modes = RIG_MODE_NONE; int i; for (i=0; istate.tx_range_list[i]; if (RIG_IS_FRNG_END(*rng)) { return (rmode_t)modes; } if (freq >= rng->startf && freq <= rng->endf) modes |= (unsigned)rng->modes; } return (rmode_t)modes; } hamlib-4.6.5/c++/Makefile.in0000664000175000017500000011666515056640452011110 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CXX_TRUE@check_PROGRAMS = testcpp$(EXEEXT) subdir = c++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) @ENABLE_CXX_TRUE@libhamlib___la_DEPENDENCIES = \ @ENABLE_CXX_TRUE@ $(top_builddir)/src/libhamlib.la am__libhamlib___la_SOURCES_DIST = rigclass.cc rotclass.cc ampclass.cc @ENABLE_CXX_TRUE@am_libhamlib___la_OBJECTS = rigclass.lo rotclass.lo \ @ENABLE_CXX_TRUE@ ampclass.lo libhamlib___la_OBJECTS = $(am_libhamlib___la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libhamlib___la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libhamlib___la_LDFLAGS) \ $(LDFLAGS) -o $@ @ENABLE_CXX_TRUE@am_libhamlib___la_rpath = -rpath $(libdir) am__testcpp_SOURCES_DIST = testcpp.cc @ENABLE_CXX_TRUE@am_testcpp_OBJECTS = testcpp.$(OBJEXT) testcpp_OBJECTS = $(am_testcpp_OBJECTS) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ampclass.Plo \ ./$(DEPDIR)/rigclass.Plo ./$(DEPDIR)/rotclass.Plo \ ./$(DEPDIR)/testcpp.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libhamlib___la_SOURCES) $(testcpp_SOURCES) DIST_SOURCES = $(am__libhamlib___la_SOURCES_DIST) \ $(am__testcpp_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ $$am__collect_skipped_logs \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(IGNORE_SKIPPED_LOGS)'; then \ am__collect_skipped_logs='--collect-skipped-logs no'; \ else \ am__collect_skipped_logs=''; \ fi; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @ENABLE_CXX_TRUE@lib_LTLIBRARIES = libhamlib++.la @ENABLE_CXX_TRUE@libhamlib___la_SOURCES = rigclass.cc rotclass.cc ampclass.cc @ENABLE_CXX_TRUE@libhamlib___la_LDFLAGS = -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) $(LDFLAGS) @ENABLE_CXX_TRUE@libhamlib___la_LIBADD = $(top_builddir)/src/libhamlib.la @ENABLE_CXX_TRUE@testcpp_SOURCES = testcpp.cc @ENABLE_CXX_TRUE@testcpp_LDADD = libhamlib++.la $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) @ENABLE_CXX_TRUE@testcpp_DEPENDENCIES = libhamlib++.la @ENABLE_CXX_TRUE@TESTS = $(check_PROGRAMS) all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: $(am__rm_f) $(check_PROGRAMS) test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=) install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib++.la: $(libhamlib___la_OBJECTS) $(libhamlib___la_DEPENDENCIES) $(EXTRA_libhamlib___la_DEPENDENCIES) $(AM_V_CXXLD)$(libhamlib___la_LINK) $(am_libhamlib___la_rpath) $(libhamlib___la_OBJECTS) $(libhamlib___la_LIBADD) $(LIBS) testcpp$(EXEEXT): $(testcpp_OBJECTS) $(testcpp_DEPENDENCIES) $(EXTRA_testcpp_DEPENDENCIES) @rm -f testcpp$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(testcpp_OBJECTS) $(testcpp_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcpp.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ output_system_information () \ { \ echo; \ { uname -a | $(AWK) '{ \ printf "System information (uname -a):"; \ for (i = 1; i < NF; ++i) \ { \ if (i != 2) \ printf " %s", $$i; \ } \ printf "\n"; \ }'; } 2>&1; \ if test -r /etc/os-release; then \ echo "Distribution information (/etc/os-release):"; \ sed 8q /etc/os-release; \ elif test -r /etc/issue; then \ echo "Distribution information (/etc/issue):"; \ cat /etc/issue; \ fi; \ }; \ please_report () \ { \ echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \ echo "together with the test-suite.log file (gzipped) and your system"; \ echo "information. Thanks."; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ output_system_information; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\ if test -n "$(PACKAGE_BUGREPORT)"; then \ please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @$(am__rm_f) $(RECHECK_LOGS) @$(am__rm_f) $(RECHECK_LOGS:.log=.trs) @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? testcpp.log: testcpp$(EXEEXT) @p='testcpp$(EXEEXT)'; \ b='testcpp'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) install-checkPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -$(am__rm_f) $(TEST_LOGS) -$(am__rm_f) $(TEST_LOGS:.log=.trs) -$(am__rm_f) $(TEST_SUITE_LOG) clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ampclass.Plo -rm -f ./$(DEPDIR)/rigclass.Plo -rm -f ./$(DEPDIR)/rotclass.Plo -rm -f ./$(DEPDIR)/testcpp.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ampclass.Plo -rm -f ./$(DEPDIR)/rigclass.Plo -rm -f ./$(DEPDIR)/rotclass.Plo -rm -f ./$(DEPDIR)/testcpp.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-libLTLIBRARIES .PRECIOUS: Makefile @ENABLE_CXX_TRUE@$(top_builddir)/src/libhamlib.la: @ENABLE_CXX_TRUE@ $(MAKE) -C $(top_builddir)/src/ libhamlib.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/c++/Makefile.am0000664000175000017500000000111315056640442011053 if ENABLE_CXX lib_LTLIBRARIES = libhamlib++.la libhamlib___la_SOURCES = rigclass.cc rotclass.cc ampclass.cc libhamlib___la_LDFLAGS = -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) $(LDFLAGS) libhamlib___la_LIBADD = $(top_builddir)/src/libhamlib.la check_PROGRAMS = testcpp testcpp_SOURCES = testcpp.cc testcpp_LDADD = libhamlib++.la $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) testcpp_DEPENDENCIES = libhamlib++.la TESTS = $(check_PROGRAMS) $(top_builddir)/src/libhamlib.la: $(MAKE) -C $(top_builddir)/src/ libhamlib.la endif hamlib-4.6.5/amplifiers/0000775000175000017500000000000015056640503010664 5hamlib-4.6.5/amplifiers/gemini/0000775000175000017500000000000015056640503012134 5hamlib-4.6.5/amplifiers/gemini/dx1200.c0000664000175000017500000000577515056640442013156 /* * Hamlib backend library for the Gemini DX1200 and HF-1K command set. * * dx1200.c - (C) Michael Black W9MDB 2022 * * This shared library provides an API for communicating * to Gemini amplifiers. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "register.h" #include "gemini.h" struct gemini_priv_data *gemini_priv; /* * API local implementation * */ /* * Private helper function prototypes */ //static int gemini_send_priv_cmd(AMP *amp, const char *cmd); //static int gemini_flush_buffer(AMP *amp); /* ************************************* * * Separate model capabilities * * ************************************* */ /* * Gemini */ const struct amp_caps gemini_amp_caps = { AMP_MODEL(AMP_MODEL_GEMINI_DX1200), .model_name = "DX1200/HF-1K", .mfg_name = "Gemini", .version = "20230318.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 2, .has_get_level = AMP_LEVEL_SWR | AMP_LEVEL_PWR_FWD | AMP_LEVEL_PWR_PEAK | AMP_LEVEL_FAULT | AMP_LEVEL_PWR, .has_set_level = AMP_LEVEL_PWR, .amp_open = NULL, .amp_init = gemini_init, .amp_close = gemini_close, .reset = gemini_reset, .get_info = gemini_get_info, .get_powerstat = gemini_get_powerstat, .set_powerstat = gemini_set_powerstat, .get_freq = gemini_get_freq, .set_freq = gemini_set_freq, .get_level = gemini_get_level, .set_level = gemini_set_level, }; /* ************************************ * * API functions * * ************************************ */ /* * */ #if 0 // not implemented yet /* * Send command string to amplifier */ static int gemini_send_priv_cmd(AMP *amp, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } err = write_block(AMPPORT(amp), cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* * Initialize backend */ DECLARE_INITAMP_BACKEND(gemini) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); amp_register(&gemini_amp_caps); return RIG_OK; } hamlib-4.6.5/amplifiers/gemini/README.gemini0000664000175000017500000000022015056640442014177 Back end for Gemini DX1200 and HF-1K https://github.com/Hamlib/Hamlib/files/9063647/NetworkConnectionProtocol_3.pdf Initial prototype 20220710 hamlib-4.6.5/amplifiers/gemini/Android.mk0000664000175000017500000000033115056640442013764 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := gemini LOCAL_MODULE := gemini LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/amplifiers/gemini/Makefile.in0000664000175000017500000005303415056640452014131 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = amplifiers/gemini ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_gemini_la_LIBADD = am__objects_1 = gemini.lo am__objects_2 = dx1200.lo am_libhamlib_gemini_la_OBJECTS = $(am__objects_1) $(am__objects_2) libhamlib_gemini_la_OBJECTS = $(am_libhamlib_gemini_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dx1200.Plo ./$(DEPDIR)/gemini.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_gemini_la_SOURCES) DIST_SOURCES = $(libhamlib_gemini_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SRC = gemini.c GEMINISRC = dx1200.c gemini.h noinst_LTLIBRARIES = libhamlib-gemini.la libhamlib_gemini_la_SOURCES = $(SRC) $(GEMINISRC) EXTRA_DIST = README.gemini Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amplifiers/gemini/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu amplifiers/gemini/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-gemini.la: $(libhamlib_gemini_la_OBJECTS) $(libhamlib_gemini_la_DEPENDENCIES) $(EXTRA_libhamlib_gemini_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_gemini_la_OBJECTS) $(libhamlib_gemini_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dx1200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gemini.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dx1200.Plo -rm -f ./$(DEPDIR)/gemini.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dx1200.Plo -rm -f ./$(DEPDIR)/gemini.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/amplifiers/gemini/gemini.h0000664000175000017500000000412615056640442013502 /* * Hamlib backend library for the Gemini amplifier set. * * gemini.h - (C) Michael Black W9MDB 2022 * * This shared library provides an API for communicating * via serial interface to Gemini amplifiers. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_GEMINI_H #define _AMP_GEMINI_H 1 #include #include #include // Is this big enough? #define GEMINIBUFSZ 1024 extern const struct amp_caps gemini_amp_caps; /* * Private data structure */ struct gemini_priv_data { long band; // Hz char antenna; int power_current; // Watts int power_peak; // Watts double vswr; int current; // Amps int temperature; // Centigrade char state[8]; int ptt; char trip[256]; }; int gemini_init(AMP *amp); int gemini_close(AMP *amp); int gemini_reset(AMP *amp, amp_reset_t reset); int gemini_flush_buffer(AMP *amp); int gemini_transaction(AMP *amp, const char *cmd, char *response, int response_len); const char *gemini_get_info(AMP *amp); int gemini_get_freq(AMP *amp, freq_t *freq); int gemini_set_freq(AMP *amp, freq_t freq); int gemini_get_level(AMP *amp, setting_t level, value_t *val); int gemini_set_level(AMP *amp, setting_t level, value_t val); int gemini_get_powerstat(AMP *amp, powerstat_t *status); int gemini_set_powerstat(AMP *amp, powerstat_t status); #endif /* _AMP_GEMINI_H */ hamlib-4.6.5/amplifiers/gemini/gemini.c0000664000175000017500000002220115056640442013467 /* * Hamlib Gemini amplifier backend - low level communication routines * Copyright (c) 2019 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "gemini.h" #if 0 struct fault_list { int code; char *errmsg; }; #endif /* * Initialize data structures */ int gemini_init(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } AMPSTATE(amp)->priv = (struct gemini_priv_data *) calloc(1, sizeof(struct gemini_priv_data)); if (!AMPSTATE(amp)->priv) { return -RIG_ENOMEM; } AMPPORT(amp)->type.rig = RIG_PORT_NETWORK; return RIG_OK; } int gemini_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (AMPSTATE(amp)->priv) { free(AMPSTATE(amp)->priv); } AMPSTATE(amp)->priv = NULL; return RIG_OK; } int gemini_flushbuffer(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return rig_flush(AMPPORT(amp)); } int gemini_transaction(AMP *amp, const char *cmd, char *response, int response_len) { hamlib_port_t *ampp = AMPPORT(amp); int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s\n", __func__, cmd); if (!amp) { return -RIG_EINVAL; } gemini_flushbuffer(amp); // Now send our command err = write_block(ampp, (unsigned char *) cmd, strlen(cmd)); if (err != RIG_OK) { return err; } if (response) // if response expected get it { response[0] = 0; int len = read_string(ampp, (unsigned char *) response, response_len, "\n", 1, 0, 1); if (len < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, error=%s\n", __func__, rigerror(len)); return len; } rig_debug(RIG_DEBUG_VERBOSE, "%s called, response='%s'\n", __func__, response); } return RIG_OK; } /* * Get Info * returns the model name string */ // cppcheck-suppress constParameterPointer const char *gemini_get_info(AMP *amp) { const struct amp_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return (const char *) - RIG_EINVAL; } rc = amp->caps; return rc->model_name; } int gemini_status_parse(AMP *amp) { int retval, n = 0; char *p; char responsebuf[GEMINIBUFSZ]; struct gemini_priv_data *priv = AMPSTATE(amp)->priv; retval = gemini_transaction(amp, "S\n", responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error sending command 'S'\n", __func__); } p = strtok(responsebuf, ",\n"); rig_debug(RIG_DEBUG_VERBOSE, "%s: responsebuf=%s\n", __func__, responsebuf); while (p) { char tmp[8]; double freq; n += sscanf(p, "BAND=%lf%7s", &freq, tmp); if (tmp[0] == 'K') { priv->band = freq * 1000; } if (tmp[0] == 'M') { priv->band = freq * 1000000; } n += sscanf(p, "ANTENNA=%c", &priv->antenna); n += sscanf(p, "POWER=%dW%d", &priv->power_current, &priv->power_peak); n += sscanf(p, "VSWR=%lf", &priv->vswr); n += sscanf(p, "CURRENT=%d", &priv->current); n += sscanf(p, "TEMPERATURE=%d", &priv->temperature); n += sscanf(p, "STATE=%7s", priv->state); n += sscanf(p, "PTT=%7s", tmp); priv->ptt = tmp[0] == 'T'; n += sscanf(p, "TRIP=%7s", priv->trip); if (n == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unknown status item=%s\n", __func__, p); } } if (n == 0) { return -RIG_EPROTO; } return RIG_OK; } int gemini_get_freq(AMP *amp, freq_t *freq) { int retval; struct gemini_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } priv = AMPSTATE(amp)->priv; retval = gemini_status_parse(amp); if (retval != RIG_OK) { return retval; } *freq = priv->band; return RIG_OK; } int gemini_set_freq(AMP *amp, freq_t freq) { int retval; char *cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (freq < 1.0) { cmd = "B472KHZ\n"; } else if (freq < 2.0) { cmd = "B1.8MHZ\n"; } else if (freq < 4.0) { cmd = "B3.5MHZ\n"; } else if (freq < 6.0) { cmd = "B50MHZ\n"; } else if (freq < 9.0) { cmd = "B70MHZ\n"; } else if (freq < 12.0) { cmd = "B10MHZ\n"; } else if (freq < 16.0) { cmd = "B14MHZ\n"; } else if (freq < 19.0) { cmd = "B18MHZ\n"; } else if (freq < 22.0) { cmd = "B21MHZ\n"; } else if (freq < 26.0) { cmd = "B24MHZ\n"; } else { cmd = "B50MHZ\n"; } retval = gemini_transaction(amp, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int gemini_get_level(AMP *amp, setting_t level, value_t *val) { int retval; struct gemini_priv_data *priv = AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = gemini_status_parse(amp); if (retval != RIG_OK) { return retval; } switch (level) { case AMP_LEVEL_SWR: val->f = priv->vswr; return RIG_OK; case AMP_LEVEL_PWR_FWD: val->i = priv->power_peak; return RIG_OK; case AMP_LEVEL_PWR_PEAK: val->i = priv->power_peak; return RIG_OK; case AMP_LEVEL_FAULT: val->s = priv->trip; return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s unknown level=%s\n", __func__, rig_strlevel(level)); } return -RIG_EINVAL; } int gemini_set_level(AMP *amp, setting_t level, value_t val) { char *cmd = "?"; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case AMP_LEVEL_PWR: // 0-.33 = low, .34-.67 = medium, .68-1.0 = high cmd = "PH\n"; if (val.f < .33) { cmd = "PL\n"; } if (val.f < .67) { cmd = "PM\n"; } break; } retval = gemini_transaction(amp, cmd, NULL, 0); if (retval == RIG_OK) { return retval; } rig_debug(RIG_DEBUG_ERR, "%s: Unknown level=%s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } int gemini_get_powerstat(AMP *amp, powerstat_t *status) { char responsebuf[GEMINIBUFSZ]; int retval; int ampon; int nargs; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *status = RIG_POWER_UNKNOWN; if (!amp) { return -RIG_EINVAL; } retval = gemini_transaction(amp, "R\n", responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "%d", &on); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } switch (ampon) { case 0: *status = RIG_POWER_STANDBY; return RIG_OK; case 1: *status = RIG_POWER_ON; break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s Error: 'R' unknown response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } return RIG_OK; } int gemini_set_powerstat(AMP *amp, powerstat_t status) { int retval; char *cmd = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } switch (status) { case RIG_POWER_UNKNOWN: break; case RIG_POWER_OFF: cmd = "R0\n"; break; case RIG_POWER_ON: cmd = "LP1\n"; break; case RIG_POWER_OPERATE: cmd = "R1\n"; break; case RIG_POWER_STANDBY: cmd = "R0\n"; break; default: rig_debug(RIG_DEBUG_ERR, "%s invalid status=%d\n", __func__, status); } retval = gemini_transaction(amp, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int gemini_reset(AMP *amp, amp_reset_t reset) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = gemini_transaction(amp, "T\n", NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting RIG_POWER_STANDBY '%s'\n", __func__, strerror(retval)); } // toggling from standby to operate perhaps does a reset retval = gemini_set_powerstat(amp, RIG_POWER_STANDBY); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting RIG_POWER_STANDBY '%s'\n", __func__, strerror(retval)); } return gemini_set_powerstat(amp, RIG_POWER_OPERATE); } hamlib-4.6.5/amplifiers/gemini/Makefile.am0000664000175000017500000000026215056640442014112 SRC = gemini.c GEMINISRC = dx1200.c gemini.h noinst_LTLIBRARIES = libhamlib-gemini.la libhamlib_gemini_la_SOURCES = $(SRC) $(GEMINISRC) EXTRA_DIST = README.gemini Android.mk hamlib-4.6.5/amplifiers/expert/0000775000175000017500000000000015056640503012173 5hamlib-4.6.5/amplifiers/expert/expert.c0000664000175000017500000004457415056640442013606 /* * Hamlib Expert amplifier backend - low level communication routines * Copyright (c) 2023 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "expert.h" #include "register.h" #include "misc.h" struct fault_list { int code; char *errmsg; }; const struct fault_list expert_fault_list [] = { {0, "No fault condition"}, {0x10, "Watchdog Timer was reset"}, {0x20, "PA Current is too high"}, {0x40, "Temperature is too high"}, {0x60, "Input power is too high"}, {0x61, "Gain is too low"}, {0x70, "Invalid frequency"}, {0x80, "50V supply voltage too low or too high"}, {0x81, "5V supply voltage too low or too high"}, {0x82, "10V supply voltage too low or too high"}, {0x83, "12V supply voltage too low or too high"}, {0x84, "-12V supply voltage too low or too high"}, {0x85, "5V or 400V LPF board supply voltages not detected"}, {0x90, "Reflected power is too high"}, {0x91, "SWR very high"}, {0x92, "ATU no match"}, {0xB0, "Dissipated power too high"}, {0xC0, "Forward power too high"}, {0xE0, "Forward power too high for current setting"}, {0xF0, "Gain is too high"}, {0, NULL} }; /* * Initialize data structures */ int expert_init(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } AMPSTATE(amp)->priv = (struct expert_priv_data *) calloc(1, sizeof(struct expert_priv_data)); if (!AMPSTATE(amp)->priv) { return -RIG_ENOMEM; } AMPPORT(amp)->type.rig = RIG_PORT_SERIAL; return RIG_OK; } int expert_open(AMP *amp) { unsigned char cmd = 0x80; unsigned char response[256]; rig_debug(RIG_DEBUG_TRACE, "%s: entered\n", __func__); expert_transaction(amp, &cmd, 1, response, 256); return RIG_OK; } int expert_close(AMP *amp) { unsigned char cmd = 0x81; unsigned char response[256]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); expert_transaction(amp, &cmd, 1, response, 4); if (AMPSTATE(amp)->priv) { free(AMPSTATE(amp)->priv); } AMPSTATE(amp)->priv = NULL; return RIG_OK; } int expert_flushbuffer(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return rig_flush(AMPPORT(amp)); } int expert_transaction(AMP *amp, const unsigned char *cmd, int cmd_len, unsigned char *response, int response_len) { hamlib_port_t *ampp = AMPPORT(amp); int err; int len = 0; char cmdbuf[64]; int checksum = 0; if (cmd) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%80s\n", __func__, cmd); } else { rig_debug(RIG_DEBUG_ERR, "%s: cmd empty\n", __func__); return -RIG_EINVAL; } if (!amp) { return -RIG_EINVAL; } expert_flushbuffer(amp); cmdbuf[0] = cmdbuf[1] = cmdbuf[2] = 0x55; for (int i = 0; i < cmd_len; ++i) { checksum += cmd[i]; } checksum = checksum % 256; cmdbuf[3] = cmd_len; memcpy(&cmdbuf[4], cmd, cmd_len); cmdbuf[3 + cmd_len + 1] = checksum; // Now send our command err = write_block(ampp, (unsigned char *) cmdbuf, 3 + cmd_len + 2); if (err != RIG_OK) { return err; } if (response) // if response expected get it { int bytes = 0; response[0] = 0; // read the 4-byte header x55x55x55xXX where XX is the hex # of bytes len = read_block_direct(ampp, (unsigned char *) response, 4); rig_debug(RIG_DEBUG_ERR, "%s: len=%d, bytes=%02x\n", __func__, len, response[3]); if (len < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=%s\n", __func__, rigerror(len)); return len; } if (len == 4) { bytes = response[3]; } rig_debug(RIG_DEBUG_ERR, "%s: bytes=%d\n", __func__, bytes); len = read_block_direct(ampp, (unsigned char *) response, bytes - 3); dump_hex(response, len); } else // if no response expected try to get one { char responsebuf[KPABUFSZ]; responsebuf[0] = 0; int loop = 3; do { char c = ';'; rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__); err = write_block(ampp, (unsigned char *) &c, 1); if (err != RIG_OK) { return err; } len = read_string(ampp, (unsigned char *) responsebuf, KPABUFSZ, ";", 1, 0, 1); if (len < 0) { return len; } } while (--loop > 0 && (len != 1 || responsebuf[0] != ';')); } return RIG_OK; } /* * Get Info * returns the model name string */ // cppcheck-suppress constParameterCallback const char *expert_get_info(AMP *amp) { const struct amp_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return (const char *) - RIG_EINVAL; } rc = amp->caps; return rc->model_name; } /* Example response 2024-07-09T00:01:58.947563-0500: 0000 aa aa aa 43 2c 31 33 4b 2c 53 2c 52 2c 41 2c 31 ...C,13K,S,R,A,1 2024-07-09T00:01:58.950923-0500: 0010 2c 30 37 2c 32 61 2c 30 72 2c 4d 2c 30 30 30 30 ,07,2a,0r,M,0000 2024-07-09T00:01:58.954332-0500: 0020 2c 20 30 2e 30 30 2c 20 30 2e 30 30 2c 20 30 2e , 0.00, 0.00, 0. 2024-07-09T00:01:58.957544-0500: 0030 30 2c 20 30 2e 30 2c 30 37 37 2c 30 30 30 2c 30 0, 0.0,077,000,0 2024-07-09T00:01:58.959656-0500: 0040 30 30 2c 4e 2c 4e 2c 51 0d 2c 0d 0a 00,N,N,Q.,.. */ int expert_get_freq(AMP *amp, freq_t *freq) { char responsebuf[KPABUFSZ] = "\0"; int retval; unsigned long tfreq; int nargs; unsigned char cmd = 0x90; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } retval = expert_transaction(amp, &cmd, 1, NULL, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^FR%lu", &tfreq); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^FR response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } *freq = tfreq * 1000; return RIG_OK; } int expert_set_freq(AMP *amp, freq_t freq) { char responsebuf[KPABUFSZ] = "\0"; int retval; unsigned long tfreq; int nargs; unsigned char cmd[KPABUFSZ]; rig_debug(RIG_DEBUG_VERBOSE, "%s called, freq=%"PRIfreq"\n", __func__, freq); if (!amp) { return -RIG_EINVAL; } // SNPRINTF(cmd, sizeof(cmd), "^FR%05ld;", (long)freq / 1000); cmd[0] = 0x00; retval = expert_transaction(amp, cmd, 0, NULL, 0); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^FR%lu", &tfreq); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s Error: ^FR response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } if (tfreq * 1000 != freq) { rig_debug(RIG_DEBUG_ERR, "%s Error setting freq: ^FR freq!=freq2, %f=%lu '%s'\n", __func__, freq, tfreq * 1000, responsebuf); return -RIG_EPROTO; } return RIG_OK; } int expert_get_level(AMP *amp, setting_t level, value_t *val) { char responsebuf[KPABUFSZ] = "\0"; unsigned char cmd[8]; int retval; int fault; int i; int nargs; int antenna; int pwrpeak; int pwrref; int pwrfwd; int pwrinput; float float_value = 0; int int_value = 0, int_value2 = 0; struct expert_priv_data *priv = AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // get the current antenna selected cmd[0] = 0x00; retval = expert_transaction(amp, cmd, 0, NULL, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } antenna = 0; nargs = sscanf(responsebuf, "^AE%d", &antenna); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s: invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, antenna=%d\n", __func__, cmd, antenna); switch (level) { case AMP_LEVEL_SWR: cmd[0] = 0x00; break; case AMP_LEVEL_NH: cmd[0] = 0x00; break; case AMP_LEVEL_PF: cmd[0] = 0x00; break; case AMP_LEVEL_PWR_INPUT: cmd[0] = 0x00; break; case AMP_LEVEL_PWR_FWD: cmd[0] = 0x00; break; case AMP_LEVEL_PWR_REFLECTED: cmd[0] = 0x00; break; case AMP_LEVEL_PWR_PEAK: cmd[0] = 0x00; break; case AMP_LEVEL_FAULT: cmd[0] = 0x00; break; } retval = expert_transaction(amp, cmd, 0, NULL, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } switch (level) { case AMP_LEVEL_SWR: //nargs = sscanf(responsebuf, "^SW%f", &float_value); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->f = float_value / 10.0f; return RIG_OK; case AMP_LEVEL_NH: case AMP_LEVEL_PF: //nargs = sscanf(responsebuf, "^DF%d,%d", &int_value, &int_value2); if (nargs != 2) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s freq range=%dKHz,%dKHz\n", __func__, int_value, int_value2); // do { retval = read_string(AMPPORT(amp), (unsigned char *) responsebuf, sizeof(responsebuf), ";", 1, 0, 1); if (retval != RIG_OK) { return retval; } if (strstr(responsebuf, "BYPASS") != 0) { int antenna2 = 0; nargs = sscanf(responsebuf, "AN%d Side TX %d %*s %*s %d", &antenna2, &int_value, &int_value2); rig_debug(RIG_DEBUG_VERBOSE, "%s response='%s'\n", __func__, responsebuf); if (nargs != 3) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s antenna=%d,nH=%d\n", __func__, antenna2, int_value); val->i = level == AMP_LEVEL_NH ? int_value : int_value2; return RIG_OK; } } while (strstr(responsebuf, "BYPASS")); break; case AMP_LEVEL_PWR_INPUT: cmd[0] = 0x00; nargs = sscanf(responsebuf, "^SW%d", &pwrinput); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrinput; return RIG_OK; break; case AMP_LEVEL_PWR_FWD: cmd[0] = 0x00; nargs = sscanf(responsebuf, "^SW%d", &pwrfwd); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrfwd; return RIG_OK; break; case AMP_LEVEL_PWR_REFLECTED: cmd[0] = 0x00; nargs = sscanf(responsebuf, "^SW%d", &pwrref); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrref; return RIG_OK; break; case AMP_LEVEL_PWR_PEAK: cmd[0] = 0x00; nargs = sscanf(responsebuf, "^SW%d", &pwrpeak); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrpeak; return RIG_OK; break; case AMP_LEVEL_FAULT: cmd[0] = 0x00; nargs = sscanf(responsebuf, "^SW%d", &fault); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } for (i = 0; expert_fault_list[i].errmsg != NULL; ++i) { if (expert_fault_list[i].code == fault) { val->s = expert_fault_list[i].errmsg; return RIG_OK; } } rig_debug(RIG_DEBUG_ERR, "%s unknown fault from %s\n", __func__, responsebuf); SNPRINTF(priv->tmpbuf, sizeof(priv->tmpbuf), "Unknown fault code=0x%02x", fault); val->s = priv->tmpbuf; return RIG_OK; break; default: rig_debug(RIG_DEBUG_ERR, "%s unknown level=%s\n", __func__, rig_strlevel(level)); } return -RIG_EINVAL; } int expert_get_powerstat(AMP *amp, powerstat_t *status) { unsigned char responsebuf[KPABUFSZ] = "\0"; int retval; int operate = 0; int ampon = 0; int nargs = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *status = RIG_POWER_UNKNOWN; if (!amp) { return -RIG_EINVAL; } retval = expert_transaction(amp, NULL, 0, responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } //nargs = sscanf(responsebuf, "^ON%d", &on); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } switch (ampon) { case 0: *status = RIG_POWER_OFF; return RIG_OK; case 1: *status = RIG_POWER_ON; break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON unknown response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } retval = expert_transaction(amp, NULL, 0, responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } //nargs = sscanf(responsebuf, "^ON%d", &operate); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } *status = operate == 1 ? RIG_POWER_OPERATE : RIG_POWER_STANDBY; return RIG_OK; } int expert_set_powerstat(AMP *amp, powerstat_t status) { int retval; unsigned char cmd[8]; int cmd_len = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } switch (status) { case RIG_POWER_UNKNOWN: break; case RIG_POWER_OFF: cmd[0] = 0x0a; break; case RIG_POWER_ON: cmd[0] = 0x0b; break; case RIG_POWER_OPERATE: cmd[0] = 0x0d; break; case RIG_POWER_STANDBY: cmd[0] = 0x0a; break; default: rig_debug(RIG_DEBUG_ERR, "%s invalid status=%d\n", __func__, status); cmd[0] = 0x00; } retval = expert_transaction(amp, cmd, cmd_len, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int expert_reset(AMP *amp, amp_reset_t reset) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // toggling from standby to operate supposed to reset retval = expert_set_powerstat(amp, RIG_POWER_STANDBY); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting RIG_POWER_STANDBY '%s'\n", __func__, strerror(retval)); } return expert_set_powerstat(amp, RIG_POWER_OPERATE); } struct expert_priv_data *expert_priv; /* * API local implementation * */ /* * Private helper function prototypes */ /* ************************************* * * Separate model capabilities * * ************************************* */ /* * Expert 1.3K-FA, 1.5K-FA, and 2K-FA */ const struct amp_caps expert_amp_caps = { AMP_MODEL(AMP_MODEL_EXPERT_FA), .model_name = "1.3K-FA/1.5K-FA/2K-FA", .mfg_name = "Expert", .version = "20240709.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 2, // .has_get_level = AMP_LEVEL_SWR | AMP_LEVEL_NH | AMP_LEVEL_PF | AMP_LEVEL_PWR_INPUT | AMP_LEVEL_PWR_FWD | AMP_LEVEL_PWR_REFLECTED | AMP_LEVEL_FAULT, .has_set_level = 0, .amp_open = expert_open, .amp_init = expert_init, .amp_close = expert_close, .reset = expert_reset, .get_info = expert_get_info, .get_powerstat = expert_get_powerstat, .set_powerstat = expert_set_powerstat, // .set_freq = expert_set_freq, // .get_freq = expert_get_freq, .get_level = expert_get_level, }; /* ************************************ * * API functions * * ************************************ */ /* * */ #if 0 // not implemented yet /* * Send command string to amplifier */ static int expert_send_priv_cmd(AMP *amp, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } err = write_block(AMPPORT(amp), cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* * Initialize backend */ DECLARE_INITAMP_BACKEND(expert) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); amp_register(&expert_amp_caps); return RIG_OK; } hamlib-4.6.5/amplifiers/expert/Android.mk0000664000175000017500000000033315056640442014025 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := expert.c LOCAL_MODULE := expert LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/amplifiers/expert/Makefile.in0000664000175000017500000005253015056640452014170 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = amplifiers/expert ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_expert_la_LIBADD = am__objects_1 = expert.lo am__objects_2 = am_libhamlib_expert_la_OBJECTS = $(am__objects_1) $(am__objects_2) libhamlib_expert_la_OBJECTS = $(am_libhamlib_expert_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/expert.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_expert_la_SOURCES) DIST_SOURCES = $(libhamlib_expert_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SRC = expert.c EXPERTSRC = expert.h noinst_LTLIBRARIES = libhamlib-expert.la libhamlib_expert_la_SOURCES = $(SRC) $(EXPERTSRC) EXTRA_DIST = README.expert Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amplifiers/expert/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu amplifiers/expert/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-expert.la: $(libhamlib_expert_la_OBJECTS) $(libhamlib_expert_la_DEPENDENCIES) $(EXTRA_libhamlib_expert_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_expert_la_OBJECTS) $(libhamlib_expert_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expert.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/expert.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/expert.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/amplifiers/expert/expert.h0000664000175000017500000000357715056640442013611 /* * Hamlib backend library for the Expert amplifier set. * * expert.h - (C) Michael Black W9MDB 2023 * * This shared library provides an API for communicating * via serial interface to Expert amplifiers. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_EXPERT_H #define _AMP_EXPERT_H 1 #include #include #include // Is this big enough? #define KPABUFSZ 100 extern const struct amp_caps expert_amp_caps; /* * Private data structure */ struct expert_priv_data { char tmpbuf[256]; // for unknown error msg }; int expert_init(AMP *amp); int expert_close(AMP *amp); int expert_reset(AMP *amp, amp_reset_t reset); int expert_flush_buffer(AMP *amp); int expert_transaction(AMP *amp, const unsigned char *cmd, int cmd_len, unsigned char *response, int response_len); const char *expert_get_info(AMP *amp); int expert_get_freq(AMP *amp, freq_t *freq); int expert_set_freq(AMP *amp, freq_t freq); int expert_get_level(AMP *amp, setting_t level, value_t *val); int expert_get_powerstat(AMP *amp, powerstat_t *status); int expert_set_powerstat(AMP *amp, powerstat_t status); #endif /* _AMP_EXPERT_H */ hamlib-4.6.5/amplifiers/expert/README.expert0000664000175000017500000000022015056640442014275 hamlib - Copyright (C) 2023 The Hamlib Group File: README.expert Notes on Expert backends 2023-03-20 Initial prototype for Expert amplifiers hamlib-4.6.5/amplifiers/expert/Makefile.am0000664000175000017500000000025115056640442014147 SRC = expert.c EXPERTSRC = expert.h noinst_LTLIBRARIES = libhamlib-expert.la libhamlib_expert_la_SOURCES = $(SRC) $(EXPERTSRC) EXTRA_DIST = README.expert Android.mk hamlib-4.6.5/amplifiers/elecraft/0000775000175000017500000000000015056640503012451 5hamlib-4.6.5/amplifiers/elecraft/kpa1500.c0000664000175000017500000000626115056640442013625 /* * Hamlib backend library for the Elecraft KPA1500 command set. * * kpa1500.c - (C) Michael Black W9MDB 2019 * * This shared library provides an API for communicating * to an Elecraft KPA1500 amplifier. * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "register.h" #include "kpa.h" struct kpa_priv_data *kpa1500_priv; /* * API local implementation * */ /* * Private helper function prototypes */ //static int kpa1500_send_priv_cmd(AMP *amp, const char *cmd); //static int kpa1500_flush_buffer(AMP *amp); /* ************************************* * * Separate model capabilities * * ************************************* */ /* * Elecraft KPA1500 */ const struct amp_caps kpa1500_amp_caps = { AMP_MODEL(AMP_MODEL_ELECRAFT_KPA1500), .model_name = "KPA1500", .mfg_name = "Elecraft", .version = "20220710.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 230400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 2, .has_get_level = AMP_LEVEL_SWR | AMP_LEVEL_NH | AMP_LEVEL_PF | AMP_LEVEL_PWR_INPUT | AMP_LEVEL_PWR_FWD | AMP_LEVEL_PWR_REFLECTED | AMP_LEVEL_FAULT, .has_set_level = 0, .amp_open = NULL, .amp_init = kpa_init, .amp_close = kpa_close, .reset = kpa_reset, .get_info = kpa_get_info, .get_powerstat = kpa_get_powerstat, .set_powerstat = kpa_set_powerstat, .set_freq = kpa_set_freq, .get_freq = kpa_get_freq, .get_level = kpa_get_level, }; /* ************************************ * * API functions * * ************************************ */ /* * */ #if 0 // not implemented yet /* * Send command string to amplifier */ static int kpa1500_send_priv_cmd(AMP *amp, const char *cmdstr) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } err = write_block(AMPPORT(amp), cmdstr, strlen(cmdstr)); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* * Initialize backend */ DECLARE_INITAMP_BACKEND(kpa1500) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); amp_register(&kpa1500_amp_caps); return RIG_OK; } hamlib-4.6.5/amplifiers/elecraft/kpa.h0000664000175000017500000000351015056640442013316 /* * Hamlib backend library for the Elecraft amplifier set. * * elecraft.h - (C) Michael Black W9MDB 2019 * * This shared library provides an API for communicating * via serial interface to Elecraft amplifiers. * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_ELECRAFT_H #define _AMP_ELECRAFT_H 1 #include #include #include // Is this big enough? #define KPABUFSZ 100 extern const struct amp_caps kpa1500_amp_caps; /* * Private data structure */ struct kpa_priv_data { char tmpbuf[256]; // for unknown error msg }; int kpa_init(AMP *amp); int kpa_close(AMP *amp); int kpa_reset(AMP *amp, amp_reset_t reset); int kpa_flush_buffer(AMP *amp); int kpa_transaction(AMP *amp, const char *cmd, char *response, int response_len); const char *kpa_get_info(AMP *amp); int kpa_get_freq(AMP *amp, freq_t *freq); int kpa_set_freq(AMP *amp, freq_t freq); int kpa_get_level(AMP *amp, setting_t level, value_t *val); int kpa_get_powerstat(AMP *amp, powerstat_t *status); int kpa_set_powerstat(AMP *amp, powerstat_t status); #endif /* _AMP_ELECRAFT_H */ hamlib-4.6.5/amplifiers/elecraft/Android.mk0000664000175000017500000000035715056640442014311 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := elecraft.c kpa.c kpa1500.c LOCAL_MODULE := elecraft LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib include $(BUILD_STATIC_LIBRARY) hamlib-4.6.5/amplifiers/elecraft/Makefile.in0000664000175000017500000005306515056640452014452 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = amplifiers/elecraft ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_elecraft_la_LIBADD = am__objects_1 = kpa1500.lo am__objects_2 = kpa.lo am_libhamlib_elecraft_la_OBJECTS = $(am__objects_1) $(am__objects_2) libhamlib_elecraft_la_OBJECTS = $(am_libhamlib_elecraft_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/kpa.Plo ./$(DEPDIR)/kpa1500.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_elecraft_la_SOURCES) DIST_SOURCES = $(libhamlib_elecraft_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SRC = kpa1500.c ELECRAFTSRC = kpa.c kpa.h noinst_LTLIBRARIES = libhamlib-elecraft.la libhamlib_elecraft_la_SOURCES = $(SRC) $(ELECRAFTSRC) EXTRA_DIST = README.elecraft Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amplifiers/elecraft/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu amplifiers/elecraft/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ echo rm -f $${locs}; \ $(am__rm_f) $${locs} libhamlib-elecraft.la: $(libhamlib_elecraft_la_OBJECTS) $(libhamlib_elecraft_la_DEPENDENCIES) $(EXTRA_libhamlib_elecraft_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_elecraft_la_OBJECTS) $(libhamlib_elecraft_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kpa.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kpa1500.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/kpa.Plo -rm -f ./$(DEPDIR)/kpa1500.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/kpa.Plo -rm -f ./$(DEPDIR)/kpa1500.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/amplifiers/elecraft/kpa.c0000664000175000017500000003550515056640442013322 /* * Hamlib Elecraft amplifier backend - low level communication routines * Copyright (c) 2019 by Michael Black W9MDB * * * 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.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kpa.h" struct fault_list { int code; char *errmsg; }; const struct fault_list kpa_fault_list [] = { {0, "No fault condition"}, {0x10, "Watchdog Timer was reset"}, {0x20, "PA Current is too high"}, {0x40, "Temperature is too high"}, {0x60, "Input power is too high"}, {0x61, "Gain is too low"}, {0x70, "Invalid frequency"}, {0x80, "50V supply voltage too low or too high"}, {0x81, "5V supply voltage too low or too high"}, {0x82, "10V supply voltage too low or too high"}, {0x83, "12V supply voltage too low or too high"}, {0x84, "-12V supply voltage too low or too high"}, {0x85, "5V or 400V LPF board supply voltages not detected"}, {0x90, "Reflected power is too high"}, {0x91, "SWR very high"}, {0x92, "ATU no match"}, {0xB0, "Dissipated power too high"}, {0xC0, "Forward power too high"}, {0xE0, "Forward power too high for current setting"}, {0xF0, "Gain is too high"}, {0, NULL} }; /* * Initialize data structures */ int kpa_init(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } AMPSTATE(amp)->priv = (struct kpa_priv_data *) calloc(1, sizeof(struct kpa_priv_data)); if (!AMPSTATE(amp)->priv) { return -RIG_ENOMEM; } AMPPORT(amp)->type.rig = RIG_PORT_SERIAL; return RIG_OK; } int kpa_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (AMPSTATE(amp)->priv) { free(AMPSTATE(amp)->priv); } AMPSTATE(amp)->priv = NULL; return RIG_OK; } int kpa_flushbuffer(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return rig_flush(AMPPORT(amp)); } int kpa_transaction(AMP *amp, const char *cmd, char *response, int response_len) { hamlib_port_t *ampp = AMPPORT(amp); int err; int len = 0; int loop; rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s\n", __func__, cmd); if (!amp) { return -RIG_EINVAL; } kpa_flushbuffer(amp); loop = 3; do // wake up the amp by sending ; until we receive ; { char c = ';'; rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__); err = write_block(ampp, (unsigned char *) &c, 1); if (err != RIG_OK) { return err; } len = read_string(ampp, (unsigned char *) response, response_len, ";", 1, 0, 1); if (len < 0) { return len; } } while (--loop > 0 && (len != 1 || response[0] != ';')); // Now send our command err = write_block(ampp, (unsigned char *) cmd, strlen(cmd)); if (err != RIG_OK) { return err; } if (response) // if response expected get it { response[0] = 0; len = read_string(ampp, (unsigned char *) response, response_len, ";", 1, 0, 1); if (len < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, error=%s\n", __func__, rigerror(len)); return len; } rig_debug(RIG_DEBUG_VERBOSE, "%s called, response='%s'\n", __func__, response); } else // if no response expected try to get one { char responsebuf[KPABUFSZ]; responsebuf[0] = 0; loop = 3; do { char c = ';'; rig_debug(RIG_DEBUG_VERBOSE, "%s waiting for ;\n", __func__); err = write_block(ampp, (unsigned char *) &c, 1); if (err != RIG_OK) { return err; } len = read_string(ampp, (unsigned char *) responsebuf, KPABUFSZ, ";", 1, 0, 1); if (len < 0) { return len; } } while (--loop > 0 && (len != 1 || responsebuf[0] != ';')); } return RIG_OK; } /* * Get Info * returns the model name string */ // cppcheck-suppress * const char *kpa_get_info(AMP *amp) { const struct amp_caps *rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return (const char *) - RIG_EINVAL; } rc = amp->caps; return rc->model_name; } int kpa_get_freq(AMP *amp, freq_t *freq) { char responsebuf[KPABUFSZ]; int retval; unsigned long tfreq; int nargs; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } retval = kpa_transaction(amp, "^FR;", responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^FR%lu", &tfreq); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^FR response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } *freq = tfreq * 1000; return RIG_OK; } int kpa_set_freq(AMP *amp, freq_t freq) { char responsebuf[KPABUFSZ] = "\0"; int retval; unsigned long tfreq; int nargs; char cmd[KPABUFSZ]; rig_debug(RIG_DEBUG_VERBOSE, "%s called, freq=%"PRIfreq"\n", __func__, freq); if (!amp) { return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "^FR%05ld;", (long)freq / 1000); retval = kpa_transaction(amp, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^FR%lu", &tfreq); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s Error: ^FR response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } if (tfreq * 1000 != freq) { rig_debug(RIG_DEBUG_ERR, "%s Error setting freq: ^FR freq!=freq2, %f=%lu '%s'\n", __func__, freq, tfreq * 1000, responsebuf); return -RIG_EPROTO; } return RIG_OK; } int kpa_get_level(AMP *amp, setting_t level, value_t *val) { char responsebuf[KPABUFSZ]; char *cmd; int retval; int fault; int i; int nargs; int antenna; int pwrpeak; int pwrref; int pwrfwd; int pwrinput; float float_value = 0; int int_value = 0, int_value2 = 0; struct kpa_priv_data *priv = AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // get the current antenna selected cmd = "^AE;"; retval = kpa_transaction(amp, cmd, responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } antenna = 0; nargs = sscanf(responsebuf, "^AE%d", &antenna); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s: invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, antenna=%d\n", __func__, cmd, antenna); switch (level) { case AMP_LEVEL_SWR: cmd = "^SW;"; break; case AMP_LEVEL_NH: cmd = "^DF;"; break; case AMP_LEVEL_PF: cmd = "^DF;"; break; case AMP_LEVEL_PWR_INPUT: cmd = "^PWI;"; break; case AMP_LEVEL_PWR_FWD: cmd = "^PWF;"; break; case AMP_LEVEL_PWR_REFLECTED: cmd = "^PWR;"; break; case AMP_LEVEL_PWR_PEAK: cmd = "^PWK;"; break; case AMP_LEVEL_FAULT: cmd = "^SF;"; break; } retval = kpa_transaction(amp, cmd, responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } switch (level) { case AMP_LEVEL_SWR: nargs = sscanf(responsebuf, "^SW%f", &float_value); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->f = float_value / 10.0f; return RIG_OK; case AMP_LEVEL_NH: case AMP_LEVEL_PF: nargs = sscanf(responsebuf, "^DF%d,%d", &int_value, &int_value2); if (nargs != 2) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s freq range=%dKHz,%dKHz\n", __func__, int_value, int_value2); // do { retval = read_string(AMPPORT(amp), (unsigned char *) responsebuf, sizeof(responsebuf), ";", 1, 0, 1); if (retval != RIG_OK) { return retval; } if (strstr(responsebuf, "BYPASS") != 0) { int antenna2 = 0; nargs = sscanf(responsebuf, "AN%d Side TX %d %*s %*s %d", &antenna2, &int_value, &int_value2); rig_debug(RIG_DEBUG_VERBOSE, "%s response='%s'\n", __func__, responsebuf); if (nargs != 3) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s antenna=%d,nH=%d\n", __func__, antenna2, int_value); val->i = level == AMP_LEVEL_NH ? int_value : int_value2; return RIG_OK; } } while (strstr(responsebuf, "BYPASS")); break; case AMP_LEVEL_PWR_INPUT: cmd = "^PWI;"; nargs = sscanf(responsebuf, "^SW%d", &pwrinput); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrinput; return RIG_OK; break; case AMP_LEVEL_PWR_FWD: cmd = "^PWF;"; nargs = sscanf(responsebuf, "^SW%d", &pwrfwd); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrfwd; return RIG_OK; break; case AMP_LEVEL_PWR_REFLECTED: cmd = "^PWR;"; nargs = sscanf(responsebuf, "^SW%d", &pwrref); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrref; return RIG_OK; break; case AMP_LEVEL_PWR_PEAK: cmd = "^PWK;"; nargs = sscanf(responsebuf, "^SW%d", &pwrpeak); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } val->i = pwrpeak; return RIG_OK; break; case AMP_LEVEL_FAULT: cmd = "^SF;"; nargs = sscanf(responsebuf, "^SW%d", &fault); if (nargs != 1) { rig_debug(RIG_DEBUG_ERR, "%s invalid value %s='%s'\n", __func__, cmd, responsebuf); return -RIG_EPROTO; } for (i = 0; kpa_fault_list[i].errmsg != NULL; ++i) { if (kpa_fault_list[i].code == fault) { val->s = kpa_fault_list[i].errmsg; return RIG_OK; } } rig_debug(RIG_DEBUG_ERR, "%s unknown fault from %s\n", __func__, responsebuf); SNPRINTF(priv->tmpbuf, sizeof(priv->tmpbuf), "Unknown fault code=0x%02x", fault); val->s = priv->tmpbuf; return RIG_OK; break; default: rig_debug(RIG_DEBUG_ERR, "%s unknown level=%s\n", __func__, rig_strlevel(level)); } return -RIG_EINVAL; } int kpa_get_powerstat(AMP *amp, powerstat_t *status) { char responsebuf[KPABUFSZ]; int retval; int operate; int ampon; int nargs; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *status = RIG_POWER_UNKNOWN; if (!amp) { return -RIG_EINVAL; } retval = kpa_transaction(amp, "^ON;", responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^ON%d", &on); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } switch (ampon) { case 0: *status = RIG_POWER_OFF; return RIG_OK; case 1: *status = RIG_POWER_ON; break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON unknown response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } retval = kpa_transaction(amp, "^OP;", responsebuf, sizeof(responsebuf)); if (retval != RIG_OK) { return retval; } nargs = sscanf(responsebuf, "^ON%d", &operate); if (nargs != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s Error: ^ON response='%s'\n", __func__, responsebuf); return -RIG_EPROTO; } *status = operate == 1 ? RIG_POWER_OPERATE : RIG_POWER_STANDBY; return RIG_OK; } int kpa_set_powerstat(AMP *amp, powerstat_t status) { int retval; char *cmd = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!amp) { return -RIG_EINVAL; } switch (status) { case RIG_POWER_UNKNOWN: break; case RIG_POWER_OFF: cmd = "^ON0;"; break; case RIG_POWER_ON: cmd = "^ON1;"; break; case RIG_POWER_OPERATE: cmd = "^OS1;"; break; case RIG_POWER_STANDBY: cmd = "^OS0;"; break; default: rig_debug(RIG_DEBUG_ERR, "%s invalid status=%d\n", __func__, status); } retval = kpa_transaction(amp, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int kpa_reset(AMP *amp, amp_reset_t reset) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // toggling from standby to operate supposed to reset retval = kpa_set_powerstat(amp, RIG_POWER_STANDBY); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting RIG_POWER_STANDBY '%s'\n", __func__, strerror(retval)); } return kpa_set_powerstat(amp, RIG_POWER_OPERATE); } hamlib-4.6.5/amplifiers/elecraft/README.elecraft0000664000175000017500000000021215056640442015032 hamlib - Copyright (C) 2019 The Hamlib Group File: README.elecraft Notes on Elecraft backends 2019-06-25 Initial prototype for KPA1500 hamlib-4.6.5/amplifiers/elecraft/Makefile.am0000664000175000017500000000026715056640442014434 SRC = kpa1500.c ELECRAFTSRC = kpa.c kpa.h noinst_LTLIBRARIES = libhamlib-elecraft.la libhamlib_elecraft_la_SOURCES = $(SRC) $(ELECRAFTSRC) EXTRA_DIST = README.elecraft Android.mk hamlib-4.6.5/README.developer0000664000175000017500000007532715056640442011335 Hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) (C) Stephane Fillod 2000-2011 (C) The Hamlib Group 2000-2025 Primary site for the latest development version of Hamlib is https://github.com/Hamlib/Hamlib Also take a look at http://sourceforge.net/projects/hamlib/ Here you will find a mail list, and the latest releases. See README.md for frontend/backend outline. See README.betatester for background on testing Hamlib. The library provides functions for both radio, rotator, and amplifier control, and data retrieval from the radio, rotator, or amplifier. A number of functions useful for calculating distance and bearing and grid square conversion are included. libhamlib.so - library that provides generic API for all RIG types. This is what Application programmers will "see". Will have different names on other platforms, e.g. libhamlib-2.dll on MS windows. Also contains all radio, rotator, and amplifier "backends" (formerly in their own dlopen'ed libraries) provided by Hamlib. Backend Examples are: --------------------- 1. yaesu will provide connectivity to Yaesu FT 747GX Transceiver, FT 847 "Earth Station", etc. via a standard API. 2. xxxx. will provide connectivity to the Wiz-bang moon-melter 101A (yikes..) Hamlib also enables developers to develop professional looking GUI's towards a standard control library API, and they would not have to worry about the underlying connection towards physical hardware. Serial (RS232) connectivity is built in as are RPC, IP (also via a socket utility), and USB. Other connectivity will follow afterwards. General Guidelines. ------------------- 0. The top level directory looks like this as of 2025-05-03 $ tree -d -I .git . . ├── amplifiers │   ├── elecraft │   ├── expert │   └── gemini ├── android ├── autom4te.cache ├── bindings │   └── csharp │   └── multicast ├── build-aux ├── c++ ├── doc │   ├── man1 │   ├── man7 │   └── manuals ├── docker-build ├── extra │   ├── gnuradio │   └── kylix │   └── tests ├── include │   └── hamlib ├── lib ├── macros ├── perl ├── rigs │   ├── adat │   ├── alinco │   ├── anytone │   ├── aor │   ├── barrett │   ├── codan │   ├── commradio │   ├── dorji │   ├── drake │   ├── dummy │   ├── elad │   ├── flexradio │   ├── gomspace │   │   └── gs100_sim │   ├── icmarine │   ├── icom │   ├── jrc │   ├── kachina │   ├── kenwood │   ├── kit │   ├── lowe │   ├── mds │   ├── motorola │   ├── pcr │   ├── prm80 │   ├── racal │   ├── rft │   ├── rs │   ├── skanti │   ├── tapr │   ├── tentec │   ├── tuner │   ├── uniden │   ├── winradio │   │   └── linradio │   ├── wj │   └── yaesu ├── rotators │   ├── amsat │   ├── androidsensor │   ├── apex │   ├── ars │   ├── celestron │   ├── cnctrk │   ├── easycomm │   ├── ether6 │   ├── flir │   ├── fodtrack │   ├── grbltrk │   ├── gs232a │   ├── heathkit │   ├── indi │   ├── ioptron │   ├── m2 │   ├── meade │   ├── prosistel │   ├── radant │   ├── rotorez │   ├── saebrtrack │   ├── sartek │   ├── satel │   ├── skywatcher │   ├── spid │   └── ts7400 │   └── include ├── scripts │   └── MSVC ├── security ├── simulators ├── src └── tests ├── config ├── rigctl.test ├── testbcd.test ├── testfreq.test └── testloc.test 103 directories 1. Building If you just want to recompile the library, please refer to the INSTALL file. This document introduces hacking the code of Hamlib. 1.1 Obtaining sources: git clone git clone git://git.code.sf.net/p/hamlib/code hamlib The clone has to only be done the first time. After the initial clone, whenever you want to update your local repository, issue the following command in the root directory of Hamlib: git pull This will download and merge any changes from the canonical Hamlib Git repository (what Git calls origin by default). This command actually combines two Git commands, fetch and merge into one that will first check for conflicting changes between your local repository and the remote (origin) repository and will not apply any changes if conflicts are found. A pull can be restricted to just a single branch if desired: git pull origin master 1.1.1 Obtaining more info on Git Check out the Source Forge page at https://sourceforge.net/scm/?type=git&group_id=8305 for more information about how to use the Git repository of Hamlib. Much documentation on Git exists. A good starting point is: http://git-scm.com/documentation From this page are links to tutorials, books (Pro Git proved useful for me), and references (http://gitref.org/ is another good resource). Another site: http://www-cs-students.stanford.edu/~blynn/gitmagic/ 1.1.2 Providing patches with Git Git provides tools to generate patches and submit them to the Hamlib developers via email. Use of these tools is preferred as Git allows credit to be given to the author and submitter of the patches. Please submit the patches to the hamlib-developer mailing list. See section 8.3. 1.1.3 Git and branches One of the most powerful features of Git is its ability to make working with branches easy. It also allows the developers to "cherry pick" patches from the master development branch into stable release branches. In this manner we can accommodate patches submitted against a stable release and merge them into master as well. Such parallel development is a new feature for our project and there will be a learning curve! After cloning the repository as above, the repository is synchronized with the "master" branch. This can be confirmed by 'git branch'. A new branch can be created by providing a name, 'git branch n0nb_k3_level' which will now exist as a branch in your local repository. This is a good way to work on new features as Git keeps changes to files in each branch separate. As you can see: $ git branch Hamlib-1.2.13 Hamlib-1.2.13.1 * master n0nb_k3 there are a number of branches in my local repository. Most, such as "Hamlib-1.2.13", exist in the canonical repository as well. They can be seen by 'git branch -r' and you can switch to any of them using the 'git checkout BRANCH_NAME' command. Finally, once your changes are ready for inclusion in Hamlib, commit your changes to the branch you are working in, checkout the master branch, and use 'git merge' to synchronize your changes into the master branch. Lastly, push your changes to the canonical repository (developer write access and checkout using the SSH protocol required. See https://sourceforge.net/scm/?type=git&group_id=8305) or email them to hamlib-developer@lists.sourceforge.net for inclusion into Hamlib. 1.1.4 Summary This is a very brief introduction to Git for Hamlib developers. Day-to-day Git usage involves a handful of commands--clone, status, commit, pull, branch, checkout, merge, and push are probably the most common. Other useful commands are log and diff to see changes (especially when color output is enabled in your Git configuration). See the references above to learn about setting up Git to your preference. If you like a GUI tool several exist. Gitk and Gitg are similar with the former being written with the Tk toolkit and the latter in GTK+. Another is Giggle with its own interface. All allow looking at the complete history of the repository and changes made to any file. 1.2. Requirements Hamlib is entirely developed using GNU tools, under various Linux systems. Note that Hamlib is not restricted to Linux systems. We welcome anyone who has access to a POSIXish system to port Hamlib. Contact us for help. That is, if you want to take part in the development of Hamlib, you'll need the following tools. Make sure you have at least the required version or you won't even be able to build from the Git clone. N.B. The Debian and derivatives (Ubuntu and friends) 'build-essential' package will install a number of tools and minimize the number of packages that need to be installed manually (Debian package names are listed, other distributions may differ). * Gnu C or any C99 compliant compiler # gcc --version * Gnu make (or any modern one, BSD okay) # make --version * autoconf 2.67 # autoconf --version * automake 1.11 # automake --version * libtool 2.2.6b+ # libtool --version * Git for connection to git.code.sf.net/p/hamlib/code N.B. Hamlib requires libtool >= 2.2.6b in compliance with CVE-2009-3736. Optional, but highly recommended: * GNU C++ # g++ --version * swig (for bindings) # swig -version * perl devel # h2xs * tcl devel # tcltk-depends * python devel # python-config * lua devel * libxml2 devel # xml2-config --version * libgd2 devel # gdlib-config --version (rigmatrix) * libindi devel # INDI rotators * libnova devel * libusb-1.0 devel # 1.0.0 or newer * libreadline devel # ver 5.2 or newer * pkg-config # pkg-config --version (libxml and USRP) * zlib1g devel # (rigmatrix) N.B.: The libusb-1.0 package is required for building most of the 'kit' backend. The older version of libusb 0.1.x is no longer supported. N.B.: Some systems can have several versions of the autotools installed. In that case, autoconf may be called "autoconf2.59", autoheader "autoheader2.59", and automake "automake-1.9", aclocal "aclocal-1.9" or a newer version. IMPORTANT: If autoconf or automake are installed on your system, make sure they are matching *at least* the version shown above. 1.3. configure and build stage It is important to note that the Git repository holds no Autotools generated files, i.e. configure, config.guess, Makefile, etc. Hence after a fresh checkout, you'll have to generate those files. To proceed, first edit the bootstrap script, and set appropriately the AUTORECONF, AUTOMAKE, and LIBTOOLIZE variables with the required versions seen in the previous section (most systems will be fine with the default names, only do this if a problem arises and please let us know). cd hamlib ./bootstrap ./configure [CFLAGS="-g -O0"] make make install Note: Depending on the value of '--prefix' passed to 'configure', superuser (root) privileges may be needed for 'make install'. If you don't want the build files cluttering the source directories, do the following in the same parent directory of hamlib: mkdir build && cd build ../hamlib/bootstrap ../hamlib/configure [CFLAGS="-g -O0"] make make install Note: In the examples above, passing the CFLAGS environment variable is optional as shown using the square brackets.. This will keep the binary output files separate from the source tree and aid in development by reducing clutter in the source tree. Once you've run 'bootstrap', make sure you've got some recent config.guess and config.sub (needed to guess your system type). Anything of at least year 2004 should be fine, unless you run some exotic hardware/software system (modern Linux distributions and Cygwin keep these up to date): ./config.guess --version ./config.sub --version The '--prefix' option to 'configure' is optional and not shown as it defaults to /usr/local. Convention is that locally built packages be installed in /usr/local away from distribution installed packages. The 'CFLAGS="-g -O0"' environment variable generates less optimized binaries with the '-O0' while the '-g' option adds debugging info which can be changed to -ggdb to generate debugging info for gdb. Additionally, you may want to add the '--with-perl-binding' or '--with-python-binding' or '--with-tcl-binding' or '--with-lua-binding' if you are interested in SWIG binding support for those scripting languages. For LUA bindings if you run "lua luatest.lua" and see this error message: luatest.lua:44: Error in Rig::set_mode (arg 2), expected 'rmode_t' got 'string' This means you need to upgrade both swig and lua for 64-bit lua support This is known to work on swig 4.0.1 and lua 5.3.5 NOTE: The bootstrap script has only to be run the first time after a fresh checkout or when a Makefile.am or other build file is modified or added. For a Tcl build, add this if needed: --with-tcl=/usr/lib/tcl8.2 Note: C-shell users may have to run bootstrap and make through a bourne shell instead, or pass "SHELL=bash" as a parameter to make. Some basic testing is accomplished with the 'make check' target which will run a few predetermined tests using the 'dummy' (rig model 1) backend and some other Hamlib functions in the build tree. This is a basic sanity check and cannot test all backends. Likewise, a complete test of the build system is accomplished with 'make distcheck' which exercises a complete build sequence from creating a distribution tarball, building, installing, uninstalling, and cleaning Hamlib. All packages listed above except for Swig and Doxygen are required for this target as neither the bindings or old documentation are generated in a default build. NOTE! If Hamlib has not been previously installed as a locally built package you will need to make sure that 'ldconfig' is configured correctly and run periodically after 'make install'. Most modern distributions have an /etc/ld.so.conf.d/ directory where local configuration can be made. Later versions of Debian and derivatives have a file named 'libc.conf' in this directory. The contents of libc.conf are: # libc default configuration /usr/local/lib If your system does not have such a file, one will need to be created and then 'ldconfig' will need to be run as the root user so that applications using the Hamlib libraries can find them. 1.3.1 Doxygen generated reference manual The following packages need to be installed: * Doxygen * GNU Source-highlight 1.3.1.1 HTML manual In the top level of the build directory: cd doc make doc will build the HTML manual. The resulting 'doc/html' directory contains all of the files needed for the HTML manual. The 'index.html' file is the entry point to the manual. 1.3.1.2 PDF manual To generate the PDF version of the reference manual the following texlive packages are required (Debian package names shown): * texlive-latex-base * texlive-latex-recommended * texlive-latex-extra Set GENERATE_LATEX in 'doc/hamlib.cfg.in' to 'YES' which will enable the LaTEX build. Then run: make doc as above and once the run is complete: cd latex make The resulting generated document in the 'latex' directory is 'refman.pdf'. 1.4. Feedback The Hamlib team is very interested to hear from you, how Hamlib builds and works on your system, especially on non-Linux or non-PC systems. We are trying to make Hamlib as portable as possible. Please report problems to our developer mailing list, hamlib-developer@lists.sourceforge.net Patches are welcome too! Just send them to the mailing list. Git formatted patches are preferred. Unified diff format (diff -u) is also welcome. Patches should apply to the current Git master branch or a testing branch, if possible. If you're patching against an older released version of Hamlib, we can take those as well but please document the release the diff is generated against. So far, Hamlib has been tested successfully under the following systems: (if your system is not present, please report to the mailing list) * Debian i386 (plus derivatives--Ubuntu, etc.) * Debian sid mipsel * Raspbian armhf (Raspberry Pi Debian derivative) * RedHat i386 * Linux ppc * Slackware i386 * FreeBSD & NetBSD * Solaris 2.6 * Mac OS X * MS Windows: Cygwin, Mingw 2. How to add a new backend The rule is one backend per protocol family. Try to share code between rigs of the same family, if applicable. The steps in Section 3 below will need to be followed as well. Version numbers used are in the form YYYYMMDD.N where the .N is intended for multiple versions in one day....so typically would be .0 2.1. mkdir mybackend Create a new subdir, of the name of the protocol backend. NB: the directory MUST be the same as the backend name. 2.2. Add to the DIST_SUBDIRS variable in the topdir Makefile.am (not needed for rotators) 2.3. Add the backend name to the BACKEND_LIST variable (add to ROT_BACKEND_LIST for a new rotor backend or to AMP_BACKEND_LIST for a new amplifier) in configure.ac. 2.4. Add "mybackend/Makefile" in the AC_CONFIG_FILES macro at the bottom of configure.ac. 2.5. Add DEFINE_INITRIG_BACKEND(mybackend); to the end of the existing list in src/register.c or, for a new rotor backend, add DEFINE_INITROT_BACKEND(myrotbackend); to src/rot_reg.c. 2.6. Add { RIG_MYBACKEND, RIG_BACKEND_MYBACKEND, RIG_FUNCNAM(mybackend) }, to the rig_backend_list structure in src/register.c or, add { ROT_MYROTBACKEND, ROT_BACKEND_MYROTBACKEND, ROT_FUNCNAMA(myrotbackend) }, to the rot_backend_list structure in src/rot_reg.c. { AMP_MYAMPBACKEND, AMP_BACKEND_MYAMPBACKEND, AMP_FUNCNAMA(myaotbackend) }, to the aot_backend_list structure in src/amp_reg.c. 2.7. Add the new backend to include/hamlib/riglist.h or include/hamlib/rotlist.h or include/hamlib/amplist.h by selecting the next higher backend ID number. 2.8. Create mybackend/Makefile.am, mybackend.c mybackend.h Use 'dummy' backend as a template. Here are commands for the bourne shell: $ automake mybackend/Makefile $ CONFIG_HEADERS= CONFIG_LINKS= CONFIG_FILES=mybackend/Makefile ./config.status make in topdir to rebuild all 2.9. Commit your work to your local repository. (developer access to Hamlib Git required for pushing to the canonical Hamlib repository (origin)) Provide patches to the mailing list: (Please let N0NB know if the commands below are incorrect) $ git status # Show uncommitted/staged/unstaged files $ git add mybackend $ cd mybackend (The following command might not be necessary) $ git add Makefile.am mybackend.c mybackend.h While specifying each file individually as above allows for fine- grained control, git offers a wildcard shortcut to add all new files: $ git add . Be careful! If you have other files that were created as part of the build process, this command will add them too unless they match a pattern in .gitignore. Always check with 'git status' first! $ git commit -m "Initial release" Makefile.am mybackend.c mybackend.h Note: The '-m' switch passes a short message to the Git repository upon a commit. If a longer message is desired, do not use the '-m' option. The editor specified in the EDITOR or VISUAL environment variables will be started where a more detailed message may be composed. 2.10 If you have developer access to the Git repository hosted at Source Forge, you can do the following: $ git push origin Your changes will now be available to others. 3. How to add a new model to an existing backend 3.1. make sure there's already a (unique) ID for the model to be added in include/hamlib/riglist.h or include/hamlib/rotlist.h or include/hamlib/amplist.h 3.2. locate the existing backend 3.3. Clone the most similar model in the backend 3.4. Add the new C file to the _SOURCES variable of the backend's Makefile.am 3.5. Add "extern const struct rig_caps _caps;" to mybackend.h 3.6. In initrigs_ of mybackend.c, add "rig_register(&_caps);" 3.7. Run 'make' if you have dependencies, or the following to regenerate the makefile: $ automake mybackend/Makefile $ CONFIG_HEADERS= CONFIG_LINKS= CONFIG_FILES=mybackend/Makefile ./config.status Run 'make' in topdir to rebuild all. 3.8. Commit your work (once tests are satisfactory): $ git add . $ git commit -m "added to ". Note: See Note in section 2.6 above. Note: The '.' character is a Git wildcard that includes all new and modified files in your working tree. The '-m' option may be omitted, in which case Git will start your default editor for a longer commit message. Commit messages generally have the form of a short subject line, then a blank line, and then as much text (broken into paragraphs as needed) as needed for a good description of the commit. Assuming your working tree was cloned from the SF.net repository or N0NB's GitHub repository, you can now issue a pull request inclusion of your new model into Hamlib. 4. Read README.betatester to test the new backend/model. Report to mailing list. 5. Basic functions: set/get_freq, set/get_mode, and set/get_vfo would be a good starting point for your new backend. 6. C code examples. A C code snippet to connect to a FT847 and set the frequency of the main VFO to 439,700,000 Hz, using FM as the required mode, would look something like this. The error checking is removed for simplicity. See tests/testrig.c 7. Where are the GUI's? "Build it and they will come ..." Seriously, I am hoping the API's will provide a solid framework for some cool GUI development. I would like to see some GTK or Qt apps that use the hamlib API's so they can be used by end users as a nice part of the Ham shack. Starting points (not exhaustive): Fldigi, CQRlog, gmfsk, gpredict, grig, klog, kontakt, ktrack, xlog 8. Contributing code 8.1 License Contributed code to the Hamlib frontend must be released under the LGPL. Contributed code to Hamlib backends must follow backend current license. Needless to say, the LGPL is the license of choice. End user applications like rigctl, rotctl, ampctl and networked daemons should be released under the GPL, so any contributed code must follow the license. 8.2 Coding guidelines and style For specific requirements for formatting the C source code, see README.coding_style. Any header files included from the hamlib/ directory should be enclosed in '<>': #include # Per GNU GCC documentation Other included header files (backend and rig specific headers) should be enclosed in "": #include "yaesu.h" Contributed code should always keep the source base in a compilable state, and not regress unless stated otherwise. There's no need to tag the source in a patch with your name in comments behind each modification, we already know the culprit from commit logs (also see "git blame"). :-) Patches should take portability issues into account. Keep in mind Hamlib has to run under: * various Linux's * NetBSD, FreeBSD * MacOS X * Windows: MinGW/Cygwin, and VisualC++ support for rig.h Hamlib should also compile with the following common compilers: * gcc-3.0 and gcc-3.2+ (nearly deprecated?) * gcc-4.x and newer * in shared and static * C++ compiler against rig.h, riglist.h, rotator.h, amplifier.h * clang compiler Portability issues to watch: * C99 is probably (in 2016) a reasonable target * little vs. big endian systems (use shifts or adhoc functions) * 64 bit int: avoid them in API * printf/scanf of 64bit int: use PRIll (cast value to int64_t) and SCNll * printf/scanf of freq_t: use PRIfreq and SCNfreq Testing: * The acid test for the build system is 'make distcheck' which will make a distribution tarball, extract, configure, and build it in a subdirectory, run 'make check', install it, uninstall it, and clean it up. When all those tests pass, the GNU build system declares the package ready for distribution. This is a good test if you have touched the build system files or added a backend. Simulators: * The 'simulators' directory contains programs to simulate the protocol of many devices. They are built invoking "make -C simulators/ check" or "make check" from topdir. While simulators are made to test Hamlib with rigctl and rigctld, you should be able to guess the model number that corresponds to a given simulator and configure an application such as wsjtx to use that model and the port name printed by the simulator, as shown in the examples below. To use a simulator on *nix-like systems, run its executable and take note of the port name: $ ./simulators/simft991 name=/dev/pts/6 then from another terminal run rigctl/rigctld using that port and a matching model number (see rigctl --list): $ ./tests/rigctl --model=1035 --rig-file=/dev/pts/6 \get_freq 14074000 To use a simulator on Windows, first install a virtual COM port, then run the simulator passing the port name as first and only argument: > simulators\simft991 COM1234 then from another command prompt run rigctl/rigctld or your application. The COM port argument is currently ignored on *nix but it can be handled if there is a need to test a low level issue with RS-232 and/or USB communication, if your machine has the needed hardware. 8.2.1 Use of rig_debug() function Hamlib provides a debugging aid in the form of the rig_debug() function, It is essentially a wrapper around printf() and takes many of the same flags and conversion specifiers as the C library's various printf() functions. It adds an additional parameter for specifying the desired debug level for the output string. Six levels of debugging are defined in include/hamlib/rig.h and they are: NONE No bug reporting BUG Serious bug ERR Error case (e.g. protocol, memory allocation) WARN Warning VERBOSE Verbose TRACE Tracing They correspond to the use of the -v switch (from no -v switch to -vvvvv) to rigctl's command line. Hamlib applications can also set the debug level via the Hamlib API. From an application's perspective, setting a specific level includes all messages at that level and all at any lower level. In the library, passing RIG_DEBUG_ERR to rig_debug() limits display of that message to a level setting of ERR or any higher level. In this case if the application sets the message level to RIG_DEBUG_INFO, the message will not be seen. Use of a given level can show the value of a critical variable without the need of a TRACE level message where it can get lost in the stream of output produced by low-level Hamlib functions. Here are my (N0NB's) suggested use of rig_debug() levels in backends. * Many backend functions should have an initial call to rig_debug() as follows: rig_debug(RIG_DEBUG_VERBOSE, "%s() entered\n", __func__); The use of RIG_DEBUG_VERBOSE allows tracking the chain of function calls through the backend while still keeping rigctl's output mostly uncluttered by use of the -vvvv switch. * Developers will want to call rig_debug() to display values of critical variable(s) in a backend function. For this RIG_DEBUG_VERBOSE (rigctl -vvvv) should be a good choice as the output won't be lost in the stream of RIG_DEBUG_TRACE (rigctl -vvvvv) level output by various low-level Hamlib functions. It will also match the display of the values of critical variable(s) with the function calls as above. * Use RIG_DEBUG_TRACE when it makes sense to see the variable(s) in the context of a lot of low-level debugging output (rigctl -vvvvv). * Lower levels (BUG, ERR, and WARN) should be used where it makes sense that information be printed when the user selects less verbosity. Use sparingly. Many backends do not conform to this suggestion at the moment. The use of the RIG_DEBUG_LEVEL values has been somewhat haphazard (at least by this scribe) so fixing these when working in a given backend is encouraged. If an application sets the debugging level to RIG_DEBUG_NONE, then rig_debug() functions will produce no output. Therefore rig_debug() cannot be counted on to output a message in all runtime cases. The debugging levels may be an area for consideration in Hamlib 3. 8.3 Submitting patches Git provides tools to generate patches and submit them to the Hamlib developers via email. Use of these tools is preferred as Git allows credit to be given to the author and submitter of the patches. Alternately, patches can be submitted in unified format (diff -u), against the Git master branch or a given release (please note well which one!). Both formats make patches easily readable. The patches are to be sent to the hamlib-developer mailing list (hamlib-developer@lists.sourceforge.net). If the file is too big, you can send it as a compressed attachment. 8.3.1 Changelog A ChangeLog file is no longer manually maintained. At some point it may be automatically generated from the Git commit log for source tarballs. Simply summarize your changes when the files are committed to Git or, if providing patches to the mailing list, provide a summary so the uploader can include it in the commit message which will show in the commit log (Git formatted emails will include this already). 8.4 Git commit access Generally, volunteers can get commit access to the SourceForge Hamlib Git repository upon asking one of the project administrators. Sometimes we'll ask you! However, before your start committing, the project admins would like first to have a look at your "style", just to make sure you grok the Hamlib approach (c.f. previous section on submitting a patch). Then you'll be able to commit by yourself to the backend you chose to maintain. Please follow the rules hereunder: * Always keep the Git repository (all branches) in a compilable state. * Follow the coding guidelines * Touching the frontend (files in src/ and include/hamlib) always requires discussion beforehand on the hamlib-developer list. * Announce on the hamlib-developer list if you're about to do serious maintenance work Thanks for contributing and have fun! Stephane Fillod f8cfe and The Hamlib Group hamlib-4.6.5/build-aux/0000775000175000017500000000000015056640475010433 5hamlib-4.6.5/build-aux/depcomp0000755000175000017500000005621715056640452011734 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2024-06-19.01; # UTC # Copyright (C) 1999-2024 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v | --v*) echo "depcomp (GNU Automake) $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interference from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsolete pre-3.x GCC compilers. ## but also to in-use compilers like IBM xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/missing0000755000175000017500000001706015056640452011747 #! /bin/sh # Common wrapper for a few potentially missing GNU and other programs. scriptversion=2024-06-07.14; # UTC # shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells # Copyright (C) 1996-2024 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autogen autoheader autom4te automake autoreconf bison flex help2man lex makeinfo perl yacc Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Report bugs to . GNU Automake home page: . General help using GNU software: ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing (GNU Automake) $scriptversion" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake|autoreconf) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; *) : ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" autoheader_deps="'acconfig.h'" automake_deps="'Makefile.am'" aclocal_deps="'acinclude.m4'" case $normalized_program in aclocal*) echo "You should only need it if you modified $aclocal_deps or" echo "$configure_deps." ;; autoconf*) echo "You should only need it if you modified $configure_deps." ;; autogen*) echo "You should only need it if you modified a '.def' or '.tpl' file." echo "You may want to install the GNU AutoGen package:" echo "<$gnu_software_URL/autogen/>" ;; autoheader*) echo "You should only need it if you modified $autoheader_deps or" echo "$configure_deps." ;; automake*) echo "You should only need it if you modified $automake_deps or" echo "$configure_deps." ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." ;; autoreconf*) echo "You should only need it if you modified $aclocal_deps or" echo "$automake_deps or $autoheader_deps or $automake_deps or" echo "$configure_deps." ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; perl*) echo "You should only need it to run GNU Autoconf, GNU Automake, " echo " assorted other tools, or if you modified a Perl source file." echo "You may want to install the Perl 5 language interpreter:" echo "<$perl_URL>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac program_details "$normalized_program" } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/test-driver0000755000175000017500000001213715056640452012546 #! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2024-06-19.01; # UTC # Copyright (C) 2011-2024 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <. GNU Automake home page: . General help using GNU software: . END } test_name= # Used for reporting. log_file= # Where to save the output of the test script. trs_file= # Where to save the metadata of the test run. expect_failure=no color_tests=no collect_skipped_logs=yes enable_hard_errors=yes while test $# -gt 0; do case $1 in --help) print_usage; exit $?;; --version) echo "test-driver (GNU Automake) $scriptversion"; exit $?;; --test-name) test_name=$2; shift;; --log-file) log_file=$2; shift;; --trs-file) trs_file=$2; shift;; --color-tests) color_tests=$2; shift;; --collect-skipped-logs) collect_skipped_logs=$2; shift;; --expect-failure) expect_failure=$2; shift;; --enable-hard-errors) enable_hard_errors=$2; shift;; --) shift; break;; -*) usage_error "invalid option: '$1'";; *) break;; esac shift done missing_opts= test x"$test_name" = x && missing_opts="$missing_opts --test-name" test x"$log_file" = x && missing_opts="$missing_opts --log-file" test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" if test x"$missing_opts" != x; then usage_error "the following mandatory options are missing:$missing_opts" fi if test $# -eq 0; then usage_error "missing argument" fi if test $color_tests = yes; then # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. red='' # Red. grn='' # Green. lgn='' # Light green. blu='' # Blue. mgn='' # Magenta. std='' # No color. else red= grn= lgn= blu= mgn= std= fi do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' trap "st=129; $do_exit" 1 trap "st=130; $do_exit" 2 trap "st=141; $do_exit" 13 trap "st=143; $do_exit" 15 # Test script is run here. We create the file first, then append to it, # to ameliorate tests themselves also writing to the log file. Our tests # don't, but others can (automake bug#35762). : >"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=$collect_skipped_logs;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/install-sh0000755000175000017500000003611515056640452012356 #!/bin/sh # install - install a program, script, or datafile scriptversion=2024-06-19.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Report bugs to . GNU Automake home page: . General help using GNU software: ." while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibility with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/py-compile0000755000175000017500000001503015056640452012347 #!/bin/sh # py-compile - Compile a Python program scriptversion=2024-06-19.01; # UTC # Copyright (C) 2000-2024 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . if test -z "$PYTHON"; then PYTHON=python fi me=py-compile usage_error () { echo "$me: $*" >&2 echo "Try '$me --help' for more information." >&2 exit 1 } basedir= destdir= while test $# -ne 0; do case "$1" in --basedir) if test $# -lt 2; then usage_error "option '--basedir' requires an argument" else basedir=$2 fi shift ;; --destdir) if test $# -lt 2; then usage_error "option '--destdir' requires an argument" else destdir=$2 fi shift ;; -h|--help) cat <<\EOF Usage: py-compile [options] FILES... Byte compile some python scripts FILES. Use --destdir to specify any leading directory path to the FILES that you don't want to include in the byte compiled file. Specify --basedir for any additional path information you do want to be shown in the byte compiled file. Options: --basedir DIR Prefix all FILES with DIR, and include in error messages. --destdir DIR Prefix all FILES with DIR before compiling. -v, --version Display version information. -h, --help This help screen. Example: py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py Report bugs to . GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v|--version) echo "$me (GNU Automake) $scriptversion" exit $? ;; --) shift break ;; -*) usage_error "unrecognized option '$1'" ;; *) break ;; esac shift done if test $# -eq 0; then usage_error "no files given" fi # if basedir was given, then it should be prepended to filenames before # byte compilation. if test -z "$basedir"; then pathtrans="path = file" else pathtrans="path = os.path.join('$basedir', file)" fi # if destdir was given, then it needs to be prepended to the filename to # byte compile but not go into the compiled file. if test -z "$destdir"; then filetrans="filepath = path" else filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" fi python_major=`$PYTHON -c 'import sys; print(sys.version_info[0])'` if test -z "$python_major"; then usage_error "could not determine $PYTHON major version" fi case $python_major in [01]) usage_error "python version 0.x and 1.x not supported" ;; esac python_minor=`$PYTHON -c 'import sys; print(sys.version_info[1])'` # NB: When adding support for newer versions, prefer copying & adding new cases # rather than try to keep things merged with shell variables. # First byte compile (no optimization) all the modules. # This works for all currently known Python versions. $PYTHON -c " import sys, os, py_compile try: import importlib except ImportError: importlib = None # importlib.util.cache_from_source was added in 3.4 if ( hasattr(importlib, 'util') and hasattr(importlib.util, 'cache_from_source') ): destpath = importlib.util.cache_from_source else: destpath = lambda filepath: filepath + 'c' sys.stdout.write('Byte-compiling python modules...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, destpath(filepath), path) sys.stdout.write('\n')" "$@" || exit $? # Then byte compile w/optimization all the modules. $PYTHON -O -c " import sys, os, py_compile try: import importlib except ImportError: importlib = None # importlib.util.cache_from_source was added in 3.4 if ( hasattr(importlib, 'util') and hasattr(importlib.util, 'cache_from_source') ): destpath = importlib.util.cache_from_source else: destpath = lambda filepath: filepath + 'o' # pypy2 does not use .pyo optimization if sys.version_info.major <= 2 and hasattr(sys, 'pypy_translation_info'): sys.exit(0) sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, destpath(filepath), path) sys.stdout.write('\n')" "$@" 2>/dev/null || exit $? # Then byte compile w/more optimization. # Only do this for Python 3.5+, see https://bugs.gnu.org/38043 for background. case $python_major.$python_minor in 2.*|3.[0-4]) ;; *) $PYTHON -OO -c " import sys, os, py_compile, importlib sys.stdout.write('Byte-compiling python modules (more optimized versions)' ' ...\n') for file in sys.argv[1:]: $pathtrans $filetrans if ( not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py') ): continue sys.stdout.write(file + ' ') sys.stdout.flush() py_compile.compile(filepath, importlib.util.cache_from_source(filepath), path) sys.stdout.write('\n')" "$@" 2>/dev/null || exit $? ;; esac # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/config.guess0000755000175000017500000014306715056640452012677 #! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still # use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #if defined(__ANDROID__) LIBC=android #else #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #elif defined(__LLVM_LIBC__) LIBC=llvm #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-pc-managarm-mlibc" ;; *:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __ARM_EABI__ #ifdef __ARM_PCS_VFP ABI=eabihf #else ABI=eabi #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; esac fi GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:cos:*:*) GUESS=$UNAME_MACHINE-unknown-cos ;; kvx:mbr:*:*) GUESS=$UNAME_MACHINE-unknown-mbr ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; *:Ironclad:*:*) GUESS=$UNAME_MACHINE-unknown-ironclad ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif int main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: hamlib-4.6.5/build-aux/compile0000755000175000017500000001670515056640452011733 #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2024-06-19.01; # UTC # Copyright (C) 1999-2024 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.lo | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v | --v*) echo "compile (GNU Automake) $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.5/build-aux/config.sub0000755000175000017500000011544115056640452012335 #! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale timestamp='2024-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in cloudabi*-eabi* \ | kfreebsd*-gnu* \ | knetbsd*-gnu* \ | kopensolaris*-gnu* \ | linux-* \ | managarm-* \ | netbsd*-eabi* \ | netbsd*-gnu* \ | nto-qnx* \ | os2-emx* \ | rtmk-nova* \ | storm-chaos* \ | uclinux-gnu* \ | uclinux-uclibc* \ | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) case $field1-$field2 in # Shorthands that happen to contain a single dash convex-c[12] | convex-c3[248]) basic_machine=$field2-convex basic_os= ;; decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Do not treat sunos as a manufacturer sun*os*) basic_machine=$field1 basic_os=$field2 ;; # Manufacturers 3100* \ | 32* \ | 3300* \ | 3600* \ | 7300* \ | acorn \ | altos* \ | apollo \ | apple \ | atari \ | att* \ | axis \ | be \ | bull \ | cbm \ | ccur \ | cisco \ | commodore \ | convergent* \ | convex* \ | cray \ | crds \ | dec* \ | delta* \ | dg \ | digital \ | dolphin \ | encore* \ | gould \ | harris \ | highlevel \ | hitachi* \ | hp \ | ibm* \ | intergraph \ | isi* \ | knuth \ | masscomp \ | microblaze* \ | mips* \ | motorola* \ | ncr* \ | news \ | next \ | ns \ | oki \ | omron* \ | pc533* \ | rebel \ | rom68k \ | rombug \ | semi \ | sequent* \ | siemens \ | sgi* \ | siemens \ | sim \ | sni \ | sony* \ | stratus \ | sun \ | sun[234]* \ | tektronix \ | tti* \ | ultra \ | unicom* \ | wec \ | winbond \ | wrs) basic_machine=$field1-$field2 basic_os= ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) cpu=m68k vendor=motorola ;; # This used to be dpx2*, but that gets the RS6000-based # DPX/20 and the x86-based DPX/2-100 wrong. See # https://oldskool.silicium.org/stations/bull_dpx20.htm # https://www.feb-patrimoine.com/english/bull_dpx2.htm # https://www.feb-patrimoine.com/english/unix_and_bull.htm dpx2 | dpx2[23]00 | dpx2[23]xx) cpu=m68k vendor=bull ;; dpx2100 | dpx21xx) cpu=i386 vendor=bull ;; dpx20) cpu=rs6000 vendor=bull ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. obj= case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) saved_IFS=$IFS IFS="-" read kernel os <&2 fi ;; *) echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 exit 1 ;; esac case $obj in aout* | coff* | elf* | pe*) ;; '') # empty is fine ;; *) echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 exit 1 ;; esac # Here we handle the constraint that a (synthetic) cpu and os are # valid only in combination with each other and nowhere else. case $cpu-$os in # The "javascript-unknown-ghcjs" triple is used by GHC; we # accept it here in order to tolerate that, but reject any # variations. javascript-ghcjs) ;; javascript-* | *-ghcjs) echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os-$obj in linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ | linux-mlibc*- | linux-musl*- | linux-newlib*- \ | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) ;; uclinux-uclibc*- | uclinux-gnu*- ) ;; managarm-mlibc*- | managarm-kernel*- ) ;; windows*-msvc*-) ;; -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; -kernel*- ) echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 exit 1 ;; *-kernel*- ) echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 exit 1 ;; *-msvc*- ) echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 exit 1 ;; kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; nto-qnx*-) ;; os2-emx-) ;; rtmk-nova-) ;; *-eabi*- | *-gnueabi*-) ;; none--*) # None (no kernel, i.e. freestanding / bare metal), # can be paired with an machine code file format ;; -*-) # Blank kernel with real OS is always fine. ;; --*) # Blank kernel and OS with real machine code file format is always fine. ;; *-*-*) echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: hamlib-4.6.5/build-aux/ar-lib0000755000175000017500000001403115056640452011437 #! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2024-06-19.01; # UTC # Copyright (C) 2010-2024 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin | msys) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v | --v*) echo "$me (GNU Automake) $scriptversion" exit $? ;; esac if test $# -lt 3; then func_error "you must specify a program, an action and an archive" fi AR=$1 shift while : do if test $# -lt 2; then func_error "you must specify a program, an action and an archive" fi case $1 in -lib | -LIB \ | -ltcg | -LTCG \ | -machine* | -MACHINE* \ | -subsystem* | -SUBSYSTEM* \ | -verbose | -VERBOSE \ | -wx* | -WX* ) AR="$AR $1" shift ;; -nologo | -NOLOGO) # We always invoke AR with -nologo, so don't need to add it again. shift ;; *) action=$1 shift break ;; esac done orig_archive=$1 shift func_file_conv "$orig_archive" archive=$file # strip leading dash in $action action=${action#-} delete= extract= list= quick= replace= index= create= while test -n "$action" do case $action in d*) delete=yes ;; x*) extract=yes ;; t*) list=yes ;; q*) quick=yes ;; r*) replace=yes ;; s*) index=yes ;; S*) ;; # the index is always updated implicitly c*) create=yes ;; u*) ;; # TODO: don't ignore the update modifier v*) ;; # TODO: don't ignore the verbose modifier *) func_error "unknown action specified" ;; esac action=${action#?} done case $delete$extract$list$quick$replace,$index in yes,* | ,yes) ;; yesyes*) func_error "more than one action specified" ;; *) func_error "no action specified" ;; esac if test -n "$delete"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi for member do case $1 in @*) func_at_file "${1#@}" -REMOVE "$archive" ;; *) func_file_conv "$1" $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $? ;; esac done elif test -n "$extract"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi if test $# -gt 0; then for member do case $1 in @*) func_at_file "${1#@}" -EXTRACT "$archive" ;; *) func_file_conv "$1" $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $? ;; esac done else $AR -NOLOGO -LIST "$archive" | tr -d '\r' | sed -e 's/\\/\\\\/g' \ | while read member do $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $? done fi elif test -n "$quick$replace"; then if test ! -f "$orig_archive"; then if test -z "$create"; then echo "$me: creating $orig_archive" fi orig_archive= else orig_archive=$archive fi for member do case $1 in @*) func_file_conv "${1#@}" set x "$@" "@$file" ;; *) func_file_conv "$1" set x "$@" "$file" ;; esac shift shift done if test -n "$orig_archive"; then $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $? else $AR -NOLOGO -OUT:"$archive" "$@" || exit $? fi elif test -n "$list"; then if test ! -f "$orig_archive"; then func_error "archive not found" fi $AR -NOLOGO -LIST "$archive" || exit $? fi hamlib-4.6.5/build-aux/ltmain.sh0000755000175000017500000122276515056640447012212 #! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 # libtool (GNU libtool) 2.5.4 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.5.4 Debian-2.5.4-4" package_revision=2.5.4 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2024-12-01.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # These NLS vars are set unconditionally (bootstrap issue #24). Unset those # in case the environment reset is needed later and the $save_* variant is not # defined (see the code above). LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # func_unset VAR # -------------- # Portably unset VAR. # In some shells, an 'unset VAR' statement leaves a non-zero return # status if VAR is already unset, which might be problematic if the # statement is used at the end of a function (thus poisoning its return # value) or when 'set -e' is active (causing even a spurious abort of # the script in this case). func_unset () { { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } } # Make sure CDPATH doesn't cause `cd` commands to output the target dir. func_unset CDPATH # Make sure ${,E,F}GREP behave sanely. func_unset GREP_OPTIONS ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" # require_check_ifs_backslash # --------------------------- # Check if we can use backslash as IFS='\' separator, and set # $check_ifs_backshlash_broken to ':' or 'false'. require_check_ifs_backslash=func_require_check_ifs_backslash func_require_check_ifs_backslash () { _G_save_IFS=$IFS IFS='\' _G_check_ifs_backshlash='a\\b' for _G_i in $_G_check_ifs_backshlash do case $_G_i in a) check_ifs_backshlash_broken=false ;; '') break ;; *) check_ifs_backshlash_broken=: break ;; esac done IFS=$_G_save_IFS require_check_ifs_backslash=: } ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # usable or anything else if it does not work. if test -z "$_G_HAVE_PLUSEQ_OP" && \ __PLUSEQ_TEST="a" && \ __PLUSEQ_TEST+=" b" 2>/dev/null && \ test "a b" = "$__PLUSEQ_TEST"; then _G_HAVE_PLUSEQ_OP=yes fi if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1=\$$1\\ \$func_quote_arg_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value returned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list in case some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_portable EVAL ARG # ---------------------------- # Internal function to portably implement func_quote_arg. Note that we still # keep attention to performance here so we as much as possible try to avoid # calling sed binary (so far O(N) complexity as long as func_append is O(1)). func_quote_portable () { $debug_cmd $require_check_ifs_backslash func_quote_portable_result=$2 # one-time-loop (easy break) while true do if $1; then func_quote_portable_result=`$ECHO "$2" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` break fi # Quote for eval. case $func_quote_portable_result in *[\\\`\"\$]*) # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string # contains the shell wildcard characters. case $check_ifs_backshlash_broken$func_quote_portable_result in :*|*[\[\*\?]*) func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ | $SED "$sed_quote_subst"` break ;; esac func_quote_portable_old_IFS=$IFS for _G_char in '\' '`' '"' '$' do # STATE($1) PREV($2) SEPARATOR($3) set start "" "" func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy IFS=$_G_char for _G_part in $func_quote_portable_result do case $1 in quote) func_append func_quote_portable_result "$3$2" set quote "$_G_part" "\\$_G_char" ;; start) set first "" "" func_quote_portable_result= ;; first) set quote "$_G_part" "" ;; esac done done IFS=$func_quote_portable_old_IFS ;; *) ;; esac break done func_quote_portable_unquoted_result=$func_quote_portable_result case $func_quote_portable_result in # double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # many bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_portable_result=\"$func_quote_portable_result\" ;; esac } # func_quotefast_eval ARG # ----------------------- # Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', # but optimized for speed. Result is stored in $func_quotefast_eval. if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then printf -v _GL_test_printf_tilde %q '~' if test '\~' = "$_GL_test_printf_tilde"; then func_quotefast_eval () { printf -v func_quotefast_eval_result %q "$1" } else # Broken older Bash implementations. Make those faster too if possible. func_quotefast_eval () { case $1 in '~'*) func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result ;; *) printf -v func_quotefast_eval_result %q "$1" ;; esac } fi else func_quotefast_eval () { func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result } fi # func_quote_arg MODEs ARG # ------------------------ # Quote one ARG to be evaled later. MODEs argument may contain zero or more # specifiers listed below separated by ',' character. This function returns two # values: # i) func_quote_arg_result # double-quoted (when needed), suitable for a subsequent eval # ii) func_quote_arg_unquoted_result # has all characters that are still active within double # quotes backslashified. Available only if 'unquoted' is specified. # # Available modes: # ---------------- # 'eval' (default) # - escape shell special characters # 'expand' # - the same as 'eval'; but do not quote variable references # 'pretty' # - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might # be used later in func_quote to get output like: 'echo "a b"' instead # of 'echo a\ b'. This is slower than default on some shells. # 'unquoted' # - produce also $func_quote_arg_unquoted_result which does not contain # wrapping double-quotes. # # Examples for 'func_quote_arg pretty,unquoted string': # # string | *_result | *_unquoted_result # ------------+-----------------------+------------------- # " | \" | \" # a b | "a b" | a b # "a b" | "\"a b\"" | \"a b\" # * | "*" | * # z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" # # Examples for 'func_quote_arg pretty,unquoted,expand string': # # string | *_result | *_unquoted_result # --------------+---------------------+-------------------- # z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" func_quote_arg () { _G_quote_expand=false case ,$1, in *,expand,*) _G_quote_expand=: ;; esac case ,$1, in *,pretty,*|*,expand,*|*,unquoted,*) func_quote_portable $_G_quote_expand "$2" func_quote_arg_result=$func_quote_portable_result func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result ;; *) # Faster quote-for-eval for some shells. func_quotefast_eval "$2" func_quote_arg_result=$func_quotefast_eval_result ;; esac } # func_quote MODEs ARGs... # ------------------------ # Quote all ARGs to be evaled later and join them into single command. See # func_quote_arg's description for more info. func_quote () { $debug_cmd _G_func_quote_mode=$1 ; shift func_quote_result= while test 0 -lt $#; do func_quote_arg "$_G_func_quote_mode" "$1" if test -n "$func_quote_result"; then func_append func_quote_result " $func_quote_arg_result" else func_append func_quote_result "$func_quote_arg_result" fi shift done } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_arg pretty,expand "$_G_cmd" eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_arg expand,pretty "$_G_cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # # Set a version string for this script. scriptversion=2019-02-19.15; # UTC ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # in the main code. A hook is just a list of function names that can be # run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of hook functions to be called by # FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_propagate_result FUNC_NAME_A FUNC_NAME_B # --------------------------------------------- # If the *_result variable of FUNC_NAME_A _is set_, assign its value to # *_result variable of FUNC_NAME_B. func_propagate_result () { $debug_cmd func_propagate_result_result=: if eval "test \"\${${1}_result+set}\" = set" then eval "${2}_result=\$${1}_result" else func_propagate_result_result=false fi } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd _G_rc_run_hooks=false case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do func_unset "${_G_hook}_result" eval $_G_hook '${1+"$@"}' func_propagate_result $_G_hook func_run_hooks if $func_propagate_result_result; then eval set dummy "$func_run_hooks_result"; shift fi done } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list from your hook function. You may remove # or edit any options that you action, and then pass back the remaining # unprocessed options in '_result', escaped # suitably for 'eval'. # # The '_result' variable is automatically unset # before your hook gets called; for best performance, only set the # *_result variable when necessary (i.e. don't call the 'func_quote' # function unnecessarily because it can be an expensive operation on some # machines). # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). Leave # # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@" in case we need it later, # # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then # func_quote eval ${1+"$@"} # my_silent_option_result=$func_quote_result # fi # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd func_run_hooks func_options ${1+"$@"} func_propagate_result func_run_hooks func_options_finish } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do func_unset func_${my_func}_result func_unset func_run_hooks_result eval func_$my_func '${1+"$@"}' func_propagate_result func_$my_func func_options if $func_propagate_result_result; then eval set dummy "$func_options_result"; shift _G_options_quoted=: fi done $_G_options_quoted || { # As we (func_options) are top-level options-parser function and # nobody quoted "$@" for us yet, we need to do it explicitly for # caller. func_quote eval ${1+"$@"} func_options_result=$func_quote_result } } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} func_propagate_result func_run_hooks func_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} func_propagate_result func_run_hooks func_parse_options if $func_propagate_result_result; then eval set dummy "$func_parse_options_result"; shift # Even though we may have changed "$@", we passed the "$@" array # down into the hook and it quoted it for us (because we are in # this if-branch). No need to quote it again. _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break # We expect that one of the options parsed in this function matches # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" >&2 $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_parse_options_requote=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac if $_G_match_parse_options; then _G_parse_options_requote=: fi done if $_G_parse_options_requote; then # save modified positional parameters for caller func_quote eval ${1+"$@"} func_parse_options_result=$func_quote_result fi } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables # after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} if test "x$func_split_equals_lhs" = "x$1"; then func_split_equals_rhs= fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. # The version message is extracted from the calling file's header # comments, with leading '# ' stripped: # 1. First display the progname and version # 2. Followed by the header comment line matching /^# Written by / # 3. Then a blank line followed by the first following line matching # /^# Copyright / # 4. Immediately followed by any lines between the previous matches, # except lines preceding the intervening completely blank line. # For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /^# Written by /!b s|^# ||; p; n :fwd2blnk /./ { n b fwd2blnk } p; n :holdwrnt s|^# || s|^# *$|| /^Copyright /!{ /./H n b holdwrnt } s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| G s|\(\n\)\n*|\1|g p; q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.5.4' # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd year=`date +%Y` cat < This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Originally written by Gordon Matzigkeit, 1996 (See AUTHORS for complete contributor listing) EOF exit $? } # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information --finish use operation '--mode=finish' --mode=MODE use operation mode MODE --no-finish don't update shared library cache --no-quiet, --no-silent print default informational messages --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --reorder-cache=DIRS reorder shared library cache for preferred DIRS --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.5.4-4 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_reorder_cache=false opt_preserve_dup_deps=false opt_quiet=false opt_finishing=true opt_warning= nonopt= preserve_args= _G_rc_lt_options_prep=: _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote eval ${1+"$@"} libtool_options_prep_result=$func_quote_result fi } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument '$1' for $_G_opt" exit_cmd=exit ;; esac shift ;; --no-finish) opt_finishing=false func_append preserve_args " $_G_opt" ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --reorder-cache) opt_reorder_cache=true shared_lib_dirs=$1 if test -n "$shared_lib_dirs"; then case $1 in # Must begin with /: /*) ;; # Catch anything else as an error (relative paths) *) func_error "invalid argument '$1' for $_G_opt" func_error "absolute paths are required for $_G_opt" exit_cmd=exit ;; esac fi shift ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote eval ${1+"$@"} libtool_parse_options_result=$func_quote_result fi } func_add_hook func_parse_options libtool_parse_options # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { if $opt_warning; then $debug_cmd $warning_func ${1+"$@"} fi } # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host_os in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote eval ${1+"$@"} libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, windows, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. Assumes ARG has no leading or trailing path separator # characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep # func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER # Replaces a delimiter for a given path. func_convert_delimited_path () { converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"` } # end func_convert_delimited_path ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_reorder_shared_lib_cache DIRS # Reorder the shared library cache by unconfiguring previous shared library cache # and configuring preferred search directories before previous search directories. # Previous shared library cache: /usr/lib /usr/local/lib # Preferred search directories: /tmp/testing # Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib func_reorder_shared_lib_cache () { $debug_cmd case $host_os in openbsd*) get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` func_convert_delimited_path "$get_search_directories" ':' '\ ' save_search_directories=$converted_path func_convert_delimited_path "$1" ':' '\ ' # Ensure directories exist for dir in $converted_path; do # Ensure each directory is an absolute path case $dir in /*) ;; *) func_error "Directory '$dir' is not an absolute path" exit $EXIT_FAILURE ;; esac # Ensure no trailing slashes func_stripname '' '/' "$dir" dir=$func_stripname_result if test -d "$dir"; then if test -n "$preferred_search_directories"; then preferred_search_directories="$preferred_search_directories $dir" else preferred_search_directories=$dir fi else func_error "Directory '$dir' does not exist" exit $EXIT_FAILURE fi done PATH="$PATH:/sbin" ldconfig -U $save_search_directories PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` func_convert_delimited_path "$get_search_directories" ':' '\ ' reordered_search_directories=$converted_path $ECHO "Original: $save_search_directories" $ECHO "Reordered: $reordered_search_directories" exit $EXIT_SUCCESS ;; *) func_error "--reorder-cache is not supported for host_os=$host_os." exit $EXIT_FAILURE ;; esac } # end func_reorder_shared_lib_cache # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_arg pretty "$libobj" test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | windows* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_arg pretty "$srcfile" qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wa,FLAG -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # If option '--reorder-cache', reorder the shared library cache and exit. if $opt_reorder_cache; then func_reorder_shared_lib_cache $shared_lib_dirs fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done if test "false" = "$opt_finishing"; then echo echo "NOTE: finish_cmds were not executed during testing, so you must" echo "manually run ldconfig to add a given test directory, LIBDIR, to" echo "the search path for generated executables." fi echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_arg pretty "$nonopt" install_prog="$func_quote_arg_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_arg pretty "$arg" func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_arg pretty "$arg" func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then func_quote_arg pretty "$arg2" fi func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_arg pretty "$install_override_mode" func_append install_shared_prog " -m $func_quote_arg_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Strip any trailing slash from the destination. func_stripname '' '/' "$libdir" destlibdir=$func_stripname_result func_stripname '' '/' "$destdir" s_destdir=$func_stripname_result # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | windows* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw* | *windows*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_arg expand,pretty "$relink_command" eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *windows* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 case $host in i[3456]86-*-mingw32*) eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" ;; *) eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'" ;; esac } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *windows* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw/windows # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw/windows-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" func_quote_arg pretty "$ECHO" qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw/windows when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #if defined _WIN32 && !defined __GNUC__ # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ _CRTIMP int __cdecl _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw* | windows*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= compile_rpath_tail= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= temp_rpath_tail= thread_safe=no vinfo= vinfo_number=no weak_libs= rpath_arg= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_arg pretty,unquoted "$arg" qarg=$func_quote_arg_unquoted_result func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "argument to -rpath is not absolute: $arg" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xassembler) func_append compiler_flags " -Xassembler $qarg" prev= func_append compile_command " -Xassembler $qarg" func_append finalize_command " -Xassembler $qarg" continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. # -q

hamlib-4.6.5/doc/hamlib.png0000664000175000017500000000437015056640442011166 PNG  IHDR00`nIDATxXkl\G33}{:$&I P%ED@BB<G((HZ"U[@3"Hqb;~?b;ݽ{3sݗhwΜ9ٳg;C;sz[  #T`,*t{YvZbyX CUvQ/9KE Uji, }_h0X*=_A`0 )1oQL/b}(ne`܋9W֎mޏhhB78Wc=;c>H8o~tsĉe;{100C)s/)YO v>?cGiu_Sv{E"><;Gz+v64V a"^QJHRb)t,C |yYwPuy4-2CX(zfOh,Z,2(e)+VPAr- YR?XfJx* +*_pZݝeT@M㊙H)o`HС}4Οc5zIp._3ZҶ]|=k qaW 7̻{XS ӼCv,B_+dڱ{$C:ڵHY21>厎V޾[L71鏌R6B)|ڵ'$MJU}<n9EzKRs ϴmՁp.K7ڿ)sƻT!| /TEw_Y|?15oI#UjС!֖{PL͆;:qӥvpP_+4Q19MLN\a}S -cwc7.|O^s`[OܵcS_{T.d=Ab1s#'k͠S?6n(7;ڍ &љ1;Q &nԪFϔku@h_QTVB'Bۿg;h"G|AÖGyN%13)[J P20YE"7ǕToKA,PL|KN'?s (524?2RMFV"H,1MH$> Bt<+NZf $iJu=)!~hxa,r]]B,Q,ڔR4rR| GV; z~-J’1eS+^e:ϗuT1kwDYuλ:fY3@Z7pFM3|䋦JrPI@PjLݽ VA篱bޛ&Fg;D«`*ʖ^Ck{+Sc*#A6X"ҚhXo~t*WX'h$:9׮P#AM(Umf_&$X=Bٟܿ9ϯzfo(嬹g'PSH8s^ Y+n=)[D}P;*)k?]I| h/EFh2AjZa6%h4H%}<8h$:a U|O DhjAX^m(7< Ask}5n N,Ӌ/2[. +cmds.txt" .RB > " # File of commands" .RB > " F 14250000" .RB > " f" .RB > " l PWRINPUT" .RB > " l PWRFORWARD" .RB > " l SWR" > \fB\\dump_caps\fP .RB > " .EOF." .RB $ " ampctl -m1 - " ampctl -m 201 -r COM1 -vvvvv" .EE .in . .PP Connect to a running .B ampctld with amplifier model 2 (\(lqNET ampctl\(rq) on the local host and specifying the TCP port, setting frequency and mode: . .PP .in +4n .EX .RB $ " ampctl -m 2 -r localhost:4531 F 7253500" .EE .in . . .SH BUGS . This almost empty section... .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2011 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2010-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR less (1), .BR more (1), .BR ampctld (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigctlsync.10000664000175000017500000001517615056640442012331 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigctlsync.c .\" .TH RIGCTLSYNC "1" "2023-01-27" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigctlsync \- synchronize a rig to SDR# (or other rig) . .SH SYNOPSIS . . .SY rigctlsync .OP \-hlLuV .OP \-m id .OP \-r device .OP \-R device .OP \-s baud .OP \-S baud .OP \-c id .OP \-C parm=val .OP \-B .RB [ \-v [ \-Z ]] .YS . .SH DESCRIPTION Allows you to synchronize frequency from a rig to SDR#. Best when used with rigctld, FlRig, or a multiport radio. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. .IP See model list (use \(lqrigctlsync -l\(rq). .IP .BR Note : .B rigctlsync (or third party software using the C API) will use radio model 2 for .B NET rigctl (communicating with .BR rigctld ). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. .IP The special string \(lquh\-rig\(rq may be given to enable micro-ham device support. . .TP .BR \-R ", " \-\-rig\-file2 = \fIdevice\fP Use .I device as the file name of one of the virtual com ports -- your program will connect to the other com port of the virtual pair. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-S ", " \-\-serial\-speed2 = \fIbaud\fP Set serial speed to .I baud rate for virtual com port (see .BR -R ). . .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the rig. .IP Only useful for Icom and some Ten-Tec rigs. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-L ", " \-\-show\-conf List all config parameters for the radio defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set radio configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the radio defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrigctl -l | more\(rq. . .TP .BR \-n ", " \-\-no\-restore\-ai .B rigctl restores the state of auto information (AI) on the controlled rig. .IP If this is not desired, for example if you are using .B rigctl to turn AI mode on or off, pass this option. . .TP .BR \-B ", " \-\-mapa2b Maps set_freq on VFOA to VFOB instead. This allows using CW skimmer with the rig in split mode and clicking on a frequency in CW skimmer will set VFOB to the transmit frequency. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigctl and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS .B rigctlsync exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib . . . .SH EXAMPLE . Start .B rigctlsync with FLRig as the Hamlib model .UE . . .PP .in +4n .EX .RB $ " rigctlsync -m 4 -M 9 -R 192.168.1.1:4532" .EE .in . .PP The following diagram shows the communications flow that allows N1MM Logger+ to communicate with a radio connected to Flrig: . .PP .in +4n .EX Flrig -><- rigctlcom -> COM9 <- virt_port_pipe -> COM10 <- N1MM .EE .in . . .SH BUGS . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2011 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2010-2020 Nate Bargmann .br Copyright \(co 2019 Michael Black W9MDB . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR rigctld (1), .BR rigctl (1), .BR socat (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigctlcom.10000664000175000017500000002125015056640442012121 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigctlcom.c .\" .TH RIGCTLCOM "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigctlcom \- COM port passthru as TS-2000 emulator to your rig . .SH SYNOPSIS . . .SY rigctlcom .OP \-hlLuV .OP \-m id .OP \-r device .OP \-R device .OP \-p device .OP \-d device .OP \-P type .OP \-D type .OP \-s baud .OP \-S baud .OP \-c id .OP \-C parm=val .OP \-B .RB [ \-v [ \-Z ]] .YS . .SH DESCRIPTION Allows programs which can connect to TS-2000 via COM port to use Hamlib or FLRig radios. Multiple programs can connect to the radio via FLRig or rigctld. . .PP Virtual serial/COM ports must be set up first using .BR socat (1) or similar on POSIX systems (BSD, Linux, OS/X). On Microsoft Windows available utilities are .UR http://com0com.sourceforge.net com0com .UE , .UR https://freevirtualserialports.com Free Virtual Serial Ports .UE , or .UR http://www.virtualserialportdriver.com/ VPSD .UE . . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. .IP See model list (use \(lqrigctlcom -l\(rq). .IP .BR Note : .B rigctlcom (or third party software using the C API) will use radio model 2 for .B NET rigctl (communicating with .BR rigctld ). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. .IP The special string \(lquh\-rig\(rq may be given to enable micro-ham device support. . .TP .BR \-R ", " \-\-rig\-file2 = \fIdevice\fP Use .I device as the file name of one of the virtual com ports -- your program will connect to the other com port of the virtual pair. . .IP Virtual serial ports on POSIX systems can be done with .BR socat (1): . .IP .in +4n .EX .RB $ " socat -d -d pty,raw,echo=0 pty,raw,echo=0" .EE .in . .IP See this .UR https://stackoverflow.com/a/19733677 Stackoverflow answer for using socat .UE . . .IP On Microsoft Windows available utilities are com0com, Free Virtual Serial Ports, or VPSD (see .B DESCRIPTION above for WWW links). . .TP .BR \-p ", " \-\-ptt\-file = \fIdevice\fP Use .I device as the file name of the Push-To-Talk device using a device file as described above. . .TP .BR \-d ", " \-\-dcd\-file = \fIdevice\fP Use .I device as the file name of the Data Carrier Detect device using a device file as described above. . .TP .BR \-P ", " \-\-ptt\-type = \fItype\fP Use .I type of Push-To-Talk device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDTR\(cq, \(oqRTS\(cq, \(oqPARALLEL\(cq, \(oqNONE\(cq, overriding PTT type defined in the rig's backend. .IP Some side effects of this command are that when type is set to DTR, read PTT state comes from the .B Hamlib frontend, not read from the radio. When set to NONE, PTT state cannot be read or set even if rig backend supports reading/setting PTT status from the rig. . .TP .BR \-D ", " \-\-dcd\-type = \fItype\fP Use .I type of Data Carrier Detect device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDSR\(cq, \(oqCTS\(cq, \(oqCD\(cq, \(oqPARALLEL\(cq, \(oqNONE\(cq. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-S ", " \-\-serial\-speed2 = \fIbaud\fP Set serial speed to .I baud rate for virtual com port (see .BR -R ). . .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the rig. .IP Only useful for Icom and some Ten-Tec rigs. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-L ", " \-\-show\-conf List all config parameters for the radio defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set radio configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the radio defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrigctl -l | more\(rq. . .TP .BR \-n ", " \-\-no\-restore\-ai .B rigctl restores the state of auto information (AI) on the controlled rig. .IP If this is not desired, for example if you are using .B rigctl to turn AI mode on or off, pass this option. . .TP .BR \-B ", " \-\-mapa2b Maps set_freq on VFOA to VFOB instead. This allows using CW skimmer with the rig in split mode and clicking on a frequency in CW skimmer will set VFOB to the transmit frequency. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigctl and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS .B rigctlcom exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib . . . .SH EXAMPLE . Start .B rigctlcom with FLRig as the Hamlib model and virtual com port pair COM9/COM10, e.g. .UR http://n1mm.hamdocs.com N1MM Logger+ .UE attaching to COM10 and using the TS-2000 emulator attached to COM9 (assumes virtual serial/COM ports pipe has been created with the proper utility as described above): . .PP .in +4n .EX .RB $ " rigctlcom -m 4 -R COM9 -S 115200" .EE .in . .PP The following diagram shows the communications flow that allows N1MM Logger+ to communicate with a radio connected to Flrig: . .PP .in +4n .EX Flrig -><- rigctlcom -> COM9 <- virt_port_pipe -> COM10 <- N1MM .EE .in . . .SH BUGS . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2011 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2010-2020 Nate Bargmann .br Copyright \(co 2019 Michael Black W9MDB . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR rigctld (1), .BR rigctl (1), .BR socat (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigmem.10000664000175000017500000001367715056640442011434 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigmem.c .\" .TH RIGMEM "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigmem \- backup and restore memory of radio transceivers and receivers . . .SH SYNOPSIS . . .SY rigmem .OP \-ahvVx .OP \-m id .OP \-r device .OP \-s baud .OP \-c id .OP \-C parm=val .OP \-p sep command .RI [ file ] .YS . . .SH DESCRIPTION . Backup and restore memory of radio transceivers and receivers. .B rigmem accepts .IR command s from the command line only. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete radio support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. .IP See model list (use \(lqrigctl \-l\(rq). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set radio serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the radio. .IP Only useful for Icom and some Ten-Tec radios. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set radio configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option of .B rigctl for a list of configuration parameters for a given model number. . .TP .BR \-p ", " \-\-set\-separator = \fIsep\fP Set character as column separator instead of the CSV comma. .IP Some common alternatives are the vertical bar (pipe), \(oq|\(cq, semicolon, \(oq;\(cq, and colon, \(oq:\(cq. . .TP .BR \-a ", " \-\-all Bypass mem_caps, apply to all fields of channel_t. . .TP .BR \-x ", " \-\-xml Use XML format instead of CSV, if libxml2 is available. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigmem and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf option. . . .SH COMMANDS . Backup and restore are supported for basic CSV file and XML format where available. . .PP Please note that the backend for the radio to be controlled, or the radio itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . .PP Here is a summary of the supported commands: . .TP .BI save " file" Save all the content of memory in a CSV (or XML) file given as an argument to the command. . .TP .BI load " file" Load the content into all the memory from a CSV (or XML) file given as an argument to the command. . .TP .BI save_parm " file" Save all the parameters of the radio in a CSV (or XML) file given as an argument to the command. . .TP .BI load_parm " file" Load the parameters of the radio from a CSV (or XML) file given as an argument to the command. . .TP .B clear This is a very .B DANGEROUS command, as it will completely clear out everything you have programmed in the memory of your radio. .BR "ALL DATA WILL BE LOST" . Use at your own risk! . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS . .B rigmem exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib . . .TP .B 3 the .B Hamlib backend has no memory support implemented and/or the radio has no memory access available. . . .SH BUGS . Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2003-2011 Stephane Fillod .br Copyright \(co 2007,2019-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR rigctl (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigctl.10000664000175000017500000013132515056640442011427 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigctl.c .\" .TH RIGCTL "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigctl \- control radio transceivers and receivers . .SH SYNOPSIS . . .SY rigctl .OP \-hiIlLnouV .OP \-m id .OP \-r device .OP \-p device .OP \-d device .OP \-P type .OP \-D type .OP \-s baud .OP \-c id .OP \-t char .OP \-C parm=val .RB \-Y .RB [ \-v [ \-Z ]] .RB [ command | \- ] .YS . .SH DESCRIPTION Control radio transceivers and receivers. .B rigctl accepts .B commands from the command line as well as in interactive mode if none are provided on the command line. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete rig support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. Defaults to dummy rig. .IP See model list (use \(lqrigctl -l\(rq). .IP .BR Note : .B rigctl (or third party software using the C API) will use radio model 2 for .B NET rigctl (communicating with .BR rigctld ). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. .IP Can be a network address:port, e.g. .IR 127.0.0.1:12345 .IP The special string \(lquh\-rig\(rq may be given to enable micro-ham device support. . .TP .BR \-p ", " \-\-ptt\-file = \fIdevice\fP Use .I device as the file name of the Push-To-Talk device using a device file as described above. . .TP .BR \-d ", " \-\-dcd\-file = \fIdevice\fP Use .I device as the file name of the Data Carrier Detect device using a device file as described above. . .TP .BR \-P ", " \-\-ptt\-type = \fItype\fP Use .I type of Push-To-Talk device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDTR\(cq, \(oqRTS\(cq, \(oqPARALLEL\(cq, \(oqCM108\(cq, \(oqGPIO\(cq, \(oqGPION\(cq, \(oqNONE\(cq, overriding PTT type defined in the rig's backend. .IP Some side effects of this command are that when type is set to DTR, read PTT state comes from the .B Hamlib frontend, not read from the radio. When set to NONE, PTT state cannot be read or set even if rig backend supports reading/setting PTT status from the rig. . .TP .BR \-D ", " \-\-dcd\-type = \fItype\fP Use .I type of Data Carrier Detect device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDSR\(cq, \(oqCTS\(cq, \(oqCD\(cq, \(oqPARALLEL\(cq, \(oqCM108\(cq, \(oqGPIO\(cq, \(oqGPION\(cq, \(oqNONE\(cq. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the rig. .IP Only useful for Icom and some Ten-Tec rigs. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-t ", " \-\-send\-cmd\-term = \fIchar\fP Change the termination .I char for text protocol when using the .B send_cmd command. .IP The default value is ASCII CR (\(oq0x0D\(cq). ASCII non-printing characters can be given as the ASCII number in hexadecimal format prepended with \(lq0x\(rq. You may pass an empty string for no termination char. The string \(lq\-1\(rq tells .B rigctl to switch to binary protocol. See the .B send_cmd command for further explanation. .IP For example, to specify a command terminator for Kenwood style text commands pass \(lq-t ';'\(rq to rigctl. See .B EXAMPLE below. . .TP .BR \-L ", " \-\-show\-conf List all config parameters for the radio defined with .B \-m above. Will exit if no -r is given. Note the dummy device has no serial parameters. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set configuration parameter(s). Some common ones are: .in +4n .EX .BR async: "True enables asynchronous data transfer for backends that support it. This allows use of transceive and spectrum data." .BR auto_power_on: "True enables compatible rigs to be powered up on open" .BR auto_power_off: "True enables compatible rigs to be powered down on close" .BR auto_disable_screensaver: "True enables compatible rigs to have their screen saver disabled on open" .BR dcd_type: "Data Carrier Detect (or squelch) interface type override" .BR dcd_pathname: "Path name to the device file of the Data Carrier Detect (or squelch)" .BR disable_yaesu_bandselect: "True disables the automatic band select on band change for Yaesu rigs" .BR dtr_state: "ON turns on DTR, OFF turns it off, Unset disables it" .BR lo_freq: "Frequency to add to the VFO frequency for use with a transverter" .BR post_write_delay: "Delay in ms between each command sent out" .BR ptt_share: "True enables ptt port to be shared with other apps" .BR ptt_type: "Push-To-Talk interface type override" .BR ptt_pathname: "Path name to the device file of the Push-To-Talk" .BR ptt_bitnum: "Push-To-Talk GPIO bit number" .BR retry: "Max number of retry" .BR rts_state: "ON turns on DTR, OFF turns it off, Unset disables it" .BR twiddle_timeout: "For satellite ops when VFOB is twiddled will pause VFOB commands until timeout" .BR twiddle_rit: "Suppress get_freq on VFOB for RIT tuning satellites" .BR timeout: "Timeout in ms" .BR write_delay: "Delay in ms between each byte sent out" .BR tuner_control_pathname: "Path name to a script/program to control a tuner with 1 argument of 0/1 for Tuner Off/On" .EE .in .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the radio defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrigctl -l | more\(rq. . .TP .BR \-o ", " \-\-vfo Enable vfo mode. .IP An extra VFO argument will be required in front of each appropriate command (except .BR set_vfo ). Otherwise, \(oqcurrVFO\(cq is used when this option is not set and an extra VFO argument is not used. . .TP .BR \-n ", " \-\-no\-restore\-ai On exit .B rigctl restores the state of auto information (AI) on the controlled rig. .IP If this is not desired, for example if you are using .B rigctl to turn AI mode on or off, pass this option. . .TP .BR \-i ", " \-\-read\-history Read previously saved command and argument history from a file (default .IR $HOME/.rigctl_history ) for the current session. .IP Available when .B rigctl is built with Readline support (see READLINE below). .IP .BR Note : To read a history file stored in another directory, set the .B RIGCTL_HIST_DIR environment variable, e.g. \(lqRIGCTL_HIST_DIR=~/tmp rigctl -i\(rq. When RIGCTL_HIST_DIR is not set, the value of .B HOME is used. . .TP .BR \-I ", " \-\-save\-history Write current session (and previous session(s), if .B -i option is given) command and argument history to a file (default .IR $HOME/.rigctl_history ) at the end of the current session. .IP Complete commands with arguments are saved as a single line to be recalled and used or edited. Available when .B rigctl is built with Readline support (see .B READLINE below). .IP .BR Note : To write a history file in another directory, set the .B RIGCTL_HIST_DIR environment variable, e.g. \(lqRIGCTL_HIST_DIR=~/tmp rigctl -I\)Rq. When RIGCTL_HIST_DIR is not set, the value of .B HOME is used. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). .TP .BR \-Y "," \-\-\ignore\-err Ignores rig open errors . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigctl and exit. . .TP .BR \-! ", " \-\-cookie Sets the cookie to be used for remote access security . .TP .BR \-# ", " \-\-skip_init Skips most startup initialization. . .TP .B \- Stop option processing and read commands from standard input. .IP See .B Standard Input below. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . .PP Please note that the backend for the radio to be controlled, or the radio itself may not support some commands. In that case, the operation will fail with a .B Hamlib error code. . . .SH COMMANDS . Commands can be entered either as a single char, or as a long command name. The commands are not prefixed with a dash as the options are. They may be typed in when in interactive mode or provided as argument(s) in command line interface mode. In interactive mode commands and their arguments may be entered on a single line: . .PP .in +4n .EX .B M LSB 2400 .EE .in . .PP Since most of the .B Hamlib operations have a .BR set " and a " get method, a single upper case letter will be used for .B set methods whereas the corresponding single lower case letter refers to the .B get method. Each operation also has a long name; in interactive mode, prepend a backslash, \(oq\\\(cq, to enter a long command name all lower case. . .PP Example: Use \(lq\\dump_caps\(rq to see what capabilities this radio and backend support. . .IP .BR Note : The backend for the radio to be controlled, or the radio itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . . .SS Standard Input . As an alternative to the .B READLINE interactive command entry or a single command for each run, .B rigctl features a special option where a single dash (\(oq\-\(cq) may be used to read commands from standard input .RB ( stdin ). Commands must be separated by whitespace similar to the commands given on the command line. Comments may be added using the \(oq#\(cq character, all text up until the end of the current line including the \(oq#\(cq character is ignored. . .PP A simple example (typed text is in bold): . .PP .in +4n .EX .RB $ " cat <<.EOF. >cmds.txt" .RB > " # File of commands" .RB > " v f m # query rig" .RB > " V VFOB F 14200000 M CW 500 # set rig" .RB > " v f m # query rig" .RB > " .EOF." .RB $ " rigctl -m1 - 0 is 1-based antenna# (\(oq1\(cq, \(oq2\(cq, \(oq3\(cq, ...). .IP Option returned depends on rig. For Icom it is likely the RX only flag. . .TP .BR b ", " send_morse " \(aq" \fIMorse\fP \(aq Send .RI \(aq Morse \(aq symbols. For Yaesu rigs use memory# (1-5 for most rigs) or up to 50 char message (which will use memory#1) Example from command line: .EX rigctl -m 3073 -r /dev/ttyUSB0 b "CQ CQ DE ME" .EE Yaesu example to send message#1: .EX rigctl -m 1035 -r /dev/ttyUSB0 b 1 .EE . .TP .BR 0xbb ", " stop_morse " Stop sending the current morse code. . .TP .BR 0xbc ", " wait_morse " Wait for morse to finish -- only works on full break-in. . .TP .BR 0x94 ", " send_voice_mem " \(aq" \fIMsgnum\fP \(aq Have rig transmit internal message .RI \(aq Msgnum \(aq . .TP .BR 0x8b ", " get_dcd Get .RI \(aq DCD \(aq (squelch) status: \(oq0\(cq (Closed) or \(oq1\(cq (Open). . .TP .BR R ", " set_rptr_shift " \(aq" "\fIRptr Shift\fP" \(aq Set .RI \(aq "Rptr Shift" \(aq. .IP Rptr Shift is one of: \(oq+\(cq, \(oq-\(cq, or something else for \(oqNone\(cq. . .TP .BR r ", " get_rptr_shift Get .RI \(aq "Rptr Shift" \(aq. .IP Returns \(oq+\(cq, \(oq-\(cq, or \(oqNone\(cq. . .TP .BR O ", " set_rptr_offs " \(aq" "\fIRptr Offset\fP" \(aq Set .RI \(aq "Rptr Offset" \(aq, in Hz. . .TP .BR o ", " get_rptr_offs Get .RI \(aq "Rptr Offset" \(aq, in Hz. . .TP .BR C ", " set_ctcss_tone " \(aq" "\fICTCSS Tone\fP" \(aq Set .RI \(aq "CTCSS Tone" \(aq, in tenths of Hz. . .TP .BR c ", " get_ctcss_tone Get .RI \(aq "CTCSS Tone" \(aq, in tenths of Hz. . .TP .BR D ", " set_dcs_code " \(aq" "\fIDCS Code\fP" \(aq Set .RI \(aq "DCS Code" \(aq. . .TP .BR d ", " get_dcs_code Get .RI \(aq "DCS Code" \(aq. . .TP .BR 0x90 ", " set_ctcss_sql " \(aq" "\fICTCSS Sql\fP" \(aq Set .RI \(aq "CTCSS Sql" \(aq tone, in tenths of Hz. . .TP .BR 0x91 ", " get_ctcss_sql Get .RI \(aq "CTCSS Sql" \(aq tone, in tenths of Hz. . .TP .BR 0x92 ", " set_dcs_sql " \(aq" "\fIDCS Sql\fP" \(aq Set .RI \(aq "DCS Sql" \(aq code. . .TP .BR 0x93 ", " get_dcs_sql Get .RI \(aq "DCS Sql" \(aq code. . .TP .BR N ", " set_ts " \(aq" "\fITuning Step\fP" \(aq Set .RI \(aq "Tuning Step" \(aq, in Hz. . .TP .BR n ", " get_ts Get .RI \(aq "Tuning Step" \(aq, in Hz. . .TP .BR U ", " set_func " \(aq" \fIFunc\fP "\(aq \(aq" "\fIFunc Status\fP" \(aq Set .RI \(aq Func \(aq and .RI \(aq "Func Status" \(aq. .IP Func is a token: \(oqABM\(cq, \(oqAFC\(cq, \(oqAFLT\(cq, \(oqAIP\(cq, \(oqANF\(cq, \(oqANL\(cq, \(oqAPF\(cq, \(oqARO\(cq, \(oqBC2\(cq, \(oqBC\(cq, \(oqCOMP\(cq, \(oqCSQL\(cq, \(oqDIVERSITY\(cq, \(oqDSQL\(cq, \(oqDUAL_WATCH\(cq, \(oqFAGC\(cq, \(oqFBKIN\(cq, \(oqLOCK\(cq, \(oqMBC\(cq, \(oqMN\(cq, \(oqMON\(cq, \(oqMUTE\(cq, \(oqNB2\(cq, \(oqNB\(cq, \(oqNR\(cq, \(oqOVF_STATUS\(cq, \(oqRESUME\(cq, \(oqREV\(cq, \(oqRF\(cq, \(oqRIT\(cq, \(oqSATMODE\(cq, \(oqSBKIN\(cq, \(oqSCEN\(cq, \(oqSCOPE\(cq, \(oqSEND_MORSE\(cq, \(oqSEND_VOICE_MEM\(cq, \(oqSPECTRUM\(cq, \(oqSPECTRUM_HOLD\(cq, \(oqSQL\(cq, \(oqSYNC\(cq, \(oqTBURST\(cq, \(oqTONE\(cq, \(oqTRANSCEIVE\(cq, \(oqTSQL\(cq, \(oqTUNER\(cq, \(oqVOX\(cq, \(oqVSC\(cq, \(oqXIT\(cq. ABM -- Auto Band Mode AFC -- Auto Frequency Control ON/OFF AFLT -- AF Filter setting AIP -- RF pre-amp (AIP on Kenwood, IPO on Yaesu, etc.) ANF -- Automatic Notch Filter (DSP) ANL -- Noise limiter setting APF -- Audio Peak Filter ARO -- Auto Repeater Offset BC -- Beat Canceller BC2 -- 2nd Beat Cancel COMP -- Speech Compression CSQL -- DCS Squelch setting DIVERSITY -- Diversity receive DSQL -- Digital modes squelch DUAL_WATCH -- Dual Watch / Sub Receiver FAGC -- Fast AGC FBKIN -- Full Break-in (CW mode) LOCK -- Lock MBC -- Manual Beat Canceller MN -- Manual Notch MON -- Monitor transmitted signal MUTE -- Mute NB -- Noise Blanker NB2 -- 2nd Noise Blanker NR -- Noise Reduction (DSP) OVF_STATUS -- Read overflow status 0=Off, 1=On RESUME -- Scan auto-resume REV -- Reverse transmit and receive frequencies RF -- RTTY Filter RIT -- Receiver Incremental Tuning SATMODE -- Satellite mode ON/OFF SBKIN -- Semi Break-in (CW mode) SCEN -- scrambler/encryption SCOPE -- Simple bandscope ON/OFF SEND_MORSE -- Send specified characters using CW SEND_VOICE_MEM -- Transmit in SSB message stored in memory SPECTRUM -- Spectrum scope data output ON/OFF SPECTRUM_HOLD -- Pause spectrum scope updates ON/OFF SQL -- Turn Squelch Monitor on/off SYNC -- Synchronize VFOs TBURST -- 1750 Hz tone burst TONE -- CTCSS Tone TX TRANSCEIVE -- Send radio state changes automatically ON/OFF TSQL -- CTCSS Activate/De-activate RX TUNER -- Enable automatic tuner VOX -- Voice Operated Relay VSC -- Voice Scan Control XIT -- Transmitter Incremental Tuning .IP Func Status is a non null value for \(lqactivate\(rq or \(lqde-activate\(rq otherwise, much as TRUE/FALSE definitions in the C language (true is non-zero and false is zero, \(oq0\(cq). .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Func token will return a space separated list of radio backend supported set function tokens. Use this to determine the supported functions of a given radio backend. . .TP .BR u ", " get_func " \(aq" \fIFunc\fP \(aq Get .RI \(aq "Func Status" \(aq. .IP Returns Func Status as a non null value for the Func token given as in .B set_func above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Func token will return a space separated list of radio backend supported get function tokens. Use this to determine the supported functions of a given radio backend. . .TP .BR L ", " set_level " \(aq" \fILevel\fP "\(aq \(aq" "\fILevel Value\fP" \(aq Set .RI \(aq Level \(aq and .RI \(aq "Level Value" \(aq. .IP Level is a token: \(oqAF\(cq, \(oqAGC\(cq, \(oqAGC_TIME\(cq, \(oqALC\(cq, \(oqANTIVOX\(cq, \(oqAPF\(cq, \(oqATT\(cq, \(oqBAL\(cq, \(oqBAND_SELECT\(cq, \(oqBKINDL\(cq, \(oqBKIN_DLYMS\(cq, \(oqCOMP\(cq, \(oqCOMP_METER\(cq, \(oqCWPITCH\(cq, \(oqID_METER\(cq, \(oqIF\(cq, \(oqKEYSPD\(cq, \(oqMETER\(cq, \(oqMGC\(cq, \(oqMGF\(cq, \(oqMGL\(cq, \(oqMICGAIN\(cq, \(oqMONITOR_GAIN\(cq, \(oqNB\(cq, \(oqNOTCHF\(cq, \(oqNOTCHF_RAW\(cq, \(oqNR\(cq, \(oqPBT_IN\(cq, \(oqPBT_OUT\(cq, \(oqPREAMP\(cq, \(oqRAWSTR\(cq, \(oqRF\(cq, \(oqRFPOWER\(cq, \(oqRFPOWER_METER\(cq, \(oqRFPOWER_METER_WATTS\(cq, \(oqSLOPE_HIGH\(cq, \(oqSLOPE_LOW\(cq, \(oqSPECTRUM_ATT\(cq, \(oqSPECTRUM_AVG\(cq, \(oqSPECTRUM_EDGE_HIGH\(cq, \(oqSPECTRUM_EDGE_LOW\(cq, \(oqSPECTRUM_MODE\(cq, \(oqSPECTRUM_REF\(cq, \(oqSPECTRUM_SPAN\(cq, \(oqSPECTRUM_SPEED\(cq, \(oqSQL\(cq, \(oqSTRENGTH\(cq, \(oqSWR\(cq, \(oqTEMP_METER\(cq, \(oqUSB_AF\(cq, \(oqUSB_AF_INPUT\(cq, \(oqVD_METER\(cq, \(oqVOXDELAY\(cq, \(oqVOXGAIN\(cq. .IP The Level Value can be a float or an integer value. For the AGC token the value is one of \(oq0\(cq = OFF, \(oq1\(cq = SUPERFAST, \(oq2\(cq = FAST, \(oq3\(cq = SLOW, \(oq4\(cq = USER, \(oq5\(cq = MEDIUM, \(oq6\(cq = AUTO. Note that not all values work on all rigs. To list usable values do "rigctl -m [modelnum] -u | grep AGC levels" or for Windows "rigctl -m [modelnum] -u | find "AGC levels"". .IP Level units .in +4n .EX 0.0-1.0 where 0=0% and 1.0=100% (except for BAL where 50% is center) AF, ALC, ANTIVOX, BAL, COMP, MICGAIN, MONITOR_GAIN, NOTCHF_RAW, NR, RF, RFPOWER, RFPOWER_METER, USB_AF, VOXGAIN Amps ID_METER(A) dB NL, COMP_METER, PREAMP, ATT, SLOPE_LOW, SLOPE_HIGH, SPECTRUM_REF, SPECTRUM_ATT, STRENGTH Degrees(temperature) TEMP_METER(C) Hz CWPITCH, IF, NOTCHF, PBT_IN, PBT_OUT, SPECTRUM_EDGE_LOW, SPECTRUM_EDGE_HIGH, SPECTRUM_SPAN Seconds VOXDELAY(ds), BKINDL(ms), BKIN_DLYMS(ms) Raw info from rig RAWSTR, BANDSELECT (subject to change -- index right now but may convert to band name) SWR SWR Volts VD_METER Lookup - if level shows 0/0/0 then it's probably a lookup value METER RIG_METER_XXXX 1=SWR, 2=COMP, 4=ALC, 8=IC, 16=DB, 32=PO, 64=VDD, 128=Temp AGC 0=None, 1=SuperFast, 2=Fast, 3=Slow, 4=User, 5=Medium, 6=Auto Note: Not all AGC values may be available -- see AGC Level in dumpcaps (e.g. rigctl -m 1035 -u | grep AGC) SPECTRUM_MODE 0=None, 1=Center, 2=Fixed, 3=Center Scroll, 4=Fixed Scroll SPECTRUM_AVG rig specific METER -- SWR,COMP,ALC,IC/ID,DB,PO,VDD,TEMP or can use the numbers above in Lookup l METER returns the meter number=name Watts RFPOWER_METER_WATTS WPM KEYSPD .in .EE .IP .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Level token will return a space separated list of radio backend supported set level tokens. Use this to determine the supported levels of a given radio backend. . .TP .BR l ", " get_level " \(aq" \fILevel\fP \(aq Get .RI \(aq "Level Value" \(aq. .IP Returns Level Value as a float or integer for the Level token given as in .B set_level above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Level token will return a space separated list of radio backend supported get level tokens. Use this to determine the supported levels of a given radio backend. . .TP .BR P ", " set_parm " \(aq" \fIParm\fP "\(aq \(aq" "\fIParm Value\fP" \(aq Set .RI \(aq Parm \(aq and .RI \(aq "Parm Value" \(aq. .IP Parm is a token: \(oqAFIF\(cq, \(oqAFIF_ACC\(cq, \(oqAFIF_LAN\(cq, \(oqAFIF_WLAN\(cq, \(oqANN\(cq, \(oqAPO\(cq, \(oqBACKLIGHT\(cq, \(oqBANDSELECT\(cq, \(oqBAT\(cq, \(oqBEEP\(cq, \(oqKEYERTYPE\(cq, \(oqKEYLIGHT\(cq, \(oqSCREENSAVER\(cq, \(oqTIME\(cq. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Parm token will return a space separated list of radio backend supported set parameter tokens. Use this to determine the supported parameters of a given radio backend. .IP ANN -- "Announce" level, see ann_t APO -- Auto power off, int in minute BACKLIGHT -- LCD light, float [0.0 ... 1.0] BEEP -- Beep on keypressed, int (0,1) TIME -- hh:mm:ss, int in seconds from 00:00:00 BAT -- battery level, float [0.0 ... 1.0] KEYLIGHT -- Button backlight, on/off SCREENSAVER -- rig specific timeouts AFIF -- 0=AF audio, 1=IF audio -- see IC-7300/9700/705 BANDSELECT -- band name, e.g. BAND160M, BAND80M.... a ? instead of band will show band possibilities KEYERTYPE -- Icom keyer type 0,1,2 or STRAIGHT,BUG,PADDLE . .TP .BR p ", " get_parm " \(aq" \fIParm\fP \(aq Get .RI \(aq "Parm Value" \(aq. .IP Returns Parm Value as a float or integer for the Parm token given as in .B set_parm above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Parm token will return a space separated list of radio backend supported get parameter tokens. Use this to determine the supported parameters of a given radio backend. . .TP .BR B ", " set_bank " \(aq" \fIBank\fP \(aq Set .RI \(aq Bank \(aq. .IP Sets the current memory bank number. . .TP .BR E ", " set_mem " \(aq" \fIMemory#\fP \(aq Set .RI \(aq Memory# \(aq channel number. . .TP .BR e ", " get_mem Get .RI \(aq Memory# \(aq channel number. . .TP .BR G ", " vfo_op " \(aq" "\fIMem/VFO Op\fP" \(aq Perform a .RI \(aq "Mem/VFO Op" \(aq. .IP Mem/VFO Operation is a token: \(oqCPY\(cq, \(oqXCHG\(cq, \(oqFROM_VFO\(cq, \(oqTO_VFO\(cq, \(oqMCL\(cq, \(oqUP\(cq, \(oqDOWN\(cq, \(oqBAND_UP\(cq, \(oqBAND_DOWN\(cq, \(oqLEFT\(cq, \(oqRIGHT\(cq, \(oqTUNE\(cq, \(oqTOGGLE\(cq. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Mem/VFO Op token will return a space separated list of radio backend supported Set Mem/VFO Op tokens. Use this to determine the supported Mem/VFO Ops of a given radio backend. . .TP .BR g ", " scan " \(aq" "\fIScan Fct\fP" "\(aq \(aq" "\fIScan Channel\fP" \(aq Perform a .RI \(aq "Scan Fct" \(aq on a .RI \(aq "Scan Option" \(aq. .IP Scan Function is a token: \(oqSTOP\(cq, \(oqMEM\(cq, \(oqSLCT\(cq, \(oqPRIO\(cq, \(oqPROG\(cq, \(oqDELTA\(cq, \(oqVFO\(cq, \(oqPLT\(cq. .IP Scan Option is an integer. .IP Scan Option for Yaesu rigs 0=STOP, 1=UP, 2=DOWN. .IP Scan Option for Icom rigs is a channel number to program with G otherwise not used. .IP Scan Option for Kenwood rigs is not used. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Scan Fct token will return a space separated list of radio backend supported Scan Function tokens. Use this to determine the supported Scan Functions of a given radio backend. . .TP .BR H ", " set_channel " \(aq" \fIChannel\fP \(aq Set memory .RI \(aq Channel \(aq data. .IP Sets memory channel information . .TP .BR h ", " get_channel " \(aq" \fIreadonly\fP \(aq Get channel memory. .IP If readonly!=0 then only channel data is returned and rig remains on the current channel. If readonly=0 then rig will be set to the channel requested. . .TP .BR A ", " set_trn " \(aq" \fITransceive\fP \(aq Set .RI \(aq Transceive \(aq mode. .IP Transceive is a token: \(oqOFF\(cq, \(oqRIG\(cq, \(oqPOLL\(cq. .IP Transceive is a mechanism for radios to report events without a specific call for information. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Transceive token will return a space separated list of radio backend supported Transceive mode tokens. Use this to determine the supported Transceive modes of a given radio backend. . .TP .BR a ", " get_trn Get .RI \(aq Transceive \(aq mode. .IP Transceive mode (reporting event) as in .B set_trn above. . .TP .BR * ", " reset " \(aq" \fIReset\fP \(aq Perform rig .RI \(aq Reset \(aq. .IP Reset is a value: \(oq0\(cq = None, \(oq1\(cq = Software reset, \(oq2\(cq = VFO reset, \(oq4\(cq = Memory Clear reset, \(oq8\(cq = Master reset. .IP Since these values are defined as a bitmask in .IR include/hamlib/rig.h , it should be possible to OR these values together to do multiple resets at once, if the backend supports it or supports a reset action via rig control at all. . .TP .BR 0x87 ", " set_powerstat " \(aq" "\fIPower Status\fP" \(aq Set .RI \(aq "Power Status" \(aq. .IP Power Status is a value: \(oq0\(cq = Power Off, \(oq1\(cq = Power On, \(oq2\(cq = Power Standby (enter standby), \(oq4\(cq = Power Operate (leave standby). . .TP .BR 0x88 ", " get_powerstat Get .RI \(aq "Power Status" \(aq as in .B set_powerstat above. . .TP .BR 0x89 ", " send_dtmf " \(aq" \fIDigits\fP \(aq Set DTMF .RI \(aq Digits \(aq. . .TP .BR 0x8a ", " recv_dtmf Get DTMF .RI \(aq Digits \(aq. . .TP .BR _ ", " get_info Get misc information about the rig. . .TP .BR 0xf5 ", " get_rig_info Get misc information about the rig vfo status and other info. . .TP .BR 0xf3 ", " get_vfo_info " \(aq" \fIVFO\fP \(aq Get misc information about a specific vfo. . .TP .B dump_state Return certain state information about the radio backend. . .TP .BR 1 ", " dump_caps Not a real rig remote command, it just dumps capabilities, i.e. what the backend knows about this model, and what it can do. .IP TODO: Ensure this is in a consistent format so it can be read into a hash, dictionary, etc. Bug reports requested. .IP .BR Note : This command will produce many lines of output so be very careful if using a fixed length array! For example, running this command against the Dummy backend results in over 5kB of text output. .IP VFO parameter not used in 'VFO mode'. . .TP .BR 2 ", " power2mW " \(aq" "\fIPower [0.0..1.0]\fP" "\(aq \(aq" \fIFrequency\fP "\(aq \(aq" \fIMode\fP \(aq Returns .RI \(aq "Power mW" \(aq. .IP Converts a Power value in a range of .IR 0.0 ... 1.0 to the real transmit power in milli-Watts (integer). .IP .RI \(aq Frequency \(aq and .RI \(aq Mode \(aq also need to be provided as output power may vary according to these values. .IP VFO parameter is not used in VFO mode. . .TP .BR 4 ", " mW2power " \(aq" "\fIPower mW\fP" "\(aq \(aq" \fIFrequency\fP "\(aq \(aq" \fIMode\fP \(aq Returns .RI \(aq "Power [0.0..1.0]" \(aq. .IP Converts the real transmit power in milli-Watts (integer) to a Power value in a range of .IR "0.0 ... 1.0" . .IP .RI \(aq Frequency \(aq and .RI \(aq Mode \(aq also need to be provided as output power may vary according to these values. .IP VFO parameter is not used in VFO mode. . .TP .BR w ", " send_cmd " \(aq" \fICmd\fP \(aq Send a raw command string to the radio. .IP This is useful for testing and troubleshooting radio commands and responses when developing a backend. .IP For binary protocols enter values as \\0xAA\\0xBB. Expect a .RI \(aq Reply \(aq from the radio which will likely be a binary block or an ASCII string depending on the radio's protocol (see your radio's computer control documentation). If you are testing a protocol like SmartSDR where there are spaces in the commands use quote, e.g. w "C0|set slice 0 tx=1" .IP The command terminator, set by the .B send-cmd-term option above, will terminate each command string sent to the radio. This character should not be a part of the input string. . .TP .BR W ", " send_cmd_rx " \(aq" \fICmd\fP\(aq " " \fInbytes_or_terminator_char\fP Send a raw command string to the radio and expect nbytes returned or the terminator char (e.g. ;). .IP This is useful for testing and troubleshooting radio commands and responses when developing a backend. If the # of bytes requested is <= the number actually returned no timeout will occur. If a char is provided it will be used to terminate reading the string so ';' is popular for Kenwood/Yaesu commands for example. .IP The command argument can have no spaces in it. For binary protocols enter values as \\0xAA\\0xBB. Expect a .RI \(aq Reply \(aq from the radio which will likely be a binary block or an ASCII string depending on the radio's protocol (see your radio's computer control documentation). .IP The command terminator, set by the .B send-cmd-term option above, will terminate each command string sent to the radio. This character should not be a part of the input string. . .TP .BR set_clock " \(aq" \fIDateTime\fP \(aq Set .RI \(aq DateTime \(aq .IP Sets rig clock -- note that some rigs do not handle seconds or milliseconds. If you try to set sec/msec and rig does not support it you will get a debug warning message. Format is ISO8601. Formats accepted allow for 2-digit or 4-digit time zone .EX YYYY-MM-DDTHH:MM:SS.SSS+ZZ (where +ZZ is either -/+ UTC offset HH) YYYY-MM-DDTHH:MM:SS.SSS+ZZZZ (where +ZZZZ is either -/+ UTC offset HHMM) YYYY-MM-DDTHH:MM:SS+ZZ YYYY-MM-DDTHH:MM:SS+ZZZZ YYYY-MM-DDTHH:MM+ZZ YYYY-MM-DDTHH:MM+ZZZZ YYYY-MM-DD (sets date only) local (sets both clocks to local time) utc (sets both clocks to utc time) .EE Note: Icom rigs expect you to set local time and the hours off to UTC. So...4PM EST example would be 2021-12-01T16:00:00-0500 But...if you want to display GMT you must set the clock for GMT with zero UTC offset. Hopefully Icom will allow displaying either clock in the future Note: Kenwood rigs only allow setting local clock, and then only if not autoset by NTP. Trying to set clock when NTP is in use will set the offset, but not the time - and no error status will be returned. Time displayed on the auxiliary clock is solely determined by UTC and the aux offset. .TP .BR get_clock Get .RI \(aq RigTime \(aq .IP Gets rig clock -- note that some rigs do not handle seconds or milliseconds. Format is ISO8601 YYYY-MM-DDTHH:MM:SS.sss+ZZ where +ZZ is either -/+ UTC offset . .TP .BR chk_vfo Get .RI \(aq Status \(aq .IP Returns Status as 1 if vfo option is on and 0 if vfo option is off. This command reflects the -o switch for rigctl and ritctld and can be dynamically changed by .B set_vfo_opt. . .TP .BR set_vfo_opt " \(aq" \fIStatus\fP \(aq Set .RI \(aq Status \(aq .IP Set vfo option Status 1=on or 0=off This is the same as using the -o switch for rigctl and ritctld. This can be dynamically changed while running. . .TP .BR get_separator Get .RI \(aq SeparatorChar \(aq .IP Shows the current SeparatorChar . .TP .BR set_separator " \(aq" \fISeparatorChar\fP \(aq Set .RI \(aq SeparatorChar \(aq .IP Change rigctld response to use a special char instead of newline (recommend #). Handy for node-red's tcprequest node. This can be dynamically changed while running. . .TP .BR pause " \(aq" \fISeconds\fP \(aq Pause for the given whole (integer) number of .RI \(aq Seconds \(aq before sending the next command to the radio. . .TP .BR password " \(aq" \fIPassword\fP \(aq Sends password to rigctld when rigctld has been secured with -A. Must use the 32-char shared secret from rigctld. (NOT IMPLEMENTED) . .TP .BR set_lock_mode " \(aq" \fILocked\fP \(aq Turns mode lock on(1) or off(0) (only when using rigctld). Turning on will prevent all clients from changing the rig mode. For example this is useful when running CW Skimmer in FM mode on an IC-7300. Clicking spots in a spotting program will not change the VFOA mode when lock is on. So "set_lock_mode 1" when CW Skimmer is started and "set_lock_mode 0" when CW Skimmer is stopped. . .TP .BR get_lock_mode Returns current lock mode status 1=On, 2=Off (only useful when using rigctld) . .TP .BR send_raw " \(aq" \fITerminator\fP "\(aq \(aq" \fIString\fP \(aq Can send ASCII string or 0xnn values or xnn values -- there can be no spaces in the command string. Possible terminator values are CR, LF, ;, ICOM, 0-100 (bytes to read), or -1 meaning unknown (will timeout on read) Examples (note that a ; must be escaped in Unix/Linux): .IP For Windows & Unix/Linux we have a new colon-separated format for hex digits .EX send_raw icom 0xFE:0xFE:0x94:0x03:0xFD Note: colon-separated does not have to be escaped on Unix/Linux send_raw -1 0xFE:0xFE:0x94:0x03:0xFD send_raw 14 0xFE:0xFE:0x94:0x03:0xFD Note that ASCII commands still require escaping the semicolon on Unix/Linux send_raw \; FA\;MD\; .EE For Windows: .EX send_raw icom 0xFE;0xFE;0x94;0x03;0xFD send_raw -1 0xFE;0xFE;0x94;0x03;0xFD send_raw 14 0xFE;0xFE;0x94;0x03;0xFD .EE For Unix/Linux .EX send_raw icom 0xFE\;0xFE\;0x94\;0x03\;0xFD send_raw \; FA\;MD\; send_raw -1 0xFE\;0xFE\;0x94\;0x03\;0xFD send_raw 14 0xFE\;0xFE\;0x94\;0x03\;0xFD .EE . .TP .BR client_version " \(aq" \fIString\fP "\(aq Client can send its version to .B rigctld and get feedback on compatibility, deprecation, and alternatives .TP .BR hamlib_version Returns Hamlib version with ISO8601 date/time . .TP .BR test Performs test routines. Under development. . .TP .BR set_gpio " \(aq" \fIGPIO#\fP "\(aq Sets GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port Can also use 1,2,3,4 . .TP .BR get_gpio " \(aq" \fIGPIO#\fP "\(aq Reads GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port Can also use 1,2,3,4 . .TP .BR skip_init Skips rig initialization -- useful when executing commands with rigctl to speed up things . .TP .BR freq_skip " " 'skip' When skip!=0 skips setting freq on TX_VFO when in RX and on RX_VFO when in TX -- for use with gpredict and rigs that do not have TARGETABLE_VFO . .SH READLINE . If .B Readline library development files are found at configure time, .B rigctl will be conditionally built with Readline support for command and argument entry. Readline command key bindings are at their defaults as described in the .UR https://tiswww.cwru.edu/php/chet/readline/rluserman.html Readline manual .UE . .B rigctl sets the name \(lqrigctl\(rq which can be used in Conditional Init Constructs in the Readline Init File .RI ( $HOME/.inputrc by default) for custom keybindings unique to .BR rigctl . . .PP Command history is available with Readline support as described in the .UR https://tiswww.case.edu/php/chet/readline/history.html#SEC1 Readline History manual .UE . Command and argument strings are stored as single lines even when arguments are prompted for input individually. Commands and arguments are not validated and are stored as typed with values separated by a single space. . .PP Normally session history is not saved, however, use of either of the .BR \-i / \-\-read\-history or .BR \-I / \-\-save\-history options when starting .B rigctl will cause any previously saved history to be read in and/or the current and any previous session history (assuming the .BR -i " and " -I options are given together) will be written out when .B rigctl is closed. Each option is mutually exclusive, i.e. either may be given separately or in combination. This is useful to save a set of commands and then read them later but not write the modified history for a consistent set of test commands in interactive mode, for example. . .PP History is stored in .I $HOME/.rigctl_history by default although the destination directory may be changed by setting the .B RIGCTL_HIST_DIR environment variable. When RIGCTL_HIST_DIR is unset, the value of the .B HOME environment variable is used instead. Only the destination directory may be changed at this time. . .PP If Readline support is not found at configure time the original internal command handler is used. Readline is not used for .B rigctl commands entered on the command line regardless if Readline support is built in or not. . .PP .BR Note : Readline support is not included in the MS Windows 32 or 64 bit binary builds supplied by the Hamlib Project. Running .B rigctl on the MS Windows platform in the \(oqcmd\(cq shell does give session command line history, however, it is not saved to disk between sessions. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS .B rigctl exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib . . . .SH EXAMPLES . Start .B rigctl for a Yaesu FT-920 using a USB to serial adapter on Linux in interactive mode: . .PP .in +4n .EX .RB $ " rigctl -m 1014 -r /dev/ttyUSB1" .EE .in . .PP Start .B rigctl for a Yaesu FT-920 using COM1 on MS Windows while generating TRACE output to .IR stderr : . .PP .in +4n .EX .RB > " rigctl -m 1014 -r COM1 -vvvvv" .EE .in . .PP Start .B rigctl for a Yaesu FT-920 using a USB to serial adapter while setting baud rate and stop bits: . .PP .in +4n .EX .RB $ " rigctl -m 1014 -r /dev/ttyUSB1 -s 4800 -C stop_bits=2" .EE .in . .PP Start .B rigctl for an Elecraft K3 using a USB to serial adapter while specifying a command terminator for the .B w command: . .PP .in +4n .EX .RB $ " rigctl -m 2029 -r /dev/ttyUSB0 -t';'" .EE .in . .PP Connect to a running .B rigctld with radio model 2 (\(lqNET rigctl\(rq) on the local host and specifying the TCP port, setting frequency and mode: . .PP .in +4n .EX .RB $ " rigctl -m 2 -r localhost:4532 F 7253500 M LSB 0" .EE .in . . .SH BUGS . .B set_chan has no entry method as of yet, hence left unimplemented. .PP This almost empty section... .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2011 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2010-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR less (1), .BR more (1), .BR rigctld (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rotctld.10000664000175000017500000005327715056640442011627 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rotctld.c .\" .TH ROTCTLD "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . . rotctld \- TCP rotator control daemon . .SH SYNOPSIS . .SY rotctld .OP \-hlLuV .OP \-m id .OP \-r device .OP \-s baud .OP \-T IPADDR .OP \-t number .OP \-C parm=val .RB [ \-v [ \-Z ]] .YS . . .SH DESCRIPTION . The .B rotctld program is a rotator control daemon that handles client requests via TCP sockets. This allows multiple user programs to share one rotator (this needs more development). Multiple rotators can be controlled on different TCP ports by use of multiple .B rotctld processes. The syntax of the commands are the same as .BR rotctl (1). It is hoped that .B rotctld will be especially useful for client authors using languages such as Perl, Python, PHP, and others. . .PP .B rotctld communicates to a client through a TCP socket using text commands shared with .BR rotctl . The protocol is simple, commands are sent to .B rotctld on one line and .B rotctld responds to \(lqget\(rq commands with the requested values, one per line, when successful, otherwise, it responds with one line \(lqRPRT x\(rq, where \(oqx\(cq is a negative number indicating the error code. Commands that do not return values respond with the line \(lqRPRT x\(rq, where \(oqx\(cq is \(oq0\(cq when successful, otherwise is a regative number indicating the error code. Each line is terminated with a newline \(oq\\n\(cq character. This protocol is primarily for use by the .B NET rotctl (rotator model 2) backend. . .PP A separate .B Extended Response Protocol extends the above behavior by echoing the received command string as a header, any returned values as a key: value pair, and the \(lqRPRT x\(rq string as the end of response marker which includes the .B Hamlib success or failure value. See the .B PROTOCOL section for details. Consider using this protocol for clients that will interact with .B rotctld directly through a TCP socket. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete rotator support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select rotator model number. .IP See model list (use \(lqrotctld -l\(rq). .IP .BR Note : .B rotctl (or third party software using the C API) will use rotator model 2 for .B NET rotctl (this model number is not used for rotctld even though it shows in the model list). . .TP .BR \-r ", " \-\-rot\-file = \fIdevice\fP Use .I device as the file name of the port connected to the rotator. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from rotator backend capabilities as the default. . .TP .BR \-T ", " \-\-listen\-addr = \fIIPADDR\fP Use .I IPADDR as the listening IP address. .IP The default is ANY. .IP .B rotctld can be run and connected to like this: . .IP .EX rotctld (binds to all interfaces) . .in +4n rotctl -m 2 rotctl -m 2 -r 127.0.0.1 rotctl -m 2 -r localhost rotctl -m 2 -r 192.168.1.1 (local IP address) rotctl -m 2 -r ::1 (on Linux rotctld doesn't listen on IPV6 by default) .in . .IP rotctld -T 127.0.0.1 (bind only to 127.0.0.1) .in +4n rotctl -m 2 (binds to all interfaces) rotctl -m 2 -r 127.0.0.1 (bind only to 127.0.0.1) .EE . .TP .BR \-t ", " \-\-port = \fInumber\fP Use .I number as the TCP listening port. .IP The default is 4533. .IP .BR Note : As .BR rotctld \(aqs default port is 4533, it is advisable to use odd numbered ports for .BR rotctld , e.g. 4533, 4535, 4537, etc. . .TP .BR \-L ", " \-\-show\-conf List all configuration parameters for the rotator defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set rotator configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-state Dump state for the rotator defined with .B -m above and exit. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the rotator defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all rotator model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrotctl -l | more\(rq. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rotctld and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . .PP Be aware that the backend for the rotator to be controlled, or the rotator itself may not support some commands. In that case, the operation will fail with a .B Hamlib error code. . . .SH COMMANDS . Commands can be sent over the TCP socket either as a single char, or as a long command name plus the value(s) space separated on one \(oq\\n\(cq terminated line. See .BR PROTOCOL . . .PP Since most of the .B Hamlib operations have a .BR set " and a " get method, an upper case letter will be used for .B set methods whereas the corresponding lower case letter refers to the .B get method. Each operation also has a long name; prepend a backslash, \(oq\\\(cq, to send a long command name. . .PP Example (Perl): \(lqprint $socket "\\\\dump_caps\\n";\(rq to see what the rotator's backend can do .RB ( Note : In Perl and many other languages a \(oq\\\(cq will need to be escaped with a preceding \(oq\\\(cq so that even though two backslash characters appear in the code, only one will be passed to .BR rotctld . This is a possible bug, beware!). . .PP .BR Note : The backend for the rotator to be controlled, or the rotator itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . .PP Here is a summary of the supported commands (In the case of .B set commands the quoted italicized string is replaced by the value in the description. In the case of .B get commands the quoted italicized string is the key name of the value returned.): . .TP .BR P ", " set_pos " \(aq" \fIAzimuth\fP "\(aq \(aq" \fIElevation\fP \(aq Set position. .IP .RI \(aq Azimuth \(aq and .RI \(aq Elevation \(aq are floating point values. .IP For example (typed text shown in bold): . .IP .in +4n .EX .B P 163.0 41.0 .EE .in . .IP .BR Note : If the rotator does not support setting elevation (most do not) supply \(lq0.0\(rq for .RI \(aq Elevation \(aq. . .TP .BR p ", " get_pos Get position. .IP .RI \(aq Azimuth \(aq and .RI \(aq Elevation \(aq are returned as double precision floating point values. . .TP .BR M ", " move " \(aq" \fIDirection\fP "\(aq \(aq" \fISpeed\fP \(aq Move the rotator in a specific direction at the given rate. .IP .RI \(aq Direction \(aq is an integer or keyword defined as \(oq2\(cq = UP, \(oq4\(cq = DOWN, \(oq8\(cq = LEFT or CCW, \(oq16\(cq = RIGHT or CW, \(oq32\(cq = UP_LEFT or UP_CCW, \(oqR64\(cq = UP_RIGHT = UP_CW, \(oq128\(cq = DOWN_LEFT or DOWN_CCW, \(oq256\(cq = DOWN_RIGHT or DOWN_CW .IP .RI \(aq Speed \(aq is an integer between 1 and 100. Use -1 for no change to current speed. .IP .BR Note : Not all backends that implement the move command use the Speed value. . .TP .BR S ", " stop Stop the rotator. . .TP .BR K ", " park Park the rotator. . .TP .BR C ", " set_conf " \(aq" \fIToken\fR "\(aq \(aq" \fIValue\fP \(aq Set a configuration parameter. .IP .RI \(aq Token \(aq is a string; see the .B \-C option and the .B \-L output. .IP .RI \(aq Value \(aq is a string of up to 20 characters. .\" FIXME: Need to describe the reset parameters available. . .TP .BR R ", " reset " \(aq" \fIReset\fP \(aq Reset the rotator. .IP .RI \(aq Reset \(aq accepts an integer value of \(oq1\(cq for \(lqReset All\(rq. .TP .BR _ ", " get_info Get misc information about the rotator. .IP Returns .RI \(aq Info \(aq \(lqModel Name\(rq. . .TP .B dump_state Return certain state information about the rotator backend. . .TP .BR 1 ", " dump_caps Not a real rot remote command, it just dumps capabilities, i.e. what the backend knows about this model, and what it can do. . .TP .BR w ", " send_cmd " \(aq" \fICmd\fP \(aq Send a raw command string to the rotator. .IP ASCII CR is appended automatically at the end of the command for text protocols. For binary protocols, enter hexadecimal values as \(lq\\0xAA\\0xBB\(rq. . . .SS Locator Commands . These commands offer conversions of Degrees Minutes Seconds to other formats, .B Maidenhead square locator conversions and distance and azimuth conversions. .TP .BR L ", " lonlat2loc " \(aq" \fILongitude\fP "\(aq \(aq" \fILatitude\fP "\(aq \(aq" "\fILoc Len\fP" \(aq Returns the .B Maidenhead .RI \(aq Locator \(aq for the given .RI \(aq Longitude "\(aq and \(aq" Latitude \(aq. .IP .RI \(aq Longitude "\(aq and \(aq" Latitude \(aq are floating point values. .IP .RI \(aq "Loc Len" \(aq is the precision of the returned square and should be an even numbered integer value between 2 and 12. .IP For example: . .IP .in +4n .EX .B L -170.0 -85.0 12 .EE .in . .IP returns: . .IP .in +4n .EX Locator: AA55AA00AA00 .EE .in . .TP .BR l ", " loc2lonlat " \(aq" \fILocator\fP \(aq Returns .RI \(aq Longitude "\(aq and \(aq" Latitude \(aq in decimal degrees at the approximate center of the requested .B Maidenhead grid square. .IP .RI \(aq Locator \(aq can be from 2 to 12 characters in length. .IP West longitude is expressed as a negative value. .IP South latitude is expressed as a negative value. .IP For example: . .IP .in +4n .EX .B l AA55AA00AA00 .EE .in . .IP returns: . .IP .in +4n .EX Longitude: -169.999983 Latitude: -84.999991 .EE .in . .IP .BR Note : Despite the use of double precision variables internally, some rounding error occurs. . .TP .BR D ", " dms2dec " \(aq" \fIDegrees\fP "\(aq \(aq" \fIMinutes\fP "\(aq \(aq" \fISeconds\fP "\(aq \(aq" \fIS/W\fP \(aq Returns .RI \(aq "Dec Degrees" \(aq, a signed floating point value. .IP .RI \(aq Degrees "\(aq and \(aq" Minutes \(aq are integer values. .IP .RI \(aq Seconds \(aq is a floating point value. .IP .RI \(aq S/W \(aq is a flag with \(oq1\(cq indicating South latitude or West longitude and \(oq0\(cq North or East (the flag is needed as computers don't recognize a signed zero even though only the .RI \(aq Degrees \(aq value is typically signed in DMS notation). . .TP .BR d ", " dec2dms " \(aq" "\fIDec Degrees\fP" \(aq Returns .RI \(aq Degrees "\(aq \(aq" Minutes "\(aq \(aq" Seconds "\(aq \(aq" S/W \(aq. .IP Values are as in .B dms2dec above. . .TP .BR E ", " dmmm2dec " \(aq" \fIDegrees\fP "\(aq \(aq" "\fIDec Minutes\fP" "\(aq \(aq" \fIS/W\fP \(aq Returns .RI \(aq "Dec Degrees" \(aq, a signed floating point value. .IP .RI \(aq Degrees \(aq is an integer value. .IP .RI \(aq "Dec Minutes" \(aq is a floating point value. .IP .RI \(aq S/W \(aq is a flag as in .B dms2dec above. . .TP .BR e ", " dec2dmmm " \(aq" "\fIDec Deg\fP" \(aq Returns .RI \(aq Degrees "\(aq \(aq" Minutes "\(aq \(aq" S/W \(aq. .IP Values are as in .B dmmm2dec above. . .TP .BR B ", " qrb " \(aq" "\fILon 1\fP" "\(aq \(aq" "\fILat 1\fP" "\(aq \(aq" "\fILon 2\fP" "\(aq \(aq" "\fILat 2\fP" \(aq Returns .RI \(aq Distance "\(aq and \(aq" Azimuth \(aq. .IP .RI \(aq Distance \(aq is in km. .IP .RI \(aq Azimuth \(aq is in degrees. .IP Supplied .IR Lon / Lat values are signed floating point numbers. . .TP .BR A ", " a_sp2a_lp " \(aq" "\fIShort Path Deg\fP" \(aq Returns .RI \(aq "Long Path Deg" \(aq. .IP Both the supplied argument and returned value are floating point values within the range of 0.00 to 360.00. .IP .BR Note : Supplying a negative value will return an error message. . .TP .BR a ", " d_sp2d_lp " \(aq" "\fIShort Path km\fP" \(aq Returns .RI \(aq "Long Path km" \(aq. .IP Both the supplied argument and returned value are floating point values. . .TP .BR pause " \(aq" \fISeconds\fP \(aq Pause for the given whole (integer) number of .RI \(aq Seconds \(aq before sending the next command to the rotator. . . .SH PROTOCOL . There are two protocols in use by .BR rotctld , the .B Default Protocol and the .BR "Extended Response Protocol" . . .PP The .B Default Protocol is intended primarily for the communication between .B Hamlib library functions and .B rotctld (\(lqNET rotctl\(rq, available using rotator model \(oq2\(cq). . .PP The .B Extended Response Protocol is intended to be used with scripts or other programs interacting directly with .B rotctld as consistent feedback is provided. . . .SS Default Protocol . The .B Default Protocol is intentionally simple. Commands are entered on a single line with any needed values. In practice, reliable results are obtained by terminating each command string with a newline character, \(oq\\n\(cq. . .PP Example set position (Perl code): . .PP .in +4n .EX \fBprint $socket "P 135 10\\n";\fP .EE .in . .PP or: . .PP .in +4n .EX \fBprint $socket "\\\\set_pos 135 10\\n";\fP # escape leading \(oq\\\(cq .EE .in . .PP A one line response will be sent as a reply to .B set commands, \(lqRPRT \fIx\fP\\n\(rq where .I x is the Hamlib error code with \(oq0\(cq indicating success of the command. . .PP Responses from .B rotctld .B get commands are text values and match the same tokens used in the .B set commands. Each value is returned on its own line. On error the string \(lqRPRT \fIx\fP\\n\(rq is returned where .I x is the Hamlib error code. . .PP Example get position (Perl code): . .PP .in +4n .EX \fBprint $socket "p\\n";\fP "135" "10" .EE .in . .PP Most .B get functions return one to three values. A notable exception is the .B dump_caps command which returns many lines of \fBkey\fR:\fIvalue\fR pairs. . .PP This protocol is primarily used by the \(lqNET rotctl\(rq (rotctl model 2) backend which allows applications already written for Hamlib's C API to take advantage of .B rotctld without the need of rewriting application code. An application's user can select rotator model 2 (\(lqNET rotctl\(rq) and then set .B rot_pathname to \(lqlocalhost:4533\(rq or other network .IR host : port (set by the .BR \-T / \-t options, respectively, above). . . .SS Extended Response Protocol . The Extended Response protocol adds several rules to the strings returned by .B rotctld and adds a rule for the command syntax. . .PP 1. The command received by .B rotctld is echoed with its long command name followed by the value(s) (if any) received from the client terminated by the specified response separator as the first record of the response. . .PP 2. The last record of each block is the string \(lqRPRT \fIx\fP\\n\(rq where .I x is the numeric return value of the Hamlib backend function that was called by the command. . .PP 3. Any records consisting of data values returned by the rotator backend are prepended by a string immediately followed by a colon then a space and then the value terminated by the response separator, e.g. \(lqAzimuth: 90.000000\\n\(rq when the command was prepended by \(oq+\(cq. . .PP 4. All commands received will be acknowledged by .B rotctld with records from rules 1 and 2. Records from rule 3 are only returned when data values must be returned to the client. . .PP An example response to a .B P command sent from the shell prompt (note the prepended \(oq+\(cq): . .PP .in +4n .EX $ \fBecho "+P 90 45" | nc -w 1 localhost 4533\fP set_pos: 90 45 RPRT 0 .EE .in . .PP In this case the long command name and values are returned on the first line and the second line contains the end of block marker and the numeric rotor backend return value indicating success. . .PP An example response to a .B get_pos query: . .PP .in +3n .EX $ \fBecho "+\\get_pos" | nc -w 1 localhost 4533\fP get_pos: Azimuth: 90.000000 Elevation: 45.000000 RPRT 0 .EE .in . .IP .BR Note : The \(oq\\\(cq is still required for the long command name even with the ERP character. . .PP In this case, as no value is passed to .BR rotctld , the first line consists only of the long command name. The final line shows that the command was processed successfully by the rotor backend. . .PP Invoking the Extended Response Protocol requires prepending a command with a punctuation character. As shown in the examples above, prepending a \(oq+\(cq character to the command results in the responses being separated by a newline character (\(oq\\n\(cq). Any other punctuation character recognized by the C .BR ispunct () function except \(oq\\\(cq, \(oq?\(cq, or \(oq_\(cq will cause that character to become the response separator and the entire response will be on one line. . .PP Separator character summary: . .TP .RB \(oq + \(cq Each record of the response is appended with a newline (\(oq\\n\(cq). . .TP .RB \(oq ; "\(cq, \(oq" | "\(cq, or, \(oq" , \(cq Each record of the response is appended by the given character resulting in entire response on one line. .IP These are common record separators for text representations of spreadsheet data, etc. . .TP .RB \(oq ? \(cq Reserved for help in .BR rotctl . . .TP .RB \(oq _ \(cq Reserved for .B get_info short command . .TP .RB \(oq # \(cq Reserved for comments when reading a command file script. .IP .BR Note : Other punctuation characters have not been tested! Use at your own risk. . .PP For example, invoking a .B get_pos query with a leading \(oq;\(cq returns: . .PP .in +4n .EX get_pos:;Azimuth: 90.000000;Elevation: 45.000000;RPRT 0 .EE .in . .PP Or, using the pipe character \(oq|\(cq returns: . .PP .in +4n .EX get_pos:|Azimuth: 90.000000|Elevation: 45.000000|RPRT 0 .EE .in . .PP And a .B set_pos command prepended with a \(oq|\(cq returns: . .PP .in +4n .EX set_pos: 135 22.5|RPRT 0 .EE .in . .PP Such a format will allow reading a response as a single event using a preferred response separator. Other punctuation characters have not been tested! . .PP All commands with the exception of .B set_conf have been tested with the Extended Response protocol and the included .B testrotctld.pl Perl script. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXAMPLES . Start .B rotctld for a Hy-Gain Ham IV rotor with the Idiom Press RotorEZ board installed using a USB-to-serial adapter and backgrounding: . .PP .in +4n .EX $ \fBrotctld \-m 401 \-r /dev/ttyUSB1 &\fP .EE .in . .PP Start .B rotctld for RotorEZ using COM2 on Win32: . .PP .in +4n .EX > \fBrotctl \-m 401 \-r COM2\fP .EE .in . .PP Connect to the already running .BR rotctld , and set position to 135.0 degrees azimuth and 30.0 degrees elevation with a 1 second read timeout from the shell prompt: . .PP .in +4n .EX $ \fBecho "\\set_pos 135.0 30.0" | nc \-w 1 localhost 4533\fP .EE .in . .PP Connect to a running .B rotctld with .B rotctl on the local host: .PP .in +4n .EX $ \fBrotctl \-m 2\fP .EE .in . . .SH SECURITY . No authentication whatsoever; DO NOT leave this TCP port open wide to the Internet. Please ask if stronger security is needed or consider using a Secure Shell .RB ( ssh (1)) tunnel. . .PP As .B rotctld does not need any greater permissions than .BR rotctl , it is advisable to not start .B rotctld as \(lqroot\(rq or another system user account in order to limit any vulnerability. . . .SH BUGS . The daemon is not detaching and backgrounding itself. . .PP No method to exit the daemon so the .BR kill (1) command must be used to terminate it. . .PP Multiple clients using the daemon may experience contention with the connected rotator. . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2009 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2011-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR kill (1), .BR rotctl (1), .BR ssh (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rotctl.10000664000175000017500000004611615056640442011455 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rotctl.c .\" .TH ROTCTL "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rotctl \- control antenna rotators . . .SH SYNOPSIS . .SY rotctl .OP \-hiIlLuV .OP \-m id .OP \-r device .OP \-R device2 .OP \-s baud .OP \-t char .OP \-C parm=val .OP \-o azoffset .OP \-O eloffset .RB [ \-v [ \-Z ]] .RB [ command | \- ] .YS . . .SH DESCRIPTION . Control antenna rotators. . .PP .B rotctl accepts .I commands from the command line as well as in interactive mode if none are provided on the command line. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete rotator support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select rotator model number. .IP See model list (use \(lqrotctl -l\(rq). .IP .BR Note : .B rotctl (or third party software using the C API) will use rotator model 2 for .B NET rotctl (communicating with .BR rotctld ). . .TP .BR \-r ", " \-\-rot\-file = \fIdevice\fP Use .I device as the file name of the port connected to the rotator. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-R ", " \-\-rot\-file2 = \fIdevice\fP Use .I device as the file name of the port connected to the 2nd rotator. e.g. 2nd rotator used for elevation. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from rotator backend capabilities as the default. . .TP .BR \-t ", " \-\-send\-cmd\-term = \fIchar\fP Change the termination .I char for text protocol when using the .B send_cmd command. .IP The default value is ASCII CR (\(oq0x0D\(cq). ASCII non-printing characters can be given as the ASCII number in hexadecimal format prepended with \(lq0x\(rq. You may pass an empty string for no termination char. The string \(lq\-1\(rq tells .B rotctl to switch to binary protocol. See the .B send_cmd command for further explanation. .IP .BR Note : The semicolon (\(oq;\(cq) is a common terminator for rotators that accept ASCII character strings. . .TP .BR \-o ", " \-\-set\-azoffset Azimuth correction floating point -- during set value is added, during get value is subtracted. . .TP .BR \-O ", " \-\-set\-eloffset Elevation correction floating point -- during set value is added, during get value is subtracted. . . .TP .BR \-L ", " \-\-show\-conf List all configuration parameters for the rotator defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set rotator configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the rotator defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all rotator model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrotctl -l | more\(rq. . .TP .BR \-i ", " \-\-read\-history Read previously saved command and argument history from a file (default .IR $HOME/.rotctl_history ) for the current session. .IP Available when .B rotctl is built with Readline support (see .B READLINE below). .IP .BR Note : To read a history file stored in another directory, set the .B ROTCTL_HIST_DIR environment variable, e.g. \(lqROTCTL_HIST_DIR=$HOME/tmp rotctl -i\(rq. When ROTCTL_HIST_DIR is not set, the value of .B HOME is used. . .TP .BR \-I ", " \-\-save\-history Write current session (and any previous session(s), if .B -i option is also given) command and argument history to a file (default .IR $HOME/.rotctl_history ) at the end of the current session. .IP Complete commands with arguments are saved as a single line to be recalled and used or edited. Available when .B rotctl is built with Readline support (see .B READLINE below). .IP .BR Note : To write a history file in another directory, set the .B ROTCTL_HIST_DIR environment variable, e.g. \(lqROTCTL_HIST_DIR=$HOME/tmp rotctl -I\(rq. When ROTCTL_HIST_DIR is not set, the value of .B HOME is used. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rotctl and exit. . .TP .B \- Stop option processing and read commands from standard input. .IP See .B Standard Input below. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . .PP Be aware that the backend for the rotator to be controlled, or the rotator itself may not support some commands. In that case, the operation will fail with a .B Hamlib error code. . . .SH COMMANDS . Commands can be entered either as a single char, or as a long command name. The commands are not prefixed with a dash as the options are. They may be typed in when in interactive mode or provided as argument(s) in command line interface mode. In interactive mode commands and their arguments may be entered on a single line (typed text shown in bold): . .PP .in +4n .EX .B P 123 45 .EE .in . .PP Since most of the .B Hamlib operations have a .BR set " and a " get method, an upper case letter will often be used for a .B set method whereas the corresponding lower case letter refers to the .B get method. Each operation also has a long name; in interactive mode, prepend a backslash, \(oq\\\(cq, to enter a long command name. . .PP Example: Use \(lq\\get_info\(rq in interactive mode to see the rotator's information. . .IP .BR Note : The backend for the rotator to be controlled, or the rotator itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . . .SS Standard Input . As an alternative to the .B READLINE interactive command entry or a single command for each run, .B rotctl features a special option where a single dash (\(oq\-\(cq) may be used to read commands from standard input .RB ( stdin ). Commands must be separated by whitespace similar to the commands given on the command line. Comments may be added using the \(oq#\(cq character, all text up until the end of the current line including the \(oq#\(cq character is ignored. . .PP A simple example: . .PP .in +4n .EX .RB $ " cat <<.EOF. >cmds.txt" .RB > " # File of commands" .RB > " set_pos 180.0 10.0 # rotate" .RB > " pause 30 # wait for action to complete" .RB > " get_pos # query rotator" .RB > .EOF. .RB $ " rotctl -m 1 - " rotctl -m 401 -r COM2" .EE .in . .PP Connect to a running .B rotctld with rotator model 2 (\(lqNET rotctl\(rq) on the local host and specifying the TCP port, and querying the position: . .PP .in +4n .EX .RB $ " rotctl -m 2 -r localhost:4533 \\get_pos" .EE .in . . .SH BUGS . Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2001-2011 Stephane Fillod .br Copyright \(co 2002-2017 the Hamlib Group (various contributors) .br Copyright \(co 2003-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR less (1), .BR more (1), .BR rotctld (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/ampctld.10000664000175000017500000004251715056640442011573 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, ampctld.c .\" .TH AMPCTLD "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . ampctld \- TCP amplifier control daemon . . .SH SYNOPSIS . .SY ampctld .OP \-hlLuV .OP \-m id .OP \-r device .OP \-s baud .OP \-T IPADDR .OP \-t number .OP \-C parm=val .RB [ \-v [ \-Z ]] .YS . . .SH DESCRIPTION . The .B ampctld program is an amplifier control daemon that handles client requests via TCP sockets. This allows multiple user programs to share one amplifier (this needs more development). Multiple amplifiers can be controlled on different TCP ports by use of multiple .B ampctld processes. Note that multiple processes/ports are also necessary if some clients use extended responses and/or vfo mode. So up to 4 processes/ports may be needed for each combination of extended response/vfo mode. The syntax of the commands are the same as .BR ampctl (1). It is hoped that .B ampctld will be especially useful for client authors using languages such as Perl, Python, PHP, and others. . .PP .B ampctld communicates to a client through a TCP socket using text commands shared with .BR ampctl . The protocol is simple, commands are sent to .B ampctld on one line and .B ampctld responds to .B get commands with the requested values, one per line, when successful, otherwise, it responds with one line \(lqRPRT x\(rq, where \(oqx\(cq is a negative number indicating the error code. Commands that do not return values respond with the line \(lqRPRT x\(rq, where \(oqx\(cq is \(oq0\(cq when successful, otherwise is a regative number indicating the error code. Each line is terminated with a newline \(oq\\n\(cq character. This protocol is primarily for use by the .B NET ampctl (amplifier model 2) backend. . .PP A separate .B Extended Response Protocol extends the above behavior by echoing the received command string as a header, any returned values as a key: value pair, and the \(lqRPRT x\(rq string as the end of response marker which includes the .B Hamlib success or failure value. See the .B PROTOCOL section for details. Consider using this protocol for clients that will interact with .B ampctld directly through a TCP socket. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete amplifier support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select amplifier model number. .IP See model list (use \(lqampctl -l\(rq). .IP .BR Note : .B ampctl (or third party software using the C API) will use amplifier model 2 for .B NET ampctl (communicating with .BR ampctld ). . .TP .BR \-r ", " \-\-amp\-file = \fIdevice\fP Use .I device as the file name of the port connected to the amplifier. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from amplifier backend capabilities (set by .B -m above) as the default. . .TP .BR \-t ", " \-\-port = \fInumber\fP Use .I number as the TCP listening port. .IP The default is 4531. .IP .BR Note : As .BR rigctld 's default port is 4532 and .BR rotctld 's default port is 4533, it is recommended to use DESCENDING odd numbered ports for multiple .BR ampctld instances, e.g. 4529, 4527, 4525, etc. . .TP .BR \-T ", " \-\-listen\-addr = \fIIPADDR\fP Use .I IPADDR as the listening IP address. .IP The default is ANY. . .TP .BR \-L ", " \-\-show\-conf List all config parameters for the amplifier defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set amplifier configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the amplifier defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all amplifier model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqampctl -l | more\(rq. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B ampctl and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . .PP Please note that the backend for the amplifier to be controlled, or the amplifier itself may not support some commands. In that case, the operation will fail with a .B Hamlib error code. . . .SH COMMANDS . Commands can be sent over the TCP socket either as a single char, or as a long command name plus the value(s) space separated on one \(oq\\n\(cq terminated line. See .BR PROTOCOL . . .PP Since most of the .B Hamlib operations have a .B set and a .B get method, an upper case letter will be used for .B set methods whereas the corresponding lower case letter refers to the .B get method. Each operation also has a long name; prepend a backslash, \(oq\\\(cq, to send a long command name. . .PP Example (Perl): \(lqprint $socket "\\\\dump_caps\\n";\(rq to see what the amplifier's backend can do .RB ( Note : In Perl and many other languages a \(oq\\\(cq will need to be escaped with a preceding \(oq\\\(cq so that even though two backslash characters appear in the code, only one will be passed to .BR ampctld . This is a possible bug, beware!). . .PP .BR Note : The backend for the amplifier to be controlled, or the amplifier itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . .PP Here is a summary of the supported commands (In the case of .B set commands the quoted italicized string is replaced by the value in the description. In the case of .B get commands the quoted italicized string is the key name of the value returned.): . .TP .BR F ", " set_freq " \(aq" \fIFrequency\fP \(aq Set .RI \(aq Frequency \(aq, in Hz. .IP Frequency may be a floating point or integer value. . .TP .BR f ", " get_freq Get .RI \(aq Frequency \(aq, in Hz. .IP Returns an integer value. . .TP .BR l ", " get_level " \(aq" \fILevel\fP \(aq Get .RI \(aq "Level Value" \(aq. .IP Returns Level Value as a float or integer for the Level token given. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Level token will return a space separated list of amplifier backend supported get level tokens. Use this to determine the supported levels of a given amplifier backend. . .TP .B dump_state Return certain state information about the amplifier backend. . .TP .BR 1 ", " dump_caps Not a real amplifier remote command, it just dumps capabilities, i.e. what the backend knows about this model, and what it can do. .IP TODO: Ensure this is in a consistent format so it can be read into a hash, dictionary, etc. Bug reports requested. .IP .BR Note : This command will produce many lines of output so be very careful if using a fixed length array! For example, running this command against the Dummy backend results in a number of lines of text output. . .TP .BR _ ", " get_info Return information from the amplifier backend. . .TP .BR R ", " reset " \(aq" \fIReset\fP \(aq Perform amplifier .RI \(aq Reset \(aq. .IP Reset is an integer value: \(oq0\(cq = None, \(oq1\(cq = Memory reset, \(oq2\(cq = Fault reset, \(oq3\(cq = Amplifier reset. . .TP .BR set_powerstat " \(aq" "\fIPower Status\fP" \(aq Set .RI \(aq "Power Status" \(aq. .IP Power Status is an integer value: \(oq0\(cq = Power Off, \(oq1\(cq = Power On, \(oq2\(cq = Power Standby (enter standby), \(oq4\(cq = Power Operate (leave standby). . .TP .B get_powerstat Get .RI \(aq "Power Status" \(aq as in .B set_powerstat above. . . .SH PROTOCOL . There are two protocols in use by .BR ampctld , the .B Default Protocol and the .BR "Extended Response Protocol" . . .PP The .B Default Protocol is intended primarily for the communication between .B Hamlib library functions and .B ampctld (\(lqNET ampctl\(rq, available using amplifier model \(oq2\(cq). . .PP The .B Extended Response Protocol is intended to be used with scripts or other programs interacting directly with .B ampctld as consistent feedback is provided. . . .SS Default Protocol . The .B Default Protocol is intentionally simple. Commands are entered on a single line with any needed values. In practice, reliable results are obtained by terminating each command string with a newline character, \(oq\\n\(cq. . .PP Example set frequency and mode commands (Perl code (typed text shown in bold)): . .PP .in +4n .EX \fBprint $socket "F 14250000\\n";\fP \fBprint $socket "\\\\set_powerstat 1\\n";\fP # escape leading '\\' .EE .in . .PP A one line response will be sent as a reply to .B set commands, \(lqRPRT \fIx\fP\\n\(rq where .I x is the Hamlib error code with \(oq0\(cq indicating success of the command. . .PP Responses from .B ampctld .B get commands are text values and match the same tokens used in the .B set commands. Each value is returned on its own line. On error the string \(lqRPRT \fIx\fP\\n\(rq is returned where .I x is the Hamlib error code. . .PP Example get frequency (Perl code): . .PP .in +4n .EX \fBprint $socket "f\\n";\fP "14250000\\n" .EE .in . .PP Most .B get functions return one to three values. A notable exception is the .B dump_caps command which returns many lines of \fBkey\fR:\fIvalue\fR pairs. . .PP This protocol is primarily used by the \(lqNET ampctl\(rq (ampctl model 2) backend which allows applications already written for Hamlib's C API to take advantage of .B ampctld without the need of rewriting application code. An application's user can select amplifier model 2 (\(lqNET ampctl\(rq) and then set .B amp_pathname to \(lqlocalhost:4531\(rq or other network .IR host : port (set by the .BR \-T / \-t options, respectively, above). . . .SS Extended Response Protocol . The Extended Response protocol adds several rules to the strings returned by .B ampctld and adds a rule for the command syntax. . .PP 1. The command received by .B ampctld is echoed with its long command name followed by the value(s) (if any) received from the client terminated by the specified response separator as the first record of the response. . .PP 2. The last record of each block is the string \(lqRPRT \fIx\fP\\n\(rq where .I x is the numeric return value of the Hamlib backend function that was called by the command. . .PP 3. Any records consisting of data values returned by the amplifier backend are prepended by a string immediately followed by a colon then a space and then the value terminated by the response separator. e.g. \(lqFrequency: 14250000\\n\(rq when the command was prepended by \(oq+\(cq. . .PP 4. All commands received will be acknowledged by .B ampctld with records from rules 1 and 2. Records from rule 3 are only returned when data values must be returned to the client. . .PP An example response to a .B set_frequency command sent from the shell prompt (note the prepended \(oq+\(cq): . .PP .in +4n .EX $ \fBecho "+F 14250000" | nc -w 1 localhost 4531\fP set_freq: 14250000 RPRT 0 .EE .in . .PP In this case the long command name and values are returned on the first line and the second line contains the end of block marker and the numeric amplifier backend return value indicating success. . .PP An example response to a .B get_freq query: . .PP .in +4n .EX $ \fBecho "+\\get_freq" | nc -w 1 localhost 4531\fP get_freq: Frequency(Hz): 14250000 RPRT 0 .EE .in . .IP .BR Note : The \(oq\\\(cq is still required for the long command name even with the ERP character. . .PP In this case, as no value is passed to .BR ampctld , the first line consists only of the long command name. The final line shows that the command was processed successfully by the amplifier backend. . .PP Invoking the Extended Response Protocol requires prepending a command with a punctuation character. As shown in the examples above, prepending a \(oq+\(cq character to the command results in the responses being separated by a newline character (\(oq\\n\(cq). Any other punctuation character recognized by the C .BR ispunct () function except \(oq\\\(cq, \(oq?\(cq, or \(oq_\(cq will cause that character to become the response separator and the entire response will be on one line. . .PP Separator character summary: .TP .RB \(oq + \(cq Each record of the response is appended with a newline (\(oq\\n\(cq). . .TP .RB \(oq ; "\(cq, \(oq" | "\(cq, or, \(oq" , \(cq Each record of the response is appended by the given character resulting in entire response on one line. .IP These are common record separators for text representations of spreadsheet data, etc. . .TP .RB \(oq ? \(cq Reserved for help in .BR ampctl . . .TP .RB \(oq _ \(cq Reserved for .B get_info short command . .TP .RB \(oq # \(cq Reserved for comments when reading a command file script. .IP .BR Note : Other punctuation characters have not been tested! Use at your own risk. . .PP For example, invoking a .B get_freq query with a leading \(oq;\(cq returns: . .PP .in +4n .EX get_freq:;Frequency(Hz): 14250000;RPRT 0 .EE .in . .PP Or, using the pipe character \(oq|\(cq returns: . .PP .in +4n .EX get_freq:|Frequency(Hz): 14250000|RPRT 0 .EE .in . .PP And a .B set_freq command prepended with a \(oq|\(cq returns: . .PP .in +4n .EX set_freq: 14250000|RPRT 0 .EE .in . .PP Such a format will allow reading a response as a single event using a preferred response separator. Other punctuation characters have not been tested! . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the amplifier which is very useful for amplifier backend library development and may be requested by the developers. . . .SH EXAMPLES . Start .B ampctld for an Elecraft KPA-1500 using a USB-to-serial adapter and backgrounding: . .PP .in +4n .EX .RB $ " ampctld -m 201 -r /dev/ttyUSB1 &" .EE .in . .PP Start .B ampctld for an Elecraft KPA-1500 using COM2 on MS Windows: . .PP .in +4n .EX .RB $ " ampctld -m 201 -r COM2" .EE .in . .PP Connect to the already running .B ampctld and set the frequency to 14.266 MHz with a 1 second read timeout using the default protocol from the shell prompt: . .PP .in +4n .EX $ \fBecho "\\set_freq 14266000" | nc -w 1 localhost 4531\fP .EE .in . .PP Connect to a running .B ampctld with .B ampctl on the local host: . .PP .in +4n .EX .RB $ " ampctl -m2" .EE .in . . .SH SECURITY . No authentication whatsoever; DO NOT leave this TCP port open wide to the Internet. Please ask if stronger security is needed or consider using a Secure Shell .RB ( ssh (1)) tunnel. . .PP As .B ampctld does not need any greater permissions than .BR ampctl , it is advisable to not start .B ampctld as \(lqroot\(rq or another system user account in order to limit any vulnerability. . . .SH BUGS . The daemon is not detaching and backgrounding itself. .PP No method to exit the daemon so the .BR kill (1) command must be used to terminate it. . .PP Multiple clients using the daemon may experience contention with the connected amplifier. . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2010 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2011-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR kill (1), .BR ampctl (1), .BR ssh (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigctld.10000664000175000017500000012555615056640442011604 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigctld.c .\" .TH RIGCTLD "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigctld \- TCP radio control daemon . . .SH SYNOPSIS . .SY rigctld .OP \-hlLouV .OP \-m id .OP \-r device .OP \-p device .OP \-d device .OP \-P type .OP \-D type .OP \-s baud .OP \-c id .OP \-S char .OP \-T IPADDR .OP \-t number .OP \-C parm=val .OP \-X seconds .RB [ \-v [ \-Z ]] .YS . . .SH DESCRIPTION . The .B rigctld program is a radio control daemon that handles client requests via TCP sockets. This allows multiple user programs to share one radio (this needs more development). Multiple radios can be controlled on different TCP ports by use of multiple .B rigctld processes. Note that multiple processes/ports are also necessary if some clients use extended responses and/or vfo mode. So up to 4 processes/ports may be needed for each combination of extended response/vfo mode. The syntax of the commands are the same as .BR rigctl (1). It is hoped that .B rigctld will be especially useful for client authors using languages such as Perl, Python, PHP, and others. . .PP .B rigctld communicates to a client through a TCP socket using text commands shared with .BR rigctl . The protocol is simple, commands are sent to .B rigctld on one line and .B rigctld responds to .B get commands with the requested values, one per line, when successful, otherwise, it responds with one line \(lqRPRT x\(rq, where \(oqx\(cq is a negative number indicating the error code. Commands that do not return values respond with the line \(lqRPRT x\(rq, where \(oqx\(cq is \(oq0\(cq when successful, otherwise is a regative number indicating the error code. Each line is terminated with a newline \(oq\\n\(cq character. This protocol is primarily for use by the .B NET rigctl (radio model 2) backend. . .PP A separate .B Extended Response Protocol extends the above behavior by echoing the received command string as a header, any returned values as a key: value pair, and the \(lqRPRT x\(rq string as the end of response marker which includes the .B Hamlib success or failure value. See the .B PROTOCOL section for details. Consider using this protocol for clients that will interact with .B rigctld directly through a TCP socket. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete rig support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. Defaults to dummy rig. .IP See model list (use \(lqrigctld -l\(rq). .IP .BR Note : .B rigctl (or third party software using the C API) will use radio model 2 for .B NET rigctl (this model number is not used for .B rigctld even though it shows in the model list). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. .IP Can be a network address:port, e.g. .IR 127.0.0.1:12345 .IP The special string \(lquh\-rig\(rq may be given to enable micro-ham device support. . .TP .BR \-p ", " \-\-ptt\-file = \fIdevice\fP Use .I device as the file name of the Push-To-Talk device using a device file as described above. . .TP .BR \-d ", " \-\-dcd\-file = \fIdevice\fP Use .I device as the file name of the Data Carrier Detect device using a device file as described above. . .TP .BR \-P ", " \-\-ptt\-type = \fItype\fP Use .I type of Push-To-Talk device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDTR\(cq, \(oqRTS\(cq, \(oqPARALLEL\(cq, \(oqCM108\(cq, \(oqGPIO\(cq, \(oqGPION\(cq, \(oqNONE\(cq, overriding PTT type defined in the rig's backend. .IP Some side effects of this command are that when type is set to DTR, read PTT state comes from the .B Hamlib frontend, not read from the radio. When set to NONE, PTT state cannot be read or set even if rig backend supports reading/setting PTT status from the rig. . .TP .BR \-D ", " \-\-dcd\-type = \fItype\fP Use .I type of Data Carrier Detect device. .IP Supported types are \(oqRIG\(cq (CAT command), \(oqDSR\(cq, \(oqCTS\(cq, \(oqCD\(cq, \(oqPARALLEL\(cq, \(oqCM108\(cq, \(oqGPIO\(cq, \(oqGPION\(cq, \(oqNONE\(cq. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities (set by .B -m above) as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the rig. .IP Only useful for Icom and some Ten-Tec rigs. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-S ", " \-\-separator = \fIchar\fP Use .I char as separator instead of line feed. .IP The default is \(oq\\n\(cq. Recommend using $ or @ as they work on both Unix and Windows. .IP . .TP .BR \-T ", " \-\-listen\-addr = \fIIPADDR\fP Use .I IPADDR as the listening IP address. .IP The default is ANY (0.0.0.0). .IP .B rigctld can be run and connected to like this: . .IP .EX rigctld . .in +4n rigctl -m 2 rigctl -m 2 -r 127.0.0.1 rigctl -m 2 -r localhost rigctl -m 2 -r 192.168.1.1 (local IP address) rigctl -m 2 -r ::1 (on Linux rigctld doesn't listen on IPV6 by default) .in . .IP rigctld -T 127.0.0.1 .in +4n rigctl -m 2 (binds to all interfaces) rigctl -m 2 -r 127.0.0.1 (bind only to 127.0.0.1) .EE Exceptions: .EX rigctl -m 2 -r localhost (only works if localhost is IPV4 address) .EE .in . .IP .EX rigctld -T localhost (will set up on IPV4 or IPV6 based on localhost) .in +4n rigctl -m 2 rigctl -m 2 -r localhost rigctl -m 2 ip6-localhost .EE Exceptions: .EX rigctl -m 2 -r 127.0.0.1 (only works if localhost is IPV4 address) rigctl -m 2 -r ::1 (only works if localhost is IPV6 address) .EE .in . .IP On Linux only where ip6-localhost is fe00::0: .EX rigctld -T ip6-localhost .in +4n rigctl -m 2 -r ip6-localhost .in .EE . .TP .BR \-t ", " \-\-port = \fInumber\fP Use .I number as the TCP listening port. .IP The default is 4532. .IP .BR Note : As .BR rotctld 's default port is 4533, it is advisable to use even numbered ports for .BR rigctld , e.g. 4532, 4534, 4536, etc. . .TP .BR \-L ", " \-\-show\-conf List all config parameters for the radio defined with .B \-m above. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set configuration parameter(s). Some common ones are: .in +4 .EX .BR async: "True enables asynchronous data transfer for backends that support it. This allows use of transceive and spectrum data." .BR auto_power_on: "True enables compatible rigs to be powered up on open" .BR auto_power_off: "True enables compatible rigs to be powered down on close" .BR auto_disable_screensaver: "True enables compatible rigs to have their screen saver disabled on open" .BR dcd_type: "Data Carrier Detect (or squelch) interface type override" .BR dcd_pathname: "Path name to the device file of the Data Carrier Detect (or squelch)" .BR disable_yaesu_bandselect: "True disables the automatic band select on band change for Yaesu rigs" .BR dtr_state: "ON turns on DTR, OFF turns it off, Unset disables it" .BR lo_freq: "Frequency to add to the VFO frequency for use with a transverter" .BR post_write_delay: "Delay in ms between each command sent out" .BR ptt_share: "True enables ptt port to be shared with other apps" .BR ptt_type: "Push-To-Talk interface type override" .BR ptt_pathname: "Path name to the device file of the Push-To-Talk" .BR ptt_bitnum: "Push-To-Talk GPIO bit number" .BR retry: "Max number of retry" .BR rts_state: "ON turns on DTR, OFF turns it off, Unset disables it" .BR twiddle_timeout: "For satellite ops when VFOB is twiddled will pause VFOB commands until timeout" .BR twiddle_rit: "Suppress get_freq on VFOB for RIT tuning satellites" .BR timeout: "Timeout in ms" .BR write_delay: "Delay in ms between each byte sent out" .BR tuner_control_pathname: "Path name to a script/program to control a tuner with 1 argument of 0/1 for Tuner Off/On" .EE .in .IP Use the .B -L option above for a list of configuration parameters for a given model number. . .TP .BR \-u ", " \-\-dump\-caps Dump capabilities for the radio defined with .B -m above and exit. . .TP .BR \-l ", " \-\-list List all model numbers defined in .B Hamlib and exit. .IP The list is sorted by model number. .IP .BR Note : In Linux the list can be scrolled back using .BR Shift-PageUp / Shift-PageDown , or using the scrollbars of a virtual terminal in X or the cmd window in Windows. The output can be piped to .BR more (1) or .BR less (1), e.g. \(lqrigctld -l | more\(rq. . .TP .BR \-o ", " \-\-vfo Enable vfo mode. .IP An extra VFO argument will be required in front of each appropriate command (except .BR set_vfo ). Otherwise, \(oqcurrVFO\(cq is used when this option is not set and an extra VFO argument is not used. .IP See .B chk_vfo below. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-W ", " \-\-twiddle_timeout = \fIseconds\fP Enables timeout when VFO twiddling is detected. Some functions will be ignored. .IP Should only be needed when controlling software should be "paused" so you can move the VFO. Continuous movement extends the timeout. . .TP .BR \-w ", " \-\-twiddle_rit = \fIseconds\fP Suppress VFOB getfreq so RIT can be twiddled. . .TP .BR \-x ", " \-\-uplink = \fIoption\fP 1=Sub, 2=Main .IP For GPredict use to ignore get_freq for Sub or Main uplink VFO. .IP Should allow downlink VFO movement without confusing GPredict or the uplink. . .TP .BR \-Z ", " \-\-debug\-time\-stamps Enable time stamps for the debug messages. .IP Use only in combination with the .B -v option as it generates no output on its own. . .TP .BR \-A ", " \-\-password Sets password on .B rigctld which requires hamlib to use rig_set_password and rigctl to use \\password to access rigctld. A 32-char shared secret will be displayed to be used on the client side. (NOT IMPLEMENTED) . .TP .BR \-R ", " \-\-rigctld\-idle Will make .B rigctld close the rig when no clients are connected. Normally remains connected to speed up connects. . .TP .BR \-b ", " \-\-bind\-all Will make .B rigctld try to bind to first network device available. . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigctld and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf and .B \-\-show\-conf options. . .PP Please note that the backend for the radio to be controlled, or the radio itself may not support some commands. In that case, the operation will fail with a .B Hamlib error code. . . .SH COMMANDS . Commands can be sent over the TCP socket either as a single char, or as a long command name plus the value(s) space separated on one \(oq\\n\(cq terminated line. See .BR PROTOCOL . . .PP Since most of the .B Hamlib operations have a .BR set " and a " get method, a single upper case letter will be used for .B set methods whereas the corresponding single lower case letter refers to the .B get method. Each operation also has a long name; prepend a backslash, \(oq\\\(cq, to send a long command name all in lower case. . .PP Example (Perl): \(lqprint $socket "\\\\dump_caps\\n";\(rq to see what the radio's backend can do .RB ( Note : In Perl and many other languages a \(oq\\\(cq will need to be escaped with a preceding \(oq\\\(cq so that even though two backslash characters appear in the code, only one will be passed to .BR rigctld . This is a possible bug, beware!). . .PP .BR Note : The backend for the radio to be controlled, or the radio itself may not support some commands. In that case, the operation will fail with a .B Hamlib error message. . .PP Here is a summary of the supported commands (In the case of .B set commands the quoted italicized string is replaced by the value in the description. In the case of .B get commands the quoted italicized string is the key name of the value returned.): . .TP .BR F ", " set_freq " \(aq" \fIFrequency\fP \(aq Set .RI \(aq Frequency \(aq, in Hz. .IP Frequency may be a floating point or integer value. . .TP .BR f ", " get_freq Get .RI \(aq Frequency \(aq, in Hz. .IP Returns an integer value and the VFO hamlib thinks is active. Note that some rigs (e.g. all Icoms) cannot track current VFO so hamlib can get out of sync with the rig if the user presses rig buttons like the VFO. rigctld clients should ensure they set the intended VFO or use vfo mode. . .TP .BR M ", " set_mode " \(aq" \fIMode\fP "\(aq \(aq" \fIPassband\fP \(aq Set .RI \(aq Mode \(aq and .RI \(aq Passband \(aq. .IP Mode is a token: \(oqUSB\(cq, \(oqLSB\(cq, \(oqCW\(cq, \(oqCWR\(cq, \(oqRTTY\(cq, \(oqRTTYR\(cq, \(oqAM\(cq, \(oqFM\(cq, \(oqWFM\(cq, \(oqAMS\(cq, \(oqPKTLSB\(cq, \(oqPKTUSB\(cq, \(oqPKTFM\(cq, \(oqECSSUSB\(cq, \(oqECSSLSB\(cq, \(oqFA\(cq, \(oqSAM\(cq, \(oqSAL\(cq, \(oqSAH\(cq, \(oqDSB\(cq. .IP Passband is in Hz as an integer, -1 for no change, or \(oq0\(cq for the radio backend default. IC7300 can use 1,2,3 to select which filter to use .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Mode token will return a space separated list of radio backend supported Modes. Use this to determine the supported Modes of a given radio backend. . .TP .BR m ", " get_mode Get .RI \(aq Mode \(aq and .RI \(aq Passband \(aq. .IP Returns Mode as a token and Passband in Hz as in .B set_mode above. . .TP .BR V ", " set_vfo " \(aq" \fIVFO\fP \(aq Set .RI \(aq VFO \(aq. .IP VFO is a token: \(oqVFOA\(cq, \(oqVFOB\(cq, \(oqVFOC\(cq, \(oqcurrVFO\(cq, \(oqVFO\(cq, \(oqMEM\(cq, \(oqMain\(cq, \(oqSub\(cq, \(oqTX\(cq, \(oqRX\(cq, \(oqMainA\(cq, \(oqMainB\(cq, \(oqMainC\(cq, \(oqSubA\(cq, \(oqSubB\(cq \(oqSubC\(cq. .IP In VFO mode (see .B \-\-vfo option above) only a single VFO parameter is required: . .IP .in +4n .EX $ rigctl -m 229 -r /dev/rig -o Rig command: V VFO: VFOB Rig command: .EE .in . .TP .BR v ", " get_vfo Get current .RI \(aq VFO \(aq. .IP Returns VFO as a token as in .B set_vfo above. . .TP .BR J ", " set_rit " \(aq" \fIRIT\fP \(aq Set .RI \(aq RIT \(aq. .IP RIT is in Hz and can be + or -. A value of \(oq0\(cq resets RIT (Receiver Incremental Tuning) to match the VFO frequency. .IP .BR Note : RIT needs to be explicitly activated or deactivated with the .B set_func command. This allows setting the RIT offset independently of its activation and allows RIT to remain active while setting the offset to \(oq0\(cq. . .TP .BR j ", " get_rit Get .RI \(aq RIT \(aq in Hz. .IP Returned value is an integer. . .TP .BR Z ", " set_xit " \(aq" \fIXIT\fP \(aq Set .RI \(aq XIT \(aq. .IP XIT is in Hz and can be + or -. A value of \(oq0\(cq resets XIT (Transmitter Incremental Tuning) to match the VFO frequency. .IP .BR Note : XIT needs to be explicitly activated or deactivated with the .B set_func command. This allows setting the XIT offset independently of its activation and allows XIT to remain active while setting the offset to \(oq0\(cq. . .TP .BR z ", " get_xit Get .RI \(aq XIT \(aq in Hz. .IP Returned value is an integer. . .TP .BR T ", " set_ptt " \(aq" \fIPTT\fP \(aq Set .RI \(aq PTT \(aq. .IP PTT is a value: \(oq0\(cq (RX), \(oq1\(cq (TX), \(oq2\(cq (TX mic), or \(oq3\(cq (TX data). . .TP .BR t ", " get_ptt Get .RI \(aq PTT \(aq status. .IP Returns PTT as a value in .B set_ptt above. . .TP .BR S ", " set_split_vfo " \(aq" \fISplit\fP "\(aq \(aq" "\fITX VFO\fP" \(aq Set .RI \(aq Split \(aq mode. .IP Split is either \(oq0\(cq = Normal or \(oq1\(cq = Split. .IP Set .RI \(aq "TX VFO" \(aq. .IP TX VFO is a token: \(oqVFOA\(cq, \(oqVFOB\(cq, \(oqVFOC\(cq, \(oqcurrVFO\(cq, \(oqVFO\(cq, \(oqMEM\(cq, \(oqMain\(cq, \(oqSub\(cq, \(oqTX\(cq, \(oqRX\(cq. . .TP .BR s ", " get_split_vfo Get .RI \(aq Split \(aq mode. .IP Split is either \(oq0\(cq = Normal or \(oq1\(cq = Split. .IP Get .RI \(aq "TX VFO" \(aq. .IP TX VFO is a token as in .B set_split_vfo above. . .TP .BR I ", " set_split_freq " \(aq" "\fITx Frequency\fP" \(aq Set .RI \(aq "TX Frequency" \(aq, in Hz. .IP Frequency may be a floating point or integer value. . .TP .BR i ", " get_split_freq Get .RI \(aq "TX Frequency" \(aq, in Hz. .IP Returns an integer value. . .TP .BR X ", " set_split_mode " \(aq" "\fITX Mode\fP" "\(aq \(aq" "\fITX Passband\fP" \(aq Set .RI \(aq "TX Mode" \(aq and .RI \(aq "TX Passband" \(aq. .IP TX Mode is a token: \(oqUSB\(cq, \(oqLSB\(cq, \(oqCW\(cq, \(oqCWR\(cq, \(oqRTTY\(cq, \(oqRTTYR\(cq, \(oqAM\(cq, \(oqFM\(cq, \(oqWFM\(cq, \(oqAMS\(cq, \(oqPKTLSB\(cq, \(oqPKTUSB\(cq, \(oqPKTFM\(cq, \(oqECSSUSB\(cq, \(oqECSSLSB\(cq, \(oqFA\(cq, \(oqSAM\(cq, \(oqSAL\(cq, \(oqSAH\(cq, \(oqDSB\(cq. .IP TX Passband is in Hz as an integer, or \(oq0\(cq for the radio backend default. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a TX Mode token will return a space separated list of radio backend supported TX Modes. Use this to determine the supported TX Modes of a given radio backend. . .TP .BR x ", " get_split_mode Get .RI \(aq "TX Mode" \(aq and .RI \(aq "TX Passband" \(aq. .IP Returns TX Mode as a token and TX Passband in Hz as in .B set_split_mode above. . .TP .BR Y ", " set_ant " \(aq" \fIAntenna\fP "\(aq \(aq" \fIOption\fP \(aq Set .RI \(aq Antenna \(aq and .RI \(aq Option \(aq. .IP Number is 1-based antenna# (\(oq1\(cq, \(oq2\(cq, \(oq3\(cq, ...). .IP Option depends on rig. For Icom it probably sets the Tx & Rx antennas as in the IC-7851. See your manual for rig specific option values. Most rigs don't care about the option. .IP For the IC-7851, FTDX3000 (and perhaps others) it means this: .IP .in +4n .EX 1 = TX/RX = ANT1 FTDX3000=ANT1/ANT3 2 = TX/RX = ANT2 FTDX3000=ANT2/ANT3 3 = TX/RX = ANT3 FTDX3000=ANT3 4 = TX/RX = ANT1/ANT4 5 = TX/RX = ANT2/ANT4 6 = TX/RX = ANT3/ANT4 .EE .in . .TP .BR y ", " get_ant " \(aq" \fIAntenna\fP \(aq Get .RI \(aq Antenna \(aq .IP A value of 0 for Antenna will return the current TX antenna .IP > 0 is 1-based antenna# (\(oq1\(cq, \(oq2\(cq, \(oq3\(cq, ...). .IP Option returned depends on rig. For Icom it is likely the RX only flag. . .TP .BR b ", " send_morse " \(aq" \fIMorse\fP \(aq Send .RI \(aq Morse \(aq symbols. For Yaesu rigs use memory# (1-5 for most rigs) or up to 50 char message (which will use memory#1) Example from rigctld socket: .EX b CQ CQ DE ME .EE Yaesu example to send message#1 from rigctld socket: .EX b 1 .EE . .TP .BR 0xbb ", " stop_morse " Stop sending the current morse code. . .TP .BR 0xbc ", " wait_morse " Wait for morse to finish -- only works on full break-in. . .TP .BR 0x94 ", " send_voice_mem " \(aq" \fIMsgnum\fP \(aq Have rig transmit internal message .RI \(aq Msgnum \(aq . .TP .BR 0x8b ", " get_dcd Get .RI \(aq DCD \(aq (squelch) status: \(oq0\(cq (Closed) or \(oq1\(cq (Open). . .TP .BR R ", " set_rptr_shift " \(aq" "\fIRptr Shift\fP" \(aq Set .RI \(aq "Rptr Shift" \(aq. .IP Rptr Shift is one of: \(oq+\(cq, \(oq-\(cq, or something else for \(oqNone\(cq. . .TP .BR r ", " get_rptr_shift Get .RI \(aq "Rptr Shift" \(aq. .IP Returns \(oq+\(cq, \(oq-\(cq, or \(oqNone\(cq. . .TP .BR O ", " set_rptr_offs " \(aq" "\fIRptr Offset\fP" \(aq Set .RI \(aq "Rptr Offset" \(aq, in Hz. . .TP .BR o ", " get_rptr_offs Get .RI \(aq "Rptr Offset" \(aq, in Hz. . .TP .BR C ", " set_ctcss_tone " \(aq" "\fICTCSS Tone\fP" \(aq Set .RI \(aq "CTCSS Tone" \(aq, in tenths of Hz. . .TP .BR c ", " get_ctcss_tone Get .RI \(aq "CTCSS Tone" \(aq, in tenths of Hz. . .TP .BR D ", " set_dcs_code " \(aq" "\fIDCS Code\fP" \(aq Set .RI \(aq "DCS Code" \(aq. . .TP .BR d ", " get_dcs_code Get .RI \(aq "DCS Code" \(aq. . .TP .BR 0x90 ", " set_ctcss_sql " \(aq" "\fICTCSS Sql\fP" \(aq Set .RI \(aq "CTCSS Sql" \(aq tone, in tenths of Hz. . .TP .BR 0x91 ", " get_ctcss_sql Get .RI \(aq "CTCSS Sql" \(aq tone, in tenths of Hz. . .TP .BR 0x92 ", " set_dcs_sql " \(aq" "\fIDCS Sql\fP" \(aq Set .RI \(aq "DCS Sql" \(aq code. . .TP .BR 0x93 ", " get_dcs_sql Get .RI \(aq "DCS Sql" \(aq code. . .TP .BR N ", " set_ts " \(aq" "\fITuning Step\fP" \(aq Set .RI \(aq "Tuning Step" \(aq, in Hz. . .TP .BR n ", " get_ts Get .RI \(aq "Tuning Step" \(aq, in Hz. . .TP .BR U ", " set_func " \(aq" \fIFunc\fP "\(aq \(aq" "\fIFunc Status\fP" \(aq Set .RI \(aq Func \(aq and .RI \(aq "Func Status" \(aq. .IP Func is a token: \(oqABM\(cq, \(oqAFC\(cq, \(oqAFLT\(cq, \(oqAIP\(cq, \(oqANF\(cq, \(oqANL\(cq, \(oqAPF\(cq, \(oqARO\(cq, \(oqBC2\(cq, \(oqBC\(cq, \(oqCOMP\(cq, \(oqCSQL\(cq, \(oqDIVERSITY\(cq, \(oqDSQL\(cq, \(oqDUAL_WATCH\(cq, \(oqFAGC\(cq, \(oqFBKIN\(cq, \(oqLOCK\(cq, \(oqMBC\(cq, \(oqMN\(cq, \(oqMON\(cq, \(oqMUTE\(cq, \(oqNB2\(cq, \(oqNB\(cq, \(oqNR\(cq, \(oqOVF_STATUS\(cq, \(oqRESUME\(cq, \(oqREV\(cq, \(oqRF\(cq, \(oqRIT\(cq, \(oqSATMODE\(cq, \(oqSBKIN\(cq, \(oqSCEN\(cq, \(oqSCOPE\(cq, \(oqSEND_MORSE\(cq, \(oqSEND_VOICE_MEM\(cq, \(oqSPECTRUM\(cq, \(oqSPECTRUM_HOLD\(cq, \(oqSQL\(cq, \(oqSYNC\(cq, \(oqTBURST\(cq, \(oqTONE\(cq, \(oqTRANSCEIVE\(cq, \(oqTSQL\(cq, \(oqTUNER\(cq, \(oqVOX\(cq, \(oqVSC\(cq, \(oqXIT\(cq. .IP Func Status is a non null value for \(lqactivate\(rq or \(lqde-activate\(rq otherwise, much as TRUE/FALSE definitions in the C language (true is non-zero and false is zero, \(oq0\(cq). .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Func token will return a space separated list of radio backend supported set function tokens. Use this to determine the supported functions of a given radio backend. . .TP .BR u ", " get_func " \(aq" \fIFunc\fP \(aq Get .RI \(aq "Func Status" \(aq. .IP Returns Func Status as a non null value for the Func token given as in .B set_func above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Func token will return a space separated list of radio backend supported get function tokens. Use this to determine the supported functions of a given radio backend. . .TP .BR L ", " set_level " \(aq" \fILevel\fP "\(aq \(aq" "\fILevel Value\fP" \(aq Set .RI \(aq Level \(aq and .RI \(aq "Level Value" \(aq. .IP Level is a token: \(oqAF\(cq, \(oqAGC\(cq, \(oqAGC_TIME\(cq, \(oqALC\(cq, \(oqANTIVOX\(cq, \(oqAPF\(cq, \(oqATT\(cq, \(oqBAL\(cq, \(oqBAND_SELECT\(cq, \(oqBKINDL\(cq, \(oqBKIN_DLYMS\(cq, \(oqCOMP\(cq, \(oqCOMP_METER\(cq, \(oqCWPITCH\(cq, \(oqID_METER\(cq, \(oqIF\(cq, \(oqKEYSPD\(cq, \(oqMETER\(cq, \(oqMGC\(cq, \(oqMGF\(cq, \(oqMGL\(cq, \(oqMICGAIN\(cq, \(oqMONITOR_GAIN\(cq, \(oqNB\(cq, \(oqNOTCHF\(cq, \(oqNOTCHF_RAW\(cq, \(oqNR\(cq, \(oqPBT_IN\(cq, \(oqPBT_OUT\(cq, \(oqPREAMP\(cq, \(oqRAWSTR\(cq, \(oqRF\(cq, \(oqRFPOWER\(cq, \(oqRFPOWER_METER\(cq, \(oqRFPOWER_METER_WATTS\(cq, \(oqSLOPE_HIGH\(cq, \(oqSLOPE_LOW\(cq, \(oqSPECTRUM_ATT\(cq, \(oqSPECTRUM_AVG\(cq, \(oqSPECTRUM_EDGE_HIGH\(cq, \(oqSPECTRUM_EDGE_LOW\(cq, \(oqSPECTRUM_MODE\(cq, \(oqSPECTRUM_REF\(cq, \(oqSPECTRUM_SPAN\(cq, \(oqSPECTRUM_SPEED\(cq, \(oqSQL\(cq, \(oqSTRENGTH\(cq, \(oqSWR\(cq, \(oqTEMP_METER\(cq, \(oqUSB_AF\(cq, \(oqUSB_AF_INPUT\(cq, \(oqVD_METER\(cq, \(oqVOXDELAY\(cq, \(oqVOXGAIN\(cq. .IP The Level Value can be a float or an integer value. For the AGC token the value is one of \(oq0\(cq = OFF, \(oq1\(cq = SUPERFAST, \(oq2\(cq = FAST, \(oq3\(cq = SLOW, \(oq4\(cq = USER, \(oq5\(cq = MEDIUM, \(oq6\(cq = AUTO. Note that not all values work on all rigs. To list usable values do 'rigctl -m [modelnum] -u | grep "AGC levels"' or for Windows 'rigctl -m [modelnum] -u | find "AGC levels"'. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Level token will return a space separated list of radio backend supported set level tokens. Use this to determine the supported levels of a given radio backend. . .TP .BR l ", " get_level " \(aq" \fILevel\fP \(aq Get .RI \(aq "Level Value" \(aq. .IP Returns Level Value as a float or integer for the Level token given as in .B set_level above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Level token will return a space separated list of radio backend supported get level tokens. Use this to determine the supported levels of a given radio backend. . .TP .BR P ", " set_parm " \(aq" \fIParm\fP "\(aq \(aq" "\fIParm Value\fP" \(aq Set .RI \(aq Parm \(aq and .RI \(aq "Parm Value" \(aq. .IP Parm is a token: \(oqAFIF\(cq, \(oqAFIF_ACC\(cq, \(oqAFIF_LAN\(cq, \(oqAFIF_WLAN\(cq, \(oqANN\(cq, \(oqAPO\(cq, \(oqBACKLIGHT\(cq, \(oqBANDSELECT\(cq, \(oqBAT\(cq, \(oqBEEP\(cq, \(oqKEYERTYPE\(cq, \(oqKEYLIGHT\(cq, \(oqSCREENSAVER\(cq, \(oqTIME\(cq. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Parm token will return a space separated list of radio backend supported set parameter tokens. Use this to determine the supported parameters of a given radio backend. . .TP .BR p ", " get_parm " \(aq" \fIParm\fP \(aq Get .RI \(aq "Parm Value" \(aq. .IP Returns Parm Value as a float or integer for the Parm token given as in .B set_parm above. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Parm token will return a space separated list of radio backend supported get parameter tokens. Use this to determine the supported parameters of a given radio backend. . .TP .BR B ", " set_bank " \(aq" \fIBank\fP \(aq Set .RI \(aq Bank \(aq. .IP Sets the current memory bank number. . .TP .BR E ", " set_mem " \(aq" \fIMemory#\fP \(aq Set .RI \(aq Memory# \(aq channel number. . .TP .BR e ", " get_mem Get .RI \(aq Memory# \(aq channel number. . .TP .BR G ", " vfo_op " \(aq" "\fIMem/VFO Op\fP" \(aq Perform a .RI \(aq "Mem/VFO Op" \(aq. .IP Mem/VFO Operation is a token: \(oqCPY\(cq, \(oqXCHG\(cq, \(oqFROM_VFO\(cq, \(oqTO_VFO\(cq, \(oqMCL\(cq, \(oqUP\(cq, \(oqDOWN\(cq, \(oqBAND_UP\(cq, \(oqBAND_DOWN\(cq, \(oqLEFT\(cq, \(oqRIGHT\(cq, \(oqTUNE\(cq, \(oqTOGGLE\(cq. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Mem/VFO Op token will return a space separated list of radio backend supported Set Mem/VFO Op tokens. Use this to determine the supported Mem/VFO Ops of a given radio backend. . .TP .BR g ", " scan " \(aq" "\fIScan Fct\fP" "\(aq \(aq" "\fIScan Channel\fP" \(aq Perform a .RI \(aq "Scan Fct" \(aq on a .RI \(aq "Scan Channel" \(aq. .IP Scan Function is a token: \(oqSTOP\(cq, \(oqMEM\(cq, \(oqSLCT\(cq, \(oqPRIO\(cq, \(oqPROG\(cq, \(oqDELTA\(cq, \(oqVFO\(cq, \(oqPLT\(cq. .IP .\" FIXME: What is a scan channel value? Scan Channel is an integer (maybe?). .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Scan Fct token will return a space separated list of radio backend supported Scan Function tokens. Use this to determine the supported Scan Functions of a given radio backend. . .TP .BR H ", " set_channel " \(aq" \fIChannel\fP \(aq Set memory .RI \(aq Channel \(aq data. .IP Not implemented yet. . .TP .BR h ", " get_channel " \(aq" \fIreadonly\fP \(aq Get channel memory. .IP If readonly!=0 then only channel data is returned and rig remains on the current channel. If readonly=0 then rig will be set to the channel requested. . .TP .BR A ", " set_trn " \(aq" \fITransceive\fP \(aq Set .RI \(aq Transceive \(aq mode. .IP Transceive is a token: \(oqOFF\(cq, \(oqRIG\(cq, \(oqPOLL\(cq. .IP Transceive is a mechanism for radios to report events without a specific call for information. .IP .BR Note : Passing a \(oq?\(cq (query) as the first argument instead of a Transceive token will return a space separated list of radio backend supported Transceive mode tokens. Use this to determine the supported Transceive modes of a given radio backend. . .TP .BR a ", " get_trn Get .RI \(aq Transceive \(aq mode. .IP Transceive mode (reporting event) as in .B set_trn above. . .TP .BR * ", " reset " \(aq" \fIReset\fP \(aq Perform rig .RI \(aq Reset \(aq. .IP Reset is a value: \(oq0\(cq = None, \(oq1\(cq = Software reset, \(oq2\(cq = VFO reset, \(oq4\(cq = Memory Clear reset, \(oq8\(cq = Master reset. .IP Since these values are defined as a bitmask in .IR include/hamlib/rig.h , it should be possible to OR these values together to do multiple resets at once, if the backend supports it or supports a reset action via rig control at all. . .TP .BR 0x87 ", " set_powerstat " \(aq" "\fIPower Status\fP" \(aq Set .RI \(aq "Power Status" \(aq. .IP Power Status is a value: \(oq0\(cq = Power Off, \(oq1\(cq = Power On, \(oq2\(cq = Power Standby (enter standby), \(oq4\(cq = Power Operate (leave standby). . .TP .BR 0x88 ", " get_powerstat Get .RI \(aq "Power Status" \(aq as in .B set_powerstat above. . .TP .BR 0x89 ", " send_dtmf " \(aq" \fIDigits\fP \(aq Set DTMF .RI \(aq Digits \(aq. . .TP .BR 0x8a ", " recv_dtmf Get DTMF .RI \(aq Digits \(aq. . .TP .BR _ ", " get_info Get misc information about the rig. . .TP .BR 0xf5 ", " get_rig_info Get misc information about the rig vfo status and other info. . .TP .BR 0xf3 ", " get_vfo_info " \(aq" \fIVFO\fP \(aq Get misc information about a specific vfo. . .TP .B dump_state Return certain state information about the radio backend. . .TP .BR 1 ", " dump_caps Not a real rig remote command, it just dumps capabilities, i.e. what the backend knows about this model, and what it can do. .IP TODO: Ensure this is in a consistent format so it can be read into a hash, dictionary, etc. Bug reports requested. .IP .BR Note : This command will produce many lines of output so be very careful if using a fixed length array! For example, running this command against the Dummy backend results in over 5kB of text output. .IP VFO parameter not used in 'VFO mode'. . .TP .BR 2 ", " power2mW " \(aq" "\fIPower [0.0..1.0]\fP" "\(aq \(aq" \fIFrequency\fP "\(aq \(aq" \fIMode\fP \(aq Returns .RI \(aq "Power mW" \(aq. .IP Converts a Power value in a range of .IR 0.0 ... 1.0 to the real transmit power in milli-Watts (integer). .IP .RI \(aq Frequency \(aq and .RI \(aq Mode \(aq also need to be provided as output power may vary according to these values. .IP VFO parameter is not used in VFO mode. . .TP .BR 4 ", " mW2power " \(aq" "\fIPower mW\fP" "\(aq \(aq" \fIFrequency\fP "\(aq \(aq" \fIMode\fP \(aq Returns .RI \(aq "Power [0.0..1.0]" \(aq. .IP Converts the real transmit power in milli-Watts (integer) to a Power value in a range of .IR "0.0 ... 1.0" . .IP .RI \(aq Frequency \(aq and .RI \(aq Mode \(aq also need to be provided as output power may vary according to these values. .IP VFO parameter is not used in VFO mode. .TP .BR set_clock " \(aq" \fIDateTime\fP \(aq Set .RI \(aq DateTime \(aq .IP Sets rig clock -- note that some rigs do not handle seconds or milliseconds. If you try to set sec/msec and rig does not support it you will get a debug warning message. Format is ISO8601. Formats accepted allow for 2-digit or 4-digit time zone .EX YYYY-MM-DDTHH:MM:SS.SSS+ZZ (where +ZZ is either -/+ UTC offset HH) YYYY-MM-DDTHH:MM:SS.SSS+ZZZZ (where +ZZZZ is either -/+ UTC offset HHMM) YYYY-MM-DDTHH:MM:SS+ZZ YYYY-MM-DDTHH:MM:SS+ZZZZ YYYY-MM-DDTHH:MM+ZZ YYYY-MM-DDTHH:MM+ZZZZ YYYY-MM-DD (sets date only) local (sets both clocks to local time) utc (sets both clocks to utc time) .EE Note: Icom rigs expect you to set local time and the hours off to UTC. So...4PM EST example would be 2021-12-01T16:00:00-0500 But...if you want to display GMT you must set the clock for GMT with zero UTC offset. Hopefully Icom will allow displaying either clock in the future Note: Kenwood rigs only allow setting local clock, and then only if not autoset by NTP. Trying to set clock when NTP is in use will set the offset, but not the time - and no error status will be returned. Time displayed on the auxiliary clock is solely determined by UTC and the aux offset. . .TP .BR get_clock Get .RI \(aq RigTime \(aq .IP Gets rig clock -- note that some rigs do not handle seconds or milliseconds. Format is ISO8601 YYYY-MM-DDTHH:MM:SS.sss+ZZ where +ZZ is either -/+ UTC offset . .TP .B chk_vfo Returns \(lq1\\n\(rq (single line only) if .B rigctld was invoked with the .BR \-o / \-\-vfo option and \(lq0\\n\(rq if not. .IP When in VFO mode the client will need to pass .RI \(aq VFO \(aq as the first parameter to .B set or .B get commands. VFO is one of the strings defined in .B set_vfo above. . .TP .BR set_vfo_opt " \(aq" \fIStatus\fP \(aq Set .RI \(aq Status \(aq .IP Set vfo option Status 1=on or 0=off This is the same as using the -o switch for rigctl and ritctld. This can be dynamically changed while running. . .TP .BR set_lock_mode " \(aq" \fILocked\fP \(aq Turns mode lock on(1) or off(0) (only when using rigctld). Turning on will prevent all clients from changing the rig mode. For example this is useful when running CW Skimmer in FM mode on an IC-7300. Clicking spots in a spotting program will not change the VFOA mode when lock is on. So "set_lock_mode 1" when CW Skimmer is started and "set_lock_mode 0" when CW Skimmer is stopped. . .TP .BR get_lock_mode Returns current lock mode status 1=On, 2=Off (only useful with rigctld) . .TP .BR send_raw " \(aq" \fITerminator\fP "\(aq \(aq" \fIString\fP \(aq Can send ASCII string or 0xnn values -- there can be no spaces in the command string. Possible terminator values are CR, LF, ;, ICOM, 0-100 (bytes to read), or -1 meaning unknown (will timeout on read) Examples: .EX send_raw ; FA;MD; send_raw icom 0xFE;0xFE;0x94;0x03;0xFD send_raw -1 0xFE;0xFE;0x94;0x03;0xFD send_raw 14 0xFE;0xFE;0x94;0x03;0xFD .EE . .TP .BR client_version " \(aq" \fIString\fP "\(aq Client can send its version to .B rigctld and get feedback on compatibility, deprecation, and alternatives .TP .BR hamlib_version Returns Hamlib version with ISO8601 date/time . .TP .BR test Performs test routines. Under development. . .TP .BR set_gpio " \(aq" \fIGPIO#\fP "\(aq Sets GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port Can also use 1,2,3,4 . .TP .BR get_gpio " \(aq" \fIGPIO#\fP "\(aq Reads GPIO1, GPIO2, GPIO3, GPIO4 on the GPIO ptt port Can also use 1,2,3,4 . .SH PROTOCOL . There are two protocols in use by .BR rigctld , the .B Default Protocol and the .BR "Extended Response Protocol" . . .PP The .B Default Protocol is intended primarily for the communication between .B Hamlib library functions and .B rigctld (\(lqNET rigctl\(rq, available using radio model \(oq2\(cq). . .PP The .B Extended Response Protocol is intended to be used with scripts or other programs interacting directly with .B rigctld as consistent feedback is provided. . . .SS Default Protocol . The .B Default Protocol is intentionally simple. Commands are entered on a single line with any needed values. In practice, reliable results are obtained by terminating each command string with a newline character, \(oq\\n\(cq. . .PP Example set frequency and mode commands (Perl code (typed text shown in bold)): . .PP .in +4n .EX \fBprint $socket "F 14250000\\n";\fP \fBprint $socket "\\\\set_mode LSB 2400\\n";\fP # escape leading '\\' .EE .in . .PP A one line response will be sent as a reply to .B set commands, \(lqRPRT \fIx\fP\\n\(rq where .I x is the Hamlib error code with \(oq0\(cq indicating success of the command. . .PP Responses from .B rigctld .B get commands are text values and match the same tokens used in the .B set commands. Each value is returned on its own line. On error the string \(lqRPRT \fIx\fP\\n\(rq is returned where .I x is the Hamlib error code. . .PP Example get frequency (Perl code): . .PP .in +4n .EX \fBprint $socket "f\\n";\fP "14250000\\n" .EE .in . .PP Most .B get functions return one to three values. A notable exception is the .B dump_caps command which returns many lines of \fBkey\fR:\fIvalue\fR pairs. . .PP This protocol is primarily used by the \(lqNET rigctl\(rq (rigctl model 2) backend which allows applications already written for Hamlib's C API to take advantage of .B rigctld without the need of rewriting application code. An application's user can select rotator model 2 (\(lqNET rigctl\(rq) and then set .B rig_pathname to \(lqlocalhost:4532\(rq or other network .IR host : port (set by the .BR \-T / \-t options, respectively, above). . . .SS Extended Response Protocol . The Extended Response protocol adds several rules to the strings returned by .B rigctld and adds a rule for the command syntax. . .PP 1. The command received by .B rigctld is echoed with its long command name followed by the value(s) (if any) received from the client terminated by the specified response separator as the first record of the response. . .PP 2. The last record of each block is the string \(lqRPRT \fIx\fP\\n\(rq where .I x is the numeric return value of the Hamlib backend function that was called by the command. . .PP 3. Any records consisting of data values returned by the radio backend are prepended by a string immediately followed by a colon then a space and then the value terminated by the response separator. e.g. \(lqFrequency: 14250000\\n\(rq when the command was prepended by \(oq+\(cq. . .PP 4. All commands received will be acknowledged by .B rigctld with records from rules 1 and 2. Records from rule 3 are only returned when data values must be returned to the client. . .PP An example response to a .B set_mode command sent from the shell prompt (note the prepended \(oq+\(cq): . .PP .in +4n .EX $ \fBecho "+M USB 2400" | nc -w 1 localhost 4532\fP set_mode: USB 2400 RPRT 0 .EE .in . .PP In this case the long command name and values are returned on the first line and the second line contains the end of block marker and the numeric radio backend return value indicating success. . .PP An example response to a .B get_mode query: . .PP .in +4n .EX $ \fBecho "+\\get_mode" | nc -w 1 localhost 4532\fP get_mode: Mode: USB Passband: 2400 RPRT 0 .EE .in . .IP .BR Note : The \(oq\\\(cq is still required for the long command name even with the ERP character. . .PP In this case, as no value is passed to .BR rigctld , the first line consists only of the long command name. The final line shows that the command was processed successfully by the radio backend. . .PP Invoking the Extended Response Protocol requires prepending a command with a punctuation character. As shown in the examples above, prepending a \(oq+\(cq character to the command results in the responses being separated by a newline character (\(oq\\n\(cq). Any other punctuation character recognized by the C .BR ispunct () function except \(oq\\\(cq, \(oq?\(cq, or \(oq_\(cq will cause that character to become the response separator and the entire response will be on one line. . .PP Separator character summary: .TP .RB \(oq + \(cq Each record of the response is appended with a newline (\(oq\\n\(cq). . .TP .RB \(oq ; "\(cq, \(oq" | "\(cq, or, \(oq" , \(cq Each record of the response is appended by the given character resulting in entire response on one line. .IP These are common record separators for text representations of spreadsheet data, etc. . .TP .RB \(oq ? \(cq Reserved for help in .BR rigctl . . .TP .RB \(oq _ \(cq Reserved for .B get_info short command . .TP .RB \(oq # \(cq Reserved for comments when reading a command file script. .IP .BR Note : Other punctuation characters have not been tested! Use at your own risk. . .PP For example, invoking a .B get_mode query with a leading \(oq;\(cq returns: . .PP .in +4n .EX get_mode:;Mode: USB;Passband: 2400;RPRT 0 .EE .in . .PP Or, using the pipe character \(oq|\(cq returns: . .PP .in +4n .EX get_mode:|Mode: USB|Passband: 2400|RPRT 0 .EE .in . .PP And a .B set_mode command prepended with a \(oq|\(cq returns: . .PP .in +4n .EX set_mode: USB 2400|RPRT 0 .EE .in . .PP Such a format will allow reading a response as a single event using a preferred response separator. Other punctuation characters have not been tested! . .PP The following commands have been tested with the Extended Response protocol and the included .B testctld.pl Perl script: .IP .BR set_freq , .BR get_freq , .BR set_split_freq , .BR get_split_freq , .BR set_mode , .BR get_mode , .BR set_split_mode , .BR get_split_mode , .BR set_vfo , .BR get_vfo , .BR set_split_vfo , .BR get_split_vfo , .BR set_rit , .BR get_rit , .BR set_xit , .BR get_xit , .BR set_ptt , .BR get_ptt , .BR power2mW , .BR mW2power , .BR dump_caps . . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXAMPLES . Start .B rigctld for a Yaesu FT-920 using a USB-to-serial adapter and backgrounding: . .PP .in +4n .EX .RB $ " rigctld -m 1014 -r /dev/ttyUSB1 &" .EE .in . .PP Start .B rigctld for a Yaesu FT-920 using a USB-to-serial adapter while setting baud rate and stop bits, and backgrounding: . .PP .in +4n .EX .RB $ " rigctld -m 1014 -r /dev/ttyUSB1 -s 4800 -C stop_bits=2 &" .EE .in . .PP Start .B rigctld for an Elecraft K3 using COM2 on MS Windows: . .PP .in +4n .EX .RB $ " rigctld -m 2029 -r COM2" .EE .in . .PP Connect to the already running .B rigctld and set the frequency to 14.266 MHz with a 1 second read timeout using the default protocol from the shell prompt: . .PP .in +4n .EX $ \fBecho "\\set_freq 14266000" | nc -w 1 localhost 4532\fP .EE .in . .PP Connect to a running .B rigctld with .B rigctl on the local host: . .PP .in +4n .EX .RB $ " rigctl -m2" .EE .in . . .SH SECURITY . No authentication whatsoever; DO NOT leave this TCP port open wide to the Internet. Please ask if stronger security is needed or consider using a Secure Shell .RB ( ssh (1)) tunnel. . .PP As .B rigctld does not need any greater permissions than .BR rigctl , it is advisable to not start .B rigctld as \(lqroot\(rq or another system user account in order to limit any vulnerability. . . .SH BUGS . The daemon is not detaching and backgrounding itself. .PP No method to exit the daemon so the .BR kill (1) command must be used to terminate it. . .PP Multiple clients using the daemon may experience contention with the connected radio. . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2000-2010 Stephane Fillod .br Copyright \(co 2000-2018 the Hamlib Group (various contributors) .br Copyright \(co 2011-2020 Nate Bargmann . .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR kill (1), .BR rigctl (1), .BR ssh (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigsmtr.10000664000175000017500000001520515056640442011630 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigsmtr.c .\" .TH RIGSMTR "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigsmtr \- measure S-Meter vs azimuth using Hamlib . . .SH SYNOPSIS . .SY rigsmtr .OP \-hvV .OP \-m id .OP \-r device .OP \-s baud .OP \-c id .OP \-C parm=val .OP \-M id .OP \-R device .OP \-S baud .OP \-N parm=val .RI [ time_step ] .YS . . .SH DESCRIPTION . .B rigsmtr uses .B Hamlib to control a radio to measure S-Meter value versus antenna azimuth. . .PP It rotates the antenna from minimum azimuth to maximum azimuth. Every second, or .I time_step if specified in seconds, it retrieves the signal strength. Azimuth in degrees and the corresponding S-Meter level in dB relative to S9 are then printed on .BR stdout . . .PP To work correctly, rigsmtr needs a radio that could measure S-Meter and a Hamlib backend that is able to retrieve it, connected to a Hamlib supported rotator. . .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete radio support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options. . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. .IP See model list (use \(lqrigctl \-l\(rq). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set radio serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities as the default. . .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the radio. .IP Only useful for Icom and some Ten-Tec radios. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set radio configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option of .B rigctl for a list of configuration parameters for a given model number. . .TP .BR \-M ", " \-\-rot\-model = \fIid\fP Select rotator model number. .IP See model list (use \(lqrotctl \-l\(rq). . .TP .BR \-R ", " \-\-rot\-file = \fIdevice\fP Use .I device as the file name of the port connected to the rotator. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-S ", " \-\-rot\-serial\-speed = \fIbaud\fP Set rotator serial speed to .I baud rate. .IP Uses maximum serial speed from rotator backend capabilities as the default. . .TP .BR \-N ", " \-\-rot\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set rotator configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option of .B rotctl for a list of configuration parameters for a given model number. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigsmtr and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .BR \-\-set\-conf " and " \-\-rot\-set\-conf options. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS . .B rigsmtr exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib ; . .TP .B 3 if the radio doesn't have the required capabilities. . . .SH EXAMPLE . Collect S-Meter readings on a TS\-850 while an EasycommII rotator makes a full 360\(de rotation and record measurements in the file .I csmtr (typed text shown in bold): . .PP .in +4n .EX .RB $ " rigsmtr \-m 2009 \-r /dev/ttyS1 \-M 202 > csmtr" .EE .in . .PP After completion the file .I csmtr contains lines such as: . .PP .in +4n .EX 0 \-47 30 \-40 60 \-22 90 \-3 120 10 150 1 180 \-11 210 \-24 240 \-35 270 \-42 300 \-48 330 \-51 360 \-49 .EE .in . .PP The results can be plotted with .BR gnuplot (1): . .PP .in +4n .EX .RB $ " gnuplot" .B set angles degrees .B set polar .B set grid polar 15. .B unset border .B unset param .B set style data line .B set rrange [-60:60] .B set xrange [-60:60] .B set yrange [-60:60] .B plot csmtr .EE .in . . .SH BUGS . Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME .fi . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2007-2009 Stephane Fillod .br Copyright \(co 2018-2020 Nate Bargmann .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR gnuplot (1), .BR rigctl (1), .BR rotctl (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/doc/man1/rigswr.10000664000175000017500000001454415056640442011463 .\" Hey, EMACS: -*- nroff -*- .\" .\" For layout and available macros, see man(7), man-pages(7), groff_man(7) .\" Please adjust the date whenever revising the manpage. .\" .\" Note: Please keep this page in sync with the source, rigswr.c .\" .TH RIGSWR "1" "2020-09-09" "Hamlib" "Hamlib Utilities" . . .SH NAME . rigswr \- measure VSWR vs frequency. . . .SH SYNOPSIS . .SY rigswr .OP \-hvV .OP \-m id .OP \-r device .OP \-s baud .OP \-c id .OP \-C parm=val .OP \-p device .OP \-P type start_freq stop_freq .RI [ freq_step ] .SY . . .SH DESCRIPTION . .B rigswr uses .B Hamlib to control a radio to measure VSWR (Voltage Standing Wave Ratio) over a frequency range. . .PP It scans frequencies from .I start_freq to .I stop_freq with an optional increment of .I freq_step (default step is 100 kHz). All values must be entered as an integer in Hertz (cycles per second). . .PP .BR Note : .B rigswr assumes that .I start_freq is less than or equal to .IR stop_freq . If it is greater, .B rigswr will exit without doing anything. . .PP For each frequency, it transmits at 25% of total POWER during 0.5 second in CW mode and reads VSWR. . .PP Frequency and the corresponding VSWR are then printed on .BR stdout . . .PP To work correctly, .B rigswr needs a radio that can measure VSWR and a .B Hamlib backend that supports reading VSWR from the radio. .PP Keep in mind that Hamlib is BETA level software. While a lot of backend libraries lack complete radio support, the basic functions are usually well supported. . .PP Please report bugs and provide feedback at the e-mail address given in the .B BUGS section below. Patches and code enhancements sent to the same address are welcome. . . .SH OPTIONS . This program follows the usual GNU command line syntax. Short options that take an argument may have the value follow immediately or be separated by a space. Long options starting with two dashes (\(oq\-\(cq) require an \(oq=\(cq between the option and any argument. . .PP Here is a summary of the supported options: . .TP .BR \-m ", " \-\-model = \fIid\fP Select radio model number. .IP See model list (use \(lqrigctl \-l\(rq). . .TP .BR \-r ", " \-\-rig\-file = \fIdevice\fP Use .I device as the file name of the port connected to the radio. .IP Often a serial port, but could be a USB to serial adapter. Typically .IR /dev/ttyS0 ", " /dev/ttyS1 ", " /dev/ttyUSB0 , etc. on Linux, .IR COM1 ", " COM2 , etc. on MS Windows. The BSD flavors and Mac OS/X have their own designations. See your system's documentation. . .TP .BR \-s ", " \-\-serial\-speed = \fIbaud\fP Set radio serial speed to .I baud rate. .IP Uses maximum serial speed from radio backend capabilities as the default. .TP .BR \-c ", " \-\-civaddr = \fIid\fP Use .I id as the CI-V address to communicate with the radio. .IP Only useful for Icom and some Ten-Tec radios. .IP .BR Note : The .I id is in decimal notation, unless prefixed by .IR 0x , in which case it is hexadecimal. . .TP .BR \-C ", " \-\-set\-conf = \fIparm=val\fP [ \fI,parm=val\fP ] Set radio configuration parameter(s), e.g. .IR stop_bits=2 . .IP Use the .B -L option of .B rigctl for a list of configuration parameters for a given model number. . .TP .BR \-p ", " \-\-ptt\-file = \fIdevice\fP Use .I device as the file name of the Push-To-Talk port using a device file as with the .B \-r option above. .IP This is only needed if the radio doesn't have CAT PTT control and requires a separate device port to key the transmitter. . .TP .BR \-P ", " \-\-ptt\-type = \fItype\fP Use .I type of Push-To-Talk device. .IP Supported types are RIG (CAT), DTR, RTS, PARALLEL, NONE. . .TP .BR \-v ", " \-\-verbose Set verbose mode, cumulative (see .B DIAGNOSTICS below). . .TP .BR \-h ", " \-\-help Show a summary of these options and exit. . .TP .BR \-V ", " \-\-version Show version of .B rigswr and exit. . .PP .BR Note : Some options may not be implemented by a given backend and will return an error. This is most likely to occur with the .B \-\-set\-conf option. . . .SH DIAGNOSTICS . The .BR \-v , .B \-\-verbose option allows different levels of diagnostics to be output to .B stderr and correspond to \-v for .BR BUG , \-vv for .BR ERR , \-vvv for .BR WARN , \-vvvv for .BR VERBOSE , or \-vvvvv for .BR TRACE . . .PP A given verbose level is useful for providing needed debugging information to the email address below. For example, TRACE output shows all of the values sent to and received from the radio which is very useful for radio backend library development and may be requested by the developers. . . .SH EXIT STATUS . .B rigswr exits with: . .TP .B 0 if all operations completed normally; . .TP .B 1 if there was an invalid command line option or argument; . .TP .B 2 if an error was returned by .BR Hamlib ; . .TP .B 3 if the rig doesn't have the required capabilities. . . .SH EXAMPLE . Scans frequencies between 14.000 MHz and 14.200 MHz with 50 kHz step on a TS-850 and records VSWR measurements in file .I cswr (typed text shown in bold): . .PP .in +4n .EX .RB $ " rigswr -m 2009 -r /dev/ttyS1 14000000 14200000 50000 > cswr" .EE .in . .PP After completion, .I cswr contains the following lines: . .PP .in +4n .EX 14000000 1.50 14050000 1.31 14100000 1.22 14150000 1.07 14200000 1.07 .EE .in . .PP The result can be plotted with .BR gnuplot (1): . .PP .in +4n .EX .RB $ " gnuplot" .B set data style linespoints .B set grid .B plot cswr .EE .in . . .SH BUGS . Depending on keyer/QSK setup, transmissions in CW mode may not be modulated thus possibly giving a wrong result. Please report this situation if it happens. . .PP Report bugs to: .IP .nf .MT hamlib\-developer@lists.sourceforge.net Hamlib Developer mailing list .ME . . .SH COPYING . This file is part of Hamlib, a project to develop a library that simplifies radio, rotator, and amplifier control functions for developers of software primarily of interest to radio amateurs and those interested in radio communications. . .PP Copyright \(co 2004 Thierry Leconte .br Copyright \(co 2004-2011 Stephane Fillod .br Copyright \(co 2007,2018-2020 Nate Bargmann .PP This is free software; see the file COPYING for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . . .SH SEE ALSO . .BR gnuplot (1), .BR rigctl (1), .BR hamlib (7) . . .SH COLOPHON . Links to the Hamlib Wiki, Git repository, release archives, and daily snapshot archives are available via . .UR http://www.hamlib.org hamlib.org .UE . hamlib-4.6.5/hamlib.pc.in0000664000175000017500000000056015056640442010641 prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: @PACKAGE_NAME@ Description: Library to control radio and rotator equipment. URL: @PACKAGE_URL@ Version: @PACKAGE_VERSION@ Requires.private: @LIBUSB@ Cflags: -I${includedir} @PTHREAD_CFLAGS@ Libs: -L${libdir} -lhamlib Libs.private: @MATH_LIBS@ @DL_LIBS@ @NET_LIBS@ @PTHREAD_LIBS@ hamlib-4.6.5/hamlib.m40000664000175000017500000000605415056640442010156 dnl Configure Paths for Hamlib dnl Cloned from Alsa project http://www.alsa-project.org dnl AM_PATH_HAMLIB([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for libhamlib, and define HAMLIB_LTDL, dnl HAMLIB_CFLAGS and HAMLIB_LIBS as appropriate. dnl enables arguments --with-hamlib-prefix= dnl --with-hamlib-inc-prefix= dnl --disable-hamlibtest (this has no effect, as yet) dnl dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified, dnl and the hamlib libraries are not found, a fatal AC_MSG_ERROR() will result. dnl AC_DEFUN([AM_PATH_HAMLIB], [dnl Save the original CFLAGS, LDFLAGS, and LIBS hamlib_save_CFLAGS="$CFLAGS" hamlib_save_LDFLAGS="$LDFLAGS" hamlib_save_LIBS="$LIBS" hamlib_found=yes dnl dnl Get the cflags and libraries for hamlib dnl AC_ARG_WITH(hamlib-prefix, [ --with-hamlib-prefix=PFX Prefix where Hamlib library is installed(optional)], [hamlib_prefix="$withval"], [hamlib_prefix=""]) AC_ARG_WITH(hamlib-inc-prefix, [ --with-hamlib-inc-prefix=PFX Prefix where include libraries are (optional)], [hamlib_inc_prefix="$withval"], [hamlib_inc_prefix=""]) dnl FIXME: this is not yet implemented AC_ARG_ENABLE(hamlibtest, [ --disable-hamlibtest Do not try to compile and run a test Hamlib program], [enable_hamlibtest=no], [enable_hamlibtest=yes]) dnl Add any special include directories AC_MSG_CHECKING(for HAMLIB CFLAGS) if test "$hamlib_inc_prefix" != "" ; then HAMLIB_CFLAGS="$HAMLIB_CFLAGS -I$hamlib_inc_prefix" CFLAGS="$CFLAGS -I$hamlib_inc_prefix $LIBUSB_CFLAGS" fi AC_MSG_RESULT($HAMLIB_CFLAGS) dnl add any special lib dirs AC_MSG_CHECKING(for HAMLIB LDFLAGS) if test "$hamlib_prefix" != "" ; then HAMLIB_LIBS="$HAMLIB_LIBS -L$hamlib_prefix -Wl,--rpath -Wl,$hamlib_prefix" LDFLAGS="$LDFLAGS $HAMLIB_LIBS $LIBUSB_LDFLAGS" fi dnl add the hamlib library HAMLIB_LIBS="$HAMLIB_LIBS -lhamlib -lm -ldl" LIBS=$(echo $LIBS | sed 's/-lm//') LIBS=$(echo $LIBS | sed 's/-ldl//') LIBS=$(echo $LIBS | sed 's/ //') #LIBS="$HAMLIB_LIBS $LIBS" AC_MSG_RESULT($HAMLIB_LIBS) dnl add any special LTDL file AC_MSG_CHECKING(for HAMLIB LTDL) if test "$hamlib_prefix" != "" ; then HAMLIB_LTDL="$HAMLIB_LTDL $hamlib_prefix/libhamlib.la" fi AC_MSG_RESULT($HAMLIB_LTDL) dnl Check for a working version of libhamlib that is of the right version. dnl FIXME: not implemented yet! dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. #AC_CHECK_LIB([hamlib], [rig_init],, # [ifelse([$3], , [AC_MSG_ERROR(No linkable libhamlib was found.)]) # hamlib_found=no] #) if test "x$hamlib_found" = "xyes" ; then ifelse([$2], , :, [$2]) LIBS=$(echo $LIBS | sed 's/-lhamlib//g') LIBS=$(echo $LIBS | sed 's/ //') LIBS="-lhamlib $LIBS" fi if test "x$hamlib_found" = "xno" ; then ifelse([$3], , :, [$3]) CFLAGS="$hamlib_save_CFLAGS" LDFLAGS="$hamlib_save_LDFLAGS" LIBS="$hamlib_save_LIBS" HAMLIB_CFLAGS="" HAMLIB_LIBS="" fi dnl That should be it. Now just export out symbols: AC_SUBST(HAMLIB_CFLAGS) AC_SUBST(HAMLIB_LIBS) AC_SUBST(HAMLIB_LTDL) ]) hamlib-4.6.5/macros/0000775000175000017500000000000015056640474010024 5hamlib-4.6.5/macros/ax_cflags_warn_all.m40000664000175000017500000001167115056640442014015 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] # # DESCRIPTION # # Try to find a compiler option that enables most reasonable warnings. # # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. # # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and # Intel compilers. For a given compiler, the Fortran flags are much more # experimental than their C equivalents. # # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS # - $2 add-value-if-not-found : nothing # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # NOTE: These macros depend on AX_APPEND_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2010 Rhys Ulerich # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 14 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], VAR,[VAR="no, unknown" ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-warn all % -warn all" dnl Intel "-pedantic % -Wall" dnl GCC "-xstrconst % -v" dnl Solaris C "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX "-ansi -ansiE % -fullwarn" dnl IRIX "+ESlit % +w1" dnl HP-UX C "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) "-h conform % -h msglevel 2" dnl Cray C (Unicos) # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" ]) AS_VAR_POPDEF([FLAGS])dnl AC_REQUIRE([AX_APPEND_FLAG]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; esac AS_VAR_POPDEF([VAR])dnl ])dnl AX_FLAGS_WARN_ALL dnl implementation tactics: dnl the for-argument contains a list of options. The first part of dnl these does only exist to detect the compiler - usually it is dnl a global option to enable -ansi or -extrawarnings. All other dnl compilers will fail about it. That was needed since a lot of dnl compilers will give false positives for some option-syntax dnl like -Woption or -Xoption as they think of it is a pass-through dnl to later compile stages or something. The "%" is used as a dnl delimiter. A non-option comment can be given after "%%" marks dnl which will be shown but not added to the respective C/CXXFLAGS. AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C]) ]) AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([C++]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([C++]) ]) AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl AC_LANG_PUSH([Fortran]) AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) AC_LANG_POP([Fortran]) ]) hamlib-4.6.5/macros/ltversion.m40000644000175000017500000000131215056640445012224 # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4441 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.5.4]) m4_define([LT_PACKAGE_REVISION], [2.5.4]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.5.4' macro_revision='2.5.4' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) hamlib-4.6.5/macros/ax_lib_nova.m40000664000175000017500000000114315056640442012461 AU_ALIAS([VL_LIB_NOVA], [AX_LIB_NOVA]) AC_DEFUN([AX_LIB_NOVA], [ AC_CACHE_CHECK([for nova library], ax_cv_lib_nova, [ AC_LANG_PUSH(C++) AC_CHECK_HEADER(libnova/libnova.h, ax_cv_lib_nova="-lnova -lstdc++ -lz") AC_LANG_POP() if test -z "$ax_cv_lib_nova"; then ax_cv_lib_nova="no" fi ]) if test "$ax_cv_lib_nova" != "no"; then ORIG_LIBS="$LIBS" LIBS="$LIBS $ax_cv_lib_nova" AC_DEFINE(HAVE_LIBNOVA, 1, [Define if you have a nova compatible library]) LIBS="$ORIG_LIBS" NOVA_LIBS="$ax_cv_lib_nova" AC_SUBST([NOVA_LIBS]) fi ]) hamlib-4.6.5/macros/libtool.m40000644000175000017500000114100515056640445011650 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 63 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.64])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), in case it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2024 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) # Feature test to disable chained fixups since it is not # compatible with '-undefined dynamic_lookup' AC_CACHE_CHECK([for -no_fixup_chains linker flag], [lt_cv_support_no_fixup_chains], [ save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" AC_LINK_IFELSE( [AC_LANG_PROGRAM([],[])], lt_cv_support_no_fixup_chains=yes, lt_cv_support_no_fixup_chains=no ) LDFLAGS=$save_LDFLAGS ] ) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main(void) { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' if test yes = "$lt_cv_support_no_fixup_chains"; then AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains']) fi ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi _lt_dar_needs_single_mod=no case $host_os in rhapsody* | darwin1.*) _lt_dar_needs_single_mod=yes ;; darwin*) # When targeting Mac OS X 10.4 (darwin 8) or later, # -single_module is the default and -multi_module is unsupported. # The toolchain on macOS 10.14 (darwin 18) and later cannot # target any OS version that needs -single_module. case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*) _lt_dar_needs_single_mod=yes ;; esac ;; esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then # Trim trailing / since we'll always append absolute paths and we want # to avoid //, if only for less confusing output for the user. lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*|x86_64-gnu*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because that's what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_REQUIRE([AC_PROG_RANLIB]) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu* | ironclad*) # Under GNU Hurd and Ironclad, this test is not required because there # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord (void) __attribute__((visibility("default"))); #endif int fnord (void) { return 42; } int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | windows* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds # If user builds GCC with multilib enabled, # it should just install on $(libdir) # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. if test xyes = x"$multilib"; then postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ $install_prog $dir/$dlname $destdir/$dlname~ chmod a+x $destdir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib $destdir/$dlname'\'' || exit \$?; fi' else postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac case $host_cpu in powerpc64) # On FreeBSD bi-arch platforms, a different variable is used for 32-bit # binaries. See . AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[int test_pointer_size[sizeof (void *) - 5]; ]])], [shlibpath_var=LD_LIBRARY_PATH], [shlibpath_var=LD_32_LIBRARY_PATH]) ;; *) shlibpath_var=LD_LIBRARY_PATH ;; esac case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # -rpath works at least for libraries that are not overridden by # libraries installed in system locations. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directories which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; *-mlibc) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='mlibc ld.so' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; serenity*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no dynamic_linker='SerenityOS LibELF' ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; emscripten*) version_type=none need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= dynamic_linker="Emscripten linker" _LT_COMPILER_PIC($1)='-fPIC' _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(no_undefined_flag, $1)= ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw* | *-*-windows*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1
&1
conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; *-mlibc) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; serenity*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | windows* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool], [lt_cv_path_manifest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_manifest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_manifest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BCDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(void){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *-mlibc) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; serenity*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *flang* | ftn | f18* | f95*) # Flang compiler. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *-mlibc) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; serenity*) ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | windows* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | windows* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=no ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; *-mlibc) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; *-mlibc) ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; serenity*) ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e. impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(void){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | windows* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=no ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; *-mlibc) _LT_TAGVAR(ld_shlibs, $1)=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; serenity*) ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R,l}" and the path. # Remove the space. if test x-L = x"$p" || test x-R = x"$p" || test x-l = x"$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_PROG([FILECMD], [file], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* | *-*-windows* ) case $build in *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS hamlib-4.6.5/macros/ax_cxx_compile_stdcxx.m40000664000175000017500000004655015056640442014612 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and # CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) # or '14' (for the C++14 standard). # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for no added switch, and then for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is # required and that the macro should error out if no mode with that # support is found. If specified 'optional', then configuration proceeds # regardless, after defining HAVE_CXX${VERSION} if and only if a # supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper # Copyright (c) 2020 Jason Merrill # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 12 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], [$2], [noext], [], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no m4_if([$2], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi]) m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) m4_if([$2], [ext], [], [dnl if test x$ac_success = xno; then dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx$1_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi fi if test x$ac_success = xno; then HAVE_CXX$1=0 AC_MSG_NOTICE([No compiler with C++$1 support was found]) else HAVE_CXX$1=1 AC_DEFINE(HAVE_CXX$1,1, [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) ]) dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201103L #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L ]]) dnl Tests for new features in C++14 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L ]]) dnl Tests for new features in C++17 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L ]]) hamlib-4.6.5/macros/ax_lua.m40000664000175000017500000007024615056640442011463 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_lua.html # =========================================================================== # # SYNOPSIS # # AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_HEADERS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_LIBS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_READLINE[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # # DESCRIPTION # # Detect a Lua interpreter, optionally specifying a minimum and maximum # version number. Set up important Lua paths, such as the directories in # which to install scripts and modules (shared libraries). # # Also detect Lua headers and libraries. The Lua version contained in the # header is checked to match the Lua interpreter version exactly. When # searching for Lua libraries, the version number is used as a suffix. # This is done with the goal of supporting multiple Lua installs (5.1, # 5.2, 5.3, and 5.4 side-by-side). # # A note on compatibility with previous versions: This file has been # mostly rewritten for serial 18. Most developers should be able to use # these macros without needing to modify configure.ac. Care has been taken # to preserve each macro's behavior, but there are some differences: # # 1) AX_WITH_LUA is deprecated; it now expands to the exact same thing as # AX_PROG_LUA with no arguments. # # 2) AX_LUA_HEADERS now checks that the version number defined in lua.h # matches the interpreter version. AX_LUA_HEADERS_VERSION is therefore # unnecessary, so it is deprecated and does not expand to anything. # # 3) The configure flag --with-lua-suffix no longer exists; the user # should instead specify the LUA precious variable on the command line. # See the AX_PROG_LUA description for details. # # Please read the macro descriptions below for more information. # # This file was inspired by Andrew Dalke's and James Henstridge's # python.m4 and Tom Payne's, Matthieu Moy's, and Reuben Thomas's ax_lua.m4 # (serial 17). Basically, this file is a mash-up of those two files. I # like to think it combines the best of the two! # # AX_PROG_LUA: Search for the Lua interpreter, and set up important Lua # paths. Adds precious variable LUA, which may contain the path of the Lua # interpreter. If LUA is blank, the user's path is searched for an # suitable interpreter. # # Optionally a LUAJIT option may be set ahead of time to look for and # validate a LuaJIT install instead of PUC Lua. Usage might look like: # # AC_ARG_WITH(luajit, [AS_HELP_STRING([--with-luajit], # [Prefer LuaJIT over PUC Lua, even if the latter is newer. Default: no]) # ]) # AM_CONDITIONAL([LUAJIT], [test "x$with_luajit" != 'xno']) # # If MINIMUM-VERSION is supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION will be accepted. If # TOO-BIG-VERSION is also supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION and less than # TOO-BIG-VERSION will be accepted. # # The Lua version number, LUA_VERSION, is found from the interpreter, and # substituted. LUA_PLATFORM is also found, but not currently supported (no # standard representation). # # Finally, the macro finds four paths: # # luadir Directory to install Lua scripts. # pkgluadir $luadir/$PACKAGE # luaexecdir Directory to install Lua modules. # pkgluaexecdir $luaexecdir/$PACKAGE # # These paths are found based on $prefix, $exec_prefix, Lua's # package.path, and package.cpath. The first path of package.path # beginning with $prefix is selected as luadir. The first path of # package.cpath beginning with $exec_prefix is used as luaexecdir. This # should work on all reasonable Lua installations. If a path cannot be # determined, a default path is used. Of course, the user can override # these later when invoking make. # # luadir Default: $prefix/share/lua/$LUA_VERSION # luaexecdir Default: $exec_prefix/lib/lua/$LUA_VERSION # # These directories can be used by Automake as install destinations. The # variable name minus 'dir' needs to be used as a prefix to the # appropriate Automake primary, e.g. lua_SCRIPS or luaexec_LIBRARIES. # # If an acceptable Lua interpreter is found, then ACTION-IF-FOUND is # performed, otherwise ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT- # FOUND is blank, then it will default to printing an error. To prevent # the default behavior, give ':' as an action. # # AX_LUA_HEADERS: Search for Lua headers. Requires that AX_PROG_LUA be # expanded before this macro. Adds precious variable LUA_INCLUDE, which # may contain Lua specific include flags, e.g. -I/usr/include/lua5.1. If # LUA_INCLUDE is blank, then this macro will attempt to find suitable # flags. # # LUA_INCLUDE can be used by Automake to compile Lua modules or # executables with embedded interpreters. The *_CPPFLAGS variables should # be used for this purpose, e.g. myprog_CPPFLAGS = $(LUA_INCLUDE). # # This macro searches for the header lua.h (and others). The search is # performed with a combination of CPPFLAGS, CPATH, etc, and LUA_INCLUDE. # If the search is unsuccessful, then some common directories are tried. # If the headers are then found, then LUA_INCLUDE is set accordingly. # # The paths automatically searched are: # # * /usr/include/luaX.Y # * /usr/include/lua/X.Y # * /usr/include/luaXY # * /usr/local/include/luaX.Y # * /usr/local/include/lua-X.Y # * /usr/local/include/lua/X.Y # * /usr/local/include/luaXY # # (Where X.Y is the Lua version number, e.g. 5.1.) # # The Lua version number found in the headers is always checked to match # the Lua interpreter's version number. Lua headers with mismatched # version numbers are not accepted. # # If headers are found, then ACTION-IF-FOUND is performed, otherwise # ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then # it will default to printing an error. To prevent the default behavior, # set the action to ':'. # # AX_LUA_LIBS: Search for Lua libraries. Requires that AX_PROG_LUA be # expanded before this macro. Adds precious variable LUA_LIB, which may # contain Lua specific linker flags, e.g. -llua5.1. If LUA_LIB is blank, # then this macro will attempt to find suitable flags. # # LUA_LIB can be used by Automake to link Lua modules or executables with # embedded interpreters. The *_LIBADD and *_LDADD variables should be used # for this purpose, e.g. mymod_LIBADD = $(LUA_LIB). # # This macro searches for the Lua library. More technically, it searches # for a library containing the function lua_load. The search is performed # with a combination of LIBS, LIBRARY_PATH, and LUA_LIB. # # If the search determines that some linker flags are missing, then those # flags will be added to LUA_LIB. # # If libraries are found, then ACTION-IF-FOUND is performed, otherwise # ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then # it will default to printing an error. To prevent the default behavior, # set the action to ':'. # # AX_LUA_READLINE: Search for readline headers and libraries. Requires the # AX_LIB_READLINE macro, which is provided by ax_lib_readline.m4 from the # Autoconf Archive. # # If a readline compatible library is found, then ACTION-IF-FOUND is # performed, otherwise ACTION-IF-NOT-FOUND is performed. # # LICENSE # # Copyright (c) 2023 Caleb Maclennan # Copyright (c) 2015 Reuben Thomas # Copyright (c) 2014 Tim Perkins # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 47 dnl ========================================================================= dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_PROG_LUA], [ dnl Check for required tools. AC_REQUIRE([AC_PROG_GREP]) AC_REQUIRE([AC_PROG_SED]) dnl Make LUA a precious variable. AC_ARG_VAR([LUA], [The Lua interpreter, e.g. /usr/bin/lua5.1]) dnl Find a Lua interpreter. AM_COND_IF([LUAJIT], [_ax_lua_interpreter_list='luajit luajit-2.1.0-beta3 luajit-2.0.5 luajit-2.0.4 luajit-2.0.3'], [_ax_lua_interpreter_list='lua lua5.4 lua54 lua5.3 lua53 lua5.2 lua52 lua5.1 lua51 lua5.0 lua50']) m4_if([$1], [], [ dnl No version check is needed. Find any Lua interpreter. AS_IF([test "x$LUA" = 'x'], [AC_PATH_PROGS([LUA], [$_ax_lua_interpreter_list], [:])]) ax_display_LUA='lua' AS_IF([test "x$LUA" != 'x:'], [ dnl At least check if this is a Lua interpreter. AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([not a Lua interpreter]) ]) ]) ], [ dnl A version check is needed. AS_IF([test "x$LUA" != 'x'], [ dnl Check if this is a Lua interpreter. AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([not a Lua interpreter]) ]) dnl Check the version. m4_if([$2], [], [_ax_check_text="whether $LUA version >= $1"], [_ax_check_text="whether $LUA version >= $1, < $2"]) AC_MSG_CHECKING([$_ax_check_text]) _AX_LUA_CHK_VER([$LUA], [$1], [$2], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([version is out of range for specified LUA])]) ax_display_LUA=$LUA ], [ dnl Try each interpreter until we find one that satisfies VERSION. m4_if([$2], [], [_ax_check_text="for a Lua interpreter with version >= $1"], [_ax_check_text="for a Lua interpreter with version >= $1, < $2"]) AC_CACHE_CHECK([$_ax_check_text], [ax_cv_pathless_LUA], [ for ax_cv_pathless_LUA in $_ax_lua_interpreter_list none; do test "x$ax_cv_pathless_LUA" = 'xnone' && break _AX_LUA_CHK_IS_INTRP([$ax_cv_pathless_LUA], [], [continue]) _AX_LUA_CHK_VER([$ax_cv_pathless_LUA], [$1], [$2], [break]) done ]) dnl Set $LUA to the absolute path of $ax_cv_pathless_LUA. AS_IF([test "x$ax_cv_pathless_LUA" = 'xnone'], [LUA=':'], [AC_PATH_PROG([LUA], [$ax_cv_pathless_LUA])]) ax_display_LUA=$ax_cv_pathless_LUA ]) ]) AS_IF([test "x$LUA" = 'x:'], [ dnl Run any user-specified action, or abort. m4_default([$4], [AC_MSG_ERROR([cannot find suitable Lua interpreter])]) ], [ dnl Query Lua for its version number. AC_CACHE_CHECK([for $ax_display_LUA version], [ax_cv_lua_version], [ dnl Get the interpreter version in X.Y format. This should work for dnl interpreters version 5.0 and beyond. ax_cv_lua_version=[`$LUA -e ' -- return a version number in X.Y format local _, _, ver = string.find(_VERSION, "^Lua (%d+%.%d+)") print(ver or "")'`] ]) AS_IF([test "x$ax_cv_lua_version" = 'x'], [AC_MSG_ERROR([invalid Lua version number])]) AC_SUBST([LUA_VERSION], [$ax_cv_lua_version]) AC_SUBST([LUA_SHORT_VERSION], [`echo "$LUA_VERSION" | $SED 's|\.||'`]) AM_COND_IF([LUAJIT], [ AC_CACHE_CHECK([for $ax_display_LUA jit version], [ax_cv_luajit_version], [ ax_cv_luajit_version=[`$LUA -e ' local _, _, ver = string.find(jit and jit.version, "(%d+%..+)") print(ver or "")'`] ]) AS_IF([test "x$ax_cv_luajit_version" = 'x'], [AC_MSG_ERROR([invalid Lua jit version number])]) AC_SUBST([LUAJIT_VERSION], [$ax_cv_luajit_version]) AC_SUBST([LUAJIT_SHORT_VERSION], [$(echo "$LUAJIT_VERSION" | $SED 's|\.|§|;s|\..*||;s|§|.|')]) ]) dnl The following check is not supported: dnl At times (like when building shared libraries) you may want to know dnl which OS platform Lua thinks this is. AC_CACHE_CHECK([for $ax_display_LUA platform], [ax_cv_lua_platform], [ax_cv_lua_platform=[`$LUA -e 'print("unknown")'`]]) AC_SUBST([LUA_PLATFORM], [$ax_cv_lua_platform]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of LUA_PREFIX and LUA_EXEC_PREFIX. These are made distinct dnl variables so they can be overridden if need be. However, the general dnl consensus is that you shouldn't need this ability. AC_SUBST([LUA_PREFIX], ['${prefix}']) AC_SUBST([LUA_EXEC_PREFIX], ['${exec_prefix}']) dnl Lua provides no way to query the script directory, and instead dnl provides LUA_PATH. However, we should be able to make a safe educated dnl guess. If the built-in search path contains a directory which is dnl prefixed by $prefix, then we can store scripts there. The first dnl matching path will be used. AC_CACHE_CHECK([for $ax_display_LUA script directory], [ax_cv_lua_luadir], [ AS_IF([test "x$prefix" = 'xNONE'], [ax_lua_prefix=$ac_default_prefix], [ax_lua_prefix=$prefix]) dnl Initialize to the default path. ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_prefix], [script]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. _ax_strip_prefix=`echo "$ax_lua_prefix" | $SED 's|.|.|g'` ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ $SED "s|^$_ax_strip_prefix|$LUA_PREFIX|"` ]) ]) AC_SUBST([luadir], [$ax_cv_lua_luadir]) AC_SUBST([pkgluadir], [\${luadir}/$PACKAGE]) dnl Lua provides no way to query the module directory, and instead dnl provides LUA_PATH. However, we should be able to make a safe educated dnl guess. If the built-in search path contains a directory which is dnl prefixed by $exec_prefix, then we can store modules there. The first dnl matching path will be used. AC_CACHE_CHECK([for $ax_display_LUA module directory], [ax_cv_lua_luaexecdir], [ AS_IF([test "x$exec_prefix" = 'xNONE'], [ax_lua_exec_prefix=$ax_lua_prefix], [ax_lua_exec_prefix=$exec_prefix]) dnl Initialize to the default path. ax_cv_lua_luaexecdir="$LUA_EXEC_PREFIX/lib/lua/$LUA_VERSION" dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_exec_prefix], [module]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | $SED 's|.|.|g'` ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ $SED "s|^$_ax_strip_prefix|$LUA_EXEC_PREFIX|"` ]) ]) AC_SUBST([luaexecdir], [$ax_cv_lua_luaexecdir]) AC_SUBST([pkgluaexecdir], [\${luaexecdir}/$PACKAGE]) dnl Run any user specified action. $3 ]) ]) dnl AX_WITH_LUA is now the same thing as AX_PROG_LUA. AC_DEFUN([AX_WITH_LUA], [ AC_MSG_WARN([[$0 is deprecated, please use AX_PROG_LUA instead]]) AX_PROG_LUA ]) dnl ========================================================================= dnl _AX_LUA_CHK_IS_INTRP(PROG, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_IS_INTRP], [ dnl A minimal Lua factorial to prove this is an interpreter. This should work dnl for Lua interpreters version 5.0 and beyond. _ax_lua_factorial=[`$1 2>/dev/null -e ' -- a simple factorial function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end print("fact(5) is " .. fact(5))'`] AS_IF([test "$_ax_lua_factorial" = 'fact(5) is 120'], [$2], [$3]) ]) dnl ========================================================================= dnl _AX_LUA_CHK_VER(PROG, MINIMUM-VERSION, [TOO-BIG-VERSION], dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_VER], [ dnl Check that the Lua version is within the bounds. Only the major and minor dnl version numbers are considered. This should work for Lua interpreters dnl version 5.0 and beyond. _ax_lua_good_version=[`$1 -e ' -- a script to compare versions function verstr2num(verstr) local _, _, majorver, minorver = string.find(verstr, "^(%d+)%.(%d+)") if majorver and minorver then return tonumber(majorver) * 100 + tonumber(minorver) end end local minver = verstr2num("$2") local _, _, trimver = string.find(_VERSION, "^Lua (.*)") local ver = verstr2num(trimver) local maxver = verstr2num("$3") or 1e9 if minver <= ver and ver < maxver then print("yes") else print("no") end'`] AS_IF([test "x$_ax_lua_good_version" = "xyes"], [$4], [$5]) ]) dnl ========================================================================= dnl _AX_LUA_FND_PRFX_PTH(PROG, PREFIX, SCRIPT-OR-MODULE-DIR) dnl ========================================================================= AC_DEFUN([_AX_LUA_FND_PRFX_PTH], [ dnl Get the script or module directory by querying the Lua interpreter, dnl filtering on the given prefix, and selecting the shallowest path. If no dnl path is found matching the prefix, the result will be an empty string. dnl The third argument determines the type of search, it can be 'script' or dnl 'module'. Supplying 'script' will perform the search with package.path dnl and LUA_PATH, and supplying 'module' will search with package.cpath and dnl LUA_CPATH. This is done for compatibility with Lua 5.0. ax_lua_prefixed_path=[`$1 -e ' -- get the path based on search type local searchtype = "$3" local paths = "" if searchtype == "script" then paths = (package and package.path) or LUA_PATH elseif searchtype == "module" then paths = (package and package.cpath) or LUA_CPATH end -- search for the prefix local prefix = "'$2'" local minpath = "" local mindepth = 1e9 string.gsub(paths, "(@<:@^;@:>@+)", function (path) path = string.gsub(path, "%?.*$", "") path = string.gsub(path, "/@<:@^/@:>@*$", "") if string.find(path, prefix) then local depth = string.len(string.gsub(path, "@<:@^/@:>@", "")) if depth < mindepth then minpath = path mindepth = depth end end end) print(minpath)'`] ]) dnl ========================================================================= dnl AX_LUA_HEADERS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_HEADERS], [ dnl Check for LUA_VERSION. AC_MSG_CHECKING([if LUA_VERSION is defined]) AS_IF([test "x$LUA_VERSION" != 'x'], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot check Lua headers without knowing LUA_VERSION]) ]) AM_COND_IF([LUAJIT],[ dnl Check for LUAJIT_VERSION. AC_MSG_CHECKING([if LUAJIT_VERSION is defined]) AS_IF([test "x$LUAJIT_VERSION" != 'x'], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot check Lua jit headers without knowing LUAJIT_VERSION]) ]) ]) dnl Make LUA_INCLUDE a precious variable. AC_ARG_VAR([LUA_INCLUDE], [The Lua includes, e.g. -I/usr/include/lua5.1]) dnl Some default directories to search. AM_COND_IF([LUAJIT], [_ax_lua_include_list=" /usr/include/luajit-$LUAJIT_VERSION /usr/include/luajit-$LUAJIT_SHORT_VERSION /usr/local/include/luajit-$LUAJIT_VERSION /usr/local/include/luajit-$LUAJIT_SHORT_VERSION"], [_ax_lua_include_list=" /usr/include/lua$LUA_VERSION /usr/include/lua-$LUA_VERSION /usr/include/lua/$LUA_VERSION /usr/include/lua$LUA_SHORT_VERSION /usr/local/include/lua$LUA_VERSION /usr/local/include/lua-$LUA_VERSION /usr/local/include/lua/$LUA_VERSION /usr/local/include/lua$LUA_SHORT_VERSION"]) dnl Try to find the headers. _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) AM_COND_IF([LUAJIT], [AC_CHECK_HEADERS([luajit.h])]) CPPFLAGS=$_ax_lua_saved_cppflags dnl Try some other directories if LUA_INCLUDE was not set. AS_IF([test "x$LUA_INCLUDE" = 'x' && test "x$ac_cv_header_lua_h" != 'xyes' || test "x$with_luajit" != 'xno' && test "x$ac_cv_header_luajit_h" != 'xyes'], [ dnl Try some common include paths. for _ax_include_path in $_ax_lua_include_list; do test ! -d "$_ax_include_path" && continue AC_MSG_CHECKING([for Lua headers in]) AC_MSG_RESULT([$_ax_include_path]) AS_UNSET([ac_cv_header_lua_h]) AS_UNSET([ac_cv_header_lualib_h]) AS_UNSET([ac_cv_header_lauxlib_h]) AS_UNSET([ac_cv_header_luaconf_h]) AS_UNSET([ac_cv_header_luajit_h]) _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$_ax_include_path" AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) AM_COND_IF([LUAJIT], [AC_CHECK_HEADERS([luajit.h])]) CPPFLAGS=$_ax_lua_saved_cppflags AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], [ LUA_INCLUDE="-I$_ax_include_path" break ]) done ]) AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], [ dnl Make a program to print LUA_VERSION defined in the header. dnl TODO It would be really nice if we could do this without compiling a dnl program, then it would work when cross compiling. But I'm not sure how dnl to do this reliably. For now, assume versions match when cross compiling. AS_IF([test "x$cross_compiling" != 'xyes'], [ AC_CACHE_CHECK([for Lua header version], [ax_cv_lua_header_version], [ _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" AC_COMPUTE_INT(ax_cv_lua_header_version_major,[LUA_VERSION_NUM/100],[AC_INCLUDES_DEFAULT #include ],[ax_cv_lua_header_version_major=unknown]) AC_COMPUTE_INT(ax_cv_lua_header_version_minor,[LUA_VERSION_NUM%100],[AC_INCLUDES_DEFAULT #include ],[ax_cv_lua_header_version_minor=unknown]) AS_IF([test "x$ax_cv_lua_header_version_major" = xunknown || test "x$ax_cv_lua_header_version_minor" = xunknown],[ ax_cv_lua_header_version=unknown ],[ ax_cv_lua_header_version="$ax_cv_lua_header_version_major.$ax_cv_lua_header_version_minor" ]) CPPFLAGS=$_ax_lua_saved_cppflags ]) dnl Compare this to the previously found LUA_VERSION. AC_MSG_CHECKING([if Lua header version matches $LUA_VERSION]) AS_IF([test "x$ax_cv_lua_header_version" = "x$LUA_VERSION"], [ AC_MSG_RESULT([yes]) ax_header_version_match='yes' ], [ AC_MSG_RESULT([no]) ax_header_version_match='no' ]) ], [ AC_MSG_WARN([cross compiling so assuming header version number matches]) ax_header_version_match='yes' ]) ]) dnl Was LUA_INCLUDE specified? AS_IF([test "x$ax_header_version_match" != 'xyes' && test "x$LUA_INCLUDE" != 'x'], [AC_MSG_ERROR([cannot find headers for specified LUA_INCLUDE])]) dnl Test the final result and run user code. AS_IF([test "x$ax_header_version_match" = 'xyes'], [$1], [m4_default([$2], [AC_MSG_ERROR([cannot find Lua includes])])]) ]) dnl AX_LUA_HEADERS_VERSION no longer exists, use AX_LUA_HEADERS. AC_DEFUN([AX_LUA_HEADERS_VERSION], [ AC_MSG_WARN([[$0 is deprecated, please use AX_LUA_HEADERS instead]]) ]) dnl ========================================================================= dnl AX_LUA_LIBS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_LIBS], [ dnl TODO Should this macro also check various -L flags? dnl Check for LUA_VERSION. AC_MSG_CHECKING([if LUA_VERSION is defined]) AS_IF([test "x$LUA_VERSION" != 'x'], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot check Lua libs without knowing LUA_VERSION]) ]) dnl Make LUA_LIB a precious variable. AC_ARG_VAR([LUA_LIB], [The Lua library, e.g. -llua5.1]) AS_IF([test "x$LUA_LIB" != 'x'], [ dnl Check that LUA_LIBS works. _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([lua_load], [], [_ax_found_lua_libs='yes'], [_ax_found_lua_libs='no']) LIBS=$_ax_lua_saved_libs dnl Check the result. AS_IF([test "x$_ax_found_lua_libs" != 'xyes'], [AC_MSG_ERROR([cannot find libs for specified LUA_LIB])]) ], [ dnl First search for extra libs. _ax_lua_extra_libs='' _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([exp], [m]) AC_SEARCH_LIBS([dlopen], [dl]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_exp" != 'xno' && test "x$ac_cv_search_exp" != 'xnone required'], [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_exp"]) AS_IF([test "x$ac_cv_search_dlopen" != 'xno' && test "x$ac_cv_search_dlopen" != 'xnone required'], [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_dlopen"]) dnl Try to find the Lua libs. _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AM_COND_IF([LUAJIT], [AC_SEARCH_LIBS([lua_load], [ luajit$LUA_VERSION \ luajit$LUA_SHORT_VERSION \ luajit-$LUA_VERSION \ luajit-$LUA_SHORT_VERSION \ luajit], [_ax_found_lua_libs='yes'], [_ax_found_lua_libs='no'], [$_ax_lua_extra_libs])], [AC_SEARCH_LIBS([lua_load], [ lua$LUA_VERSION \ lua$LUA_SHORT_VERSION \ lua-$LUA_VERSION \ lua-$LUA_SHORT_VERSION \ lua \ ], [_ax_found_lua_libs='yes'], [_ax_found_lua_libs='no'], [$_ax_lua_extra_libs])]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_lua_load" != 'xno' && test "x$ac_cv_search_lua_load" != 'xnone required'], [LUA_LIB="$ac_cv_search_lua_load $_ax_lua_extra_libs"]) ]) dnl Test the result and run user code. AS_IF([test "x$_ax_found_lua_libs" = 'xyes'], [$1], [m4_default([$2], [AC_MSG_ERROR([cannot find Lua libs])])]) ]) dnl ========================================================================= dnl AX_LUA_READLINE([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_READLINE], [ AX_LIB_READLINE AS_IF([test "x$ac_cv_header_readline_readline_h" != 'x' && test "x$ac_cv_header_readline_history_h" != 'x'], [ LUA_LIBS_CFLAGS="-DLUA_USE_READLINE $LUA_LIBS_CFLAGS" $1 ], [$2]) ]) hamlib-4.6.5/macros/ltoptions.m40000644000175000017500000003612115056640445012240 # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2024 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 10 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --enable-aix-soname configure option, and support the # `aix-soname=aix' and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. # DEFAULT is either `aix', `both', or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_ENABLE([aix-soname], [AS_HELP_STRING([--enable-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $enableval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --enable-aix-soname]) ;; esac lt_cv_with_aix_soname=$enable_aix_soname], [_AC_ENABLE_IF([with], [aix-soname], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)]) enable_aix_soname=$lt_cv_with_aix_soname]) with_aix_soname=$enable_aix_soname AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --enable-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_ENABLE([pic], [AS_HELP_STRING([--enable-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $enableval in yes|no) pic_mode=$enableval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $enableval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [dnl Continue to support --with-pic and --without-pic, for backward dnl compatibility. _AC_ENABLE_IF([with], [pic], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])])] ) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) hamlib-4.6.5/macros/ltsugar.m40000644000175000017500000001045315056640445011666 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2024 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) hamlib-4.6.5/macros/lt~obsolete.m40000644000175000017500000001400715056640445012556 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2024 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) hamlib-4.6.5/macros/gr_doxygen.m40000664000175000017500000000410115056640442012342 dnl dnl Copyright 2003 Free Software Foundation, Inc. dnl dnl This file is part of GNU Radio dnl dnl GNU Radio is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2, or (at your option) dnl any later version. dnl dnl GNU Radio is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with GNU Radio; see the file COPYING. If not, write to dnl the Free Software Foundation, Inc., 59 Temple Place - Suite 330, dnl Boston, MA 02111-1307, USA. dnl AC_DEFUN([GR_CHECK_DOXYGEN],[ AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)]) AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no]) if test "x$enable_doxygen" = xno; then enable_doc=no else AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) if test x$DOXYGEN = x; then if test "x$enable_doxygen" = xyes; then AC_MSG_ERROR([could not find doxygen]) fi enable_doc=no else enable_doc=yes AC_PATH_PROG(DOT, dot, , $PATH) fi fi AM_CONDITIONAL(DOC, test x$enable_doc = xyes) if test x$DOT = x; then if test "x$enable_dot" = xyes; then AC_MSG_ERROR([could not find dot]) fi enable_dot=no else enable_dot=yes fi AC_SUBST(enable_dot) AC_SUBST(enable_html_docs) AC_SUBST(enable_latex_docs) ]) hamlib-4.6.5/macros/Makefile.in0000664000175000017500000003747215056640452012022 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = macros ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUAJIT_SHORT_VERSION = @LUAJIT_SHORT_VERSION@ LUAJIT_VERSION = @LUAJIT_VERSION@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MACROS = \ ax_append_flag.m4 \ ax_cflags_warn_all.m4 \ ax_cxx_compile_stdcxx.m4 \ ax_lib_indi.m4 \ ax_lib_nova.m4 \ ax_lib_readline.m4 \ ax_lua.m4 \ ax_pkg_swig.m4 \ ax_pthread.m4 \ ax_python_devel.m4 \ gr_doxygen.m4 \ gr_pwin32.m4 \ hl_getaddrinfo.m4 \ perl.m4 \ tcl.m4 EXTRA_DIST = $(MACROS) MAINTAINERCLEANFILES = macros.dep all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu macros/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu macros/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -$(am__rm_f) $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile macros.dep: Makefile.am @echo '$$(top_srcdir)/aclocal.m4: $(MACROS:%=macros/%)' > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% hamlib-4.6.5/macros/hl_getaddrinfo.m40000664000175000017500000000627215056640442013161 # Check for getaddrinfo replacement. -*- Autoconf -*- # Copyright (c) 2010 by Stephane Fillod # # This file is part of Hamlib # # 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. AC_DEFUN([HL_GETADDRINFO], [ AC_CHECK_TYPES([struct addrinfo],[],[],[ #if HAVE_NETDB_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include #endif ]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #if HAVE_NETDB_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #elif HAVE_WS2TCPIP_H # include #endif #include ]], [[getaddrinfo("", "", NULL, NULL);]])], [ac_cv_func_getaddrinfo=yes AC_DEFINE(HAVE_GETADDRINFO,[1],[Define if getaddrinfo is available])], [ac_cv_func_getaddrinfo=no]) AC_CHECK_DECLS([gai_strerror], [], [], [[ #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_WS2TCPIP_H #include #endif #include ]]) dnl Checks for replacements AC_REPLACE_FUNCS([getaddrinfo]) AH_BOTTOM( [ /* Define missing prototypes, implemented in replacement lib */ #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_STRUCT_ADDRINFO #ifdef HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #elif HAVE_WS2TCPIP_H #include #endif struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; }; #endif #ifndef HAVE_GETADDRINFO #ifdef HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #elif HAVE_WS2TCPIP_H #include #endif #ifndef AI_PASSIVE #define AI_PASSIVE 0x0001 #endif int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); #endif #if !defined(HAVE_DECL_GAI_STRERROR) && !defined(gai_strerror) const char *gai_strerror(int errcode); #endif /* !HAVE_DECL_GAI_STRERROR */ #ifdef __cplusplus } #endif ]) ]) hamlib-4.6.5/macros/ax_pkg_swig.m40000664000175000017500000001515315056640442012510 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html # =========================================================================== # # SYNOPSIS # # AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found]) # # DESCRIPTION # # This macro searches for a SWIG installation on your system. If found, # then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is # found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd. # # You can use the optional first argument to check if the version of the # available SWIG is greater than or equal to the value of the argument. It # should have the format: N[.N[.N]] (N is a number between 0 and 999. Only # the first N is mandatory.) If the version argument is given (e.g. # 1.3.17), AX_PKG_SWIG checks that the swig package is this version number # or higher. # # As usual, action-if-found is executed if SWIG is found, otherwise # action-if-not-found is executed. # # In configure.in, use as: # # AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ]) # AX_SWIG_ENABLE_CXX # AX_SWIG_MULTI_MODULE_SUPPORT # AX_SWIG_PYTHON # # LICENSE # # Copyright (c) 2008 Sebastian Huber # Copyright (c) 2008 Alan W. Irwin # Copyright (c) 2008 Rafael Laboissiere # Copyright (c) 2008 Andrew Collier # Copyright (c) 2011 Murray Cumming # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 11 AC_DEFUN([AX_PKG_SWIG],[ # Ubuntu has swig 3.0 as /usr/bin/swig3.0 AC_PATH_PROGS([SWIG],[swig swig3.0]) if test -z "$SWIG" ; then m4_ifval([$3],[$3],[:]) elif test -n "$1" ; then AC_MSG_CHECKING([SWIG version]) [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] AC_MSG_RESULT([$swig_version]) if test -n "$swig_version" ; then # Calculate the required version number components [required=$1] [required_major=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_major" ; then [required_major=0] fi [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] [required_minor=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_minor" ; then [required_minor=0] fi [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] [required_patch=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_patch" ; then [required_patch=0] fi # Calculate the available version number components [available=$swig_version] [available_major=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_major" ; then [available_major=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_minor=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_minor" ; then [available_minor=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_patch=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_patch" ; then [available_patch=0] fi # Convert the version tuple into a single number for easier comparison. # Using base 100 should be safe since SWIG internally uses BCD values # to encode its version number. required_swig_vernum=`expr $required_major \* 10000 \ \+ $required_minor \* 100 \+ $required_patch` available_swig_vernum=`expr $available_major \* 10000 \ \+ $available_minor \* 100 \+ $available_patch` if test $available_swig_vernum -lt $required_swig_vernum; then AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.]) SWIG='' m4_ifval([$3],[$3],[]) else AC_MSG_CHECKING([for SWIG library]) SWIG_LIB=`$SWIG -swiglib` AC_MSG_RESULT([$SWIG_LIB]) m4_ifval([$2],[$2],[]) fi else AC_MSG_WARN([cannot determine SWIG version]) SWIG='' m4_ifval([$3],[$3],[]) fi fi AC_SUBST([SWIG_LIB]) ]) hamlib-4.6.5/macros/tcl.m40000664000175000017500000001005115056640442010760 #------------------------------------------------------------------------ # SC_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_TCLCONFIG], [ # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, [ --with-tcl=PATH directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -dr /usr/lib/tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_WARN(Can't find Tcl configuration definitions) else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} AC_MSG_RESULT(found $TCL_BIN_DIR/tclConfig.sh) fi fi ]) #------------------------------------------------------------------------ # SC_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Subst the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE # #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . $TCL_BIN_DIR/tclConfig.sh else AC_MSG_RESULT([file not found]) AC_MSG_ERROR([failed to load tclConfig.sh]) fi # # The eval is required to do the TCL_DBGX substitution in the # TCL_LIB_FILE variable # eval TCL_LIB_FILE=${TCL_LIB_FILE} eval TCL_LIB_FLAG=${TCL_LIB_FLAG} AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) ]) hamlib-4.6.5/macros/pkg.m40000644000175000017500000003067715056640445011000 # pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------ dnl dnl Prepare a "--with-" configure option using the lowercase dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and dnl PKG_CHECK_MODULES in a single macro. AC_DEFUN([PKG_WITH_MODULES], [ m4_pushdef([with_arg], m4_tolower([$1])) m4_pushdef([description], [m4_default([$5], [build with ]with_arg[ support])]) m4_pushdef([def_arg], [m4_default([$6], [auto])]) m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) m4_case(def_arg, [yes],[m4_pushdef([with_without], [--without-]with_arg)], [m4_pushdef([with_without],[--with-]with_arg)]) AC_ARG_WITH(with_arg, AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, [AS_TR_SH([with_]with_arg)=def_arg]) AS_CASE([$AS_TR_SH([with_]with_arg)], [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], [auto],[PKG_CHECK_MODULES([$1],[$2], [m4_n([def_action_if_found]) $3], [m4_n([def_action_if_not_found]) $4])]) m4_popdef([with_arg]) m4_popdef([description]) m4_popdef([def_arg]) ])dnl PKG_WITH_MODULES dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ----------------------------------------------- dnl dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES dnl check._[VARIABLE-PREFIX] is exported as make variable. AC_DEFUN([PKG_HAVE_WITH_MODULES], [ PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) AM_CONDITIONAL([HAVE_][$1], [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ])dnl PKG_HAVE_WITH_MODULES dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------------------ dnl dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make dnl and preprocessor variable. AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], [ PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES hamlib-4.6.5/macros/ax_lib_readline.m40000664000175000017500000000771315056640442013312 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_lib_readline.html # =========================================================================== # # SYNOPSIS # # AX_LIB_READLINE # # DESCRIPTION # # Searches for a readline compatible library. If found, defines # `HAVE_LIBREADLINE'. If the found library has the `add_history' function, # sets also `HAVE_READLINE_HISTORY'. Also checks for the locations of the # necessary include files and sets `HAVE_READLINE_H' or # `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or # 'HAVE_HISTORY_H' if the corresponding include files exists. # # The libraries that may be readline compatible are `libedit', # `libeditline' and `libreadline'. Sometimes we need to link a termcap # library for readline to work, this macro tests these cases too by trying # to link with `libtermcap', `libcurses' or `libncurses' before giving up. # # Here is an example of how to use the information provided by this macro # to perform the necessary includes or declarations in a C file: # # #ifdef HAVE_LIBREADLINE # # if defined(HAVE_READLINE_READLINE_H) # # include # # elif defined(HAVE_READLINE_H) # # include # # else /* !defined(HAVE_READLINE_H) */ # extern char *readline (); # # endif /* !defined(HAVE_READLINE_H) */ # char *cmdline = NULL; # #else /* !defined(HAVE_READLINE_READLINE_H) */ # /* no readline */ # #endif /* HAVE_LIBREADLINE */ # # #ifdef HAVE_READLINE_HISTORY # # if defined(HAVE_READLINE_HISTORY_H) # # include # # elif defined(HAVE_HISTORY_H) # # include # # else /* !defined(HAVE_HISTORY_H) */ # extern void add_history (); # extern int write_history (); # extern int read_history (); # # endif /* defined(HAVE_READLINE_HISTORY_H) */ # /* no history */ # #endif /* HAVE_READLINE_HISTORY */ # # LICENSE # # Copyright (c) 2008 Ville Laurikari # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6.1 # For Hamlib, set READLINE_LIBS instead of LIBS AU_ALIAS([VL_LIB_READLINE], [AX_LIB_READLINE]) AC_DEFUN([AX_LIB_READLINE], [ AC_CACHE_CHECK([for a readline compatible library], ax_cv_lib_readline, [ ORIG_LIBS="$LIBS" for readline_lib in readline edit editline; do for termcap_lib in "" termcap curses ncurses; do if test -z "$termcap_lib"; then TRY_LIB="-l$readline_lib" else TRY_LIB="-l$readline_lib -l$termcap_lib" fi LIBS="$ORIG_LIBS $TRY_LIB" AC_TRY_LINK_FUNC(readline, ax_cv_lib_readline="$TRY_LIB") if test -n "$ax_cv_lib_readline"; then break fi done if test -n "$ax_cv_lib_readline"; then break fi done if test -z "$ax_cv_lib_readline"; then ax_cv_lib_readline="no" fi LIBS="$ORIG_LIBS" ]) if test "$ax_cv_lib_readline" != "no"; then ORIG_LIBS="$LIBS" LIBS="$LIBS $ax_cv_lib_readline" AC_DEFINE(HAVE_LIBREADLINE, 1, [Define if you have a readline compatible library]) AC_CHECK_HEADERS(readline.h readline/readline.h) AC_CACHE_CHECK([whether readline supports history], ax_cv_lib_readline_history, [ ax_cv_lib_readline_history="no" AC_TRY_LINK_FUNC(add_history, ax_cv_lib_readline_history="yes") ]) if test "$ax_cv_lib_readline_history" = "yes"; then AC_DEFINE(HAVE_READLINE_HISTORY, 1, [Define if your readline library has \`add_history']) AC_CHECK_HEADERS(history.h readline/history.h) fi LIBS="$ORIG_LIBS" READLINE_LIBS="$ax_cv_lib_readline" AC_SUBST([READLINE_LIBS]) fi ])dnl hamlib-4.6.5/macros/ax_append_flag.m40000664000175000017500000000530415056640442013133 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) # # DESCRIPTION # # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space # added in between. # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly # FLAG. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_APPEND_FLAG], [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl AS_VAR_SET_IF(FLAGS, [case " AS_VAR_GET(FLAGS) " in *" $1 "*) AC_RUN_LOG([: FLAGS already contains $1]) ;; *) AC_RUN_LOG([: FLAGS="$FLAGS $1"]) AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) ;; esac], [AS_VAR_SET(FLAGS,["$1"])]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG hamlib-4.6.5/macros/ax_pthread.m40000664000175000017500000003036615056640442012330 # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 18 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) AC_MSG_RESULT($ax_pthread_ok) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($ax_pthread_ok) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], ax_cv_PTHREAD_PRIO_INHERIT, [ AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD hamlib-4.6.5/macros/gr_pwin32.m40000664000175000017500000000604215056640442012015 # Check for (mingw)win32 POSIX replacements. -*- Autoconf -*- # Copyright 2003 Free Software Foundation, Inc. # # This file is part of GNU Radio # # GNU Radio is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Radio 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Radio; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. AC_DEFUN([GR_PWIN32], [ AC_SEARCH_LIBS([nanosleep], [pthread]) AC_CHECK_HEADERS([pthread.h]) AC_CHECK_HEADERS([sys/types.h]) AC_CHECK_HEADERS([windows.h]) AC_CHECK_HEADERS([winioctl.h winbase.h], [], [], [ #if HAVE_WINDOWS_H #include #endif ]) AC_CHECK_FUNCS([getopt getopt_long usleep sleep nanosleep gettimeofday]) AC_CHECK_TYPES([struct timezone, ssize_t],[],[],[ #if HAVE_PTHREAD_H #include #endif #if HAVE_SYS_TYPES_H # include #endif #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif ]) dnl Checks for replacements AC_REPLACE_FUNCS([getopt getopt_long usleep gettimeofday]) AC_MSG_CHECKING(for Sleep) AC_LINK_IFELSE([AC_LANG_PROGRAM([ #include #include ], [ Sleep(0); ])], [AC_DEFINE(HAVE_SSLEEP,1,[Define to 1 if you have Windows Sleep]) AC_MSG_RESULT(yes)], AC_MSG_RESULT(no) ) AH_BOTTOM( [ /* Define missing prototypes, implemented in replacement lib */ #ifdef __cplusplus extern "C" { #endif #ifndef HAVE_GETOPT int getopt (int argc, char * const argv[], const char * optstring); extern char * optarg; extern int optind, opterr, optopt; #endif #ifndef HAVE_GETOPT_LONG struct option; int getopt_long (int argc, char * const argv[], const char * optstring, const struct option * longopts, int * longindex); #endif #ifndef HAVE_USLEEP int usleep(unsigned long usec); /* SUSv2 */ #endif #ifndef HAVE_GETTIMEOFDAY #ifdef HAVE_SYS_TIME_H #include #endif #ifndef HAVE_STRUCT_TIMEZONE struct timezone { int tz_minuteswest; int tz_dsttime; }; #endif int gettimeofday(struct timeval *tv, struct timezone *tz); #endif #ifndef timersub # define timersub(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #endif #ifndef HAVE_SSIZE_T typedef size_t ssize_t; #endif #ifdef __cplusplus } #endif ]) ]) hamlib-4.6.5/macros/perl.m40000664000175000017500000000304315056640442011143 #------------------------------------------------------------------------ # SC_PATH_PERLINC -- # # Locate the perl include files # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-perl-inc=... # # Defines the following vars: # PERL_INC_DIR Full path to the directory containing # the perl include files #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_PERLINC], [ # we reset no_perl in case something fails here no_perl=true AC_ARG_WITH(perl-inc, [ --with-perl-inc directory containing perl includes], with_perl_inc=${withval}) AC_MSG_CHECKING([for perl headers]) AC_CACHE_VAL(ac_cv_c_perl_inc,[ # First check to see if --with-perl-inc was specified. if test x"${with_perl_inc}" != x ; then if test -f "${with_perl_inc}/perl.h" ; then ac_cv_c_perl_inc=`(cd ${with_perl_inc}; pwd)` else AC_MSG_ERROR([${with_perl_inc} directory doesn't contain perl.h]) fi fi # then check for a private Perl installation if test x"${ac_cv_c_perl_inc}" = x ; then eval `perl -V:archlibexp` if test -f "${archlibexp}/CORE/perl.h" ; then ac_cv_c_perl_inc=`(cd ${archlibexp}/CORE; pwd)` else AC_MSG_WARN([${with_perl_inc} directory doesn't contain perl.h]) fi fi ]) if test x"${ac_cv_c_perl_inc}" = x ; then PERL_INC_DIR= AC_MSG_WARN(Can't find Perl header files) else no_perl= PERL_INC_DIR=${ac_cv_c_perl_inc} AC_MSG_RESULT(found $PERL_INC_DIR) fi AC_SUBST(PERL_INC_DIR) ]) hamlib-4.6.5/macros/ax_python_devel.m40000775000175000017500000003361515056640442013404 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_python_devel.html # =========================================================================== # # SYNOPSIS # # AX_PYTHON_DEVEL([version]) # # DESCRIPTION # # Note: Defines as a precious variable "PYTHON_VERSION". Don't override it # in your configure.ac. # # This macro checks for Python and tries to get the include path to # 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output # variables. It also exports $(PYTHON_EXTRA_LIBS) and # $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code. # # You can search for some particular version of Python by passing a # parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please # note that you *have* to pass also an operator along with the version to # match, and pay special attention to the single quotes surrounding the # version number. Don't use "PYTHON_VERSION" for this: that environment # variable is declared as precious and thus reserved for the end-user. # # This macro should work for all versions of Python >= 2.1.0. As an end # user, you can disable the check for the python version by setting the # PYTHON_NOVERSIONCHECK environment variable to something else than the # empty string. # # If you need to use this macro for an older Python version, please # contact the authors. We're always open for feedback. # # LICENSE # # Copyright (c) 2009 Sebastian Huber # Copyright (c) 2009 Alan W. Irwin # Copyright (c) 2009 Rafael Laboissiere # Copyright (c) 2009 Andrew Collier # Copyright (c) 2009 Matteo Settenvini # Copyright (c) 2009 Horst Knorr # Copyright (c) 2013 Daniel Mullner # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 32 AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL]) AC_DEFUN([AX_PYTHON_DEVEL],[ # # Allow the use of a (user set) custom python version # AC_ARG_VAR([PYTHON_VERSION],[The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path]) PYTHON_VERSION="" fi # # Check for a version of Python >= 2.1.0 # AC_MSG_CHECKING([for a version of Python >= '2.1.0']) ac_supports_python_ver=`$PYTHON -c "import sys; \ ver = sys.version.split ()[[0]]; \ print (ver >= '2.1.0')"` if test "$ac_supports_python_ver" != "True"; then if test -z "$PYTHON_NOVERSIONCHECK"; then AC_MSG_RESULT([no]) AC_MSG_FAILURE([ This version of the AC@&t@_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. ]) else AC_MSG_RESULT([skip at user request]) fi else AC_MSG_RESULT([yes]) fi # # If the macro parameter ``version'' is set, honour it. # A Python shim class, VPy, is used to implement correct version comparisons via # string expressions, since e.g. a naive textual ">= 2.7.3" won't work for # Python 2.7.10 (the ".1" being evaluated as less than ".3"). # if test -n "$1"; then AC_MSG_CHECKING([for a version of Python $1]) cat << EOF > ax_python_devel_vpy.py class VPy: def vtup(self, s): return tuple(map(int, s.strip().replace("rc", ".").split("."))) def __init__(self): import sys self.vpy = tuple(sys.version_info) def __eq__(self, s): return self.vpy == self.vtup(s) def __ne__(self, s): return self.vpy != self.vtup(s) def __lt__(self, s): return self.vpy < self.vtup(s) def __gt__(self, s): return self.vpy > self.vtup(s) def __le__(self, s): return self.vpy <= self.vtup(s) def __ge__(self, s): return self.vpy >= self.vtup(s) EOF ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \ ver = ax_python_devel_vpy.VPy(); \ print (ver $1)"` rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py* if test "$ac_supports_python_ver" = "True"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([this package requires Python $1. If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See ``configure --help'' for reference. ]) PYTHON_VERSION="" fi fi # # Check if you have distutils, else fail # AC_MSG_CHECKING([for the sysconfig Python package]) ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1` if test $? -eq 0; then AC_MSG_RESULT([yes]) IMPORT_SYSCONFIG="import sysconfig" else AC_MSG_RESULT([no]) AC_MSG_CHECKING([for the distutils Python package]) ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1` if test $? -eq 0; then AC_MSG_RESULT([yes]) IMPORT_SYSCONFIG="from distutils import sysconfig" else AC_MSG_ERROR([cannot import Python module "distutils". Please check your Python installation. The error was: $ac_sysconfig_result]) PYTHON_VERSION="" fi fi # # Check for Python include path # AC_MSG_CHECKING([for Python include path]) if test -z "$PYTHON_CPPFLAGS"; then if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then # sysconfig module has different functions python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('include'));"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_path ('platinclude'));"` else # old distutils way python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc ());"` plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \ print (sysconfig.get_python_inc (plat_specific=1));"` fi if test -n "${python_path}"; then if test "${plat_python_path}" != "${python_path}"; then python_path="-I$python_path -I$plat_python_path" else python_path="-I$python_path" fi fi PYTHON_CPPFLAGS=$python_path fi AC_MSG_RESULT([$PYTHON_CPPFLAGS]) AC_SUBST([PYTHON_CPPFLAGS]) # # Check for Python library path # AC_MSG_CHECKING([for Python library path]) if test -z "$PYTHON_LIBS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) ac_python_version=`cat<]], [[Py_Initialize();]]) ],[pythonexists=yes],[pythonexists=no]) AC_LANG_POP([C]) # turn back to default flags CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" LDFLAGS="$ac_save_LDFLAGS" AC_MSG_RESULT([$pythonexists]) if test ! "x$pythonexists" = "xyes"; then AC_MSG_FAILURE([ Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LIBS environment variable. Example: ./configure LIBS="-L/usr/non-standard-path/python/lib" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ ]) PYTHON_VERSION="" fi # # all done! # ]) hamlib-4.6.5/macros/Makefile.am0000664000175000017500000000077015056640442011777 ## Please update this variable if any new macros are created MACROS = \ ax_append_flag.m4 \ ax_cflags_warn_all.m4 \ ax_cxx_compile_stdcxx.m4 \ ax_lib_indi.m4 \ ax_lib_nova.m4 \ ax_lib_readline.m4 \ ax_lua.m4 \ ax_pkg_swig.m4 \ ax_pthread.m4 \ ax_python_devel.m4 \ gr_doxygen.m4 \ gr_pwin32.m4 \ hl_getaddrinfo.m4 \ perl.m4 \ tcl.m4 EXTRA_DIST=$(MACROS) MAINTAINERCLEANFILES=macros.dep @MAINT@macros.dep: Makefile.am @MAINT@ @echo '$$(top_srcdir)/aclocal.m4: $(MACROS:%=macros/%)' > $@ hamlib-4.6.5/macros/ax_lib_indi.m40000664000175000017500000000115315056640442012442 AU_ALIAS([VL_LIB_INDI], [AX_LIB_INDI]) AC_DEFUN([AX_LIB_INDI], [ AC_CACHE_CHECK([for INDI library], ax_cv_lib_indi, [ AC_LANG_PUSH(C++) AC_CHECK_HEADER(libindi/baseclient.h, ax_cv_lib_indi="-lindiclient -lstdc++ -lz") AC_LANG_POP() if test -z "$ax_cv_lib_indi"; then ax_cv_lib_indi="no" fi ]) if test "$ax_cv_lib_indi" != "no"; then ORIG_LIBS="$LIBS" LIBS="$LIBS $ax_cv_lib_indi" AC_DEFINE(HAVE_LIBINDI, 1, [Define if you have an INDI compatible library]) LIBS="$ORIG_LIBS" INDI_LIBS="$ax_cv_lib_indi" AC_SUBST([INDI_LIBS]) fi ]) hamlib-4.6.5/Makefile.am0000664000175000017500000000175015056640442010512 ## Process this file with automake to produce Makefile.in aclocaldir = $(datadir)/aclocal aclocal_DATA = hamlib.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = hamlib.pc EXTRA_DIST = PLAN LICENSE hamlib.m4 hamlib.pc.in README.md README.developer \ README.betatester README.freqranges README.multicast README.osx \ Android.mk doc_DATA = ChangeLog COPYING COPYING.LIB LICENSE \ README.md README.betatester README.developer SUBDIRS = macros include lib security \ $(BACKEND_LIST) \ $(RIG_BACKEND_LIST) \ $(ROT_BACKEND_LIST) \ $(AMP_BACKEND_LIST) \ security \ src \ $(BINDINGS) \ tests doc ## Static list of distributed directories. DIST_SUBDIRS = macros include lib src c++ bindings tests doc android scripts rotators/indi simulators\ security $(BACKEND_LIST) $(RIG_BACKEND_LIST) $(ROT_BACKEND_LIST) $(AMP_BACKEND_LIST) # Install any third party macros into our tree for distribution ACLOCAL_AMFLAGS = -I macros --install AM_CFLAGS=-D_TIME_BITS=64 -Winitializer-overrides hamlib-4.6.5/README0000664000175000017500000000007315056640442007333 See README.md Seems github required this README to be here hamlib-4.6.5/ChangeLog0000664000175000017500000000101015056640442010215 For a complete log of changes to Hamlib, please visit: http://sourceforge.net/p/hamlib/code/commit_browser Major changes in 4.0 affecting usage Most rig model numbers have changed RIG_LEVEL_VOX has been deprecated and replaced by RIG_LEVEL_VOXDELAY rigctl 'f' command now returns VFO argument too rigctl 'y' and 'Y' command now take/show antenna argument and option. range_list items are undergoing changes towards a different model TBD RTS/DTR PTT sharing is off by default now -- use serial_share=1 option to enable